Skip to main content
Glama
dorkian

code-graph-mcp

by dorkian
README.md
# code-graph-mcp

Local code-intelligence MCP server for mono-repos. It indexes your repo once
into a knowledge graph — packages, components, frontend routes, HTTP calls,
backend routes, handlers — and lets any MCP client (Claude Code, Cursor, Codex
CLI, OpenCode…) query structure directly instead of grepping and re-reading
files on every question.

Ask "where does `LoginPage` land in the backend?" and get
`LoginPage → POST /api/auth/login → auth.login` in one tool call, from a graph
that's already in memory. No file reads, no grep round-trips.

## Why

Agents burn most of their tokens re-discovering structure: listing directories,
grepping for usages, opening five files to trace one request path. This server
front-loads that discovery into a single index pass and then answers structural
questions from memory, with output engineered to be cheap:

- **Compact line-oriented output** — no pretty-printed JSON, no prose padding.
- **Hard token budgets per response** (default ~2k tokens, tunable per call)
  with `…+N more (refine query)` truncation instead of overflow.
- **Path compression** — repo-relative paths, common prefixes stripped in lists.
- **Incremental re-index** — content-hash manifest; unchanged files are never
  reparsed.
- **Savings tracking** — `repo_summary` reports how many tokens of raw file
  reads the session avoided.
- **Zero query-time I/O** — every tool answers from in-memory indexes; only
  `reindex` touches disk.

## What it detects

| Layer | Detected |
|---|---|
| Packages | npm workspaces, any `package.json`, `pyproject.toml`, `requirements.txt` |
| Frontend | React Router routes (`<Route>`, `createBrowserRouter`), exported components, imports, rendered children, custom hooks/stores |
| HTTP calls | `fetch()`, `axios.<method>()`, `axios({...})`, generic `client.get/post/...()`, template-literal URLs normalized (`` `${API}/users/${id}` `` → `/users/:param`) |
| Backend | FastAPI (`@app.get`, `APIRouter(prefix=…)`, `include_router(…, prefix=…)` incl. import aliases), Flask (`@app.route`), Express (`app.get`, `router.post`, `app.use('/prefix', router)`) |
| Cross-layer | frontend call ↔ backend route matching by method + normalized path, `:param`/`{id}`/`${id}` all treated as wildcards |

Parsing is regex/heuristic (deliberately: fast, zero native deps). It won't
catch every dynamic pattern — that's the tradeoff for indexing thousands of
files in milliseconds with two pure-JS dependencies.

## Install

> **`github:dorkian/code-graph-mcp` vs `@dorkian/code-graph-mcp`?**
> The `github:` form tells npx to install straight from
> https://github.com/dorkian/code-graph-mcp — it works the moment the repo is
> public, no npm account involved. `@dorkian/code-graph-mcp` is the package's
> name on the npm registry and only works after `npm publish`; once published,
> you can use either interchangeably (npm installs are faster since they're
> cached and versioned).

### Fastest: let the CLI configure your client

```bash
# Claude Code — writes .mcp.json AND installs the companion skill
npx -y github:dorkian/code-graph-mcp install claude-code --repo .

# Cursor — writes .cursor/mcp.json
npx -y github:dorkian/code-graph-mcp install cursor --repo .

# anything else — prints ready-to-paste config for Claude Desktop, Codex CLI, …
npx -y github:dorkian/code-graph-mcp install
```

That's it — restart your client and ask *"where does LoginPage land in the backend?"*

### Or: let your AI install it

Paste this into Claude Code, Cursor, Codex, or any coding agent with shell access, from inside the repo you want indexed:

```text
Install the code-graph-mcp server in this repo:
1. Run: npx -y github:dorkian/code-graph-mcp install claude-code --repo .
   (if this isn't Claude Code, run `npx -y github:dorkian/code-graph-mcp install`
   and apply the printed config for the client you are instead)
2. Add `.codegraph/` to .gitignore if it isn't there.
3. Run: npx -y github:dorkian/code-graph-mcp --repo . --index
   and show me the node/edge counts it reports.
4. From now on, prefer the code-graph MCP tools (repo_summary,
   find_component_relations, map_frontend_to_backend, search_symbols,
   impact_of_change, visualize_graph) over grep/read_file for questions
   about repo structure, and call reindex after you edit files.
```

Step 4 is a summary of the bundled skill — Claude Code users get the full version automatically at `.claude/skills/code-graph/SKILL.md`.

### Manual

```bash
git clone https://github.com/dorkian/code-graph-mcp.git
cd code-graph-mcp && npm install
node bin/code-graph-mcp.js --repo /path/to/your/repo
```

The graph lives at `<repo>/.codegraph/` — add it to your repo's `.gitignore`.
Pre-warm the cache (e.g. in CI or a git hook):

```bash
code-graph-mcp --repo . --index          # incremental
code-graph-mcp --repo . --index --full   # rebuild from scratch
```

## Client setup (manual configs)

<details>
<summary>Claude Code (.mcp.json)</summary>

```json
{
  "mcpServers": {
    "code-graph": {
      "command": "npx",
      "args": ["-y", "github:dorkian/code-graph-mcp", "--repo", "."]
    }
  }
}
```

Then copy `skills/code-graph/` into `.claude/skills/` (the `install claude-code` command does both).
</details>

<details>
<summary>Cursor (.cursor/mcp.json)</summary>

```json
{
  "mcpServers": {
    "code-graph": {
      "command": "npx",
      "args": ["-y", "github:dorkian/code-graph-mcp", "--repo", "${workspaceFolder}"]
    }
  }
}
```
</details>

<details>
<summary>Claude Desktop (claude_desktop_config.json)</summary>

```json
{
  "mcpServers": {
    "code-graph": {
      "command": "npx",
      "args": ["-y", "github:dorkian/code-graph-mcp", "--repo", "/abs/path/to/repo"]
    }
  }
}
```
</details>

<details>
<summary>Codex CLI (~/.codex/config.toml)</summary>

```toml
[mcp_servers.code-graph]
command = "npx"
args = ["-y", "github:dorkian/code-graph-mcp", "--repo", "/abs/path/to/repo"]
```
</details>

Any other MCP client: it's a plain stdio server — run
`node bin/code-graph-mcp.js --repo <path>` and speak MCP over stdin/stdout.

## Use it as a Claude custom connector (claude.ai / Desktop / mobile)

Claude's custom connectors only accept **remote** MCP servers: Claude connects
to your server URL from Anthropic's cloud, not from your machine, so a local
stdio process can't be added directly — the server must be reachable on the
public internet over Streamable HTTP. That's what `--http` mode is for:

```bash
# on your VPS, next to a checkout of the repo you want indexed
npx -y github:dorkian/code-graph-mcp --repo /srv/my-monorepo \
  --http --port 3333 --auth-token "$(openssl rand -hex 24)"
```

Put it behind your reverse proxy with TLS (Caddy example):

```caddy
graph.yourdomain.com {
    reverse_proxy 127.0.0.1:3333
}
```

Then in Claude: **Settings → Connectors → Add custom connector** and paste

```
https://graph.yourdomain.com/mcp/<your-token>
```

The token-in-URL form exists exactly for this: the connector UI takes a plain
URL (or OAuth), so the secret rides in the path; API/CLI clients can send
`Authorization: Bearer <token>` instead. Keep in mind what you're exposing —
the graph reveals your repo's structure (routes, endpoints, file names), so
treat the URL like a password, rotate the token if it leaks, and never run
`--http` without a token on anything internet-facing. Run it as a systemd
service and add a cron/git-hook `--index` call to keep the graph fresh after
pushes.

**Who can use your hosted URL — and what they get.** Anyone you share
`https://graph.yourdomain.com/mcp/<token>` with can add it as a custom
connector in their own Claude (Settings → Connectors → Add custom connector;
available on all plans — Free accounts can add one custom connector). But be
clear about the model: one running instance indexes **one repo on your
server**, and every connected user queries **that same shared graph**. It is
not multi-tenant — users can't point your instance at their own codebases.
Host it to demo the tool or to give a team a shared brain for one codebase;
for their own repos, users run their own instance (stdio locally via the
install command, or `--http` on their own box).

## Tools

| Tool | Purpose | Key params |
|---|---|---|
| `repo_summary` | Packages, deps, FE/BE routes, counts, session token savings | `detail`, `max_tokens` |
| `find_component_relations` | Everything related to a component/route: children, parents, hooks, endpoints, imports | `name`, `detail` |
| `map_frontend_to_backend` | Full chain `Component → HTTP call → backend route → handler`; works from either end | `name` (component, route, or `/path`) |
| `visualize_graph` | Mermaid/DOT slice: `component-tree` or `fe-to-be` | `name`, `kind`, `format`, `max_nodes` |
| `search_symbols` | Fuzzy find any node by name/path — replaces grep for "where is X" | `query`, `types`, `limit` |
| `impact_of_change` | Blast radius: transitive dependents of a node or file | `name`, `depth` |
| `reindex` | Refresh graph; incremental by default | `full` |

Every tool accepts `max_tokens` (response budget) and, where lists appear,
`detail: "compact" | "full"`.

Example output (`map_frontend_to_backend`, `name: "LoginPage"`):

```
LoginPage -> POST /api/auth/login -> POST /api/auth/login (services/api/app/auth.py) -> auth.login
```

Example diagram (`visualize_graph`, `kind: "fe-to-be"`):

```mermaid
graph LR
  n1(("route /login")) --> n2["LoginPage"]
  n2 -- calls --> n3["POST /api/auth/login"]
  n3 -- hits --> n4[/"POST /api/auth/login"/]
  n4 -- handled by --> n5[["fn login"]]
```

## Storage format

`.codegraph/graph.json` — versioned node/edge lists, loaded into in-memory
Maps (by id, name, file, endpoint path) at startup; a ~1k-file repo loads in
well under a second. `.codegraph/manifest.json` — sha1 per indexed file,
drives incremental re-index and deleted-file pruning. Corrupted or missing
graph files trigger a clean full re-index, never a crash.

## Development

```bash
npm install
npm test   # 57 unit assertions against a bundled fixture mono-repo,
           # an MCP smoke test speaking real JSON-RPC over stdio,
           # and an HTTP smoke test covering --http mode + token auth
```

The fixture under `test/fixture/` is a miniature mono-repo (React app, FastAPI
service, Express service) exercising every detection path including
`include_router` alias resolution and template-literal endpoints.

## Publishing this repo to GitHub

Credentials never leave your machine, so push it yourself:

```bash
cd code-graph-mcp
git init && git add -A && git commit -m "code-graph-mcp v0.2.0"
git branch -M main
git remote add origin https://github.com/dorkian/code-graph-mcp.git
git push -u origin main

# optional: publish to npm so npx works
npm login
npm publish --access public
```

## License

MIT © dorkian

TDQS

A4.2/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: finding relations, impact analysis, frontend-to-backend mapping, reindexing, repo summary, symbol search, and visualization. No two tools overlap in functionality.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., find_component_relations, impact_of_change, map_frontend_to_backend). The naming is predictable and intuitive.

Tool Count5/5

With 7 tools, the set is well-scoped for a code graph analysis tool. Each tool serves a necessary role without redundancy or bloat.

Completeness4/5

The tools cover key operations: search, retrieval, impact analysis, mapping, visualization, and reindexing. A minor gap is direct access to file content or diff capabilities, but the set is comprehensive for its stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues