{"_id":"@ahmedshaikh/code-search-mcp","name":"@ahmedshaikh/code-search-mcp","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@ahmedshaikh/code-search-mcp","version":"0.3.0","type":"module","description":"Semantic + lexical code search as an MCP server: tree-sitter chunking, local embeddings, SQLite + sqlite-vec, hybrid ranking.","bin":{"code-search":"dist/cli.js"},"engines":{"node":">=22"},"scripts":{"index":"tsx src/cli.ts index","search":"tsx src/cli.ts search","serve":"tsx src/server.ts","build":"tsc","test":"node --import tsx --test test/*.test.ts","eval":"tsx eval/run-eval.ts","prepare":"npm run build","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.0","@xenova/transformers":"^2.17.2","chokidar":"^5.0.0","ignore":"^5.3.0","sqlite-vec":"^0.1.9","tree-sitter-wasms":"^0.1.13","web-tree-sitter":"^0.22.6","zod":"^3.23.8"},"devDependencies":{"@types/node":"^20.11.0","tsx":"^4.7.0","typescript":"^5.4.0"},"license":"MIT","author":{"name":"ahmedshaikh"},"keywords":["mcp","model-context-protocol","claude","agent","ai","semantic-search","code-search","embeddings","sqlite-vec","tree-sitter"],"repository":{"type":"git","url":"git+https://github.com/RaziStuff/code-search-mcp.git"},"homepage":"https://github.com/RaziStuff/code-search-mcp#readme","bugs":{"url":"https://github.com/RaziStuff/code-search-mcp/issues"},"publishConfig":{"access":"public"},"gitHead":"451f227740775f84037f075c65ed762d9e328dc6","_id":"@ahmedshaikh/code-search-mcp@0.3.0","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-8jnNjaOIoyv+OqJmOgMsKuCp89nhaIw9FpmnicqGX63a5LtWnd4QUYlYck/4v3ydM2LnRHVhOdppiWyBZ+2oGw==","shasum":"302db1d091efb3678d670b22942fecb35e59983d","tarball":"https://registry.npmjs.org/@ahmedshaikh/code-search-mcp/-/code-search-mcp-0.3.0.tgz","fileCount":12,"unpackedSize":45408,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDoUOITjqjBRJIhWAIB2LX+NG4t4HFiSe7wemy9Fx9FDAiB7Yb3ZVqg53WfZGbfKvxvSFro87fAfquQcegwzktH8/Q=="}]},"_npmUser":{"name":"ahmedshaikh","email":"ahmed@shaikh1.com"},"directories":{},"maintainers":[{"name":"ahmedshaikh","email":"ahmed@shaikh1.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/code-search-mcp_0.3.0_1782701018408_0.691210891491735"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-29T02:43:38.220Z","0.3.0":"2026-06-29T02:43:38.537Z","modified":"2026-06-29T02:43:38.706Z"},"maintainers":[{"name":"ahmedshaikh","email":"ahmed@shaikh1.com"}],"description":"Semantic + lexical code search as an MCP server: tree-sitter chunking, local embeddings, SQLite + sqlite-vec, hybrid ranking.","homepage":"https://github.com/RaziStuff/code-search-mcp#readme","keywords":["mcp","model-context-protocol","claude","agent","ai","semantic-search","code-search","embeddings","sqlite-vec","tree-sitter"],"repository":{"type":"git","url":"git+https://github.com/RaziStuff/code-search-mcp.git"},"author":{"name":"ahmedshaikh"},"bugs":{"url":"https://github.com/RaziStuff/code-search-mcp/issues"},"license":"MIT","readme":"# code-search\n\n[![CI](https://github.com/RaziStuff/code-search-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/RaziStuff/code-search-mcp/actions/workflows/ci.yml)\n\nSemantic + lexical code search as an MCP server. Agents query in natural language\nand get back ranked `file:line` ranges to read precisely.\n\n## Quickstart\n\nRequires Node 22+ (for the built-in `node:sqlite`).\n\n```bash\ngit clone https://github.com/RaziStuff/code-search-mcp.git\ncd code-search-mcp\nnpm install      # builds automatically; first search downloads a ~90MB model once\n```\n\nIndex a project and search it — the `.code-index.db` is written next to the code:\n\n```bash\ncd /path/to/your/project\nnode /path/to/code-search-mcp/dist/cli.js index .\nnode /path/to/code-search-mcp/dist/cli.js search \"how is the request body parsed\"\n```\n\n`npm link` puts a `code-search` command on your PATH so you can drop the long\npath. To let a coding agent search for you, see [MCP server](#mcp-server) below.\n\n## How it works\n\n- **Chunking** — syntax-aware via `web-tree-sitter` (function / class / method\n  boundaries, with symbol names), heading-section chunks for markdown, and a\n  line-window fallback otherwise.\n- **Embeddings** — local `all-MiniLM-L6-v2` via transformers.js (384-dim, no API,\n  no code leaves the machine).\n- **Index** — SQLite + `sqlite-vec` (`.code-index.db`). Incremental: only files\n  whose content hash changed are re-embedded; deleted files are dropped. (A\n  change to chunker/embedder *logic* needs a full rebuild — delete the `.db` —\n  since incremental keys on file content, not code version.) Lockfiles, minified\n  bundles, and source maps are skipped so they don't swamp results.\n- **Ranking** — hybrid: vector KNN fused with BM25 (FTS5) via reciprocal rank\n  fusion, plus an extra-weighted exact-phrase list, a small code-over-prose\n  nudge, and a test-file down-weight, so exact symbol/token matches and\n  implementing code don't get lost behind embedding-friendly prose or their own\n  test files. Each\n  result's `score` is its true cosine similarity (0–1); when the top result is\n  below `CODE_SEARCH_MIN_SCORE` (default 0.25) the response is flagged\n  low-confidence so callers can detect \"no good match\". Confidence uses the best\n  cosine in the result set, and results are hybrid-ranked (#1 = best overall),\n  so the per-row cosine is a confidence annotation, not the sort key.\n- **Freshness** — optional chokidar watcher auto-reindexes on file changes.\n\n## Setup\n\n```bash\ncd code-search-mcp\nnpm install\n```\n\nNode 22+ required (built-in `node:sqlite`). First embed downloads the model\n(~90MB), cached locally.\n\n## CLI\n\n```bash\nnpm run index ../some-project    # incremental re-index\nnpm run search \"where are auth tokens validated\"\nnpm run watch ../some-project    # index, then auto-reindex on changes\n```\n\n## MCP server\n\n```bash\nCODE_SEARCH_ROOT=/path/to/project npm run serve\n# add CODE_SEARCH_WATCH=1 to auto-reindex on file changes\n```\n\nTools exposed: `search_code` (hybrid), `reindex` (incremental sync), and\n`index_status`. Register it with any MCP client — e.g.\n`claude mcp add code-search -- node /abs/path/dist/server.js` — or add a\n`.mcp.json` entry whose `command`/`args` point at `dist/server.js`. Set\n`CODE_SEARCH_WATCH=1` in its env to auto-reindex on file changes.\n\n## Tests\n\n```bash\nnpm test\n```\n\nUses Node's built-in `node:test` runner via `tsx` (no extra deps). Store /\nindexer / watcher tests use a deterministic `FakeEmbedder`, so the suite runs in\n~1s with no model download or network. Voyage is tested against a local mock\nHTTP server — no API key needed.\n\nRetrieval *quality* is measured separately:\n\n```bash\nnpm run eval\n```\n\nRuns a labeled query set (`eval/*.jsonl`) and reports hit@1 / hit@3 / MRR plus\nno-match accuracy — so ranking changes are measured, not eyeballed. Point it at\nany prebuilt index with `EVAL_FILE=… EVAL_DB=/path/.code-index.db EVAL_SYNC=0`.\n\n## Choosing an embedder\n\nDefault is local MiniLM (private, free). To use Voyage's code-tuned model:\n\n```bash\nexport CODE_SEARCH_EMBEDDER=voyage\nexport VOYAGE_API_KEY=...           # required\n# optional: VOYAGE_MODEL (voyage-code-3), VOYAGE_DIM (1024), VOYAGE_BASE_URL\n```\n\nCaveats: this **sends your code to api.voyageai.com** and costs per token.\nSwitching embedders changes the vector dimension, which the store detects and\n**wipes the index**, forcing a full re-embed (i.e. every chunk is sent to Voyage\non the next `index`/`reindex`). The local default sends nothing off-machine.\n\n## Version pin worth knowing\n\n`web-tree-sitter` is pinned to **0.22.6** to match the prebuilt grammars in\n`tree-sitter-wasms@0.1.13`. Newer web-tree-sitter (0.25+) changed its WASM ABI\nand can't load those grammars. Bump both together or neither.\n\n## Still to come\n\n- ANN indexing when `sqlite-vec` ships it — search is currently an exhaustive\n  (but fast, compiled-C) scan, fine into the tens of thousands of chunks.\n","readmeFilename":"README.md","_rev":"1-0bfda1f04341110dc56b7ce6825c0728"}