Skip to main content

ArchGraph MCP

Tests PyPI version Python versions License: MIT

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

Two HTTP transports are available: streamable-http (recommended) and sse.

uvx archgraph-mcp serve ./your-repo --transport streamable-http --port 3847
uvx archgraph-mcp serve ./your-repo --transport sse --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

Rendering the whole graph gets unreadable past a few hundred nodes no matter how it's laid out. Type a node id into the box in /graph (or double-click any node) to re-center the view on just its neighborhood — ?center=<node_id>&depth=N on /api/graph returns only the nodes within N hops of center, in either direction (dependencies and dependents combined), instead of an arbitrary slice of the full graph.

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

{
  "mcpServers": {
    "archgraph": {
      "url": "http://your-server:3847/mcp"
    }
  }
}

Remote server (SSE):

{
  "mcpServers": {
    "archgraph": {
      "url": "http://your-server:3847/sse"
    }
  }
}

The exact path depends on the installed MCP SDK version — check server logs on startup if a client can't connect.

Start the process itself with uvx archgraph-mcp serve /repo --transport streamable-http --port 3847 (or --transport sse; 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
reanalyze_repository Re-scan the repo and refresh the graph in place

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.

The server only rescans the repository automatically on a cold start with an empty store — once running, it serves whatever was last analyzed and never looks at the repo again on its own (serve's fast-load path just deserializes Kuzu). Call reanalyze_repository() — optionally reanalyze_repository(semantic_index=True) to also refresh the vector index — instead of restarting the server when you want the graph to reflect changes you just made.

Set ARCHGRAPH_REANALYZE_INTERVAL_SECONDS to do this automatically: every N seconds, serve checks the same git fingerprint used for the staleness warning and reanalyzes only if it actually changed — an unchanged repo costs one cheap git status call, not a rescan. Reanalysis is single-flight: if a check or a manual reanalyze_repository() call is still running when the next trigger fires, the new one is discarded rather than queued or run concurrently.

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

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.

  1. Install [semantic] into the tool environment: uvx --with "archgraph-mcp[semantic]" archgraph-mcp analyze ./repo --semantic-index (or uv sync --extra semantic from a clone).
  2. 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 via sentence-transformers, installed separately ( pip install sentence-transformers).
  3. Build the index during analyze, with the flag or the env var: archgraph-mcp analyze ./repo --semantic-index or ARCHGRAPH_BUILD_SEMANTIC_INDEX=1. This writes archgraph.vectors.npz and archgraph.embeddings.json next 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

Multi-arch (amd64/arm64) images are published to GitHub Container Registry on every release:

docker pull ghcr.io/mustafa-zidan/archgraph-mcp:latest
docker run -p 3847:3847 -v /path/to/repo:/repo ghcr.io/mustafa-zidan/archgraph-mcp:latest

Pin a version with ghcr.io/mustafa-zidan/archgraph-mcp:1.1.0, or build locally from the checkout with docker build -t archgraph-mcp .. The image ships with the [semantic] extra installed, so search_nodes_semantic works once an index exists.

Point an MCP client at it over streamable HTTP rather than spawning a command:

{
  "mcpServers": {
    "archgraph": {
      "url": "http://localhost:3847/mcp"
    }
  }
}

Full walkthrough, including persisting the Kuzu store on a volume, in docs/setup-and-mcp.md.

Railway

  1. Connect the GitHub repo at railway.app.
  2. Set the environment variable REPO_PATH=/repo.
  3. Deploy; Railway picks up railway.json automatically.

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)
ARCHGRAPH_REANALYZE_INTERVAL_SECONDS unset (disabled) If set to a positive integer, serve checks every N seconds whether the repo has changed (git HEAD + working tree) and reanalyzes automatically when it has — see below

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:

  1. Bump version in pyproject.toml and add a matching section to CHANGELOG.md, then merge to the default branch.
  2. One-time setup: on PyPI, add a trusted publisher for this repo (workflow release.yml, environment pypi); on GitHub, create an environment named pypi.
  3. 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.

Metadata

Release files for archgraph-mcp 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for archgraph-mcp 1.3.0
File Size Uploaded Provenance Actions
archgraph_mcp-1.3.0.tar.gz 47.4 kB With provenance Details for archgraph_mcp-1.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for archgraph-mcp 1.3.0
File Interpreter ABI Platform Actions
archgraph_mcp-1.3.0-py3-none-any.whl Python 3 none any Details for archgraph_mcp-1.3.0-py3-none-any.whl

Total release size: 89.6 kB

Release files / archgraph_mcp-1.3.0.tar.gz

Download URL archgraph_mcp-1.3.0.tar.gz
Size 47.4 kB
Tags Source
SHA-256 checksum
How to use checksums
fafcc82acd42a548e63b643382b320a72db543c152010bcd935855ebb9fa2573
BLAKE2b-256 checksum
How to use checksums
7920c6fc956fddbb82c7c4e116516d07c49f5f3c12ad0c96a051c23196826b35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Release files / archgraph_mcp-1.3.0-py3-none-any.whl

Download URL archgraph_mcp-1.3.0-py3-none-any.whl
Size 42.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e8e6410146699f1927841c203a06cb2f7cc4e8c53fdda23b55dbde3ede38a067
BLAKE2b-256 checksum
How to use checksums
2f3b7d72b4482517f3f7078b61fa0c136d9ec5e0bec10031d33463ad113660b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

Security for archgraph-mcp 1.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for archgraph_mcp-1.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page