semantic-index
Uses Ollama's local embeddings model (nomic-embed-text) to power semantic code search by embedding code chunks and generating query embeddings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@semantic-indexfind where we validate logins and trace its callers"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
semantic-index
Semantic code search and call-graph tracing, exposed as a CLI and an MCP server, so any agent can use it — one that shells out (Claude Code, GitHub Copilot CLI, an internal "Pi agent CLI") or one that speaks MCP natively.
search "<query>"— finds code by meaning via local embeddings (Ollama,nomic-embed-text), not keyword matching.trace callers|callees <name>— call-graph lookups via a real tree-sitter AST parse, not regex.
Architecture
flowchart LR
subgraph Agents["Any agent"]
direction TB
A1["Claude Code"]
A2["GitHub Copilot CLI"]
A3["other agent CLIs"]
end
subgraph Tool["semantic-index"]
direction TB
CLI["CLI"]
MCP["MCP server (stdio)"]
ENGINE["search + trace engine"]
CLI --> ENGINE
MCP --> ENGINE
end
OLLAMA[("Ollama\nnomic-embed-text")]
AST["tree-sitter\nAST call graph"]
CODE[["your codebase"]]
A1 -. MCP .-> MCP
A1 -- shell --> CLI
A2 -- shell --> CLI
A3 -- shell --> CLI
ENGINE --> OLLAMA
ENGINE --> AST
OLLAMA --- CODE
AST --- CODEBoth surfaces call the same engine code (src/search/engine.ts, src/trace/engine.ts) — an MCP-native agent and a shell-only agent get identical results.
Related MCP server: codesteer-atlas
Why
AST tracing, not regex. Modeled loosely on grepai, which traces calls with per-language regex patterns — documented to miss arrow-function handlers. This tool parses with tree-sitter/tree-sitter-typescript and resolves identifier calls, import * as ns indirection, and this.method() calls structurally. Calls it can't resolve (dynamic dispatch, node_modules, barrel re-exports) go into an explicit unresolved list instead of being dropped, so "no callees" and "couldn't resolve" stay distinguishable.
Search, not detection. This only finds and ranks relevant code. It does not decide whether code is vulnerable. That's a deliberate boundary, not a missing feature — see docs/ARCHITECTURE.md.
Quickstart
npm install && npm run build
ollama pull nomic-embed-text
semantic-index init # parse + embed + build the call graph for this dir
semantic-index search "who validates a login" # requires init
semantic-index trace callers login # does not require init — builds the graph on the fly if needed
semantic-index agent-setup --with-subagent # writes CLAUDE.md, AGENTS.md, .github/copilot-instructions.md
semantic-index mcp # same engine, as an MCP server over stdioStatus
Proof of concept. 54 tests, all passing, no mocks:
44 unit tests — no external dependencies;
npm testand CI both run exactly this.10 e2e tests (
npm run test:e2e) — make real calls to a local Ollama instance and spawn the built CLI as an actual MCP subprocess. One of these tests indexes a sibling repo (../semantic-code-review) for an embedding-quality check and is skipped with a clear message if that repo isn't checked out next to this one.
Known limits
No vector index — still a brute-force scan of every stored chunk, no ANN structure. Embeddings are normalized to unit length at index-build time so each query does one dot product per chunk instead of full cosine math; untested at large scale.
Name/import-based call resolution, not points-to analysis — dynamic dispatch, higher-order calls, and barrel re-exports land in
unresolvedrather than being resolved (never silently dropped).Weaker same-file ranking —
nomic-embed-textcleanly separates unrelated domains (>0.5 score) but is measurably worse at ranking one helper among many similar ones in the same file. Search blends in a small function-name/query word-overlap boost to help (seesrc/search/lexical.ts) — a nudge, not a fix; the underlying model limitation is unchanged. Seetests/e2e/search.e2e.test.ts.No daemon —
watchre-parses the whole directory per change (re-embeds only what changed) and stops indexing when the process exits.
Full design rationale, including two real bugs found and fixed while validating this against ground-truth fixtures (anonymous functions invisible as callers; double-counted calls across nested callbacks), is in docs/ARCHITECTURE.md.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
An MCP server that gives your AI access to the source code and docs of all public github repos
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceLocal MCP server that provides semantic search (RAG) over code repositories, enabling AI clients like Claude and Gemini to access project context without manual re-upload.-
- AlicenseAqualityAmaintenanceLocal MCP server for semantic code search using Tree-sitter AST parsing, local embeddings, and hybrid search; enables indexing and querying codebases entirely offline.5MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for semantic code search and explanation. Allows AI agents to search, ask questions, and manage memory about a codebase with local embeddings and LLM integration.-
- FlicenseNot gradedqualityDmaintenanceGive your AI coding agents superpowers — a local MCP server for fast, token-efficient code navigation, search & analysis.-