mcp-code-indexer-react-ts
# mcp-code-indexer
The source monorepo for **[`code-graph-indexer`](https://www.npmjs.com/package/code-graph-indexer)** — a code-intelligence engine that turns any TypeScript / React / Next.js repo into a queryable **code graph** and serves it five ways: a **CLI**, an **MCP server** for AI agents, an **HTTP + WebSocket API**, a **3D web explorer with a built-in chatbot**, and **local semantic search**.
> **Just want to use it?** You don't need this repo. `npx code-graph-indexer ui --root .` gets you the whole thing — see the [package README](packages/code-indexer-dist/README.md). This repo is for working on the engine itself.
```
┌──────────────┐ ts-morph AST ┌───────────────┐ serve ┌───────────────────────────────────────┐
│ any TS/React │ ───────────────▶ │ code graph │ ─────────▶ │ CLI · MCP · HTTP/WS · 3D UI · semantic │
│ repo │ walk + resolve │ nodes + edges │ │ (consume from anywhere) │
└──────────────┘ └───────────────┘ └───────────────────────────────────────┘
```
Everything is built on [`ts-morph`](https://ts-morph.com), so edges are **resolved by the compiler, not grepped** — and conservative: an edge is drawn only when it resolves to a real indexed node. The indexer is **generic**; it discovers the workspace shape itself and handles monorepos (pnpm / turbo / lerna) and standalone single-package repos alike. Nothing about the target is hardcoded.
---
## Why it exists
An agent asked *"what breaks if I change this?"* normally reads a pile of files
into context and guesses. One graph query answers it exactly, for roughly 1% of
the tokens — because edges come from the TypeScript resolver, not from grep.
The numbers behind that claim, and the query-by-query breakdown, are in the
[package README](packages/code-indexer-dist/README.md#why-it-exists). This file
is about **working on the engine**; that one is about using it.
---
## The graph model
| Node types | Edge types |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `repo` · `app` · `package` · `folder` · `file` · `component` · `function` · `external` | `contains` · `imports` · `calls` · `renders` · `references` · `depends-on` |
Each node carries metrics (`loc`, `exportsCount`), a `status` block (type/lint/build health), and git metadata — enough to build codebase dashboards, impact analysis, and AI-agent navigation on top of.
---
## Quickstart (working on the engine)
```bash
pnpm install
pnpm build # turbo builds core → _shared → engine → server → web (topo order)
pnpm test # unit tests across the engine + schema packages
pnpm typecheck
pnpm lint
```
> Requires Node ≥ 20.19 and pnpm 10 (pinned via `packageManager`; `corepack enable` selects it). `pnpm build` is required before running the CLI or server from source.
Run the full explorer against this repo (or any path):
```bash
pnpm serve --root . # HTTP/WS server on :3002 (serves the built UI too)
pnpm ui # OR: Vite dev server on :5182 with HMR, proxying /api + /ws → :3002
```
`pnpm serve` serves the pre-built web bundle; `pnpm ui` is the hot-reloading dev server for working on the UI itself.
---
## The five surfaces
All resolve the **same engine** against a target repo root.
### 1. 3D explorer + chatbot
The [`apps/web/code-graph`](apps/web/code-graph) front-end — a [`react-force-graph-3d`](https://github.com/vasturiano/react-force-graph) viewer with folder drill-down, type/health coloring, hover tracing, blast-radius highlighting, a 2D fallback, and a chat panel grounded in the graph. It's a pure consumer of the HTTP/WS API: it loads `GET /api/graph`, then applies live `GraphPatch`es over `WS /ws` as you edit files. The published package bundles the built version so `npx code-graph-indexer ui` just works.
### 2. MCP server — 14 tools
Registers over stdio so Claude Code / Cursor can call it directly:
```bash
claude mcp add code-graph -- node "$(pwd)/tools/code-indexer/build/code-indexer/src/index.js"
```
Tools: `index_repo`, `get_graph`, `get_node`, `who_renders`, `who_calls`, `find_references`, `blast_radius`, `find_cycles`, `find_orphans`, `search_nodes`, `get_context_pack`, `build_embeddings`, `semantic_search`, and `open_explorer` (starts the 3D UI and returns its URL). Full descriptions are in the [package README](packages/code-indexer-dist/README.md#2-mcp-server--let-claude--cursor-query-your-code).
### 3. CLI
```bash
node tools/code-indexer/build/code-indexer/src/cli.js index --root /path/to/repo
node tools/code-indexer/build/code-indexer/src/cli.js query blast-radius --id "fn:src/util.ts#format" --root /path/to/repo
```
### 4. HTTP + WebSocket API
```bash
pnpm serve --root /path/to/repo
curl localhost:3002/api/graph | jq '.meta'
# { "root": "/…", "nodeCount": 908, "edgeCount": 2138, "indexerVersion": "…" }
```
Reads, reverse queries, `POST /api/reindex`, `POST /api/chat`, and `WS /ws` for live patches. Bound to `127.0.0.1` only — endpoints are unauthenticated and mutating, so never expose it off-host.
### 5. Semantic search
Local `all-MiniLM-L6-v2` embeddings (384-dim) via [`@huggingface/transformers`](https://github.com/huggingface/transformers.js) — no API key, nothing leaves the machine. It is an **optional dependency**: if it isn't installed, `semantic_search` degrades to lexical search instead of failing.
---
## Architecture
> Deeper rationale — the graph model, why ts-morph, the macro/micro split, and the honest trade-offs — is in [docs/DESIGN.md](docs/DESIGN.md).
A Turborepo of a few focused packages (plus shared config):
```
mcp-code-indexer/
├── packages/
│ ├── code-graph-core/ @repo/code-graph-core — Zod schemas: nodes, edges, snapshot, status
│ └── code-indexer-dist/ code-graph-indexer — the published npm bundle (tsup) + bundled web UI
├── tools/
│ ├── _shared/ @tools/shared — MCP server base (McpServerBase, ToolRegistry), utils
│ └── code-indexer/ code-indexer-mcp — the engine: ts-morph analysis, CLI, MCP server
└── apps/
├── indexer-server/ indexer-server — Express + ws runtime, file-watcher, REST/WS + chat
└── web/code-graph/ code-graph — the React + three.js 3D explorer
```
Dependency flow (leaves first):
```
code-graph-core ─┬─▶ code-indexer ─▶ indexer-server ─┐
_shared ──────┘ ├─▶ code-indexer-dist (the npm package)
web/code-graph ─────────────────────────────────┘
```
- **`code-graph-core`** — the contract. Zod schemas validate every node, edge, and snapshot, so the graph shape is guaranteed end-to-end. Pure and fully unit-tested.
- **`code-indexer`** — the analysis engine. `ts-morph` parsing plus workspace discovery (monorepo vs standalone), incremental snapshots to `.code-graph/`. Doubles as the MCP server.
- **`indexer-server`** — wraps the engine in Express + `ws`, indexes on boot, enriches node status in the background, watches files for live updates, and serves the chat endpoint (local `claude` CLI → API key → heuristic).
- **`web/code-graph`** — the 3D explorer, a pure API consumer.
- **`code-indexer-dist`** — bundles all of the above into the single `code-graph-indexer` npm package, web UI included.
---
## Scripts
| Command | What it does |
| -------------------------- | ---------------------------------------------------- |
| `pnpm build` | Build every package (topo order via turbo) |
| `pnpm typecheck` | `tsc --noEmit` across every package |
| `pnpm test` | Unit tests (schemas + engine) |
| `pnpm lint` | ESLint across all packages (shared flat config) |
| `pnpm serve --root <path>` | Run the server (with UI) against any repo on `:3002` |
| `pnpm ui` | Vite dev server for the explorer on `:5182` |
## Tech
TypeScript (strict) · Turborepo · pnpm workspaces · ts-morph · Zod · Express · ws · @parcel/watcher · React · three.js · Model Context Protocol SDK · Transformers.js · Vitest · tsup.
## Status
`pnpm build` ✓ · `pnpm typecheck` ✓ · `pnpm lint` ✓ · `pnpm test` ✓. CI runs the same gate on every push and PR (`.github/workflows/ci.yml`):
```
install → audit (fails on high) → build → typecheck → lint → test
```
The audit step is explicit because `npm audit` silently reports nothing on a
pnpm workspace — there's no `package-lock.json` for it to read.
TDQS
Scored across 14 tools
Most tools have distinct purposes, but there is minor overlap between 'find_references', 'who_calls', and 'who_renders' since all deal with incoming edges. However, descriptions clearly differentiate them by edge type.
Naming is mostly verb_noun (e.g., index_repo, search_nodes, find_cycles), but 'blast_radius' breaks the pattern with a noun phrase. The 'who_' prefix for call/renders is consistent but unconventional.
14 tools is a well-scoped set for a code indexing server, covering indexing, searching, dependency analysis, and visualization without excessive overlap.
Covers core CRUD (index, read, search) and dependency analysis thoroughly. Missing explicit delete or update tools for the graph, but the server's read-heavy purpose makes this acceptable.