codegraph-mcp
Provides the ability to export the call graph to Mermaid format for visualization.
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-mcp What would break if I change queue.ts?"
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
An MCP server that indexes a TypeScript/JavaScript codebase into a real call graph and import graph — using TypeScript's own type checker for symbol resolution, not regex or text matching — and exposes it to Claude (or any MCP client) as queryable tools.
Ask Claude things like:
"What would break if I change
queue.ts?""Who calls
createUser?""Show me the dependency graph of this module."
Instead of Claude re-reading your whole codebase to answer, it gets a precise, structural answer from a pre-built graph.
No paid APIs, no paid services. Free npm registry / GitHub used only for testing against real-world code (see below).
Why this exists
Code-intelligence tools that build a persistent, queryable graph of a codebase are one of the fastest-moving categories in AI developer tooling right now — this is a scoped-down, honestly-documented version of that idea, built to demonstrate the underlying technique rather than compete with the production tools in that space (see Limitations below).
Related MCP server: vue-ts-lsp
How it actually works (the part that matters)
Naive versions of this idea use regex or text matching to find function
calls — which breaks constantly (a call inside a comment, a variable that
happens to share a name with a function, an imported name that shadows a
local one). This project instead uses the real TypeScript compiler API:
it builds an actual ts.Program, asks the type checker to resolve every
call expression to its true declaration, and only records an edge when that
resolution succeeds.
This caught a real, non-obvious bug during development: when an identifier
comes from an import { x } from "...", the checker initially returns an
alias symbol pointing at the import binding itself, not the original
declaration — resolving through that alias (checker.getAliasedSymbol) is
what makes cross-file call resolution actually work. Without that step, only
same-file calls would ever be found. See src/parser.ts for the fix.
Verified output
On a hand-written 3-file fixture (test/fixtures/sample-project) — full
automated test suite, 20/20 passing, including cross-file resolution:
--- Call edges (the hard part: cross-file resolution via the type checker) ---
PASS: handleSignup calls createUser (CROSS-FILE — requires alias resolution)
PASS: main calls handleSignup (CROSS-FILE — requires alias resolution)
PASS: createUser calls hashPassword (same-file)
PASS: Exactly 3 call edges (no false positives)
--- Query engine ---
PASS: findCallers(createUser) returns exactly handleSignup
PASS: impactAnalysis(userService.ts) finds index.ts at depth 2 (TRANSITIVE, not direct)
20 passed, 0 failedOn a real, published open-source library (sindresorhus/p-queue, a well-known ~2,000-star npm package) — indexed live via the actual MCP tool call, not a script:
Indexed 5 file(s): 32 symbol(s), 7 call edge(s), 7 import edge(s).with a correctly resolved summary — lowerBound (a binary-search helper)
shown being called from within PriorityQueue.enqueue, and queue.ts
correctly identified as the most depended-on file (3 dependents) — matching
p-queue's actual architecture. This also caught a second real bug: p-queue's
source uses ESM-style imports with explicit .js extensions
(import x from './priority-queue.js') even though the real file on disk is
.ts — extremely common in modern TypeScript/NodeNext projects. The
resolver now handles that extension swap; see src/parser.ts.
Tools
Tool | Description |
| Parse a codebase into a graph. Run this first. |
| Find where a symbol is defined, by name |
| Who calls a given symbol (cross-file aware) |
| What a given symbol calls |
| Direct import relationships for a file |
| Transitive closure of files affected by changing a file |
| Stats: most-called symbols, most-depended-on files |
Setup
git clone https://github.com/SiwarKhalfaoui/codegraph-mcp.git
cd codegraph-mcp
npm install
npm run buildAs a standalone CLI (no Claude needed)
node build/cli.js index /path/to/some/project/src
node build/cli.js summary
node build/cli.js find-definition createUser
node build/cli.js impact src/queue.ts
node build/cli.js export-mermaid calls --out call-graph.mmdConnect it to Claude Desktop
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json
on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"codegraph": {
"command": "node",
"args": ["/absolute/path/to/codegraph-mcp/build/mcpServer.js"]
}
}
}Or test directly without Claude Desktop using MCP Inspector:
npx @modelcontextprotocol/inspector node build/mcpServer.jsDevelopment
npm run dev # run the CLI directly with tsx, no build step
npm test # full automated test suite against the fixture projectArchitecture notes
src/fileDiscovery.ts— walks the filesystem for source files, skippingnode_modules/build output/tests, with cross-platform path normalizationsrc/parser.ts— the core: builds ats.Program, extracts every function/method/class declaration, then resolves every call expression and import specifier via the real type checkersrc/graphStore.ts— persists the graph as JSON, not SQLite. Deliberate tradeoff: a native SQLite binding needs platform-specific compilation (node-gyp), which is exactly the kind of cross-platform friction this project avoids. A repo-sized graph fits comfortably in memory as JSON — SQLite would be the right upgrade for very large monorepos, not for this scope.src/queries.ts— builds in-memory indices (by id, by name, adjacency lists) over the loaded graph and answers the actual questionssrc/mermaid.ts— visual export for human inspectionsrc/mcpServer.ts— wraps the query engine as MCP toolssrc/cli.ts— same functionality as a standalone command-line tool
Known limitations (stated honestly)
Single-language scope. TypeScript/JavaScript only — not the 158 languages some production code-intelligence tools support. This is a focused demonstration of the technique, not a general-purpose tool.
Private class members (
#method) aren't tracked yet. TypeScript's private-field syntax uses a different AST node type than regular method names; this project doesn't yet register or resolve calls to them.Static analysis only. Dynamic dispatch (calling a function stored in a variable that could point at several different implementations) isn't resolved — only calls the type checker can statically determine.
JSON storage, not a real database. Fine at single-repo scale; wouldn't scale cleanly to a huge monorepo (see architecture notes above).
Possible extensions
Support private class members (
#foo) as trackable symbolsIncremental re-indexing (only re-parse changed files) instead of a full rebuild every time
A small web UI rendering the Mermaid export interactively instead of static text
License
MIT
Available Tools
7 toolsfind_calleesFind what a symbol callsB
Find every function/method called from within a given symbol.
Inputs: symbol_id (required), graph_path.
find_callersFind callers of a symbolA
Find every function/method that calls a given symbol, resolved via the real TypeScript type checker (handles cross-file calls correctly, not just same-file text matches). Use find_definition first to get the exact symbol id.
Inputs: symbol_id (required), graph_path.
find_definitionFind where a symbol is definedA
Find the file and line where a function, method, or class is defined, by name.
Inputs: name (required), graph_path.
get_file_dependenciesGet a file's direct import relationshipsB
Show what a file imports, and what imports that file, directly (one hop).
Inputs: file_path (required), graph_path.
get_graph_summaryGet a high-level summary of the indexed codebaseA
Summary stats: file/symbol/edge counts, most-called functions, most-depended-on files.
Inputs: graph_path.
impact_analysisImpact analysis — what depends on this fileA
Find every file that transitively depends on a given file, directly or indirectly, up to a depth limit. Answers 'what could break if I change this file' — the main practical use case for an AI agent about to edit code.
Inputs: file_path (required), max_depth, graph_path.
index_codebaseIndex a codebaseA
Parse a TypeScript/JavaScript codebase into a call graph and import graph, using the real TypeScript type checker for symbol resolution (not regex matching). Run this first before using any query tool.
Inputs: root_dir (required), graph_path.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool addresses a distinct aspect of code graph analysis: initialization, definition lookup, forward/reverse call relationships, direct file dependencies, transitive impact, and summary statistics. There is no overlap between find_callers, find_callees, and impact_analysis, as each operates at a different level of granularity or direction.
Most tools follow a clear verb_noun pattern (index_codebase, find_definition, find_callers, find_callees, get_file_dependencies, get_graph_summary), but impact_analysis breaks the convention as a compound noun rather than an imperative verb phrase. The consistency is strong overall.
Seven tools is a well-scoped count for a code graph server. Each tool covers a necessary capability without redundancy, making the set feel complete and manageable.
The tool surface covers the full lifecycle of code graph exploration: building the graph, finding definitions, traversing callers/callees, examining file dependencies, performing transitive impact analysis, and obtaining summary stats. There are no obvious dead ends or missing core operations.
Maintenance
Related MCP Connectors
Hosted code graph over MCP: exact callers, dependencies, and cross-repo blast radius for AI agents.
Repository knowledge graph MCP server for codebase understanding and debugging.
Coding agents in multi-service codebases routinely rebuild existing helpers, trust stale type definitions, and modify API contracts without knowing who consumes them. Carrick solves this by indexing your entire TypeScript ecosystem across service and repository boundaries. By integrating deeply with the TypeScript compiler, Carrick traces every route, type, and cross-service call while recording function behaviour so agents search by intent rather than name. Delivered via MCP for AI agents and LSP for IDEs, Carrick ensures models see existing endpoints and utilities before generating new code. The scanner is source-available and runs from your CLI or CI pipeline.
Stateless TS/JS compiler facts for agents: references, imports, impact. No repo index or OAuth.
Related MCP Servers
- AlicenseAqualityDmaintenanceA TypeScript-aware MCP server that provides coding agents with repository discovery, code intelligence, and web project context for local codebases. It enables deep symbol navigation, diagnostic reporting, and structural analysis of monorepos without requiring full IDE integration.716 npm1MIT
- AlicenseNot gradedqualityBmaintenanceSelf-contained MCP server providing type-aware code intelligence for TypeScript, JavaScript, and Vue files, exposing tools like hover, definition, references, and diagnostics to Claude Code without requiring global language server installations.MIT
- AlicenseNot gradedqualityCmaintenanceSemantic code intelligence MCP server for TypeScript/JavaScript codebases, enabling AI agents to retrieve specific symbols, types, and relationships without reading entire files.21MIT
- AlicenseAqualityDmaintenanceMCP server that analyzes TypeScript/JavaScript codebases via AST parsing and dependency graph tracing to identify affected tests, detect dead code, circular dependencies, and trace import chains, enabling AI agents to run only relevant tests.1557 npmMIT