MCP server that builds a knowledge graph of a software codebase
Project description
ArchGraph MCP
ArchGraph MCP turns a repository into a queryable graph. It parses TypeScript, Java, and Kotlin source with Tree-sitter, builds a directed graph of files, symbols, and dependencies, and exposes that graph to AI coding agents over the Model Context Protocol. Instead of grepping for call sites, an agent can ask what a function depends on, what breaks if it changes, or how two nodes connect.
How a repository becomes a queryable graph
Repository
↓
File Scanner (lazy, generator-based)
↓
Parser Layer (Tree-sitter: TypeScript, Java, Kotlin)
↓
Graph Builder (NetworkX DiGraph)
↓
Kuzu Storage (embedded graph DB + full-text search)
↓
Query Engine (BFS, shortest path, impact analysis)
↓
MCP Server (FastMCP: stdio, sse, or streamable-http transport)
↓
AI Agent (Cursor, Windsurf, Claude Code, etc.)
The graph itself lives in NetworkX at query time; traversals (BFS, shortest path, impact analysis) run in memory
against that structure. Kuzu's job is persistence and lexical search: it stores nodes and edges across restarts and
powers BM25-style search_nodes, falling back to substring matching when full-text search finds nothing. Semantic
search is a separate, optional layer: embedding vectors live in NumPy files next to the Kuzu path rather than inside the
graph database itself.
Documentation
This README covers installation, usage, and the reference tables. Three guides go deeper:
- Setup and MCP: install, first-time analyze, environment variables, stdio vs HTTP, Claude Desktop, Cursor, VS Code, remote URLs, Docker, troubleshooting.
- Local build and semantic: developing from a clone,
analyze --semantic-index, embedding backends, and serving with the vector index. - Release cycle: versioning and PyPI releases for maintainers.
Installing it
uvx archgraph-mcp works once the package is on PyPI. Until the first release ships, install from a clone.
From PyPI, with uvx
uvx runs the published tool in an isolated environment, no global install
needed:
uvx archgraph-mcp --help
The optional [semantic] extra pulls in NumPy for search_nodes_semantic and the vector index. Pass it with
--with so the tool environment includes it:
uvx --with "archgraph-mcp[semantic]" archgraph-mcp --help
From a git clone
git clone https://github.com/mustafa-zidan/archgraph-mcp.git
cd archgraph-mcp
uv sync --extra dev --extra semantic
uv run archgraph-mcp --help
Drop --extra semantic if you don't need vector search; the core graph and full-text search work without it.
Analyzing and serving a repository
Examples below use uvx (PyPI). From a clone, replace uvx … with uv run ….
Analyze
uvx archgraph-mcp analyze ./your-repo
This scans the repo, parses it, and writes a Kuzu database (archgraph.kuzu by default). Add --semantic-index to also
build the vector index, which needs [semantic] in the environment:
uvx --with "archgraph-mcp[semantic]" archgraph-mcp analyze ./your-repo --semantic-index
Serve over stdio (local)
Most desktop agents spawn the process and talk over stdin/stdout:
uvx archgraph-mcp serve ./your-repo
With semantic tooling available to the server process:
uvx --with "archgraph-mcp[semantic]" archgraph-mcp serve ./your-repo
Serve over HTTP (remote)
uvx archgraph-mcp serve ./your-repo --transport streamable-http --port 3847
Graph viewer (HTTP transports only)
--graph-ui (or GRAPH_UI=1) exposes a vis-network view at
/graph and raw JSON at /api/graph (optional limit query param, default 500, caps node count for responsiveness).
It's ignored under stdio, since there's no HTTP server to attach it to.
uvx archgraph-mcp serve ./your-repo --transport streamable-http --port 3847 --graph-ui
Wiring it into an MCP client
Full walkthroughs for Claude Desktop, Cursor, VS Code, and remote URLs are in
docs/setup-and-mcp.md. Quick reference below; it requires uv on PATH so uvx resolves.
Core (lexical search_nodes only):
{
"mcpServers": {
"archgraph": {
"command": "uvx",
"args": [
"archgraph-mcp",
"serve",
"/absolute/path/to/your/repo"
]
}
}
}
With [semantic] (NumPy + search_nodes_semantic, once an index exists):
{
"mcpServers": {
"archgraph": {
"command": "uvx",
"args": [
"--with",
"archgraph-mcp[semantic]",
"archgraph-mcp",
"serve",
"/absolute/path/to/your/repo"
]
}
}
}
From a git clone (before a PyPI release, or for development):
{
"mcpServers": {
"archgraph": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/archgraph-mcp",
"archgraph-mcp",
"serve",
"/absolute/path/to/your/repo"
]
}
}
}
Run uv sync --extra dev --extra semantic in that clone before starting the MCP client.
Optional env, e.g. a custom Kuzu path:
{
"mcpServers": {
"archgraph": {
"command": "uvx",
"args": [
"archgraph-mcp",
"serve",
"/path/to/repo"
],
"env": {
"ARCHGRAPH_STORE": "/path/to/repo/.archgraph/archgraph.kuzu"
}
}
}
}
Remote server (streamable-http / SSE):
{
"mcpServers": {
"archgraph": {
"url": "http://your-server:3847/mcp"
}
}
}
Start the process itself with uvx archgraph-mcp serve /repo --transport streamable-http --port 3847 (Docker
instructions below).
The tools it exposes
| Tool | Description |
|---|---|
search_nodes |
Lexical search (FTS + substring fallback) by type |
search_nodes_semantic |
Cosine similarity (requires [semantic] + index) |
trace_dependencies |
What does this node depend on? |
trace_dependents |
What depends on this node? |
impact_analysis |
What breaks if this node changes? |
trace_path |
Shortest path between two nodes |
architecture_summary |
High-level graph summary |
Node ids follow a type:identifier shape, e.g. function:auth.loginUser or file:src/auth.ts. Run search_nodes
first if you don't know the exact id.
search_nodes(query="login", node_type="function")
impact_analysis(node_id="function:auth.loginUser")
trace_path(source_id="file:src/auth.ts", target_id="database:users")
architecture_summary()
Semantic search
Lexical search (search_nodes) matches names and text. Semantic search (search_nodes_semantic) matches meaning, at
the cost of an embedding backend and a build step.
- Install
[semantic]into the tool environment:uvx --with "archgraph-mcp[semantic]" archgraph-mcp analyze ./repo --semantic-index(oruv sync --extra semanticfrom a clone). - Pick a backend via
ARCHGRAPH_EMBED_BACKEND:openai(default):POST {OPENAI_BASE_URL}/v1/embeddings. Works against LM Studio, Ollama's OpenAI-compatible mode, or OpenAI itself.local: in-process models viasentence-transformers, installed separately (pip install sentence-transformers).
- Build the index during analyze, with the flag or the env var:
archgraph-mcp analyze ./repo --semantic-indexorARCHGRAPH_BUILD_SEMANTIC_INDEX=1. This writesarchgraph.vectors.npzandarchgraph.embeddings.jsonnext to the Kuzu file (--store/ARCHGRAPH_STORE).
| Variable | Purpose |
|---|---|
ARCHGRAPH_EMBED_BACKEND |
openai or local |
ARCHGRAPH_EMBED_BATCH_SIZE |
OpenAI HTTP backend: inputs per request (default 64). If the server returns fewer vectors than inputs, the client retries one string per request automatically; set 1 to skip the slow failed-batch attempt. |
OPENAI_BASE_URL |
e.g. http://127.0.0.1:1234/v1 for LM Studio |
OPENAI_API_KEY |
Bearer token (dummy value is fine if the server ignores it) |
OPENAI_EMBEDDING_MODEL |
Model id for /v1/embeddings |
ARCHGRAPH_LOCAL_EMBED_MODEL |
Sentence-transformers model id when backend is local |
The index build and the query-time call must agree on backend and model; a mismatch produces vectors that don't line up, not an error.
Supported languages
- TypeScript / TSX
- Java
- Kotlin (
.kt,.kts)
Version support
Requires Python 3.12+ (requires-python in pyproject.toml). CI
(.github/workflows/test.yml) runs this matrix on every push:
| OS | 3.12 | 3.13 | 3.14 |
|---|---|---|---|
| Linux | ✅ | ✅ | ✅ |
| macOS | ✅ | ✅ | ✅ (built from source) |
| Windows | ✅ | ✅ | ❌ see note below |
Windows + Python 3.14 is excluded from CI. kuzu 0.11.3 ships a cp314 wheel
for Linux but not for Windows or macOS, so both fall back to a source build. macOS's build succeeds because Xcode's
command line tools provide make; the Windows runner has no such toolchain, so the same fallback fails there. It's an
upstream packaging gap, not something this project controls. Docker sidesteps it entirely, since the container is
Linux-based regardless of host OS.
Running it as a service
Docker
docker build -t archgraph-mcp .
docker run -p 3847:3847 -v /path/to/repo:/repo archgraph-mcp
Railway
- Connect the GitHub repo at railway.app.
- Set the environment variable
REPO_PATH=/repo. - Deploy; Railway picks up
railway.jsonautomatically.
Fly.io
fly launch
fly deploy
Environment variables
| Variable | Default | Description |
|---|---|---|
REPO_PATH |
. |
Path to the repository to analyze |
ARCHGRAPH_STORE |
archgraph.kuzu |
Kuzu database path (overrides the default when the CLI does not pass --store) |
PORT |
3847 |
Port for SSE transport |
MCP_TRANSPORT |
stdio |
Transport mode: stdio, sse, or streamable-http |
GRAPH_UI |
unset | Set to 1 / true to enable /graph and /api/graph (same as --graph-ui; HTTP transports only) |
ARCHGRAPH_BUILD_SEMANTIC_INDEX |
unset | Set to 1 / true to build the vector index when serving triggers a full analyze (optional) |
Developing on it
uv sync --extra dev
# or: pip install -e ".[dev]"
Lint and format:
ruff check src tests
ruff format src tests
Markdown (see .mdformat.toml; GFM tables and wrapping):
mdformat README.md CHANGELOG.md docs/
mdformat --check README.md CHANGELOG.md docs/
Static typing:
mypy src
Tests:
pytest tests/ -v
Optional pre-commit hooks run Ruff lint and format on commit:
pip install pre-commit
pre-commit install
Releasing to PyPI
.github/workflows/test.yml runs on every push and PR to main, master, or develop:
uv sync --extra dev, Ruff, mdformat, mypy, and pytest, across Ubuntu, macOS, and Windows on Python 3.12, 3.13, and
3.14.
.github/workflows/release.yml is manual (workflow_dispatch) and publishes to
PyPI via trusted publishing (OIDC, no
long-lived token). To cut a release:
- Bump
versioninpyproject.tomland add a matching section toCHANGELOG.md, then merge to the default branch. - One-time setup: on PyPI, add a trusted publisher for this repo (workflow
release.yml, environmentpypi); on GitHub, create an environment namedpypi. - Run Actions → Release → Run workflow, entering the same version string as in
pyproject.toml.
The workflow tags vX.Y.Z, builds with uv build, publishes to PyPI, signs the artifacts with Sigstore, and creates a
GitHub Release with notes pulled from the changelog. Full maintainer guide:
docs/release-cycle.md.
License
MIT, see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file archgraph_mcp-1.0.1.tar.gz.
File metadata
- Download URL: archgraph_mcp-1.0.1.tar.gz
- Upload date:
- Size: 35.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bb95466f19d0666805621c05c0828a8efde1b1977e9aa62e2f257b65a1b671e
|
|
| MD5 |
874f327d24d5eeb744bec03c4f1db455
|
|
| BLAKE2b-256 |
9ec13eb58da37399efcbbe57db7dad9c6aedc9a7e7d1698f0ece84087285c3dd
|
Provenance
The following attestation bundles were made for archgraph_mcp-1.0.1.tar.gz:
Publisher:
release.yml on mustafa-zidan/archgraph-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
archgraph_mcp-1.0.1.tar.gz -
Subject digest:
3bb95466f19d0666805621c05c0828a8efde1b1977e9aa62e2f257b65a1b671e - Sigstore transparency entry: 2205462392
- Sigstore integration time:
-
Permalink:
mustafa-zidan/archgraph-mcp@8f5c58909d619035678c641cdd97106af89a115b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mustafa-zidan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8f5c58909d619035678c641cdd97106af89a115b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file archgraph_mcp-1.0.1-py3-none-any.whl.
File metadata
- Download URL: archgraph_mcp-1.0.1-py3-none-any.whl
- Upload date:
- Size: 34.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59d47440accc9ac3d037d5feb1a880928418fc24a7ed17785944223187b0ed8d
|
|
| MD5 |
8e0107b7f73d2e08ab7980288f6102cb
|
|
| BLAKE2b-256 |
2fe11da10bff817441456cc689771ea27e71643b7b4ed32489a1f523d522a1e5
|
Provenance
The following attestation bundles were made for archgraph_mcp-1.0.1-py3-none-any.whl:
Publisher:
release.yml on mustafa-zidan/archgraph-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
archgraph_mcp-1.0.1-py3-none-any.whl -
Subject digest:
59d47440accc9ac3d037d5feb1a880928418fc24a7ed17785944223187b0ed8d - Sigstore transparency entry: 2205462398
- Sigstore integration time:
-
Permalink:
mustafa-zidan/archgraph-mcp@8f5c58909d619035678c641cdd97106af89a115b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mustafa-zidan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8f5c58909d619035678c641cdd97106af89a115b -
Trigger Event:
workflow_dispatch
-
Statement type: