codegraph-mcp

codegraph-mcp

An MCP server that indexes TypeScript/JavaScript codebases into precise call and import graphs using the TypeScript compiler API, allowing Claude or any MCP client to query definitions, callers, callees, and perform impact analysis.

Category
Visit Server

README

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).

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 failed

On 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
index_codebase Parse a codebase into a graph. Run this first.
find_definition Find where a symbol is defined, by name
find_callers Who calls a given symbol (cross-file aware)
find_callees What a given symbol calls
get_file_dependencies Direct import relationships for a file
impact_analysis Transitive closure of files affected by changing a file
get_graph_summary 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 build

As 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.mmd

Connect 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.js

Development

npm run dev    # run the CLI directly with tsx, no build step
npm test       # full automated test suite against the fixture project

Architecture notes

  • src/fileDiscovery.ts — walks the filesystem for source files, skipping node_modules/build output/tests, with cross-platform path normalization
  • src/parser.ts — the core: builds a ts.Program, extracts every function/method/class declaration, then resolves every call expression and import specifier via the real type checker
  • src/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 questions
  • src/mermaid.ts — visual export for human inspection
  • src/mcpServer.ts — wraps the query engine as MCP tools
  • src/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 symbols
  • Incremental 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

Recommended Servers

playwright-mcp

playwright-mcp

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

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

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

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

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

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

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

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

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

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

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

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

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

Official
Featured
Qdrant Server

Qdrant Server

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

Official
Featured