mcp-code-indexer-react-ts
This MCP server turns any TypeScript/React/Next.js repository into a queryable code graph, enabling AI agents and developers to perform deep code intelligence queries without reading raw files. It exposes 14 tools via the Model Context Protocol, plus an HTTP/WebSocket API and CLI.
index_repo— Index a TS/React repo (monorepo or standalone) into a persistent code graph (.code-graph/graph.json)get_graph— Retrieve the full or summarized code graph, with filtering by node type, depth, fields, and lean mode to minimize token usageget_node— Fetch a single node by its canonical IDwho_renders— Reverse lookup: find which components render a given component (incomingrendersedges)who_calls— Reverse lookup: find which symbols call a given function or component (incomingcallsedges)find_references— Find all incoming edges into a node, optionally filtered by edge type (renders, calls, imports, references, depends-on)blast_radius— Identify everything that transitively depends on a node to assess change impactfind_cycles— Detect dependency cycles (import, render, or call cycles)find_orphans— Identify dead-code candidates: exports that nothing imports, renders, or callssearch_nodes— Fuzzy-find nodes by name or path to resolve rough names to canonical IDsget_context_pack— Retrieve a dense bundle for safely editing a node: source, dependencies, dependents, and blast-radius size in one callbuild_embeddings— Compute local vector embeddings for indexed nodes (incremental, no API key required)semantic_search— Find code by natural-language meaning (e.g. "logic that decides trustee access"), with lexical fallbackopen_explorer— Launch a local 3D web explorer with a built-in chatbot and return its URL for visual graph exploration
mcp-code-indexer
The source monorepo for code-graph-indexer — a code-intelligence engine that turns any TypeScript / React / Next.js repo into a queryable code graph and serves it five ways: a CLI, an MCP server for AI agents, an HTTP + WebSocket API, a 3D web explorer with a built-in chatbot, and local semantic search.
Just want to use it? You don't need this repo.
npx code-graph-indexer ui --root .gets you the whole thing — see the package README. This repo is for working on the engine itself.
┌──────────────┐ ts-morph AST ┌───────────────┐ serve ┌───────────────────────────────────────┐
│ any TS/React │ ───────────────▶ │ code graph │ ─────────▶ │ CLI · MCP · HTTP/WS · 3D UI · semantic │
│ repo │ walk + resolve │ nodes + edges │ │ (consume from anywhere) │
└──────────────┘ └───────────────┘ └───────────────────────────────────────┘Everything is built on ts-morph, so edges are resolved by the compiler, not grepped — and conservative: an edge is drawn only when it resolves to a real indexed node. The indexer is generic; it discovers the workspace shape itself and handles monorepos (pnpm / turbo / lerna) and standalone single-package repos alike. Nothing about the target is hardcoded.
Why it makes development faster, cheaper, and more reliable
Estimated cost of the same question with an agent reading files versus one graph query (typical mid-size repo):
What you ask | Agent alone (read files) | With the code graph | You save |
"What calls | ~30k tokens · ~40s | ~0.4k tokens · <1s | ~99% tokens |
"What breaks if I change this?" | ~50k tokens · ~60s (misses edges) | ~0.6k tokens · <1s (exact) | ~99% tokens |
"Where's the code that does X?" | ~25k tokens · ~30s | ~0.3k tokens · ~2s | ~98% tokens |
"Context to edit this safely" | ~40k tokens · ~50s (5 reads) | ~0.8k tokens · <1s (1 call) | ~98% tokens |
"Any dead code or cycles?" | ~60k tokens · manual audit | ~0.5k tokens · instant | ~99% tokens |
Faster (in-memory lookups, not re-reads) · cheaper (fewer tokens = lower bill) · reliable (compiler-resolved edges — no hallucinated callers, no missed impact).
Related MCP server: code-graph-mcp
The graph model
Node types | Edge types |
|
|
Each node carries metrics (loc, exportsCount), a status block (type/lint/build health), and git metadata — enough to build codebase dashboards, impact analysis, and AI-agent navigation on top of.
Quickstart (working on the engine)
pnpm install
pnpm build # turbo builds core → _shared → engine → server → web (topo order)
pnpm test # unit tests across the engine + schema packages
pnpm typecheck
pnpm lintRequires Node ≥ 20.19 and pnpm 10 (pinned via
packageManager;corepack enableselects it).pnpm buildis required before running the CLI or server from source.
Run the full explorer against this repo (or any path):
pnpm serve --root . # HTTP/WS server on :3002 (serves the built UI too)
pnpm ui # OR: Vite dev server on :5182 with HMR, proxying /api + /ws → :3002pnpm serve serves the pre-built web bundle; pnpm ui is the hot-reloading dev server for working on the UI itself.
The five surfaces
All resolve the same engine against a target repo root.
1. 3D explorer + chatbot
The apps/web/code-graph front-end — a react-force-graph-3d viewer with folder drill-down, type/health coloring, hover tracing, blast-radius highlighting, a 2D fallback, and a chat panel grounded in the graph. It's a pure consumer of the HTTP/WS API: it loads GET /api/graph, then applies live GraphPatches over WS /ws as you edit files. The published package bundles the built version so npx code-graph-indexer ui just works.
2. MCP server — 14 tools
Registers over stdio so Claude Code / Cursor can call it directly:
claude mcp add code-graph -- node "$(pwd)/tools/code-indexer/build/code-indexer/src/index.js"Tools: index_repo, get_graph, get_node, who_renders, who_calls, find_references, blast_radius, find_cycles, find_orphans, search_nodes, get_context_pack, build_embeddings, semantic_search, and open_explorer (starts the 3D UI and returns its URL). Full descriptions are in the package README.
3. CLI
node tools/code-indexer/build/code-indexer/src/cli.js index --root /path/to/repo
node tools/code-indexer/build/code-indexer/src/cli.js query blast-radius --id "fn:src/util.ts#format" --root /path/to/repo4. HTTP + WebSocket API
pnpm serve --root /path/to/repo
curl localhost:3002/api/graph | jq '.meta'
# { "root": "/…", "nodeCount": 908, "edgeCount": 2138, "indexerVersion": "…" }Reads, reverse queries, POST /api/reindex, POST /api/chat, and WS /ws for live patches. Bound to 127.0.0.1 only — endpoints are unauthenticated and mutating, so never expose it off-host.
5. Semantic search
Local Xenova/all-MiniLM-L6-v2 embeddings via transformers.js — no API key, nothing leaves the machine. Falls back to lexical search when the model isn't installed.
Architecture
Deeper rationale — the graph model, why ts-morph, the macro/micro split, and the honest trade-offs — is in docs/DESIGN.md.
A Turborepo of a few focused packages (plus shared config):
mcp-code-indexer/
├── packages/
│ ├── code-graph-core/ @repo/code-graph-core — Zod schemas: nodes, edges, snapshot, status
│ └── code-indexer-dist/ code-graph-indexer — the published npm bundle (tsup) + bundled web UI
├── tools/
│ ├── _shared/ @tools/shared — MCP server base (McpServerBase, ToolRegistry), utils
│ └── code-indexer/ code-indexer-mcp — the engine: ts-morph analysis, CLI, MCP server
└── apps/
├── indexer-server/ indexer-server — Express + ws runtime, file-watcher, REST/WS + chat
└── web/code-graph/ code-graph — the React + three.js 3D explorerDependency flow (leaves first):
code-graph-core ─┬─▶ code-indexer ─▶ indexer-server ─┐
_shared ──────┘ ├─▶ code-indexer-dist (the npm package)
web/code-graph ─────────────────────────────────┘code-graph-core— the contract. Zod schemas validate every node, edge, and snapshot, so the graph shape is guaranteed end-to-end. Pure and fully unit-tested.code-indexer— the analysis engine.ts-morphparsing plus workspace discovery (monorepo vs standalone), incremental snapshots to.code-graph/. Doubles as the MCP server.indexer-server— wraps the engine in Express +ws, indexes on boot, enriches node status in the background, watches files for live updates, and serves the chat endpoint (localclaudeCLI → API key → heuristic).web/code-graph— the 3D explorer, a pure API consumer.code-indexer-dist— bundles all of the above into the singlecode-graph-indexernpm package, web UI included.
Scripts
Command | What it does |
| Build every package (topo order via turbo) |
|
|
| Unit tests (schemas + engine) |
| ESLint across all packages (shared flat config) |
| Run the server (with UI) against any repo on |
| Vite dev server for the explorer on |
Tech
TypeScript (strict) · Turborepo · pnpm workspaces · ts-morph · Zod · Express · ws · @parcel/watcher · React · three.js · Model Context Protocol SDK · transformers.js · Vitest · tsup.
Status
pnpm build ✓ · pnpm typecheck ✓ · pnpm lint ✓ · pnpm test ✓. CI runs the same gate (build → typecheck → lint → test) on every push and PR (.github/workflows/ci.yml).
Available Tools
14 toolsblast_radiusA
Everything that transitively depends on a node — the impact if it changes or breaks
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Target node id | |
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Core behavior (transitive dependencies) is disclosed, but without annotations, more detail is needed—such as output format (list? tree?), potential performance cost, or whether it includes the node itself. Description is adequate but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence is concise and front-loaded. However, it could be slightly expanded to include output or usage hints without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and description does not specify what the tool returns (e.g., list of node IDs, tree, etc.). For a complex graph query tool, this is insufficient for an AI agent to correctly use the results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and tool description adds no additional meaning beyond the schema. Baseline 3 is appropriate as the description does not enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it finds all transitive dependencies of a node, indicating the impact if it changes. Distinguishes from sibling tools like find_references (direct references) and who_calls/who_renders (specific dependency types).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied (use when needing to assess impact of changing a node), but no explicit when-to-use, when-not-to-use, or alternatives are provided. Sibling tool names give context but description does not guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_embeddingsA
Compute local vector embeddings for the indexed nodes (enables semantic_search). Idempotent + incremental — only changed nodes are re-embedded. No-op if the local model is unavailable.
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses idempotence, incremental behavior, and no-op handling for missing model. It does not cover performance or resource implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with purpose and behavior, with no extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description covers purpose, behavior, and edge cases. It lacks explicit mention of prerequisites or return information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single optional parameter 'root'. The description does not add any information beyond the schema's description, so it meets the baseline but does not enhance it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'compute', the resource 'local vector embeddings for indexed nodes', and the purpose 'enables semantic_search'. It is specific and distinguishes from sibling tools like semantic_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides guidance on idempotence, incremental updates (only changed nodes), and graceful degradation (no-op if model unavailable). However, it does not explicitly compare to other tools or state when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_cyclesB
Find dependency cycles in the graph (import/render/call cycles)
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description lacks details on performance, output format, or potential side effects. Only states it finds cycles.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence front-loading key information; no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks description of output (e.g., list of cycle paths), exact definition of cycles, and any prerequisites or limitations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
One parameter 'root' with full schema description. Tool description adds no extra meaning beyond defaulting to cwd.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb 'find' and resource 'dependency cycles,' specifying types (import/render/call cycles). Distinguishes from siblings like find_orphans or find_references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. Sibling tools are listed but not compared.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_orphansA
Dead-code candidates: exported files/components/functions that nothing imports, renders, or calls. Excludes entry points (index/main/App/config) unless includeEntryPoints is set. Heuristic — review, do not auto-delete.
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) | |
| includeEntryPoints | No | Also include index/main/App/config files (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the heuristic nature, warns against auto-delete, and explains the entry point exclusion behavior. This provides adequate transparency for an analysis tool, though it could mention that it only finds exports, not internal unused code.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences with no unnecessary information. It front-loads the purpose ('Dead-code candidates') and adds essential usage guidance efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and only 2 simple parameters, the description is fairly complete. It explains what the tool finds, its heuristic nature, and the entry point behavior. However, it does not describe the output format (e.g., list of paths), which could be useful for an agent to understand the return type.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (both root and includeEntryPoints are described in the schema). The description does not add additional parameter details beyond the schema, so it scores the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it finds dead-code candidates (exported files/components/functions that nothing imports, renders, or calls). The term 'orphans' suggests unused exports, which distinguishes it from siblings like find_references (which find references) and who_calls/who_renders (which find usage). The verb 'find' and resource 'orphans' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides guidance by noting it excludes entry points unless includeEntryPoints is set, and explicitly says 'Heuristic — review, do not auto-delete,' which advises caution. However, it does not explicitly name alternative tools or state when not to use this tool, leaving room for slight ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesB
All references into a node (incoming edges), optionally filtered by edge type
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Target node id | |
| root | No | Repo root (defaults to cwd) | |
| types | No | Edge types to include (renders, calls, imports, references, depends-on) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It explains the basic behavior (incoming edges, optional filtering) but does not disclose output format, pagination, performance, or permission implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with key info. Every word is essential, no fluff. Highly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is brief and lacks details about output format, return structure, or behavior when no references found. Given no output schema and no annotations, the description should provide more context for an AI agent to fully understand the tool's use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema documents all parameters. The description adds no additional meaning beyond 'optionally filtered by edge type', which is already implied by the 'types' parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it finds 'all references into a node (incoming edges)' and optionally filters by edge type. It distinguishes from siblings like 'who_calls' and 'who_renders' by focusing on edge type filtering, but does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'blast_radius' or 'get_node'. It does not mention when not to use it or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_context_packA
One dense bundle for safely editing a node: its source + what it depends on + what depends on it + blast-radius size. Use instead of get_node + source + who_calls + blast_radius.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Target node id | |
| root | No | Repo root (defaults to cwd) | |
| maxRefs | No | Cap on each dependency/dependent list (default 50) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It states the tool provides a bundle for 'safely editing a node' but does not elaborate on what 'safely' entails, side effects, or read-only behavior. It conveys the output contents but lacks depth on behavioral aspects like rate limits or data consistency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the bundle contents and usage tip. Every word earns its place; no unnecessary information. Highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description outlines the four components of the bundle but does not specify their structure or format. It lacks details on pagination, ordering, or how maxRefs affects the output. Adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description does not add meaning beyond the schema. It implies how parameters affect the output (e.g., target node id) but does not discuss default values or usage tips for root and maxRefs. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool bundles a node's source, dependencies, dependents, and blast radius for safe editing. It distinguishes from sibling tools by explicitly naming alternatives like get_node, source, who_calls, and blast_radius.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises using this tool instead of multiple separate calls (get_node + source + who_calls + blast_radius), providing clear guidance on when it is appropriate. However, it does not mention cases where using a subset of those tools might be preferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_graphA
Read the code graph. Defaults to a compact summary on large repos (pass full:true for everything). Narrow with type/depth/lean/fields to keep output small.
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Force the entire graph even when large | |
| lean | No | Drop status/knowledge/git/span from nodes | |
| root | No | Repo root (defaults to cwd) | |
| type | No | Keep only nodes of these types (e.g. component, function) | |
| depth | No | Keep only N levels from the repo root (contains tree) | |
| fields | No | Whitelist of node fields to return | |
| summary | No | Return only counts + top-level structure + cycle count |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Discloses default truncation behavior on large repos and the effect of 'full' and other parameters, but omits side effects, auth needs, or performance implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff. First sentence states purpose, second provides usage guidance. Every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters and no output schema or annotations, the description covers core behavior (read, compact default, narrowing options) adequately. Missing explicit return description and sibling differentiation, but still reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so description need not add much. It groups parameters ('type/depth/lean/fields') and explains default behavior for 'full', but adds limited new semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Read the code graph' with specific verb 'Read' and resource 'code graph'. It also mentions default behavior (compact summary) and the option for full graph, distinguishing it from sibling tools like find_cycles or blast_radius.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on narrowing output using parameters 'Narrow with type/depth/lean/fields to keep output small' and hints about default compact behavior on large repos. However, no explicit comparison to sibling tools or when-not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_nodeB
Read a single node from the persisted code graph by id
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Canonical node id | |
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Only states read operation, but lacks details on caching, permissions, or side effects. Minimal disclosure beyond basic purpose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is a single efficient sentence, front-loads the main action. Could benefit from slightly more context but remains concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple read operation with two parameters and no output schema. Lacks explanation of what a 'node' is or example usage, but sufficient for basic understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers both parameters with descriptions (100% coverage), so description adds no extra semantic value beyond the schema's own documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Read' and resource 'a single node from the persisted code graph by id', clearly distinguishing from sibling tools like get_graph (reads many nodes) or search_nodes (search by criteria).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use vs alternatives. Implication is for known id, but no explicit context or exclusion criteria provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_repoA
Index a TS/React repo (monorepo or standalone) into a code graph and persist it to .code-graph/graph.json
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden of disclosing behavior. It states the tool indexes and persists a file, but does not mention whether it overwrites existing files, requires authentication, or has any side effects. The description is minimally adequate but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that efficiently conveys the main purpose and outcome without any wasted words. It is front-loaded with the key action and result.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that the tool performs a complex operation (indexing a repo into a graph), the description provides the basic function but lacks details about the graph contents, performance implications, or whether the operation is reversible. It is minimally adequate for a simple tool but could be more informative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter ('root') with a description that matches the schema's own description. Since schema coverage is 100%, the description does not add additional meaning beyond what the schema already provides. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: indexing a TS/React repo into a code graph and persisting it to a specific file. It uses a specific verb ('Index') and resource ('TS/React repo'), and distinguishes from sibling tools which perform different actions like searching or finding references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that the tool should be used when one wants to index a repo, but it does not provide explicit guidance on when to use it versus alternatives, nor does it mention prerequisites or exclusions. Given the numerous sibling tools, more context would be helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_explorerA
Start the local 3D web explorer + chatbot for a repo and return its URL. Use when the user asks to SEE/visualize the code graph, open the UI, or explore visually. Starts a background HTTP server on 127.0.0.1 (default port 3002) and indexes the repo; returns the URL to open in a browser.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Port to serve on (default 3002; auto-mentions the next port if taken) | |
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries responsibility. It mentions starting a background HTTP server on 127.0.0.1 default port 3002, indexing the repo, and returning URL. However, it does not clarify if the server persists after tool invocation or if there are side effects like network access, which would be relevant for safety.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: first states purpose and output, second gives usage trigger, third adds behavioral and parameter details. Front-loaded with key information, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description covers expected return (URL). For a tool with two optional params and clear behavior (start server, index, return URL), the description is fairly complete. Could mention non-destructive nature, but not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% coverage with good descriptions. The description adds value by specifying default port 3002 and mentioning 'auto-mentions the next port if taken', which gives practical detail beyond the schema's 'Port to serve on'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool starts a 3D web explorer and chatbot for a repo, returning a URL. It explicitly tells when to use: when user wants to see/visualize the code graph, open UI, or explore visually. This differentiates it from sibling tools like index_repo or get_graph which are more about data retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use when the user asks to SEE/visualize the code graph, open the UI, or explore visually.' This is clear guidance, though it does not explicitly state when not to use, which is acceptable for a simple tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_nodesA
Fuzzy-find nodes by name or path (e.g. "useAuth", "Header") — resolve a rough name to canonical node ids without grepping or guessing ids
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) | |
| type | No | Restrict to node types (component, function, file, …) | |
| limit | No | Max results (default 20) | |
| query | Yes | Free-text name/path to match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Mentions fuzzy matching but does not disclose case sensitivity, match algorithm, scope (name vs path), or any side effects. Insufficient behavioral disclosure for a search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with key information, no wasted words. Extremely concise and structured effectively.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, no annotations, and moderate complexity (4 param, 100% coverage), the description is adequate but lacks behavioral details (e.g., fuzzy algorithm, return format). Missing context for complete understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds minimal value beyond schema: examples for 'query' but no extra detail for 'root', 'type', or 'limit'. Meets baseline but does not exceed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool does fuzzy-finding of nodes by name or path, with concrete examples. Distinguishes from manual grepping or guessing IDs, making the purpose highly specific and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage when you have a rough name and want to avoid grepping, but does not explicitly state when not to use it or mention alternatives like semantic_search. Adequate but lacks exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
semantic_searchA
Find code by MEANING, not just name (e.g. "logic that decides trustee access"). Ranks nodes by embedding similarity; falls back to lexical search (with a hint) if embeddings aren't built.
| Name | Required | Description | Default |
|---|---|---|---|
| root | No | Repo root (defaults to cwd) | |
| type | No | Restrict to node types (component, function, file) | |
| limit | No | Max results (default 20) | |
| query | Yes | Natural-language description of what you are looking for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: ranking by embedding similarity and fallback to lexical search. It does not mention permissions or performance, but the core behavior is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff. The core differentiator is front-loaded, and every word adds meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, behavior, and parameter context well. Absence of output schema is mitigated by clear behavior description, though return format is not detailed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with good descriptions. The description adds value by illustrating the query parameter with an example, which exceeds the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds code by meaning using embeddings, distinguishes from lexical search, and provides a concrete example. It differentiates from sibling tools like search_nodes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for meaning-based search and contrasts with name-based search, but does not explicitly compare to specific siblings or provide when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
who_callsA
Reverse lookup: which symbols call the given function/component id (incoming calls edges)
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Symbol node id (e.g. fn:src/util.ts#helper) | |
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description must carry the full burden. It only states the core functionality without disclosing authentication, rate limits, data freshness, or side effects. Minimal transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It efficiently conveys the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description lacks details on output format or behavior with edge cases (e.g., no results). Given no output schema, more completeness would be helpful. Adequate but not fully informative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with both 'id' and 'root' already described in the input schema. The description adds no additional meaning beyond the schema, meeting the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a reverse lookup for incoming calls edges, specifying the resource (function/component id) and the action. It distinguishes from siblings like 'who_renders' and 'find_references' by focusing on incoming calls.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for finding callers of a given function but does not provide explicit when-to-use or when-not-to-use context, nor does it mention alternatives among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
who_rendersC
Reverse lookup: which components render the given component id (incoming renders edges)
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Component node id (e.g. cmp:src/Foo.tsx#Foo) | |
| root | No | Repo root (defaults to cwd) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full burden. It does not disclose whether the operation is read-only, performance characteristics, or any side effects, leaving the agent guessing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence is concise but lacks details. It is front-loaded but could include more structured guidance without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists and the description fails to explain what the tool returns (e.g., list of component ids, count, or paths). Missing return value information reduces completeness for a graph query tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers both parameters with descriptions (id with example, root with default). Baseline 3 since schema coverage is 100%; description adds no extra parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool does a reverse lookup for which components render a given component id, using 'incoming renders edges'. This differentiates it from siblings like 'who_calls' which likely handles outgoing relationships.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives (e.g., 'find_references'). The description is too terse to provide usage context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v0.4.0- First observed
blast_radius - First observed
build_embeddings - First observed
find_cycles - First observed
find_orphans - First observed
find_references - First observed
get_context_pack - First observed
get_graph - First observed
get_node - First observed
index_repo - First observed
open_explorer - First observed
search_nodes - First observed
semantic_search - First observed
who_calls - First observed
who_renders
TDQS
Scored across 14 tools
Most tools have distinct purposes, but there is minor overlap between 'find_references', 'who_calls', and 'who_renders' since all deal with incoming edges. However, descriptions clearly differentiate them by edge type.
Naming is mostly verb_noun (e.g., index_repo, search_nodes, find_cycles), but 'blast_radius' breaks the pattern with a noun phrase. The 'who_' prefix for call/renders is consistent but unconventional.
14 tools is a well-scoped set for a code indexing server, covering indexing, searching, dependency analysis, and visualization without excessive overlap.
Covers core CRUD (index, read, search) and dependency analysis thoroughly. Missing explicit delete or update tools for the graph, but the server's read-heavy purpose makes this acceptable.
Maintenance
Related MCP Connectors
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Codebase intelligence for AI agents — dead code, blast radius, ownership.
Codebase graphs, caller impact analysis, and recorded project context for AI coding agents.
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceSemantic code indexer with GraphRAG knowledge graph. Index your codebase, search in natural language, and expose everything via MCP so AI agents understand architecture — not just files.474Apache 2.0
- AlicenseAqualityBmaintenanceIndexes a mono-repo into a knowledge graph and provides MCP tools to query code structure—packages, components, routes, HTTP calls—without file reads or grep round-trips.722 npmMIT
- AlicenseNot gradedqualityBmaintenanceCompiler-exact TypeScript code graph MCP server exposing find-references, change impact analysis, and repo map tools for AI agents, powered by the TypeScript compiler via ts-morph.MIT
- AlicenseNot gradedqualityDmaintenanceProvides semantic codebase understanding via a graph, enabling AI agents to search, explore, and plan changes with whole-repo context in a single tool call.33MIT