Synapse

Synapse

Provides structural code intelligence via 26 MCP tools, enabling AI assistants to query code symbols, dependencies, and call graphs accurately without file-pasting.

Category
Visit Server

README

<div align="center">

πŸ” Synapse

Your codebase. Fully understood. Zero waste.

The structural code intelligence layer that makes AI assistants dramatically more accurate, efficient, and useful on real-world codebases.

Tests Node TypeScript MCP Languages License

</div>


😀 The Problem

You have a large codebase. Your AI assistant doesn't.

Every time you start a new conversation β€” with Claude, Cursor, or any other AI β€” it starts completely blind. It has no idea what CartService does, who calls validateEmail, or whether there's a circular import hiding in your auth module. So you do what everyone does:

You paste files. Lots of files.

And the problems stack up fast:

Problem Real Cost
Hallucinated symbol names AI invents functions that don't exist β€” you burn time chasing ghosts
Pasting entire files for context 500-line files sent when you need 20 lines β€” tokens wasted, latency added
Repeating architecture every session "Here's how our auth works…" β€” again, every time
No dependency awareness AI can't know what breaking getUser() cascades into without being told
Wrong answers at scale Beyond ~3 files, accuracy collapses without structured context
No history awareness AI can't tell you who changed a function or why without git context

The bigger your codebase, the worse all of this gets.


πŸ’‘ The Solution

Synapse indexes your entire codebase into a local SQLite graph β€” every symbol, every call edge, every import, every embedding β€” and serves it to your AI through a Model Context Protocol (MCP) server with 26 precise tools.

Instead of pasting files, your AI asks for exactly what it needs:

AI: "What does CartService depend on?"

Without Synapse           β”‚  With Synapse
────────────────────────────┼──────────────────────────────────
Developer manually locates  β”‚  AI calls outgoing_calls("CartService")
and pastes cart.ts (400     β”‚  Gets: 6 precise edges, file:line
lines) + cartService.ts     β”‚  locations, resolved targets
(280 lines) into context    β”‚  β€” in ~1 KB, under 100ms
~15,000 tokens consumed     β”‚  ~300 tokens consumed

The result: AI that works from ground truth, not guesswork.


πŸ“‰ Token Consumption β€” The Numbers

This is the core business case. Token costs are real. Context limits are real. Latency from giant prompts is real.

Before Synapse

Developer asks: "Refactor CartService to support multiple currencies"

Step 1: Find relevant files (manual, ~5 min)
Step 2: Paste cart.ts          β†’ ~8,000 tokens
Step 3: Paste cartService.ts   β†’ ~6,000 tokens
Step 4: Paste product.ts       β†’ ~4,000 tokens
Step 5: Explain dependencies   β†’ ~1,000 tokens
                               ─────────────────
Total context load:             ~19,000 tokens
                               (before AI even responds)

After Synapse

AI uses Synapse tools automatically:

explore_symbol("CartService")     β†’ ~400 tokens  (definition + callers + callees)
find_references("CartService")    β†’ ~200 tokens  (who depends on it)
get_source("cart.ts", 45, 92)     β†’ ~300 tokens  (only the relevant lines)
outgoing_calls("CartService")     β†’ ~150 tokens  (exact dependencies)
                                  ─────────────────
Total context load:                ~1,050 tokens

That's an 18Γ— reduction in token consumption for this query. At scale β€” across a team, across hundreds of sessions β€” this compounds into thousands of dollars saved per month.

Why targeted queries beat file-pasting

Scenario File-paste tokens Synapse tokens Reduction
Find where a function is defined ~5,000 (whole file) ~50 (find_symbol) 100Γ—
Understand a class's dependencies ~15,000 (3 files) ~600 (explore_symbol) 25Γ—
Check who uses an API ~20,000 (search manually) ~200 (find_references) 100Γ—
Trace a call chain 3 levels deep ~40,000 (many files) ~800 (call_hierarchy) 50Γ—
Find a bug by pattern ~30,000 (manual search) ~400 (grep_code) 75Γ—

🎯 Why Synapse

βœ… Ground truth, not guesswork

Synapse reads your actual parsed AST. Every symbol location, every call edge, every import binding comes from the real code β€” not from a language model's training data. No hallucinated function names. No wrong file paths. No invented APIs.

βœ… AI that understands your architecture

The call graph tells the full story: what calls what, what imports what, what's dead, what's a hub. Your AI can answer architectural questions β€” circular imports, dependency chains, hub identification β€” that are impossible without this structure.

βœ… Works across your entire codebase, instantly

43 languages. Every file indexed. Cross-file references resolved. Semantic search via local embeddings. Whether your repo has 100 files or 100,000, the AI always has an index β€” not a partial, hallucinated memory.

βœ… Fully local β€” zero data exposure

Everything runs on your machine. The SQLite database lives in your repo. No code is sent to any server. Embedding inference runs locally via Transformers.js. This matters for enterprise codebases, proprietary code, and compliance requirements.

βœ… Persistent intelligence

Index once. Query forever. The incremental indexer detects file changes via xxhash and only re-parses what changed. Your AI doesn't need a "warm-up" monologue about your codebase every session β€” the graph is always ready.

βœ… Compatible with any MCP client

Works with Claude Desktop, Cursor, VS Code, and any editor that supports MCP. One index, any client.


πŸš€ Quick Start

# 1. Install
git clone <repo-url> && cd synapse
./setup.sh          # macOS / Linux
./setup.ps1         # Windows

# 2. Index your project (one time, incremental after that)
synapse init /path/to/your/repo

# 3. Connect to your AI client
synapse configure /path/to/your/repo

# 4. (Optional) Enable semantic search β€” 23 MB one-time download
synapse embed /path/to/your/repo

# Done. Open your AI client and ask about your code.

πŸ› οΈ Tech Stack

<table> <tr><th>Layer</th><th>Technology</th><th>Why This Choice</th></tr> <tr> <td><strong>Runtime</strong></td> <td>Node.js 20+ Β· TypeScript 5</td> <td>Native ESM, strong typing, broad ecosystem compatibility</td> </tr> <tr> <td><strong>Database</strong></td> <td>SQLite Β· better-sqlite3 Β· WAL mode</td> <td>Zero-dependency, file-local, concurrent reads, FTS5 built-in</td> </tr> <tr> <td><strong>Parsing</strong></td> <td>tree-sitter + language grammars</td> <td>Incremental AST parsing for 43 languages, production-grade</td> </tr> <tr> <td><strong>Protocol</strong></td> <td>@modelcontextprotocol/sdk</td> <td>Official MCP SDK β€” stdio + HTTP Streamable transport</td> </tr> <tr> <td><strong>Embeddings</strong></td> <td>@xenova/transformers (Transformers.js)</td> <td>Run ONNX models locally in Node.js β€” no Python, no server</td> </tr> <tr> <td><strong>Structural search</strong></td> <td>@ast-grep/napi</td> <td>AST-aware code pattern matching β€” understands code, not just text</td> </tr> <tr> <td><strong>Fast grep</strong></td> <td>ripgrep (rg) β€” streaming via spawn()</td> <td>Rust + SIMD + parallel I/O; async streaming, non-blocking, no buffer cap</td> </tr> <tr> <td><strong>Security scan</strong></td> <td>semgrep</td> <td>OWASP Top 10, secrets, language-specific rule packs</td> </tr> <tr> <td><strong>Full-text search</strong></td> <td>SQLite FTS5 (trigram tokenizer)</td> <td>Sub-millisecond symbol lookup and grep pre-filtering in the same DB</td> </tr> <tr> <td><strong>Change detection</strong></td> <td>xxhash</td> <td>Near-zero-cost file change detection β€” skips unchanged files instantly</td> </tr> <tr> <td><strong>Monorepo build</strong></td> <td>pnpm workspaces + tsup</td> <td>Fast installs, isolated packages, ESM-first bundling</td> </tr> <tr> <td><strong>Testing</strong></td> <td>Vitest β€” 261 tests, 30 files</td> <td>Native ESM support, fast hot reload, snapshot testing</td> </tr> <tr> <td><strong>Containers</strong></td> <td>Docker (Node 22 slim, multi-stage)</td> <td>Minimal attack surface, non-root runtime user</td> </tr> <tr> <td><strong>CI/CD</strong></td> <td>GitHub Actions</td> <td>Index on push, hash-based DB cache, PR API diff comments</td> </tr> </table>


πŸ“¦ Installation

Requirements: Node.js β‰₯ 20, pnpm 9.12+

<details> <summary><strong>macOS / Linux</strong></summary>

git clone <repo-url>
cd synapse
./setup.sh

</details>

<details> <summary><strong>Windows (PowerShell)</strong></summary>

git clone <repo-url>
cd synapse
./setup.ps1

</details>

<details> <summary><strong>Windows (Batch)</strong></summary>

git clone <repo-url>
cd synapse
setup.bat

</details>

The setup script handles everything: verifies Node β‰₯ 20, installs pnpm 9.12 via corepack, builds all packages, links synapse + synapse-mcp globally, and writes .vscode/mcp.json.

<details> <summary><strong>Manual VS Code / MCP client config</strong></summary>

{
  "servers": {
    "synapse": {
      "type": "stdio",
      "command": "node",
      "args": [
        "${workspaceFolder}/packages/mcp-server/dist/bin.js",
        "--root", "${workspaceFolder}",
        "--db",  "${workspaceFolder}/.synapse/graph.db"
      ]
    }
  }
}

</details>


πŸ’» CLI Reference

synapse <command> [options]
Command Description
init [root] πŸ—οΈ Index a repo β€” skips unchanged files via xxhash
reindex [root] πŸ”„ Force full re-index (ignores hash cache)
watch [root] πŸ‘οΈ Incremental indexer β€” re-parses files on save
embed [root] 🧠 Generate vector embeddings for semantic search
configure [root] βš™οΈ Write config + MCP client snippets
doctor [root] 🩺 Diagnose Node, DB, MCP binary
compact πŸ—œοΈ VACUUM + ANALYZE the DB
diff <base> [head] πŸ“Š Changed public APIs between git refs
import-scip <file> πŸ“₯ Ingest a SCIP JSON index
query <name> πŸ”Ž Look up symbols by name
refs <name> πŸ“Œ Every reference to a symbol
stats πŸ“ˆ File / symbol / edge counts
ping βœ… Sanity check

<details> <summary><strong>Global flags</strong></summary>

Flag Default Description
--db <path> ./.synapse/graph.db Override DB path
--concurrency <n> 8 Parallel file workers (init/reindex)
--languages <csv> all Restrict to specific adapter IDs
--debounce <ms> 250 Watch mode debounce window
--skip-initial β€” Watch: skip up-front full-repo index
--client <name> β€” configure: claude, cursor, or generic
--print β€” configure: print snippet only, skip writing
--limit <n> β€” query/refs: max results
--json β€” stats: emit JSON
--verbose β€” init/reindex: print parse-error file paths

</details>


πŸ”„ Keeping the Index Fresh β€” 3 Sync Modes

Synapse has three distinct modes for handling codebase changes. You don't need all three β€” pick what fits your workflow.

Mode 1 β€” synapse init (on-demand)

Run once, or re-run whenever you want a manual refresh.

synapse init /path/to/repo
  • Computes an xxhash for every file on disk
  • Compares against stored hashes in SQLite β€” skips unchanged files instantly
  • Re-parses AST only for new or modified files
  • Run synapse reindex instead to force a full re-parse (ignores hash cache)

Typical re-run on a large repo: a few seconds, not minutes.


Mode 2 β€” synapse watch (live, manual)

Long-running process in a terminal. Keeps the DB warm as you code.

synapse watch /path/to/repo
  • Does one full incremental index on startup (same as init)
  • Then starts a chokidar file watcher β€” reacts to every save/create/delete
  • Debounced β€” rapid saves don't trigger a parse storm (default 250 ms)

What it logs on each event:

[+] src/cart.ts        12 sym / 34 edge  (43ms)   ← file changed/added
[-] src/old.ts                                     ← file deleted β†’ symbols removed
[r] resolved 5 imports + 12 edges  (8ms)           ← cross-file references re-resolved

Deleted files are fully cleaned up β€” all their symbols are removed and incoming edges are nulled.


Mode 3 β€” MCP server auto-sync (always-on, zero config)

No command needed. This runs automatically every time the MCP server starts (i.e., when VS Code loads it).

What it does, in order:

  1. Lock check β€” tries to acquire a file lock. If another MCP instance is already watching β†’ silently backs off (avoids duplicate watchers)
  2. Crash recovery β€” if a previous index run crashed mid-way (indexing=true left in the manifest) β†’ forces a clean full reindex automatically
  3. HEAD check β€” compares the current git HEAD to last_indexed_head in the DB. If HEAD changed (you pulled, switched branches, rebased) β†’ triggers an incremental reindex before serving any tool calls
  4. Chokidar watcher β€” starts the same live watcher as Mode 2 in the background

This is why you never need to manually re-run init after switching branches. The MCP server catches the HEAD change on next startup and reindexes silently.


Which mode should you use?

Situation Recommended
First-time setup synapse init
Active development session synapse watch
Already using the MCP server in VS Code nothing β€” auto-sync handles it
After a large branch switch or rebase nothing β€” auto-sync detects HEAD change
CI / pre-commit hook synapse init

πŸ”Œ MCP Server

26 tools and 3 resources over stdio (default) or HTTP.

# stdio β€” VS Code / Claude Desktop
node packages/mcp-server/dist/bin.js \
  --root /path/to/repo \
  --db   /path/to/repo/.synapse/graph.db

# HTTP β€” remote, containerized, or shared deployments
node packages/mcp-server/dist/bin.js \
  --root      /path/to/repo \
  --db        /path/to/repo/.synapse/graph.db \
  --transport http --port 4000 --host 0.0.0.0 \
  --token     "$CODEGRAPH_TOKEN" \
  --redact-paths

<details> <summary><strong>HTTP transport options</strong></summary>

Flag Default Description
--transport stdio stdio or http
--port 4000 Listen port
--host 127.0.0.1 Bind address
--token <secret> β€” Bearer token auth (timing-safe comparison)
--redact-paths β€” Strip home dir and username from all responses
  • GET /healthz β†’ { ok: true, sessions: N }
  • Stateful sessions via mcp-session-id header
  • CORS restricted to localhost when auth is enabled
  • Request body limit: 10 MB

</details>


🧰 MCP Tools (26)

🏷️ Symbol Lookup β€” Find anything in your codebase instantly

Tool What it answers Token saving vs. manual
find_symbol Where is X defined? File, line, signature ~100Γ—
get_definition Canonical definition of X ~100Γ—
search_symbols Which symbols match auth*? Wildcard + kind/language/glob filters + "did you mean?" hints ~50Γ—
list_symbols_in_file Everything defined in src/cart.ts ~10Γ—
verify_symbol Is this AI-generated reference actually valid? 0–1 confidence score prevents hallucination loops

πŸ”— Call Graph β€” Understand dependencies without reading files

Tool What it answers Token saving vs. manual
find_references Who calls / imports / extends X? ~100Γ—
outgoing_calls What does X depend on? ~50Γ—
call_hierarchy Full BFS traversal β€” incoming or outgoing, configurable depth ~1000Γ—
explore_symbol Definition + source + callers + callees β€” everything in one call ~25Γ—
top_symbols What are the architectural hubs? (fan-in + fan-out ranking) unique insight

πŸ”Ž Code Search β€” Grep smarter, not broader

Tool What it does Why it saves tokens
grep_code Regex/fixed-string search β€” ripgrep β†’ FTS5 β†’ disk, auto-fallback Returns only matches + context, not whole files
structural_search AST-pattern: console.log($ARGS) matches any formatting No false positives from comments or strings
hybrid_search Exact β†’ FTS5 trigram β†’ fuzzy β†’ semantic β€” Reciprocal Rank Fusion Best result without AI guessing where to look
semantic_search "function that validates email" β€” finds by meaning, not name Eliminates exploratory file-reading
find_imports Who imports "react-query" or "./utils/cart"? Targeted import graph query

πŸ“Š Source & Metrics β€” Get exactly the lines you need

Tool Token efficiency
get_source Read only the line range that matters β€” not the whole file
get_stats Aggregate counts in ~50 tokens instead of reading the whole DB
index_status Health check, drift detection, git HEAD β€” instant summary
code_metrics Per-file complexity β€” identify hotspots without manual review
find_dead_code Remove dead code confidently β€” no guessing

πŸ“œ Git History β€” Context that lives outside the code

Tool Value
git_log Why was this function changed? Who touched it last?
git_blame Who wrote this line and in what commit?

πŸ—οΈ Architecture & Security β€” Systemic insight

Tool Value
detect_cycles Find circular imports before they cause runtime bugs (Tarjan's SCC)
reindex_file Update one file's graph atomically β€” no full re-index needed
scan_security OWASP Top 10, secrets, language-specific rules via semgrep
read_offloaded Auto-retrieve large payloads offloaded beyond the 8 KB threshold

πŸ“‚ Resources (3)

URI Returns
synapse://stats Repo-wide counts and DB size as JSON
synapse://files Every indexed file path, newline-delimited
synapse://status Schema version, counts, last-indexed time, drift hint

πŸ” grep_code β€” Smart Three-Backend Chain

  grep_code("pattern")
       β”‚
       β”œβ”€β”€β–Ί 1. ripgrep (rg)      Rust + SIMD + parallel I/O
       β”‚         ↓ not found / not installed
       β”œβ”€β”€β–Ί 2. SQLite FTS5       trigram pre-filter β†’ JS regex (no disk I/O)
       β”‚         ↓ no content stored
       └──► 3. Disk scan         readFileSync + JS RegExp (always works)

  All three return: file Β· line Β· col Β· match text Β· context lines Β· enclosing symbol

The ripgrep backend streams output asynchronously via spawn() + readline β€” the event loop is never blocked and there is no memory buffer cap, making it safe for very large repos.


🧠 Semantic & Hybrid Search

Default: Transformers.js β€” 100% local, zero server

synapse embed /path/to/repo   # ~23 MB one-time download, fully cached after
Model Xenova/all-MiniLM-L6-v2
Dimensions 384
Quantization INT8
Download ~23 MB (one-time)
Requires server ❌ No
Package @xenova/transformers (bundled)

Alternative: Ollama

ollama serve
synapse embed /path/to/repo --provider ollama --model nomic-embed-text
Default model nomic-embed-text
URL http://127.0.0.1:11434
Requires server βœ… Yes

Once embeddings exist, semantic_search and hybrid_search use them automatically.


🌐 Language Support

πŸ₯‡ Tier 1 β€” Full adapters (7 languages)

Symbols Β· call edges Β· import resolution Β· cross-file linking Β· SCIP-stable IDs

Language Extensions
TypeScript .ts .tsx .mts .cts
JavaScript .js .jsx .mjs .cjs
Python .py .pyi
Go .go
Java .java
C# .cs

πŸ₯ˆ Tier 2 β€” Generic adapters (20 languages)

AST + call tracking Β· no per-language module resolution

C++ Rust Ruby Kotlin Swift PHP Dart Scala Zig Lua Bash Elixir Elm OCaml Solidity Objective-C Vue ReScript and more

πŸ₯‰ Tier 3 β€” Text-only (16 languages)

File-level symbols Β· no AST

Markdown JSON YAML TOML SQL XML HTML CSS GraphQL Protobuf .env Dockerfile and more

43 languages Β· 100+ file extensions


πŸ—„οΈ Database Design

SQLite Β· WAL mode Β· Schema v9 Β· Dual connection handles (read-only db + write-on-demand wdb)

Table Purpose
files Indexed files: path, language, xxhash, mtime, indexed_at
symbols Definitions: SCIP IDs, kind, line range, signature, doc
edges Call/reference edges: source_id β†’ target_name / target_id, kind, location
file_imports Import bindings: specifier, resolved_file_id, import_kind (value | type)
manifest Key-value: schema_version, repo_root
symbols_fts FTS5 trigram index for symbol name search
symbol_embeddings Dense vectors: symbol_id, BLOB, model, embedded_at
file_content Raw source per file (grep backend 2)
file_content_fts FTS5 trigram index for grep pre-filtering

Cross-file edge invariant: edges.target_id has ON DELETE CASCADE. Before deleting symbols during reindex, Synapse nulls out incoming cross-file edges first β€” edges survive, and the resolver re-links them on the next pass.


πŸ›οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      AI Assistant                          β”‚
β”‚           (Claude Β· Cursor Β· any MCP client)               β”‚
β”‚                                                            β”‚
β”‚  "What breaks if I refactor CartService?"                  β”‚
β”‚       ↓ AI calls find_references + call_hierarchy          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚  MCP (stdio or HTTP)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      MCP Server                            β”‚
β”‚    26 tools Β· 3 resources Β· 8 KB auto-offload threshold    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    @synapse/core                         β”‚
β”‚                                                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   Indexer   β”‚  β”‚   Resolver   β”‚  β”‚   Embeddings    β”‚   β”‚
β”‚  β”‚ tree-sitter β”‚  β”‚ cross-file   β”‚  β”‚ Transformers.js β”‚   β”‚
β”‚  β”‚ 43 languagesβ”‚  β”‚ edges + BFS  β”‚  β”‚   or Ollama     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”˜                   β”‚            β”‚
β”‚                         └───────────────────-β”˜            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚          SQLite Β· WAL mode Β· Schema v9               β”‚  β”‚
β”‚  β”‚  files Β· symbols Β· edges Β· file_imports Β· manifest   β”‚  β”‚
β”‚  β”‚  symbols_fts Β· symbol_embeddings                     β”‚  β”‚
β”‚  β”‚  file_content Β· file_content_fts                     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Design decisions that matter:

Decision Why
SCIP-stable symbol IDs Portable, path-relative IDs survive file renames
Barrel re-export BFS Resolves re-exported names through up to 3 levels of index.ts barrel files
Async streaming grep spawn() + readline β€” never blocks event loop, no 20 MB buffer cap
Dual DB handles Concurrent reads never wait for writes; WAL checkpoint on write close
8 KB offload Large responses written to temp files; AI retrieves only if needed β€” keeps MCP stream lean
xxhash change detection Near-zero-cost file diffing β€” only changed files are re-parsed

πŸ”§ External Dependencies

All optional. Synapse degrades gracefully.

Tool Used By Install Fallback
ripgrep (rg) grep_code backend 1 brew install ripgrep Β· apt install ripgrep Β· releases FTS5 + disk scan
semgrep scan_security pip install semgrep Tool returns descriptive error
ast-grep structural_search Bundled via @ast-grep/napi β€” no install needed β€”
git git_log, git_blame Must be on PATH Tools return descriptive error
Ollama embed --provider=ollama ollama.ai Use default Transformers.js (no server)

βš™οΈ GitHub Action

Index on every push, comment API diffs on PRs β€” keep your AI's index always current:

- uses: ./
  with:
    languages: typescript,python
    db-path: .synapse/graph.db
    comment-on-pr: true
    base-ref: ${{ github.base_ref }}

Outputs: files-indexed Β· symbols-count Β· api-changes Β· db-path

The DB is cached by source-file hash β€” incremental runs re-parse only what changed.


🐳 Docker

docker build -t synapse .

docker run -p 4000:4000 \
  -v /path/to/repo:/repo:ro \
  -v /path/to/data:/data \
  synapse \
    --db /data/graph.db --root /repo \
    --transport http --host 0.0.0.0 --port 4000 \
    --token "$CODEGRAPH_TOKEN"

Multi-stage build (Node 22 slim). Non-root synapse user in the runtime stage.


πŸ§ͺ Development

packages/
  core/        @synapse/core       β€” indexer, resolver, DB, embeddings
  mcp-server/  @synapse/mcp-server β€” MCP server, HTTP transport, all 26 tools
  cli/         @synapse/cli        β€” CLI commands
fixtures/
  sample-shopping-app/               β€” TypeScript fixture used by all tests
pnpm install           # install dependencies
pnpm -r build          # build all packages
pnpm -r test           # 261 tests across 30 files
pnpm -r test --watch   # watch mode

Test coverage: indexing Β· cross-file resolution Β· all 26 MCP tools Β· HTTP transport Β· Bearer auth Β· path redaction Β· Transformers.js embeddings Β· three grep backends Β· SCIP ingestor Β· cycle detection


<div align="center">

The Bottom Line

Without Synapse, your AI is reading your codebase one pasted file at a time. With Synapse, it queries a complete, structured graph β€” and uses a fraction of the tokens to do it.

Less context waste. Fewer hallucinations. Faster answers. Better code.


100% local Β· No cloud Β· No telemetry Β· Works with any MCP client

</div>

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured