hybrid-coco
Local, self-contained code intelligence for AI agents. Index your codebase once, query it deterministically with the hc CLI and hc_* MCP tools — one install, no external services.
hybrid-coco ships everything in one component: SQLite storage, tree-sitter parsers, CLI, MCP server, host-native hooks, awareness, and agent skills. No embeddings, no vector database, no Docker, no companion tools.
pip install hybrid-coco && hc init
The problem it solves
When Claude reads a file to find one function, it pays for the entire file:
# Without hybrid-coco
Read("src/gitlab_helpers.py") > 12,140 tokens (whole file)
# With hybrid-coco
hc_file_context("src/gitlab_helpers.py") > 297 tokens (symbols only) < 97.6% savings
The hook intercepts native file-read / search tools (Read/Grep, or the host's equivalent) and suggests the equivalent hc_* tool. Same answer, fraction of the tokens.
How it works
Source files ──tree-sitter──► SQLite + FTS5 ──► CLI (hc)
│
└──────────────► MCP server (hc_*)
│
host-native hooks
intercept Read/Grep
(or host equivalent)
> suggest hc_* tools
hc index .: parses every source file with tree-sitter, extracts symbols (functions, classes, methods, imports) with their signatures, docstrings, and line numbers into a FTS5 trigram indexhc query / symbol / file-context / snippet: queries the index and returns structure or bounded source slices — not whole fileshc serve: exposes the same queries as MCP tools (hc_search,hc_symbol,hc_file_context,hc_snippet,hc_structure,hc_status)- Hooks:
hc initregisters host-native hooks that suggesthc_*tools whenever the agent is about to read or search an indexed file (hc init --host cursor|codex|opencode|devin, or--host all)
Benchmark
Measured on a real Rust codebase: 76 files, 2,242 symbols:
| Query | Baseline (full read / shell search) | hybrid-coco | Savings |
|---|---|---|---|
Symbol lookup (TimedExecution) |
2,227 tok | 51 tok | 97.7% |
Pattern search (savings) |
3,164 tok | 334 tok | 89.4% |
File structure (tracking.rs) |
12,140 tok | 1,245 tok | 89.7% |
Schema grep (CREATE TABLE) |
92 tok | 29 tok | 68.5% |
File read (git.rs) |
16,343 tok | 377 tok | 97.7% |
| Total (5 queries) | 33,966 tok | 2,036 tok | ~94% |
Baseline = recursive search plus reading whole files. hybrid-coco = hc symbol + hc query + hc file-context.
Quickstart
1. Install
Option A: One-line installer (recommended)
curl -fsSL https://raw.githubusercontent.com/jmeiracorbal/hybrid-coco/main/install.sh | bash
Installs hc and runs hc init (Claude Code by default). Other hosts: hc init --host cursor|codex|opencode|devin or --host all. Requires Python 3.11+ (detects uv, pipx, or pip automatically).
Option B: Claude Code plugin
claude plugin marketplace add jmeiracorbal/hybrid-coco
claude plugin install hybrid-coco@hybrid-coco
Registers the MCP server and hooks automatically. Requires hc in PATH — install the package first:
pip install hybrid-coco # or: uv tool install hybrid-coco
2. Index your project and register with an agent host
cd your-project/
hc init # Claude Code (default)
hc init --host cursor
hc init --host codex
hc init --host opencode
hc init --host devin
hc init --host all # every supported host
hc init does four things:
- Indexes the current directory (tree-sitter, SHA-256 incremental)
- Registers the MCP server in the host project config
- Installs host-native hooks that intercept
ReadandGrep(or the host's equivalent) - Installs host-adapted agent skills (
hybrid-coco,hc-init,hc-search) — same names, host-specific MCP paths, native tools, and hook events
Restart the agent host to activate.
3. Use from the agent
The MCP tools are now available in every conversation:
hc_search("savings_pct") # FTS5 search over names, signatures, docstrings
hc_symbol("TimedExecution") # exact/prefix symbol lookup → line range
hc_structure("function", lang=["rust"]) # tree-sitter shape search
hc_snippet("src/git.rs", 45, 67) # bounded source slice from disk
hc_file_context("src/git.rs") # all symbols in a file, structured
hc_status() # index stats
Invocable skills: /hc-init (setup/repair without full-reindex storms), /hc-search (choose the right hc_* query). The main hybrid-coco skill covers when to prefer hc_* over the host's native read/search tools.
The hooks will remind the agent (via the host's hook protocol) whenever it is about to read an indexed file directly.
Agent hosts
| Host | hc init |
MCP | Skills | Hooks |
|---|---|---|---|---|
| Claude Code | default | .claude/settings.json |
~/.claude/skills/ |
PreToolUse Read|Grep, PostToolUse Write|Edit |
| Cursor | --host cursor |
.cursor/mcp.json |
.cursor/skills/ + ~/.cursor/skills/ |
preToolUse Read|Grep, beforeReadFile, postToolUse Write|StrReplace, afterFileEdit, sessionStart |
| Codex | --host codex |
.codex/config.toml |
.agents/skills/ + ~/.agents/skills/ |
PreToolUse Bash (cat/head/rg/grep), PostToolUse apply_patch, SessionStart |
| OpenCode | --host opencode |
opencode.json |
.opencode/skills/ + ~/.config/opencode/skills/ |
plugin tool.execute.before/after (read/grep via filePath) |
| Devin | --host devin |
.devin/mcp_config.json |
.devin/skills/ + ~/.config/devin/skills/ |
.devin/hooks.v1.json (read/grep, Claude-compatible decision: block) |
Skills keep the same names on every host (hybrid-coco, hc-init, hc-search) so /hc-init and /hc-search still work. The SKILL.md body is host-adapted: MCP path, native tools to avoid, and only the hook events that host actually fires. Hooks never invent events a host does not support.
CLI reference
hc index [PATH] [--exclude PATTERN]...
Index PATH (default: cwd); optional exclude patterns
hc update [PATH] [--exclude PATTERN]...
Re-index only changed files (SHA-256 diff)
hc status [PATH] Index stats: files, symbols by kind, last update
hc query <TEXT> [--path P] [--lang L]... [--offset N] [--limit N]
FTS5 search; optional path/lang filters and pagination
hc symbol <NAME> [--path P] [--lang L]... [--offset N] [--limit N]
Exact name lookup, then prefix; same filters as query
hc file-context <PATH> All symbols in PATH grouped by kind (~97% savings vs cat)
hc snippet <PATH> <START> <END>
Read PATH lines START..END from disk (1-based, inclusive)
hc structure <KIND> [--path P] [--lang L]...
Structural search: function | method | class | import
hc doctor [PATH] Diagnostics: index, schema, languages, MCP/hooks, versions
hc reset [PATH] [-f] [--all]
Delete index DB; --all also drops project MCP entries
hc serve Start MCP server (stdio)
hc hook <HOST> <EVENT> Host lifecycle hook (JSON stdin/stdout)
hc init [PATH] [--host NAME]...
Index + .gitignore + register MCP/hooks/skills
--host: claude (default), cursor, codex, opencode, devin, all
--exclude accepts gitignore-style patterns and may be repeated. They are combined with exclude in .hybrid-coco/config.toml. If that file is missing, hc init, hc index, hc update, and hc doctor write the default and continue.
Project settings
If .hybrid-coco/config.toml is missing, hybrid-coco creates it with empty lists and keeps going. Edit the file afterwards to restrict paths or override languages. An existing invalid file is not overwritten — that fails until you fix it.
include = []
exclude = []
languages = {}
Example with restrictions:
include = ["src/**"]
exclude = ["**/generated/**"]
[languages]
".pyx" = "python"
".h" = "cpp"
include: gitignore-style patterns. Empty list = no include restriction. Non-empty = only matching paths are indexed.exclude: gitignore-style patterns, merged withhc index --exclude.languages: extension → parser language (python,rust,cpp, …). Overrides the built-in extension map.
hc reset deletes the index database and leaves config.toml in place. hc doctor writes the default file if it is missing, and fails if the existing file is invalid.
Supported languages
| Language | Parser |
|---|---|
| Python | tree-sitter-python |
| Rust | tree-sitter-rust |
| JavaScript | tree-sitter-javascript |
| TypeScript | tree-sitter-typescript |
| Go | tree-sitter-go |
| Java | tree-sitter-java |
| C | tree-sitter-c |
| C++ | tree-sitter-cpp |
| C# | tree-sitter-c-sharp |
| Kotlin | tree-sitter-kotlin |
| Swift | tree-sitter-swift |
Adding a language requires implementing a ~100-line parser in src/hybrid_coco/parsers/.
Design decisions
SQLite + FTS5, not a vector database: deterministic results, zero infrastructure, single file. Trigram search covers partial matches and is fast enough for codebases up to ~100K files. Semantic (embedding) search can be layered on top via sqlite-vec without changing the schema.
tree-sitter, not regex: symbol extraction is grammar-aware. Signatures and docstrings are extracted structurally, not by pattern matching.
No server process: hc serve runs as a stdio MCP server launched on demand by the agent host. There is no daemon to manage.
Incremental by default: hc update re-indexes only files whose SHA-256 has changed. Full re-index is only needed on first run or after .gitignore changes.
Boundaries
hybrid-coco is a single local component:
- SQLite storage in the project workspace
- tree-sitter parsers for symbol extraction
- CLI (
hc) for indexing and querying - MCP server (
hc_*) for Claude Code, Cursor, Codex, OpenCode, Devin, and other MCP hosts - hooks, awareness, and skills shipped with the package (
hc init --host)
It does not require companion services, external proxies, background daemons, or additional infrastructure.
Development
git clone https://github.com/jmeiracorbal/hybrid-coco
cd hybrid-coco
uv sync
uv pip install -e .
hc --version
Run tests:
uv run pytest
Run the benchmark against any indexed project:
cd path/to/project && hc index .
python scripts/benchmark.py path/to/project
Metadata
Release files for hybrid-coco 0.1.17
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| hybrid_coco-0.1.17.tar.gz | 139.1 kB | Without provenance | Details for hybrid_coco-0.1.17.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| hybrid_coco-0.1.17-py3-none-any.whl | Python 3 | none | any | Details for hybrid_coco-0.1.17-py3-none-any.whl |
Total release size: 252.0 kB
Release files / hybrid_coco-0.1.17.tar.gz
| Download URL | hybrid_coco-0.1.17.tar.gz |
|---|---|
| Size | 139.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f0ab15f394147777acf302db7a16c6d7a939b98187224980d2a85385be79382e
|
|
BLAKE2b-256 checksum How to use checksums |
00b08e5fa7dad19788d2bcc0af37152cf6025a4f398ae71c2e376feff73f0805
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / hybrid_coco-0.1.17-py3-none-any.whl
| Download URL | hybrid_coco-0.1.17-py3-none-any.whl |
|---|---|
| Size | 112.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
565fe6df43b840ab4c6a399838e4c5e11bc8b2254af834aadac869909bbd384a
|
|
BLAKE2b-256 checksum How to use checksums |
821605da23a5adc5a054ea787cc8454a34ef0a4e044cb8aba51e1a9987766f85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for hybrid-coco 0.1.17
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.