Back to MCP Servers

Synapse Code

Structural code context server for AI agents — compressed symbol indexes, dependency graphs, and git diffs via TypeScript AST analysis. Zero external dependencies, no vector database or embedding API required.

developer-toolstypescriptapiaiembeddingagent
By Eltortilla1
31Updated 1 week agoTypeScriptMIT

Installation

npx -y synapse-code-mcp

Configuration

{
  "mcpServers": {
    "synapse-code-mcp": {
      "command": "npx",
      "args": ["-y", "synapse-code-mcp"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes
<p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="docs/logo-dark.png"> <source media="(prefers-color-scheme: light)" srcset="docs/logo-light.png"> <img alt="Synapse MCP" src="docs/logo-light.png" width="500"> </picture> </p>

Synapse MCP

CI License: MIT Node ≥ 18 Tests: 301

A structural code context server that connects your local repository to AI assistants via the Model Context Protocol.

Instead of copy-pasting files into a prompt, Synapse lets your AI assistant dynamically explore your codebase — pulling only the code it needs, when it needs it. The result: less context waste, smarter answers, and a workflow that scales to large projects — with no vector database or embedding API to set up.

AI Assistant  ──MCP──►  Synapse MCP  ──fs/git──►  Your Repository
   (pulls)               (server)                   (local)

Status: Early-stage, actively developed. Contributions and bug reports are welcome — see Contributing.


Why Synapse?

Most AI coding tools already index files. Synapse solves a different problem: context quality at scale.

ProblemSynapse solution
Reading an entire file when you only need its API surfaceget_semantic_context with outline_only — signatures only, ≤ 50% of full content
AI doesn't know what files exist in an unfamiliar projectget_project_index — full symbol map at ≤ 40% of raw source size, one call
"Review my changes" requires pasting the diff manuallyget_changed_files — structured git diff, git-aware by default
Dependency rabbit holes filling the context windowConfigurable depth cap on import traversal

The compression ratios above are enforced as automated test budgets — not marketing estimates.

Why not vector embeddings?

Most code-context MCP servers use semantic search backed by a vector database (e.g. Milvus, Qdrant) and an embedding API (OpenAI, VoyageAI). That gives them a real capability Synapse doesn't have: finding code by conceptual meaning ("find the authentication logic") rather than by structure or text.

Synapse trades that capability for a different set of properties:

  • Zero external dependencies — no API keys, no vector database, no embedding provider to configure
  • Zero recurring cost — no per-token embedding charges, no hosted database bill
  • Fully local and deterministic — the same input always produces the same output, nothing leaves your machine, nothing to index ahead of time
  • Instant on any repo — no indexing step before first use (see Performance: 120–257 ms on real repos)

If you need natural-language semantic search across millions of lines in many languages, a vector-backed server is the better tool. If you want structural context (signatures, dependency graphs, diffs) without standing up infrastructure, Synapse is built for that.


Tools

get_project_index

Returns a compressed semantic map of the entire project: all exported functions, classes, interfaces, types, enums, and top-level constants with their signatures — no bodies. The right first call when exploring an unfamiliar codebase.

# Project Index: my-app (47 files, 312 symbols)

## src/services/user-service.ts
  UserService (class) [export]
    constructor(db: Database)
    findById(id: string): Promise<User | null>
    create(data: CreateUserDto): Promise<User>

## src/models/user.ts
  User (interface) [export]
    id: string
    email: string
    createdAt: Date
  createUser(data: Partial<User>): User [export]

Parameters: file_pattern (glob to narrow scope), include_non_exported, output_format ("markdown" default · "json" for structured output)

Use output_format: "json" to get the raw symbol data as a structured object, which is easier to post-process programmatically:

{
  "root": "/path/to/project",
  "totalFiles": 47,
  "totalSymbols": 312,
  "files": [
    {
      "relativePath": "src/services/user-service.ts",
      "language": "typescript",
      "symbols": [...]
    }
  ]
}

Large projects: output grows linearly with the number of exported symbols. For monorepos or projects with 500+ files, use file_pattern to scope the index to one area at a time — e.g. "src/services/**/*.ts".


get_semantic_context

Returns a file's content alongside its local dependency graph — everything the AI needs to understand the code in context.

Add outline_only: true to get signatures without implementation bodies. Output is enforced by the benchmark suite to be ≤ 50% of full content length, while preserving full structural understanding.

Parameters: file_path (required), depth (import hops, default: 2), outline_only, output_format ("markdown" default · "json" for structured output)


get_changed_files

Lists files changed since a git ref, grouped by status (Added / Modified / Deleted / Renamed), with optional line counts and full unified diff.

Changed files since `main` (8 files):

**Added (2):**
  src/services/payment.ts (+120 −0)
  tests/unit/payment.test.ts (+89 −0)

**Modified (5):**
  src/models/order.ts (+14 −3)
  ...

**Summary:** +245 −18 lines

Parameters: base_ref (default: HEAD~1), include_diff, file_pattern


get_project_tree

Structured view of the repository, respecting .gitignore rules.

Parameters: path, max_depth, show_hidden


search_codebase

Fast text or regex search across the project, returning matches with file paths and line numbers. Uses ripgrep when available, falls back to a pure Node.js scanner.

Parameters: query (required), file_pattern, is_regex, max_results


Language support

Synapse uses ts-morph (TypeScript compiler API) for deep analysis of TypeScript and JavaScript. For other languages, it applies regex-based extraction of function and class names.

FeatureTypeScript / JSPython · Go · RustOther
get_project_tree
search_codebase
get_semantic_context — full source
get_semantic_context — dependency graph
get_semantic_context outline_only✓ full signatures✓ names only
get_project_index✓ full signatures✓ names only

Dependency graph traversal (following import/require chains) is TypeScript/JavaScript only. For all other languages, Synapse still reads and searches files normally — it just won't walk the import graph.

Note: dependency graph traversal follows both relative imports (./foo, ../bar) and path aliases configured via tsconfig.json compilerOptions.paths (e.g. @/components/Foo), as long as a tsconfig.json is present at the project root. Projects without a tsconfig.json fall back to relative-only resolution.


Installation

Global install (recommended):

npm install -g synapse-code-mcp

Run without installing:

npx synapse-code-mcp --root /path/to/your/project

Setup

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "synapse": {
      "command": "npx",
      "args": ["synapse-code-mcp", "--root", "/absolute/path/to/your/project"]
    }
  }
}

Claude Code (CLI)

claude mcp add synapse -- npx synapse-code-mcp --root /path/to/your/project

Or add directly to ~/.claude/settings.json:

{
  "mcpServers": {
    "synapse": {
      "command": "npx",
      "args": ["synapse-code-mcp", "--root", "/path/to/your/project"]
    }
  }
}

Cursor

Add to .cursor/mcp.json in your home directory or project root:

{
  "mcpServers": {
    "synapse": {
      "command": "npx",
      "args": ["synapse-code-mcp", "--root", "/path/to/your/project"]
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "synapse": {
      "command": "npx",
      "args": ["synapse-code-mcp", "--root", "/path/to/your/project"]
    }
  }
}

Tip: Replace /path/to/your/project with the absolute path to the repository you want to serve. You can run multiple Synapse instances — one per project — each with a different key under mcpServers.


Configuration

CLI flags

Options:
  --root <path>                  Project root directory (default: cwd)
  --max-file-size <bytes>        Skip files larger than this (default: 524288 = 512 KB)
  --max-search-results <n>       Cap on search results returned (default: 50)
  --max-tree-depth <n>           Maximum directory depth for tree view (default: 5)
  --max-dependency-depth <n>     Import hops for semantic context (default: 2)
  --log-level <level>            debug | info | warn | error (default: info)

Per-project config file

Drop a synapse.config.json at your project root to override defaults for that project:

{
  "maxFileSize": 1048576,
  "maxDependencyDepth": 3,
  "extraIgnorePatterns": ["*.generated.ts", "**/__mocks__/**"],
  "cacheEnabled": true
}

cacheEnabled (default true) controls the on-disk incremental index cache (.synapse-cache/index.json) used by get_project_index and get_semantic_context to skip re-parsing unchanged files. Set to false to disable it.

All fields are optional. CLI flags take precedence over synapse.config.json.

Performance

Measured on real open-source TypeScript repositories (single run, --depth 1 clone, no warm cache):

RepositoryFiles indexedTimeHeap growth
zod55120 ms3 MB
TypeScript compiler src/247257 ms24 MB

The automated benchmark suite enforces upper bounds on a synthetic fixture (3 000 minimal .ts files) to catch regressions under worst-case conditions:

OperationCI budget (synthetic fixture)
get_project_tree — 3 000 files5 s
get_semantic_context — depth 310 s
get_changed_files2 s
get_project_index — 60 files30 s
get_project_index — 600 files120 s

The CI budgets are deliberately generous safety margins, not performance estimates — they exist to catch catastrophic regressions (e.g. an accidental O(n²) bug), not to predict real-world timing. The real-repo numbers above are the meaningful reference for expected performance. For large monorepos (1 000+ files), use file_pattern to scope the index to one area at a time.


Security

Synapse is a read-only server. It never writes to the filesystem or modifies the git repository.

  • Path traversal protection — every file read goes through resolveAndValidate(root, path), which throws a PATH_ESCAPE error if the resolved path escapes the project root. The AI client receives the error code, never the file contents.
  • Root scoping — only the directory tree under --root is accessible. Paths pointing outside (e.g. ../../etc/passwd) are rejected at the validation layer.
  • File size cap — files larger than maxFileSize (default 512 KB) are rejected before reading.
  • Binary detection — compiled artifacts and binary files are detected and skipped automatically.
  • No outbound network calls — Synapse communicates only over the local stdio pipe to the MCP client. It makes no H

View source on GitHub