Its own description says to call the index first on an unfamiliar project, and the shape of everything else follows from that — the semantic context tool takes one file and walks its dependency tree rather than a directory, and search answers with paths and line numbers rather than bodies. The change tool is what makes it useful on a branch rather than a snapshot. Nothing here writes, so it pairs with an editing tool rather than replacing one.
A code-reading server that answers with structure rather than with file dumps: a gitignore-aware tree, a signature-only project index, a file together with its local dependency tree, text or regex search, and the diff since a git ref. It reads the filesystem and git directly — there is no vector database and no embedding API to set up.
- A signature-only map of the whole project: get_project_index returns exported functions, classes, interfaces and types with their signatures and no implementation bodies, with an option to widen it to non-exported symbols and a file pattern to narrow it.
- A tree that respects .gitignore: get_project_tree returns the repository structure, with depth and hidden-file controls.
- A file with the context around it: get_semantic_context returns a file's content along with its local dependency tree, with a depth for how far it follows imports and an outline-only mode that keeps the signatures and drops the bodies — enforced by the project's own benchmarks to be at most half the full length.
- Search that answers with locations: search_codebase matches text or a regex and returns file paths with line numbers, using ripgrep when it is installed and falling back to a pure Node scanner when it is not.
- What a branch changed: get_changed_files groups files as added, modified, deleted or renamed since a base ref, with line counts and optionally the full unified diff.
A checked-out repository the server can read, and git for the change tools. Nothing is configured as a credential. The depth of the analysis depends on the language: TypeScript and JavaScript get full signatures and import-chain traversal through the TypeScript compiler API; Python, Go and Rust get names without signatures and no dependency graph; other languages get the tree, the search and the raw file, and nothing structural. On a large repository, scope the index with a file pattern — its output grows with the number of exported symbols.
One command — npx synapse-code-mcp --root /path/to/your/project
