Skip to main content
Glama

mcp-spec-nav — MCP Server for AI Code Search and Navigation

English · Tiếng Việt · 简体中文

mcp-spec-nav — Give your agent a map of your code.

mcp-spec-nav is a local MCP server for AI coding agents such as Claude Code. It reads the source code of the repository you choose and lets the agent:

  • find existing functions across services and shared packages — by words, by what they call, or by behavioural similarity to a draft;

  • read a function exactly: source, signature, documentation and the imports it uses;

  • find callers before a change — type-checked in TypeScript/JavaScript/Vue, evidence-based in Python, Go, Java, Kotlin, Swift and other languages, with dynamic uses listed;

  • map a pattern across supported source files, with the enclosing function of each match;

  • trace flows across services from source code — HTTP client → route → handler, RPC call → handler, event/topic → consumers — with the evidence for each link and what could not be resolved (static analysis, supported frameworks).

The problem it addresses: before writing new logic or changing a function, an agent needs to know what already exists and what depends on it. With grep alone it can miss code written under other names, rewrite logic that already exists, or edit same-named calls on another class.

The MCP only reads code. Your coding agent decides what to reuse, edits the files and runs the tests. The MCP does not guarantee that every related function will be found.

When it helps

Scenario

Value of the MCP

Logic is spread across multiple services

High: searches broadly and helps reduce missed code.

You want to reuse functions instead of rewriting them

High, when the query finds the right candidates.

You change function parameters and need to find callers

Useful.

You follow a request or event from one service to another

Useful for the supported frameworks: static links with evidence; unknowns are reported, not guessed.

You make a simple edit within one file

Limited benefit; may add tool calls.

Every model turn with the MCP installed also carries its tool definitions (~3.8k tokens in the benchmark), so on small, single-concept changes the gain is small. In live runs on real tasks in a private production monorepo, the spec-nav setup (MCP + workflow instructions + a hook that blocks recursive grep) finished tasks about 28% sooner (about 32% on cross-service tasks) with about the same token use and average code quality 8.5/10. It did not reduce tool calls, and on small single-service tasks it costs more tokens. The MCP installed on its own has not been measured yet (Benchmark).

Related MCP server: codeweave-mcp

Example: change an order fee

docs/examples/order-fee is a runnable four-file example. Task: raise the handling fee from 5 to 7 and let every caller waive it. The output below comes from running the tools on before/, trimmed.

1. Find existing logic — MCP, spec_nav_find_functions with { "query": "order handling fee total" }:

#1  score 3.05  billing/fees.ts:35-43  (service ., typescript)
    [function, exported] calculateTotal
    why: handling→body  fee→path(stem:fees)  total→name

2. Read the implementation — MCP, spec_nav_read_function with { "file": "billing/fees.ts", "name": "calculateTotal" }:

35| export function calculateTotal(subtotal) {
39|   const handlingFee = HANDLING_FEE;
42|   return subtotal + handlingFee;
43| }

3. Find every caller — MCP, spec_nav_callers with { "symbol": "calculateTotal", "file": "billing/fees.ts" }:

"total": 3, "exhaustive": true,
"targets": [{ "file": "billing/fees.ts", "line": 35, "resolvedBy": "type checker" }],
"sites": [
  { "file": "billing/previewInvoice.ts", "line": 3, "enclosing": "previewInvoice", "resolution": "resolved" },
  { "file": "checkout/createOrder.ts", "line": 3, "enclosing": "createOrder", "resolution": "resolved" },
  { "file": "orders/updateOrder.ts", "line": 3, "enclosing": "updateOrder", "resolution": "resolved" }

4. Follow it across services — MCP. spec_nav_callers counts direct calls only and says so: calls through HTTP/RPC/queues are not counted. In the multi-service example docs/examples/order-flow, spec_nav_trace_flow with { "file": "services/checkout/src/handlers/createOrder.ts", "name": "createOrderHandler", "direction": "both" } shows who reaches the handler and where the total goes:

steps: 5 (5 resolved) — this page 1-5 — COMPLETE
gaps: none found among the supported adapters.
#1  d1 ↑ HTTP  POST http://checkout:3000/api/orders → POST /api/orders   [resolved · high]
    from  services/storefront/src/checkout-client.ts:3  submitOrder
#2  d1 ↓ call  createOrderHandler → calculateTotal   [resolved · high]
#4  d2 ↓ EVENT event order.created → event order.created (kafka)   [resolved · medium]
    to    services/invoicing/src/consumer.ts:12  handleOrderCreated

5. Edit the code — coding agent: sets HANDLING_FEE to 7, adds an options parameter to calculateTotal, and forwards waiveHandlingFee from the three callers. The result is in after/.

6. Run the tests — coding agent:

node --test docs/examples/order-fee/verify.mjs   # 6 tests pass

Quick start (Claude Code)

Requirements: Node.js 18+, npm/npx, Git, and a local checkout of the repository to scan. The first installation needs network access.

1. Create .mcp.json at the root of the target repository. If it already exists, add the spec-nav entry to its mcpServers and keep the other servers.

{
  "mcpServers": {
    "spec-nav": {
      "command": "npx",
      "args": ["-y", "github:khoitd-voyager/mcp-spec-nav"],
      "env": {
        "SPEC_NAV_ROOT": "/Users/you/code/your-repo"
      }
    }
  }
}

Replace /Users/you/code/your-repo with the absolute path of the code to scan (the monorepo root to cover every service) — not the installation directory of mcp-spec-nav.

2. Open Claude Code in that repository, restart the session, run /mcp and check that spec-nav is connected. Approve the configuration if your client asks.

3. Send Claude:

Use spec-nav to list the services in this repository.
Show the resolved repository root and any files it could not scan.

Check that the root and services match your project before continuing.

4. Try a real task:

I want to add a parameter to calculateFee. Use spec-nav to find its declaration,
read the implementation and check its callers before planning the change.
Report any callers you could not resolve.

Installing an MCP makes its tools available; it does not ensure the agent uses them. Add the CLAUDE.md section so Claude uses them during normal coding. More prompts, the Claude Desktop extension (no Node.js needed) and installing from a local checkout: Installation.

Tools

Tool

Use it when you want to…

spec_nav_services

Check the scan root, discovered projects, counts and coverage.

spec_nav_find_functions

Find ranked candidates for existing logic across services.

spec_nav_similar_functions

Find functions that behave like a candidate or a draft, whatever they are named.

spec_nav_read_function

Read one candidate's exact source and context.

spec_nav_functions

Browse the function catalog with filters and pagination.

spec_nav_callers

Inspect calls, references, dynamic uses and unresolved usages before a change.

spec_nav_map

Find regex matches with the enclosing function.

spec_nav_trace_flow

Follow HTTP, RPC and event links between services, upstream or downstream, with evidence and what is unresolved.

Arguments, JSON examples, pagination, coverage and result statuses: Tool reference.

Supported languages

TypeScript, JavaScript, Python, Go, Java, C#, Ruby, Rust, PHP, C, C++, Scala, Elixir, Bash, Kotlin, Swift, and Vue/Svelte/Astro components (script blocks). Callers are type-checked in TS/JS/Vue/Svelte/Astro and evidence-based in every other supported language. Cross-service flows are traced for TypeScript/JavaScript and Python frameworks only. Extensions and parsing details: Supported languages.

Benchmark

Live LLM run on a private production monorepo

Claude Code on real feature and bug-fix requests in a private TypeScript monorepo (4 backend services that call each other over HTTP, a storefront and an admin app), running a 4-step spec workflow (/discuss → /resolve-solution → /create → /ship) with and without the spec-nav setup. Claude Sonnet 5.5 and Claude Opus 5.5, the same model for both setups on each task; recorded 2026-10-16 to 2026-10-18.

The spec-nav setup is the MCP plus workflow instructions plus a hook that blocks recursive grep over source code and points to spec_nav_map. There is no edit gate: the agent is never forced to call a tool before editing. The hooks are in docs/examples/hooks/; see Hooks.

With the spec-nav setup

All tasks

Larger, cross-service tasks

Time per task

−28% (13.7 → 9.9 min)

−32%

Tokens

+5% (about the same)

+2%

Average code quality (answer key, 1–10)

8.5

8.6

Tasks finished sooner

83%

100%

The setup did not reduce tool calls: the agent usually made more calls, grouped into fewer model turns. Time is what changes. On the smaller tasks the gain is about 8% in time for about 37% more tokens. One run per task, an LLM grader that is not blind; read the report before quoting these numbers.

Simulated agents

All results below come from simulated agents: deterministic policies, not an LLM, so the differences come from the tools. One agent has only Grep/Read/Edit (like Claude Code's built-in tools), the other has spec-nav plus Read/Edit. The no-MCP side is given an LLM's synonym knowledge and the same generous scoring. Each session is a whole feature request: reuse existing logic, change a function's signature and update every caller, change a constant everywhere, then read and edit every file. Repositories: a seeded synthetic monorepo (answers planted by the generator) and immich@cc7fd67 (answers from TypeScript findReferences, doc comments and ripgrep). Tokens are estimated at 3.5 characters/token.

Synthetic, 100 sessions

Synthetic, 50 large sessions

immich (real), 20 sessions

immich (real), 10 large sessions

Context per session, no MCP → MCP

31k → 24k (−25%)

92k → 71k (−24%)

116k → 98k (−16%)

302k → 227k (−25%)

…of which search phase

−57%

−55%

−70%

−69%

Input tokens with prompt caching

−18%

−26%

−16%

−38%

Tool calls (model turns)

−10%

−9%

−2%

−20%

Existing function reused

97% → 99%

90% → 95%

55% → 90%

40% → 93%

Callers complete, nothing extra

100% → 100%

100% → 100%

85% → 90%

53% → 73%

Wrong edits per session

0 → 0

0 → 0

0.3 → 0.2

14.4 → 2.4

Session fully correct

97% → 99%

70% → 86%

50% → 85%

0% → 30%

Tool time incl. MCP cold start

+4.1 s

+6.1 s

+3.2 s

+6.6 s

Reading what you will edit costs the same either way; the saving is in the search phase. Quality gains come from finding code under other names (reuse) and from not editing same-named calls on other classes (callers).

Large repository — VS Code (14,306 files, ~4.5M lines, 154k catalogued functions), Apple M4: first index 31 s, then find_functions 2.6–4.3 s, map 0.5–1.8 s, similar_functions 0.9 s, read_function 0.15 s; callers 10 s for an ordinary function (isEqualOrParent), 26 s and 3.1 GB RAM for FileService.readFile, a name mentioned in hundreds of files (12 s when asked again; 0.7.0 on the same machine: 42 s, then 78 s, 3.6 GB). Server memory 0.7–0.9 GB outside callers.

Cross-service flows (no agent, no LLM) — spec_nav_trace_flow on generated repositories (14 services each, 5 held-out seeds, 598 labelled call sites): 100% precision with 0 wrong links (linking by name only: 136 wrong links), 100% recall (84% in 0.7.0, which did not follow calls made through a wrapper function or urljoin). First call ~0.1 s (0.7 s on a 1,000-file repository), then 1–10 ms per call. The generator and the adapters share an author, so this checks the linking rules, not coverage of real code.

Method, assumptions and limitations: bench/README.md. Reports: live · synthetic · immich · VS Code timings · flows · all results.

Limits

  • Search is lexical. Words, called names, abbreviations, synonym and concept lists, IDF. spec_nav_similar_functions finds same-behaviour code under unrelated names only when it shares calls or vocabulary; two implementations with nothing in common are missed. Results are candidates, not proof that nothing else exists.

  • Translation. Vietnamese written with diacritics is matched through a built-in dictionary of ~100 common domain terms; other words are not translated. Use English keywords for English-named code.

  • Reuse. Check exports, behavior and package/service dependencies yourself.

  • Callers. Outside TS/JS, binding is by evidence (imports, qualifiers, declared receiver types), not a type checker: inferred types, inheritance and overloads can leave sites likely/ambiguous. Names built at runtime, HTTP/RPC/queue calls and external repositories are not traced by spec_nav_callers (for HTTP/RPC/events between services, see spec_nav_trace_flow).

  • Flows. Static, from source: links are inferred, never observed, and only for the supported frameworks. Not traced: gRPC, GraphQL, WebSockets, other queues (BullMQ, RabbitMQ, SQS…), Go, Java and other languages, generated API clients, wrappers more than three tiers deep, service discovery and configuration other than docker-compose, and more — see Not traced.

  • Function forms. Inline anonymous callbacks are not individually catalogued (JS/TS counts them in coverage). JS/TS destructuring assignments, dynamic property assignments, factory-created functions, Object.assign/Object.defineProperty and some chained assignments are not fully covered. Other-language assigned lambdas/closures are not catalogued.

  • Files. Dart, Lua, Objective-C, SQL and other unsupported source types are not parsed (they are counted in coverage). Dependency/build directories, hidden directories, virtualenvs, declaration files, minified JS and supported files over 1.5 MB are excluded.

  • Types. Return types are reported when explicitly written; they are not inferred by the catalog.

  • Large repos. Measured on VS Code (14k files): first index ~31 s, searches seconds. TS/JS callers type-check only files that mention the name — and, when many do, only those with an import path to a declaration — in batches, following imports two steps; a very common name takes tens of seconds and ~3 GB, and calls whose receiver type lies further away are reported unresolved.

  • Dependencies. TS/JS type resolution is best with dependencies installed (node_modules); without them, library types are unknown and more calls end up unresolved.

The server reads the current local checkout. No search API key is required, and its search does not send code to an external search service. Results are returned to your connected coding agent; that client's model/data handling settings still apply.

Documentation

License

MIT. See LICENSE.

Available Tools

8 tools
spec_nav_callersA

Call sites of a function or method across the repo, before changing its signature or behaviour. Narrow with "Class.method", className or file. TS/JS (and Vue/Svelte/Astro) are resolved with the type checker, so same-named methods on other classes are excluded; other languages are bound by evidence and each site's reason says which. likely, ambiguous, unresolved and dynamic sites are listed apart and are not confirmed callers. exhaustive is true only when type-checked targets have nothing left open; names computed at runtime, HTTP/RPC/queue calls and code outside the repo are never counted. Paged: partial names what is not shown yet.

Inputs: symbol (required), file, limit, cursor, +4 more.

spec_nav_find_functionsA

Before writing new logic: find existing functions by describing the behaviour in words ("calculate order fee"). Lexical ranking over name, aliases, class, signature, doc comment, path, called names and body, with stem, abbreviation and synonym matching; each candidate says why it matched, and matches only via calls or body rank lower. Not semantic: if nothing fits, use spec_nav_similar_functions. Returns ids for spec_nav_read_function. Paged by limit/cursor.

Inputs: file, limit, query, cursor, +5 more.

spec_nav_functionsA

Function catalog of a file, directory or service without bodies: qualified name, kind, signature, line range, export status, doc summary and id. Filter by services, file, name, kind, language. Paged; a coverage line names the files not read (syntax errors, unsupported languages, skipped), and the catalog is complete only when it says so. Inline anonymous callbacks are counted, not listed.

Inputs: file, kind, name, limit, +5 more.

spec_nav_mapA

Regex search across every project under the root (code, then config/docs/SQL), each code hit tagged with the function it sits in. When the service or file is known, narrow with services/file. Paged, never silently cut: the header says COMPLETE or gives a cursor. Default view: every matching line; view: "summary" groups them by function and says it does not show every line. Long lines end with ….

Inputs: pattern (required), file, view, cursor, +5 more.

spec_nav_read_functionA

Read functions in full (signature, doc comment, imports used, source with line numbers), up to 10 per call with functions. For code you will not edit; to edit a file, Read it (Edit requires that). Identify by id, or file+name (+line). For a long function or lines outside any function, pass lines to get only ±around lines. Long functions come in parts with a cursor; nothing is cut silently. Answers STALE if the code changed since the id was issued. Does not say whether another service may import it.

Inputs: id, file, line, name, +7 more.

spec_nav_servicesA

The projects under the root as services values, with file and function counts and a coverage summary. Use when unsure of service names or whether SPEC_NAV_ROOT is right; not needed otherwise.

Inputs: no named parameters.

spec_nav_similar_functionsA

Find functions that behave like a given one, whatever they are named, by comparing the calls they make and their body vocabulary. Subject: id, file+name, or code (a draft). Use on a draft before adding code, on a candidate to find siblings, or before changing logic that may be copied elsewhere. Ranked candidates list the calls and words they share. Similar is not interchangeable: read both.

Inputs: id, code, file, line, +8 more.

spec_nav_trace_flowA

Trace a flow across services, statically from source: HTTP client → route → handler, RPC call → handler, event/topic → consumers, plus direct calls inside each service. Use when a change touches an endpoint, RPC call or event. Start from a function (id or file+name), an endpoint or a topic; no start lists every link found. Each step has evidence, a confidence and a status (resolved, partial, ambiguous, unresolved, unmatched); partial, ambiguous and unresolved links are leads to check, and stacks without an adapter are reported as not traced.

Inputs: id, file, line, name, +9 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 8 tools

    Disambiguation4/5

    Most tools target distinct operations: regex text search (map), behavior-keyword search (find_functions), structural similarity (similar_functions), catalog listing (functions), full read (read_function), call sites (callers), flow tracing (trace_flow), and service listing (services). The main risk is overlap among map, find_functions, and similar_functions, but the descriptions explicitly differentiate them (regex vs lexical vs call/body comparison) and cross-reference each other. Boundaries are clear enough that misselection is unlikely.

    Naming Consistency5/5

    Every tool uses the same snake_case style under a uniform spec_nav_ prefix, with predictable noun/verb phrases (find_functions, read_function, trace_flow, callers). No mixing of camelCase or alternate conventions. The convention is consistent and readable throughout.

    Tool Count5/5

    Eight tools is well-scoped for a read-only code navigation server, with each tool covering a distinct navigation concern (search, discovery, similarity, catalog, read, callers, flow, services). No tool feels redundant or padded.

    Completeness4/5

    The surface covers the core navigation lifecycle: discover, list, read, find similar, find callers, and trace cross-service flows, plus a service inventory. Gaps are minor: no dependency/import-graph or class-hierarchy tool, and non-call symbol references (constants, types) aren't directly searchable, but agents can largely work around these with map and functions.

    Maintenance

    ActivityNo data
    ResponsivenessSyncing

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that transforms codebases into intelligent, queryable knowledge bases, enabling AI assistants to perform semantic search, explore architecture, and analyze code relationships.
      166
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that gives AI agents structured code understanding and precise code intelligence via local indexing of AST, call graphs, and semantic search.
      77 npm
      4
      Apache 2.0
    • A
      license
      A
      quality
      D
      maintenance
      An MCP server that helps AI agents comprehend a codebase by providing tools for navigating, searching, and understanding code structure and history.
      10
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that enables AI agents to navigate and understand codebases through file descriptions, semantic search, and code recommendations without repeatedly scanning files.
      MIT