{
  "markdown": "<div align=\"center\">\n\n![code-context: let your coding agent search, not crawl](docs/banner.png)\n\n[![CI](https://github.com/infino-ai/code-context/actions/workflows/ci.yml/badge.svg)](https://github.com/infino-ai/code-context/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@infino-ai/code-context?label=%40infino-ai%2Fcode-context&logo=npm)](https://www.npmjs.com/package/@infino-ai/code-context)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Node.js](https://img.shields.io/badge/Node.js-20%2B-green.svg)](https://nodejs.org/)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/infino-ai/code-context)\n\n</div>\n\n**code-context** is the retrieval layer under your coding agent: one local\nindex over the whole repo (keyword, semantic, hybrid, and SQL), reached\nthrough an MCP server and a CLI, with the index living in plain files inside\nyour repo. Your agent answers questions about the codebase without reading it\nfile by file.\n\nThe rule of thumb: the more a question spans the repo, the more this saves,\nbecause the answer comes from a ranked index instead of pulling source into\ncontext one file at a time.\n\n**On your own codebase, ~30-40% fewer tokens and ~50% fewer tool calls**\n(so answers land faster too - aggregation questions run about 2× quicker).\nThe harness is in the repo, so you can reproduce it on your own code.\n\n**Try it live (early preview):** ask questions about any public GitHub repo\nat [lantern.infino.ai](https://lantern.infino.ai), a demo agent that runs on\ncode-context.\n\n- 🔎 **Find code by words or meaning.** One ranked pass fuses exact keyword\n  matching with semantic similarity, and every hit carries the code with\n  `path:line` citations.\n- 📊 **Ask questions grep can't answer.** Search works as a SQL table\n  function, so \"which files have the most code about X\" is one query:\n  ranked by relevance, tallied by `GROUP BY`.\n- ⚡ **Searching in seconds, fresh forever.** The keyword index commits\n  before the embedding model even finishes downloading, vectors backfill in\n  the background, and edits re-sync incrementally: only changed files\n  re-chunk and re-embed.\n- 🔒 **Nothing leaves your machine.** No accounts, no API keys, no database\n  server, no telemetry. Embedding is a small local model, downloaded once;\n  after that everything works offline.\n\nBuilt on [infino](https://github.com/infino-ai/infino), a fast retrieval\nengine that runs SQL, full-text search, and vector search over a single copy\nof your data. Text and numeric data is stored as spec-compliant Parquet, and\nthe same engine handles logs, docs, and agent memory.\n\n![Claude Code using code-context: index a repo, then ask in plain English, and it reaches for search and SQL on its own](docs/demo.gif)\n\n<sub>Claude Code answering questions about a repo through code-context: index it, then ask, and it reaches for search and SQL on its own.</sub>\n\n## Quick start\n\nInstall the Claude Code plugin - nothing to paste into a config:\n\n```\n/plugin marketplace add infino-ai/code-context\n/plugin install code-context@infino-ai\n```\n\nIt registers code-context's three tools with `alwaysLoad` already set, so the\nagent keeps them in view and reaches for the index directly instead of falling\nback to plain file search.\n\nNot on Claude Code, or prefer a one-line command? Add it as an MCP server:\n\n```\nclaude mcp add-json code-context -s user '{\"command\":\"npx\",\"args\":[\"-y\",\"@infino-ai/code-context\",\"mcp\"],\"alwaysLoad\":true}'\n```\n\nThe `alwaysLoad` flag pins this small tool set so that in a setup with many MCP\nservers - where clients defer tool definitions behind a tool-search step - the\nagent doesn't miss the index and fall back to plain file search. (Use *either*\nthe plugin or this command, not both.)\n\nThen just ask a question about the code. The first `search` or `sql` on an\nunindexed repo builds the index inline and answers on the same call: keyword\nsearch is live in seconds, and vectors backfill in the background. (Prefer to\nkick it off yourself? The `reindex` tool does the same build on demand.)\n\nCI-tested on Linux x64 (glibc) and macOS arm64; linux-arm64, musl, and\nWindows-via-WSL are expected to work through the engine's prebuilt bindings\nbut are not CI-covered.\n\n## Evaluation\n\nReal agent runs over a codebase-Q&A suite (claude-sonnet-4-6, the same\nminimal prompt for both lanes), on a repo the model has not memorized -\n[infino](https://github.com/infino-ai/infino), the engine this is built on -\nbecause that is the realistic case for your private code. Baseline is stock\nfile tools including Bash; the code-context lane is the same tools plus the\nMCP server. Measured on three axes:\n\n![code-context vs stock file tools: tool calls, wall time, and tokens](docs/benchmark-chart.png)\n\n| Category | Tokens | Tool calls | Wall time |\n|---|---|---|---|\n| Aggregation (\"most code about X\") | **-43%** | **-71%** | **-48%** |\n| Comprehension (\"how does X work\") | **-29%** | **-27%** | **-13%** |\n| Blended | **-32%** | **-53%** | **-32%** |\n\nAggregation is the structural win - ranked search composed with `GROUP BY`,\nwhich file tools cannot express at any budget - and it roughly halves\nend-to-end time. These numbers are on a strong model; weaker, cheaper models\nexplore less efficiently, so the savings tend to be **larger** there. On\npinpoint symbol lookup, where a single grep is already cheap, an index\nmatches file tools rather than beating them.\n\nFull methodology and per-question tables are in\n[docs/benchmark.md](docs/benchmark.md), with the harness in\n[`bench/`](bench/) so you can run the same lanes on your own repo.\n\n## What you get\n\nOne index and a deliberately small tool surface for agents:\n\n| Tool | What it does | When agents use it |\n|---|---|---|\n| `search` | One ranked pass fusing exact keyword matching (BM25) with semantic similarity (reciprocal-rank fusion). Hits carry the chunk content, so answers come straight from results. | A strong default for finding and understanding code: how a subsystem works, code by meaning or exact term, context before a change, similar implementations - exact identifiers and paraphrases in the same call. |\n| `sql` | Read-only SQL over the index, with the ranked search functions (`bm25_search`/`hybrid_search`) usable as table-valued relations. | Counts, rankings, aggregates over the whole repo in one query. |\n| `reindex` | Incremental sync (the server also auto-syncs in the background). | After significant edits. |\n\nThree tools is a deliberate design: one way to find, one way to count, one\nway to stay fresh. Every additional near-duplicate retrieval tool worsens an\nagent's tool selection, and hybrid search's keyword half already ranks\nexact identifier terms highly, so a separate lexical tool has no job left.\n\n### The SQL move\n\nSearch-as-a-table composes with aggregation. Ranked by relevance, tallied by\nSQL, one engine pass:\n\n```sql\nSELECT path, SUM(end_line - start_line + 1) AS lines, COUNT(*) AS chunks\nFROM bm25_search('chunks', 'content', 'vector index quantization', 300)\nGROUP BY path ORDER BY lines DESC LIMIT 15\n```\n\n`hybrid_search(...)` and `vector_search(...)` work the same way. The CLI and\nMCP server embed `{{name}}` placeholders server-side, so agents never handle\nraw vectors.\n\n### Staged readiness\n\n`cx index` commits the keyword (BM25) index first. On a ~3,000-chunk repo\nthat takes under a second, so search works before any embedding model even\nexists on the machine. Vectors backfill in the background with a local model\n(downloaded once, no key; about two minutes for that same repo), and\nhybrid/semantic ranking unlocks automatically when they land. If the vector\nstage fails, keyword search stays live and the index says so honestly.\n\nThe default model optimizes quality-per-minute. See\n[docs/embedder-eval.md](docs/embedder-eval.md) for how it was chosen.\n\n### Your index is just files\n\nEverything lives in `.infino/` in your repo root (added to your\n`.gitignore` automatically on first index): plain files you can copy,\ncache in CI, or put on object storage. It's a live index the engine queries in place, not a snapshot you\nexport and pass around.\n\n## Setup for agents\n\ncode-context is an MCP server over stdio, so any MCP client works. Register\nit once and the tools (`search`, `sql`, `reindex`) become available to the\nagent.\n\n<details>\n<summary><strong>Claude Code</strong></summary>\n\n**Install as a plugin** - `alwaysLoad` already set, nothing to paste into a\nconfig:\n\n```\n/plugin marketplace add infino-ai/code-context\n/plugin install code-context@infino-ai\n```\n\n**Or register it as an MCP server** directly:\n\n```bash\nclaude mcp add-json code-context -s user '{\"command\":\"npx\",\"args\":[\"-y\",\"@infino-ai/code-context\",\"mcp\"],\"alwaysLoad\":true}'\n```\n\n`alwaysLoad: true` pins code-context's tools into context so the agent reaches\nfor the index directly. In sessions with many MCP servers Claude Code defers\ntool definitions behind a tool-search step; without `alwaysLoad` the agent can\nmiss code-context and fall back to grep/read. It's a small, always-loaded set\n(three tools). Omit it (or use the shorter `claude mcp add code-context -- npx\n-y @infino-ai/code-context mcp`) if you'd rather leave the tools deferred.\n\nUse *either* the plugin or the `add-json` command, not both. They register the\nsame `code-context` server, so running both just collides.\n\n**For a team,** commit a project-scoped `.mcp.json` at the repo root so\neveryone gets it (after the one-time project-server approval):\n\n```json\n{ \"mcpServers\": { \"code-context\": { \"command\": \"npx\", \"args\": [\"-y\", \"@infino-ai/code-context\", \"mcp\"], \"alwaysLoad\": true } } }\n```\n\n</details>\n\n<details>\n<summary><strong>Cursor</strong></summary>\n\nAdd to `.cursor/mcp.json`:\n\n```json\n{ \"mcpServers\": { \"code-context\": { \"command\": \"npx\", \"args\": [\"-y\", \"@infino-ai/code-context\", \"mcp\"] } } }\n```\n\n</details>\n\n<details>\n<summary><strong>Codex CLI</strong></summary>\n\nIn `~/.codex/config.toml` (note the key is `mcp_servers`):\n\n```toml\n[mcp_servers.code-context]\ncommand = \"npx\"\nargs = [\"-y\", \"@infino-ai/code-context\", \"mcp\"]\n```\n\n</details>\n\n<details>\n<summary><strong>Gemini CLI</strong></summary>\n\nIn `~/.gemini/settings.json`:\n\n```json\n{ \"mcpServers\": { \"code-context\": { \"command\": \"npx\", \"args\": [\"-y\", \"@infino-ai/code-context\", \"mcp\"] } } }\n```\n\n</details>\n\n<details>\n<summary><strong>Windsurf, Cline, and other MCP clients</strong></summary>\n\nStandard stdio MCP config:\n\n```json\n{ \"mcpServers\": { \"code-context\": { \"command\": \"npx\", \"args\": [\"-y\", \"@infino-ai/code-context\", \"mcp\"] } } }\n```\n\nPoint the server at a repo explicitly with `env: { \"CX_ROOT\": \"/path/to/repo\" }`\nwhen the client's working directory is not the repo.\n\n</details>\n\nTools: `search`, `sql`, `reindex` (incremental sync: an unchanged repo is\na fast no-op, and the server also auto-syncs in the background as queries\narrive, so results track your edits without anyone asking).\n\n**Multiple repos in one session.** Each tool takes an optional `path` (an\nabsolute repo root). Omit it and the server uses its startup root; set it to\ntarget a specific repo when a session spans more than one. One server\ninstance serves them all, each with its own index in its own `.infino/` -\nno restart, no per-repo config.\n\n## Configuration\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `CX_INDEX_DIR` | `<repo>/.infino` | where the index lives |\n| `CX_SEARCH_K` | 10 | default number of hits `search` returns (also settable per call and via the CLI `-k` flag) |\n| `CX_MAX_FILES` / `CX_MAX_FILE_BYTES` | 20000 / 1MB | indexing caps (files over the file cap are left out; `search`/`sql` then flag the index as partial so an absence isn't read as proof) |\n| `CX_ROOT` | current directory | default repo root for the MCP server / CLI when not run from the repo (each tool call can override it with a `path` argument) |\n| `CX_AUTO_INDEX` | on | `0` makes a query on an unindexed repo error instead of building the index inline on the first `search`/`sql` |\n| `CX_AUTO_SYNC` | on | `0` disables the MCP server's background staleness sync |\n| `CX_SYNC_INTERVAL_SECS` | 30 | auto-sync debounce between staleness checks |\n| `CX_NO_EMBED` | off | keyword-only mode for the MCP server (skip the vector stage) |\n| `CX_NO_RECEIPT` | off | `1` turns off usage accounting - the per-call receipt on results and the `cx usage` ledger |\n\nEvery `search` / `sql` result carries a **usage receipt** - a terse, local line\nshowing the tokens it returned, the files it spanned, and a running session\ntotal (e.g. `returned ~1.2k tokens | 4 chunks / 3 files | session ~8.4k over 7\nqueries`). Every figure is a `~` estimate, computed in-process - nothing about\nyour queries or code leaves the machine.\n\n## CLI\n\nThe same index is reachable from the terminal too, for scripting, CI, or\ninspecting results yourself. Install the binary, then run any command inside\na repo:\n\n```\nnpm install -g @infino-ai/code-context\n```\n\n```\ncx index [path]           sync the index (incremental; --full rebuilds, --watch follows edits)\ncx search <query>         exact terms + meaning, one ranked pass           (-k hits)\ncx sql <statement>        read-only SQL; --embed q=\"text\" fills {{q}}\ncx status                 what the index holds, how fresh, vector readiness\ncx usage                  ledger of queries run and what each returned  (-n, --all, --clear, --json)\ncx mcp                    serve the MCP tools over stdio\n```\n\n`cx usage` reads the local ledger at `.infino/usage.jsonl` - every `search` /\n`sql` (from the CLI or the MCP server) appends one line recording the query and\na compact summary of what came back (paths and line ranges for search, row\ncount for sql), plus the token figures from the receipt. It's a deterministic,\nmodel-independent view of what went through the index - no running server or\nagent needed to read it back. `CX_NO_RECEIPT=1` turns off both the inline\nreceipt and this ledger.\n\n### How often does the agent actually reach for it?\n\n`cx usage` can also show, per session, in how many of your prompts code-context\nwas used - e.g. `code-context used in 2 of 3 prompts (2 calls)`. The MCP server\ncan only count its own calls, not your prompts, so this ratio comes from two\nClaude Code hooks that keep a local tally (nothing is sent anywhere). Add them\nto your Claude Code settings (`~/.claude/settings.json` or a project\n`.claude/settings.json`):\n\n```json\n{\n  \"hooks\": {\n    \"UserPromptSubmit\": [\n      { \"hooks\": [{ \"type\": \"command\", \"command\": \"cx usage --hook\" }] }\n    ],\n    \"PostToolUse\": [\n      { \"matcher\": \"mcp__code-context.*\", \"hooks\": [{ \"type\": \"command\", \"command\": \"cx usage --hook\" }] }\n    ]\n  }\n}\n```\n\n`cx usage --hook` reads the event on stdin, updates `.infino/prompt-stats.json`,\nand prints nothing. If you run code-context via `npx`, use\n`npx -y @infino-ai/code-context usage --hook` as the command.\n\n## What it is, and what it isn't\n\ncode-context's lane is ranked **content** retrieval and content-relevance\naggregation: find code by words or meaning, rank whole files by how much\nthey're about a topic, always with `path:line` receipts. It deliberately\ndoes **not** do structural code intelligence (call-graph tracing, dead-code\ndetection, type resolution). Tools that do are complementary: MCP servers\nstack, so run both.\n\n## Architecture\n\n![How code-context fits together: your coding agent reaches code-context through a CLI and an MCP server, code-context runs the infino engine in-process, and the index lives as plain files in your repo](docs/architecture.png)\n\n- **Chunking:** tree-sitter (WASM, no native compiles) cuts at definition\n  boundaries for TypeScript/JS, Python, Rust, Go, Java, C/C++, Ruby, C#, PHP;\n  Markdown splits at headings; everything else falls back to fixed windows.\n  Every chunk carries `path, start_line, end_line, lang, content`.\n- **Index:** [infino](https://github.com/infino-ai/infino) tables in\n  `.infino/`: BM25 (FTS) and IVF vector indexes over a single copy of the\n  data, queried in-process through the Node binding. No server.\n- **Embeddings:** always local. A small model (chosen by a\n  [measured eval](docs/embedder-eval.md)) downloaded once; no key, no\n  per-query network, code never leaves the machine. Queries embed with the\n  same model the index was built with, and a mismatch is a clear error, not\n  silently wrong results.\n- **Freshness:** incremental by design. A per-file state map (size/mtime\n  prefilter, then content hash) means a sync re-chunks and re-embeds only\n  the files that changed: on a ~3,000-chunk repo an unchanged tree checks\n  in ~20ms and a one-file edit syncs in ~0.7s with vectors kept current\n  (larger-repo numbers in the [benchmark](docs/benchmark.md)). The MCP\n  server auto-syncs in the background as queries arrive (never blocking a\n  query), `cx index` is incremental by default (`--full` to rebuild), and\n  `cx index --watch` syncs on file events.\n\n## Learn more\n\n- [Code search for coding agents](docs/concepts/code-search-for-coding-agents.md) - the crawl-vs-retrieve model and when an index saves tokens.\n- [FAQ](docs/faq.md) - what it is, when to use it, local-only guarantees, freshness.\n- [Tradeoffs](docs/tradeoffs.md) - the honest limits.\n- [Benchmark](docs/benchmark.md) - measured results, with a harness to reproduce them on your own repo.\n\n## License\n\nApache-2.0\n",
  "bytes": 17296,
  "sha": "131f98526bc868eba56a378404cbdd1bd0fdf9585e01a4ae21db123187be1928",
  "repo_slug": "infino-ai/code-context",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_infino_ai_code_context_24f57d4a/readme"
}