codegraph-mcp
Allows indexing and querying code from GitHub repositories, enabling AI agents to analyze symbols, call edges, and cross-language dependencies directly from GitHub-hosted code.
Allows indexing and querying code from GitLab repositories, enabling AI agents to analyze symbols, call edges, and cross-language dependencies directly from GitLab-hosted code.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@codegraph-mcpwho calls get_user"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
codegraph-mcp
Part of the Accountable AI Engineering suite — provable governance for AI agents on infrastructure you own.
A no-train, on-prem code knowledge graph that you serve to AI agents over MCP — with a hash-chained audit row for every read.
Ask yourself:
Do your AI coding agents need to understand a codebase that can't be uploaded to a vendor's cloud?
Have you watched an agent miss that a one-line change breaks a caller in another language — because it only ever saw one file?
When an agent reads your source, could you produce a record of exactly what it read — and prove it wasn't edited after the fact?
If that's your world, you're in the right place. codegraph-mcp gives agents real, structural understanding of your code, on hardware you control:
No training, ever. The graph exists only to answer queries. Your code is never used to rank, sell, or train a model, and nothing leaves the machine.
Overlay, not migration. Point it at any checkout or git URL. Keep hosting your code exactly where it already lives — GitHub, GitLab, an internal mirror, an air-gapped drive.
Provable reads. Every query an agent makes lands in a tamper-evident, hash-chained audit log you can verify offline. "Which agent read what, and when" is a fact you can show a regulator, not a guess.
Sees what one-file context can't. Six languages, with cross-language edges — the dependency a giant context window misses. (Independent research keeps finding graph-structured understanding beats stuffing raw files into a prompt.)
Watch the walkthrough
A full tour — browsing the repo, the setup, the live code graph, and all five demo scenarios running for real (narrated, ~12 min):
![]()
▶ Watch the walkthrough (MP4) — click the thumbnail or the link to play.
Related MCP server: Context Zero Engine
What it does
On every push or re-index, codegraph-mcp parses your source and builds a queryable graph of:
Symbols — functions, methods, classes, and types, with signatures and exact locations.
Call edges — who calls whom, within and across files.
Cross-language edges — the edge nobody else resolves: a TypeScript
fetch('/api/users/:id')linked to the Go and Python handlers that serve that route. These files share no symbol name, so only a structural join finds the dependency.References — every call site / use of a name.
Then it answers the questions an agent (or a human) actually asks: find this symbol, who calls it, what's the blast radius if I change it, what crosses a language boundary here.
Quick start
git clone https://github.com/cognis-digital/codegraph-mcp
cd codegraph-mcp
pip install -e . # or just run via `python -m codegraph`
# 1. Index any repo (a local path, or a git URL it clones read-only)
codegraph index ./examples/sample_repo --db graph.db
codegraph index https://github.com/your-org/your-service.git --db graph.db
codegraph index . --since HEAD~1 --db graph.db # incremental: only what changed
# 2. Query the graph
codegraph query search loadUser --db graph.db
codegraph query impact 7 --db graph.db # transitive callers ("blast radius")
codegraph query xlang --db graph.db # cross-language HTTP edges
# 2b. Visualize the graph — Mermaid (renders inline on GitHub) or Graphviz DOT
codegraph viz --db graph.db --view project --format mermaid
codegraph viz --db graph.db --view impact --symbol 7 --format mermaid
codegraph viz --db graph.db --format dot | dot -Tsvg > graph.svg
# 3. Serve it to an agent over MCP — stdio or HTTP
codegraph token issue ci-agent --scopes read --db graph.db # prints a bearer token
codegraph serve --db graph.db --token cg_XXXX # stdio
codegraph serve --db graph.db --http --port 8765 --require-token # HTTP (POST /mcp)
# Diff the graph between two git refs — what changed in the *shape* of the code
codegraph diff main feature/x --repo .
# 4. Prove what happened
codegraph audit --db graph.db -n 20
codegraph audit --db graph.db --verify # replays the hash chainRun python demo.py to watch it index the sample repo, resolve cross-language edges, trace a blast radius, and verify the audit chain end to end.
See the graph
codegraph viz renders the module-level architecture as Mermaid — drawn inline by GitHub, GitLab, and Obsidian. This is the actual graph of the bundled polyglot sample repo: solid edges are calls, dashed gold edges are the cross-language HTTP boundaries a single-file context window can never see.
flowchart LR
m_api["api<br/>1f · 4s · python"]
m_dotnet["dotnet<br/>1f · 4s · csharp"]
m_jvm["jvm<br/>1f · 4s · java"]
m_server["server<br/>1f · 5s · go"]
m_svc["svc<br/>1f · 5s · rust"]
m_web["web<br/>1f · 4s · typescript"]
m_web -. "HTTP ×2" .-> m_api
m_web -. "HTTP ×2" .-> m_dotnet
m_web -. "HTTP ×2" .-> m_jvm
m_web -. "HTTP ×2" .-> m_server
m_web -. "HTTP ×2" .-> m_svc
m_api -- "calls ×2" --> m_svc
m_jvm -- "calls ×4" --> m_server
m_svc -- "calls ×2" --> m_api
classDef xlang stroke:#f4b400,stroke-width:3px;
class m_api,m_dotnet,m_jvm,m_server,m_svc,m_web xlang;Demos
Five runnable scenarios, each targeting a different audience, in demos/ — run them all with python demos/run_all.py:
Demo | Audience | Shows |
AI agent builders | look-before-you-leap: search → callers → callees → blast radius before an edit | |
Polyglot teams | TS→Go/Python/Java/C#/Rust HTTP edges resolved across the language boundary | |
Staff engineers | hotspots, dead-code orphans, and blast radius for refactor planning | |
Security & compliance | scoped tokens, hash-chained audit, live tamper detection | |
Architects & reviewers | the architecture map as Mermaid and Graphviz DOT |
See docs/ARCHITECTURE.md for how indexing, the graph store, cross-language resolution, the audit chain, and the MCP server fit together.
MCP tools
When you run codegraph serve, the following tools are advertised to the agent host over MCP (initialize → tools/list → tools/call). Every call is scope-checked and audited.
Tool | Purpose |
| Find symbols by name substring (optionally filter by kind). |
| Full record for one symbol id (signature, location, container). |
| Every call site / use of a name. |
| Direct callers of a symbol — includes cross-language edges. |
| What a symbol calls. |
| Transitive callers — the blast radius of a change. |
| All resolved cross-language HTTP edges. |
| Dead-code candidates: functions/methods with no callers and not HTTP entrypoints. |
| Most depended-on symbols (highest caller count) — where changes ripple furthest. |
| Module/package-level dependency graph — the architecture map above the symbols. |
| File / symbol / edge / language counts. |
The server speaks plain JSON-RPC 2.0 — no proprietary transport, no SDK to audit — over either stdio or HTTP. Point a subprocess-style host at codegraph serve, or an HTTP host at codegraph serve --http (bearer token via Authorization: Bearer …, GET /health for readiness). Both transports share the exact same dispatch, scope checks, and audit logging.
Graph diff
codegraph diff <refA> <refB> compares the knowledge graph between two git refs and reports what changed in the shape of the code — not the text:
codegraph diff main feature/x --repo .{ "summary": { "symbols_added": 3, "symbols_removed": 1, "signatures_changed": 2,
"endpoints_added": 1, "cross_language_edges_added": 1, ... },
"cross_language_edges": { "added": [ { "from": "load (typescript)", "to": "get_item (python)" } ] } }That last line is the one a text diff can never give you: a front-end change and a back-end change in the same PR were newly wired together across a language boundary. Reviewers see the contract that just formed.
Security model
Scoped, revocable tokens. Agents authenticate with a bearer token mapped to scopes (
read,audit,admin). Only a salted BLAKE2b hash of each token is stored, so a database leak doesn't leak usable credentials. Revocation is immediate.Tamper-evident audit log. Each record's hash commits to the previous record's hash (BLAKE2b over a canonical JSON encoding). Altering, inserting, or deleting any historical record breaks the chain, and
audit --verifyreports the first broken sequence number. The scheme is simple enough to re-implement in any language for independent verification.Local by construction. SQLite file, standard library only, no outbound network calls except an explicit, read-only
git clonewhen you index a remote.
Language support
Language | Backend | Symbols | Calls | HTTP routes |
Python |
| ✓ | ✓ | ✓ (decorators + |
JavaScript / TypeScript | regex + brace scan | ✓ | ✓ | ✓ ( |
Go | regex + brace scan | ✓ | ✓ | ✓ ( |
Rust | regex + brace scan | ✓ | ✓ | ✓ (axum |
Java | regex + brace scan | ✓ | ✓ | ✓ (Spring |
C# | regex + brace scan | ✓ | ✓ | ✓ (ASP.NET |
Six languages, with cross-language edges resolved between any of them — a single TypeScript fetch('/api/users/:id') resolves to the Python, Go, Rust, Java, and C# handlers serving that route. The extractor interface is language-agnostic; adding a language (or swapping in a tree-sitter backend for one) doesn't touch the indexer or the graph.
Benchmark
The graph earns its keep on the dependency no text search can see: a front-end caller and the back-end handler it depends on share no symbol name, only a route. bench/benchmark.py generates a multi-language repo and measures how often each strategy finds that cross-language dependency:
python bench/benchmark.py --services 120## cross-language dependency recall
(find the front-end caller that breaks if a back-end handler changes)
codegraph (graph impact): 120/120
grep by symbol name: 0/120
grep by route substring: 120/120 (files only, not symbols)100% vs 0%. A symbol-name search can't cross the language boundary at all; a route-substring search finds files but not the symbol-level, transitive impact you actually need. The graph gives you both. (This is the "Navigation Paradox" — independent research finds graph-structured navigation beats retrieval/long-context on exactly these hidden-dependency tasks.)
How it compares
Cloud code assistants give you great comprehension but require sending your code to their infrastructure, where it may be retained or used to improve a model. Self-hosted forges give you control but make you migrate your hosting to get the indexed graph. codegraph-mcp deliberately splits the difference: the comprehension layer is the product, the graph never trains anything, and it overlays the repos you already have.
Cloud assistant | Self-hosted forge | codegraph-mcp | |
Code leaves your machine | yes | no | no |
Used to train a model | often | sometimes | never |
Requires migrating your hosting | no | yes | no — overlays existing repos |
Tamper-evident audit of agent reads | no | roadmap | shipped |
Cross-language dependency graph | partial | Go + TS | 6 langs: Py · JS/TS · Go · Rust · Java · C# |
Runs air-gapped | no | heavy (DB + services) | single file, stdlib + SQLite |
Published benchmark | — | none | yes (reproducible) |
The overlay model is the wedge: you get the indexed graph and the audit trail without leaving GitHub/GitLab, and the audit is tamper-evident today, not on a roadmap.
Testing
pip install -e ".[dev]"
pytest -q # 50 testsLicense
COCL (Cognis Open Collaboration License). © Cognis Digital.
Status: v0.1 — runnable and tested. HTTP transport, KG diff, project-graph, and incremental (
--since) indexing are shipped. Roadmap: more languages (Ruby, Kotlin, PHP) and a watch mode.
Available Tools
11 toolscross_language_edgesB
List resolved cross-language HTTP edges (e.g. a TS fetch -> a Go/Python handler).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. 'List' implies a read-only operation and 'resolved' implies some filtering, but there is no disclosure of permissions, pagination, result completeness, or output characteristics.
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 definition is a single, front-loaded sentence with a useful example and no wasted wording. It is appropriately sized for a zero-parameter list tool.
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 zero-parameter list tool, the description gives enough to understand the core purpose, but without annotations or an output schema it could still clarify return shape, scope, and whether all project edges are returned. The low complexity keeps it from being inadequate, but gaps remain.
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 tool takes zero parameters, so there are no parameter semantics to document. The empty schema is consistent with the description and no additional parameter guidance is needed.
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 states a specific verb and resource: 'List resolved cross-language HTTP edges,' with a concrete example clarifying the resource. It is clear what the tool returns, though it does not explicitly differentiate itself from sibling graph/search tools.
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?
There is no explicit guidance on when to use this tool versus alternatives such as find_references, find_callers, or project_graph. The name and description imply its purpose, but no conditions, exclusions, or selection guidance are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_calleesB
List symbols the given symbol directly calls.
| Name | Required | Description | Default |
|---|---|---|---|
| symbol_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It does contribute one meaningful behavioral fact — "directly" implies a non-transitive, one-hop traversal — but it is silent on whether the call is read-only, what happens with an invalid or leaf symbol, and how the results are shaped.
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?
One sentence, front-loaded with the verb and the scope qualifier "directly"; no filler, hedging, or redundant restatement of the tool name. Every word earns its place.
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?
With no output schema and no annotations, the description should say more about what comes back (symbol list shape, handling of unresolved or dynamic calls, empty result behavior). For a simple one-parameter read tool it is adequate but not 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 0% for the single parameter, so the description must compensate and largely does not: it says "the given symbol" but never explains that symbol_id is an integer identifier or where to get one (get_symbol/search_symbols). This leaves the agent guessing about ID provenance.
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?
A specific verb ("List") plus a precisely defined resource ("symbols the given symbol directly calls"). The word "directly" implicitly marks the depth-1 boundary, which distinguishes it in spirit from find_callers, but no sibling is named so the differentiation is left to inference.
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?
There is no statement of when to use this instead of find_callers, impact_analysis, or cross_language_edges, and no prerequisite guidance such as how to obtain a valid symbol_id. The agent must infer usage entirely from the tool name and the one-line description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_callersB
List symbols that directly call the given symbol (includes cross-language).
| Name | Required | Description | Default |
|---|---|---|---|
| symbol_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'List' implies a read-only operation and 'includes cross-language' is a useful behavioral disclosure, but it says nothing about return shape, ordering, or whether non-symbol edges are included.
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?
A single front-loaded sentence with no waste. The scope qualifiers ('directly', 'cross-language') arrive immediately.
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 one-parameter query tool with no output schema the description is minimally adequate, but it omits how to obtain the symbol_id and what the returned symbol entries contain, gaps that matter for correct invocation.
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 schema coverage is 0% — symbol_id is a bare integer with no description. The description only refers to 'the given symbol' and does not explain the identifier's expected format or that it likely comes from search_symbols, leaving the sole parameter under-specified.
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?
States a specific verb and resource: it lists callers of a given symbol, with the 'directly' qualifier and cross-language scope. This clearly distinguishes it from find_callees (inverse direction) and impact_analysis (transitive), though it doesn't name those siblings explicitly.
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?
There is no explicit when-to-use or when-not guidance. The word 'directly' implicitly separates it from transitive impact tools, but the agent must infer whether to reach for this versus find_references, which is never stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_hotspotsB
Most depended-on symbols (highest caller count) — where changes ripple furthest.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden; it does disclose the ranking metric (caller count) and that results are ordered by dependency weight, which is real value. However, it omits scope (whole project vs. a file), ordering guarantees, how ties are broken, and whether test/vendored symbols are excluded.
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?
A single front-loaded sentence with no filler; the parenthetical metric definition is the most useful part and is placed early. It is arguably too terse for a graph-analysis tool, but nothing in it is wasted.
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 tool with no annotations, no output schema, and an undocumented parameter, the description should say what the returned entries look like and what 'limit' controls. Neither is addressed, so an agent knows the concept but not enough to call it confidently or interpret 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?
There is one parameter, 'limit', with zero schema description coverage, and the description never mentions it. The agent cannot tell whether 'limit' caps returned rows, truncates traversal depth, or is a top-N cutoff, so the description fails to compensate for the documentation gap.
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 defines a specific analysis resource — symbols ranked by highest caller count — which is more than the name alone conveys. It implicitly separates itself from find_callers (callers of one symbol) by framing the result as a global ranking of 'most depended-on symbols', though it never names a sibling explicitly.
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 only implied by the phrase 'where changes ripple furthest', which suggests refactoring-risk or impact triage. There is no explicit when-to-use, when-not-to-use, or statement of which sibling (impact_analysis, find_callers, project_graph) to prefer for adjacent questions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_orphansB
Dead-code candidates: functions/methods with no callers and not HTTP entrypoints.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full behavioral burden, and it does disclose the key semantics: no inbound calls plus exclusion of HTTP entrypoints. The word 'candidates' usefully signals a heuristic rather than a guarantee. However, it omits the major behavioral caveats for dead-code detection (dynamic dispatch, reflection, cross-language or framework-invoked code) and says nothing about read-only safety or result ordering.
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?
One sentence, front-loaded with the payoff ('Dead-code candidates'), qualified immediately by the two defining conditions. No filler. Terseness works against it only in that the sentence is doing definitional rather than operational work.
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 zero-required-param query with no output schema and no annotations, the description answers 'what does this return' conceptually but not concretely: no indication of return shape (symbol objects? file paths?), ordering, or whether the list is truncated at 'limit'. Adequate to call it, not adequate to interpret the result confidently.
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 single optional parameter 'limit' has 0% schema description coverage and the description never mentions it, so its meaning (max candidates returned? default 100?) is undocumented in every field the agent can see. Low stakes for a trivial integer, but the description adds no meaning beyond the raw schema type.
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?
Names the resource precisely: functions/methods with no callers that are not HTTP entrypoints, and frames the output as 'dead-code candidates'. An agent can tell this apart from find_references/find_callers because the defining condition (zero inbound edges) is stated. It stops short of a 5 because the verb is implicit and no sibling is named as an alternative.
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?
There is no when-to-use or when-not-to-use guidance relative to the many sibling graph tools (find_callers, find_references, impact_analysis). The HTTP-entrypoint exclusion is a scoping definition, not usage advice. Nothing warns that results are heuristics that should be verified with find_references before deletion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesC
List every call site / identifier use of a name across the repo.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a read-only listing but says nothing about whether the declaration itself is included, whether results span languages/workspaces, or how results are shaped or bounded. For a graph/reference tool in a repo of unknown size, these omissions matter.
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?
One front-loaded sentence with zero filler. It is efficient, though the brevity is partly a symptom of under-specification rather than disciplined editing.
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?
With no annotations, no output schema, and 0% schema description coverage, the description should explain return shape and scope. It covers neither, so an agent cannot predict whether it gets file:line entries, symbol objects, or whether declarations and dynamic references are included.
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 0% for the single 'name' parameter, so the description must compensate. It does clarify that the argument is an identifier/name and that the scope is repo-wide, which adds some meaning, but it gives no syntax guidance (fully qualified name? case sensitivity? language prefix?).
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?
Clear specific verb and resource: 'List every call site / identifier use of a name across the repo.' The phrase 'every call site / identifier use' signals it is broader than callers alone, but the description never names or contrasts with the obvious siblings find_callers and search_symbols, leaving meaningful overlap for an agent to resolve.
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 statement of when to use this versus find_callers, search_symbols, or impact_analysis. The overlap with find_callers is especially risky since 'call site' is exactly what a callers tool returns, and nothing clarifies when a repo-wide reference sweep is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_symbolB
Fetch one symbol's full record (signature, location, container) by id.
| Name | Required | Description | Default |
|---|---|---|---|
| symbol_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. 'Fetch' communicates a read-only retrieval operation, and 'full record' clarifies the scope of what is returned, which is useful. However, it does not mention behavior for missing/invalid ids, error handling, or explicit non-mutating guarantees.
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 waste. It states the action, the returned fields, and the keying mechanism 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?
For a simple one-parameter lookup with no annotations or output schema, the description covers the basic purpose and return fields. It leaves gaps around when to use it versus search_symbols and how missing/invalid ids are handled, but it is minimally adequate for a straightforward by-id fetch.
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 0%, and the description only restates that lookup is 'by id'. It does not clarify the format, source, or valid range of 'symbol_id' beyond the parameter name already in 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 gives a specific verb and resource: 'Fetch one symbol's full record' and even lists what the record contains. It does not explicitly name or differentiate from the obvious sibling 'search_symbols', but the 'by id' / 'one symbol' phrasing implicitly contrasts with discovery-based 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?
There is no explicit guidance on when to use this tool versus search_symbols or other siblings. 'By id' subtly implies the caller must already have an id, but no conditions, prerequisites, or alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
graph_statsA
Summary counts for the indexed graph (files, symbols, edges, languages).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden, but 'summary counts' inherently implies a cheap read-only operation with no side effects and no arguments. It does not state that explicitly, nor does it note whether results reflect index staleness or refresh state, which is the one behavior that could matter here.
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?
A single sentence with the resource front-loaded and the payload spelled out in a compact parenthetical. Every word earns its place and nothing is buried.
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 trivial no-param counter with no output schema, the description covers what will be returned (files, symbols, edges, languages) well enough to call it confidently. It leaves out only whether counts cover the whole index or a scoped subset, and any staleness caveat.
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 tool takes zero parameters, so there is nothing for the description to disambiguate; baseline for a zero-param tool is 4. The parenthetical list usefully describes output content rather than inputs.
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?
States a specific resource (the indexed graph) and enumerates exactly what is counted (files, symbols, edges, languages). That distinguishes it from every sibling, which query or traverse rather than summarize. It stops short of a crisp verb like 'Returns', but the intent is unambiguous.
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 statement of when to call this versus project_graph or the find_* tools, and no mention of prerequisites such as the index being built first. Usage must be inferred from the word 'summary'. It is only marginally guided by the fact that there are no parameters to misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
impact_analysisC
Transitive callers ('blast radius') of a symbol — what may break if it changes.
| Name | Required | Description | Default |
|---|---|---|---|
| max_depth | No | ||
| symbol_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It conveys that the tool computes transitive callers, but says nothing about traversal direction, depth limits, result format, performance, or how max_depth affects the blast radius.
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 definition is a single front-loaded sentence with no wasted words, and the core concept is immediately visible. Its brevity is appropriate structurally, though it leaves important operational details unstated.
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 graph-traversal tool with two parameters, no annotations, and no output schema, the description is too thin. It does not explain max_depth, result shape, or how transitive callers are ordered or bounded, leaving the agent to infer critical invocation details.
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 0%, so the description must compensate for undocumented parameters. It implies the symbol being analyzed but never explains symbol_id's expected form, and it completely omits max_depth and its default/meaning.
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 states a specific resource and scope: transitive callers, explicitly glossed as 'blast radius' and 'what may break if it changes.' This is clear enough to distinguish it conceptually from direct-caller tools, but it does not explicitly name or contrast with siblings like find_callers 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?
The phrase 'what may break if it changes' implies the use case is impact assessment rather than simple reference lookup. However, there is no explicit guidance on when to choose this over find_callers, find_references, or other graph tools, and no exclusions or prerequisites are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_graphB
Module/package-level dependency graph: modules and the (weighted) edges between them.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses almost nothing: no read-only confirmation, no scope (whole project? current workspace?), no return shape, no size or truncation limits. It also doesn't say what 'weighted' means concretely or how modules are resolved across languages. For a zero-annotation tool this is a substantial disclosure gap.
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?
A single tight sentence with no filler, and the core noun (dependency graph) is front-loaded. It is arguably under-specified rather than over-specified, but nothing in it is wasteful.
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?
With no output schema and no annotations, the description is the only source of truth about what comes back, and it gives just a phrase ('modules and weighted edges'). It doesn't state the scope of the graph, the direction of edges, the meaning of weights, or roughly how large a result to expect — all things an agent needs before invoking and parsing the result.
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 tool takes no parameters at all, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly avoids inventing parameter talk.
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 names a specific resource (module/package-level dependency graph) and states what it contains: modules and weighted edges between them. That is concrete and gives an agent a clear mental model of the output. It stops short of 5 because it never distinguishes itself from graph_stats, cross_language_edges, or impact_analysis, which all sit in adjacent territory.
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?
There is no indication of when to reach for this tool versus graph_stats or impact_analysis, and no note on prerequisites or cost. The agent must infer usage entirely from the resource noun. Only the implicit 'it's a graph' framing gives any selection signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_symbolsB
Search indexed symbols (functions, methods, classes, types) by name substring.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | ||
| limit | No | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It only implies a pre-built index exists ('indexed symbols'); it says nothing about case sensitivity, whether results are ranked or ordered, what happens on truncation at the default limit of 50, or whether the search is scoped to a specific project. For an unannotated, 0%-schema-coverage tool this is a substantial gap.
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?
One sentence, front-loaded with the action and resource, with the kind enumeration and match mode packed in efficiently. No filler; the only cost is that terseness leaves the transparency gaps noted above.
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 annotations and no output schema, so the description is the only source of runtime behavior — and it omits result shape, ordering, case sensitivity, index scope, and truncation. For a 3-parameter search tool with zero schema coverage, more is needed for an agent to call it confidently.
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?
With 0% schema description coverage, the description must compensate and it partially does: 'by name substring' defines the matching semantics of `query`, and the parenthetical '(functions, methods, classes, types)' maps onto the `kind` enum. The `limit` parameter and its truncation behavior are entirely unaddressed.
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?
States a specific verb ('Search') and resource ('indexed symbols'), enumerates the symbol kinds in a parenthetical, and pins down the match mode ('by name substring'). That already separates it from get_symbol (exact retrieval) and find_references (relationship traversal), though it never names those siblings explicitly.
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 substring-match phrase implicitly signals the use case (partial/fuzzy name lookup, as opposed to exact lookup via get_symbol), but the description never states when to prefer this tool over its siblings or what it cannot do. Usage must be inferred from the matching semantics rather than read.
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.
11 tool updates
v0.1.0- First observed
cross_language_edges - First observed
find_callees - First observed
find_callers - First observed
find_hotspots - First observed
find_orphans - First observed
find_references - First observed
get_symbol - First observed
graph_stats - First observed
impact_analysis - First observed
project_graph - First observed
search_symbols
TDQS
Scored across 11 tools
Most tools target clearly distinct graph queries: search vs id-fetch, callers vs callees, transitive impact, orphan detection, hotspot ranking, module graph, and stats. The only soft overlap is find_references (raw call sites/identifier uses by name) versus find_callers (caller symbols, cross-language), which an agent could plausibly mix up despite the descriptions.
Ten of eleven names follow a predictable snake_case verb_noun pattern (search_symbols, get_symbol, find_callers, find_orphans, impact_analysis). The noun-phrase outliers cross_language_edges, project_graph, and graph_stats break the verb-first convention slightly, though they remain readable and self-describing.
Eleven tools is a well-scoped set for a code-graph analysis server; each tool covers a distinct analysis primitive (search, traversal, ranking, aggregation) with no filler. Nothing feels redundant or missing at the count level.
Coverage of the graph-analysis lifecycle is strong: discovery, symbol detail, reference/call traversal, transitive impact, cross-language edges, dead code, hotspots, module graph, and stats. Minor gaps remain — there is no tool to trigger/refresh indexing or to query a path between two symbols (shortest call path), which agents may expect.
Maintenance
Related MCP Connectors
Persistent knowledge graph for AI-augmented teams. Store decisions, findings, and standing rules across agent sessions with semantic search and typed connections. Includes cross-session memory, audit trail, workspace isolation, and secret detection. Built for teams running agents that need to remember. Free until launch with team tier as default, anon trial available.
Shared, permission-aware company context for AI agents, with provenance, approvals and audit.
Intelligent context infrastructure for AI teams: knowledge graph, sessions, tasks, documents.
Deterministic context layer for your codebase: change impact, blast radius, answers with receipts.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAI-native code intelligence graph that builds a persistent knowledge graph of your codebase in Neo4j and exposes it to AI assistants via MCP, enabling contextual code analysis, impact analysis, and dependency tracking.23MIT
- AlicenseNot gradedqualityAmaintenanceA local code-intelligence engine for AI agents that indexes repositories into a PostgreSQL-backed code graph and serves structured, token-budgeted context over MCP and HTTP, enabling targeted queries on symbols, dependencies, contracts, and impact analysis.7Apache 2.0
- AlicenseAqualityCmaintenanceA self-contained, in-memory graph database for AI Agents. Provides semantic code understanding through the Model Context Protocol (MCP).62MIT
- AlicenseNot gradedqualityBmaintenanceTurns a codebase into a queryable graph with semantic search, call graphs, and control/data flow analysis, served to AI coding agents via the Model Context Protocol.100 npmMIT