Skip to main content
Glama

codegraph πŸ•Έ β€” Your codebase as a graph, for your eyes and your agent

codegraph parses a TypeScript / JavaScript / Vue repository into a graph of files, symbols, and the edges between them β€” imports, calls, component usage, inheritance. A WebGL viewer makes the structure visible; an MCP server lets a coding agent query it instead of grepping.

Quick start Β· Type-aware mode Β· Monorepos Β· MCP tools Β· Recipes Β· Benchmarks Β· Graph schema Β· 繁體中文

Why

grep answers "where does this string appear". It does not answer "what breaks if I change this", "which files are the risky hubs", or "what shape is this codebase". codegraph extracts the structure once, and both you and your agent query it from then on.

On a 400-file app, asking which files matter costs 369 bytes through hubs versus 29.7 KB of file reading β€” roughly 80Γ— less context for the same answer. Full numbers.

Related MCP server: lsp-intelligence

Install

Node >= 20 and pnpm (npm and yarn work too). Nothing is published to npm yet β€” clone and run it.

git clone https://github.com/RexHung0302/codegraph.git
cd codegraph
pnpm install

Quick start

# 1. index a repository
pnpm extract /path/to/your/repo

# 2. look at it
pnpm dev            # http://localhost:5173

# 3. or let an agent query it
pnpm mcp
pnpm extract <repo-path> [--out <file>] [--exclude dir1,dir2] [--types]

Flag

Default

Meaning

--out

web/public/graph.json

where to write the graph

--exclude

–

extra directory names to skip, comma separated

--types

off

resolve through the TypeScript checker instead of by name β€” see Type-aware mode

Always skipped: node_modules, .git, .next, dist, build, out, coverage, .turbo, .vercel, .output, storybook-static, and every .d.ts.

Exclude generated code. Indexing a Prisma client adds thousands of Type nodes that drown out everything else β€” --exclude generated is a common first move.

How it fits together

Three independent pieces, one JSON file between them.

  • src/extract.ts walks the AST with ts-morph and writes graph.json. The only piece that knows about source languages.

  • web/ renders the graph with sigma.js and graphology, ForceAtlas2 running in a worker.

  • src/mcp.ts serves the same file over MCP β€” seven tools, hot-reloading when the graph changes on disk.

Node

Extracted from

Edge

Meaning

Folder / File

directory tree

contains

folder β†’ folder / file

Function

declarations and arrow-function bindings

defines

file β†’ symbol it declares

Class / Interface / Type / Enum

corresponding declarations

imports

file β†’ file

Variable

remaining top-level bindings

calls

caller β†’ callee

renders

file β†’ component it uses

inherits

class extends / implements

Type-aware mode

By default every edge is resolved by name, which is fast and wrong in the corners: a re-export has no declaration to bind to, and repo.name() cannot be told apart from an imported function called name.

pnpm extract <repo> --types runs the same walk with the TypeScript checker turned on. Each identifier is resolved through its symbol first, and the name-based path stays as the fallback, so the mode only ever adds edges β€” it never drops one the default run found.

name-based (default)

--types

Re-exports (export { x } from './x')

missed

followed to the real declaration

Method call on a typed receiver

attributed to any same-named symbol in scope, or missed

attributed to the method's class

Same-name collisions

can produce a wrong edge

resolved by the checker

Vue SFC templates, .vue imports

name-based

unchanged β€” the checker cannot resolve .vue modules

Measured cost (400-file Next.js app)

1.3 s, 246 MB

5.2 s, 706 MB

Measured gain (same app)

–

+168 edges (+140 calls, +28 renders), 0 removed

Memory is the real cost: the default run frees each file's AST as it goes, and the checker cannot, because a file parsed later resolves symbols back into it. On a repo big enough to matter, run it once with --types for a reference graph and stay on the default for quick re-extractions.

meta.typeAware in graph.json records which mode produced it; graph_stats reports it, and reindex keeps it unless you pass types.

Monorepos

Point the extractor at one package, not at the workspace root. Only the configs at the repo root are read β€” tsconfig.json, jsconfig.json, referenced project configs, and the bundler config next to them β€” so from the root of a pnpm/turbo workspace the per-package paths aliases are invisible and imports come out near zero.

pnpm extract apps/web        --out graphs/web.json
pnpm extract packages/ui     --out graphs/ui.json
pnpm mcp graphs/web.json     # one graph per MCP server

Consequences worth knowing before you trust the output:

  • Cross-package edges do not exist. import { Button } from '@acme/ui' resolves to a node_modules symlink, which is never indexed β€” so a package's graph shows it as having no outside dependents. Impact analysis is per package.

  • A package's own aliases work as long as its tsconfig.json sits at the path you extracted, which is the normal layout.

  • Extracting the workspace root "works" in that it produces a graph β€” files and folders are all there β€” but imports, calls and renders collapse. Measured on one pnpm workspace: the root gives 1,610 files and 646 imports; its largest app alone gives 601 files and 1,253 imports. Fewer edges than files on a monorepo is this limitation, not a sparse codebase.

Workspace-wide extraction (reading every package's config and linking @scope/pkg specifiers to the package that declares them) is on the roadmap, not implemented.

MCP server

claude mcp add codegraph -- pnpm --dir /path/to/codegraph mcp /path/to/graph.json

Tool

Answers

graph_stats

which repo is loaded, counts by type

search_nodes

name β†’ node ids

node_info

direct neighbours of a node

impact

transitive dependents / dependencies

hubs

most-connected, riskiest-to-change nodes

orphans

files nobody imports (dead-code candidates)

reindex

re-parse the repo and reload, without restarting

The server reloads whenever the graph file changes on disk, so pnpm extract in another terminal takes effect on the next tool call. Restarting is never required.

Documentation

Goal

Start here

Use it day to day

Recipes β€” seven concrete workflows

Judge whether it is worth it

Benchmarks and cost β€” measured context savings

Drive it from an agent

MCP tools β€” parameters and sample output

Build something on the graph

Graph schema β€” node ids, edge semantics, guarantees

Contribute

CLAUDE.md β€” layout, conventions, and how to verify a change

Limitations

Read these before trusting an edge.

  • No type checker unless you ask for one. By default call edges resolve by name: a declaration in the same file, otherwise a name imported into it. Dynamic dispatch, re-exports, and method calls on typed receivers are missed; identically-named symbols can produce a wrong edge. --types fixes the last three; dynamic dispatch stays out of reach.

  • Vue templates are not parsed. renders edges for SFCs come from one SFC importing another, which works with html, pug, and jsx templates alike β€” but globally registered components are invisible.

  • Monorepos are not handled. Only the configs at the repo root are read, and cross-package imports resolve into node_modules, which is never indexed. Extract one package at a time β€” details.

  • No incremental updates. Every run is a full re-parse.

  • TS / JS / Vue only. Svelte, Python, Go and friends are not supported.

  • The viewer loads the whole JSON. Tens of thousands of nodes render, but ForceAtlas2 needs time to settle and the result is a hairball without clustering.

Development

pnpm test            # vitest: 52 cases over React, Vue and type-checker fixtures
pnpm exec tsc --noEmit
pnpm build           # production build of the viewer

Tests run the extractor against the miniature repos in tests/fixtures/ and drive the MCP server over a real stdio transport. CI runs both on Node 20 and 22. When you change extraction, add a fixture case rather than adjusting an assertion to match the new output.

Roadmap: incremental extraction, clustering in the viewer, Svelte and Astro support, and workspace-wide extraction for monorepos.

License

MIT β€” see LICENSE.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server that gives AI coding agents symbol definitions, dependency graphs, and a live architecture vocabulary for TypeScript/JavaScript repos, with no network or embeddings.
    12
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server providing 29 tools across 5 layers for semantic TypeScript/JavaScript code intelligence, enabling AI agents to find references, trace impacts, guard APIs, and explain errors without text-search false positives.
    28
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    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.
    7
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP 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.
    15
    44
    MIT

View all related MCP servers

Related MCP Connectors

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • A MCP server built for developers enabling Git based project management with project and personal…

  • MCP server for generating rough-draft project plans from natural-language prompts.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/RexHung0302/codegraph'

If you have feedback or need assistance with the MCP directory API, please join our Discord server