Skip to main content
Glama
README.md
<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](https://github.com/Juanmidev1/synapse-code-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Juanmidev1/synapse-code-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Node ≥ 18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
[![Tests: 301](https://img.shields.io/badge/tests-301%20passing-brightgreen)](#development)

> A structural code context server that connects your local repository to AI assistants via the [Model Context Protocol](https://modelcontextprotocol.io).

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](#contributing).

---

## Why Synapse?

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

| Problem | Synapse solution |
|---|---|
| Reading an entire file when you only need its API surface | `get_semantic_context` with `outline_only` — signatures only, ≤ 50% of full content |
| AI doesn't know what files exist in an unfamiliar project | `get_project_index` — full symbol map at ≤ 40% of raw source size, one call |
| "Review my changes" requires pasting the diff manually | `get_changed_files` — structured git diff, git-aware by default |
| Dependency rabbit holes filling the context window | Configurable `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](#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:

```json
{
  "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](https://github.com/BurntSushi/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](https://ts-morph.com) (TypeScript compiler API) for deep analysis of TypeScript and JavaScript. For other languages, it applies regex-based extraction of function and class names.

| Feature | TypeScript / JS | Python · Go · Rust | Other |
|---|---|---|---|
| `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):**
```bash
npm install -g synapse-code-mcp
```

**Run without installing:**
```bash
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):

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

### Claude Code (CLI)

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

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

```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:

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

### Windsurf

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

```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:

```json
{
  "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):

| Repository | Files indexed | Time | Heap growth |
|---|---|---|---|
| [zod](https://github.com/colinhacks/zod) | 55 | **120 ms** | 3 MB |
| [TypeScript compiler](https://github.com/microsoft/TypeScript) `src/` | 247 | **257 ms** | 24 MB |

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

| Operation | CI budget (synthetic fixture) |
|---|---|
| `get_project_tree` — 3 000 files | 5 s |
| `get_semantic_context` — depth 3 | 10 s |
| `get_changed_files` | 2 s |
| `get_project_index` — 60 files | 30 s |
| `get_project_index` — 600 files | 120 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 HTTP requests.

---

## Suggested workflows

**Explore a new codebase:**
```
1. get_project_index()
   → Understand the full shape of the project in one call

2. get_semantic_context("src/core/engine.ts", outline_only: true)
   → Inspect a module's API surface without reading implementation

3. get_semantic_context("src/core/engine.ts")
   → Read full source + dependency graph for the relevant file
```

**Code review before a PR:**
```
1. get_changed_files(base_ref: "main")
   → See what changed, grouped and summarised

2. get_changed_files(base_ref: "main", include_diff: true)
   → Full unified diff in context

3. get_semantic_context("src/changed-file.ts")
   → Understand the context around a changed file
```

**Debug a feature:**
```
1. search_codebase("handlePayment")
   → Find where the symbol is defined and used

2. get_semantic_context("src/services/payment.ts", depth: 3)
   → Pull the file + all its local dependencies
```

---

## Requirements

- **Node.js ≥ 18**
- **Git** — required only for `get_changed_files`
- **[ripgrep](https://github.com/BurntSushi/ripgrep)** *(optional)* — significantly faster search; Synapse falls back to a pure Node.js scanner if `rg` is not on `$PATH`

---

## Development

```bash
git clone https://github.com/Juanmidev1/synapse-code-mcp.git
cd synapse-code-mcp
npm install

npm run dev          # watch mode (tsx, no compile step)
npm test             # run all tests (Vitest)
npm run typecheck    # type-check without emitting
npm run lint         # ESLint
npm run build        # compile to dist/
```

### Test with MCP Inspector

```bash
npm run build
npx @modelcontextprotocol/inspector dist/index.js --root .
```

This opens a browser UI where you can invoke all tools interactively and inspect their input/output.

### Project structure

```
src/
  index.ts              CLI entry point, argument parsing
  server.ts             MCP server, tool registration
  tools/                Thin tool handlers (validation + formatting only)
  core/
    fs/                 File tree building, file reading, ignore resolution
    search/             ripgrep adapter + pure-Node fallback
    analysis/           Dependency graph (ts-morph), outline extractor, project indexer, index cache
    git/                Git adapter (diff, changed files)
  config/               Config loading and Zod validation
  types/                Shared TypeScript interfaces
  utils/                Logger (pino), path helpers, typed errors
tests/
  unit/                 Per-module unit tests
  integration/          Tool handler integration tests
  protocol/             End-to-end MCP protocol tests (InMemoryTransport)
  performance/          Benchmark suite with time and heap budgets
  build/                Tests against the compiled dist/ output (catches source-vs-build divergence)
```

---

## Roadmap

See [ROADMAP.md](ROADMAP.md) for what is planned and what ideas are open for community contributions.

---

## Contributing

This project is in active early development. Bug reports, feature requests, and pull requests are all welcome — the codebase is intentionally small and straightforward to navigate.

- [CONTRIBUTING.md](.github/CONTRIBUTING.md) — how to set up the environment, run tests, commit conventions, and architectural rules
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — community standards (Contributor Covenant 2.1)
- [ROADMAP.md](ROADMAP.md) — what is planned and what is open for community PRs

New to the project? Browse issues tagged [`good first issue`](https://github.com/Juanmidev1/synapse-code-mcp/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) for the best entry points.

---

## License

[MIT](LICENSE)

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: changes, semantic index, tree structure, file context with dependencies, and text search. No overlap.

Naming Consistency4/5

Most tools follow 'get_<noun>' pattern, but 'search_codebase' uses a different verb. However, all names are snake_case and descriptive, with minor inconsistency.

Tool Count5/5

Five tools is ideal for a code exploration server, covering the key tasks without bloat.

Completeness4/5

Core exploration needs are met (changes, overview, structure, context, search). Minor gaps like call hierarchy or references exist but are beyond basic requirements.

Maintenance

ActivityMaintained
ResponsivenessResponsive