nrupala

codetopo

Community nrupala
Updated

See your codebase the way an agent sees it. Rust code-graph engine: index any repo, query descendants, blast radius, paths. CLI, HTTP API, and MCP server.

codetopo

Registry identity: mcp-name: io.github.nrupala/codetopo

See your codebase the way an agent sees it. codetopo turns a sourcerepository into a queryable code graph — symbols, calls, references, andstructure — with JSON answers an AI coding agent can act on directly.

OpenSSF Best PracticesOpenSSF Scorecard

codetopo holds the OpenSSF Best Practices Passing badge — 100% of 67 criteria.

You are here because an agent just touched your codebase and you want toanswer structural questions fast: what calls this function? what breaks ifI change this? how are these two modules connected? codetopo indexes thetree once and answers those questions as data — counts first, full listsonly when asked — over a CLI, an HTTP API, or the MCP tools your agentalready speaks.

It is deliberately domain-blind: no scoring, no rankings, no opinions aboutwhat the code means. It answers structural questions about source trees, andonly that. Domain meaning belongs to the agents and teams composing on top.

Illustrative mock-up of a codetopo dependency graph (not actual tool output)

Live demo: codetopo.aimlds.org — codetopo's real map of this repository, drawn by codetopo itself and refreshed on every push to main.

60-second quickstart

Requires a stable Rust toolchain (install via rustup).

# Install the four binaries: codetopo (CLI), codetopo-server (HTTP API),
# codetopo-mcp (stdio MCP server), codetopo-acp (stdio ACP agent).
# The packages must be named — a bare install URL fails because the
# repository contains multiple binary packages.
cargo install --git https://github.com/nrupala/codetopo codetopo-cli codetopo-server codetopo-mcp codetopo-acp

# Index a repository (Rust and TypeScript/JavaScript are parsed via tree-sitter)
codetopo index ~/my-project --db graph.db

# Find a symbol's id by name (every surface has this discovery step)
codetopo search connect --db graph.db

# Ask what calls what (the package prefix is your directory's name,
# exactly as indexed — hyphen included)
codetopo descendants my-project::net::Client::connect --db graph.db --expand

That's the whole loop: index once, query as data. Aggregate-firstoutput — totals before lists — keeps token budgets and pipes sane bydefault; --expand brings the full list when you want it.

Example queries

Against the fixture repository used in the project's own end-to-endverification (docs/phase-2-verification.md) — output shown is the realoutput of the CLI:

$ codetopo index crates/codetopo-server/tests/fixture-repo --db graph.db
files indexed: 3
files failed: 0
symbols: 6
nodes: 15
edges: 23
diagnostics: 2

$ codetopo stats --db graph.db
nodes: 15
  package: 1
  module: 3
  file: 3
  function: 6
  external: 2
edges: 23
  calls: 5
  contains: 12
  reads: 6

$ codetopo descendants fixture-repo::alpha::entry --db graph.db --expand
2 descendants of fixture-repo::alpha::entry
fixture-repo::alpha::helper_a
fixture-repo::alpha::helper_b

A few more things you can ask (same engine, same data):

codetopo ancestors <node-id> --db graph.db     # what depends on this node
codetopo blast-radius <node-id> --db graph.db  # what a failure here would take with it
codetopo path <from-id> <to-id> --db graph.db  # shortest typed path between two nodes
codetopo verify --db graph.db                  # verify the hash-chained audit log
codetopo snapshot --db graph.db --out g.json   # portable frozen JSON export of the whole graph
codetopo restore --snapshot g.json --db g2.db  # restore a snapshot into a fresh database

The path answer renders as typed steps, e.g. a --calls--> x --imports--> b(illustrative; exact ids depend on your index).

Giving it to your agent

HTTP API (codetopo-server)

The same queries over JSON, behind Bearer API-key auth, with per-requestmetering — one transport for any client, any language:

echo "demo-key:change-me" > api_keys && chmod 600 api_keys
codetopo-server   # listens on 127.0.0.1:8080 by default

curl -H "Authorization: Bearer demo-key:change-me" -X POST localhost:8080/v1/index \
  -H 'Content-Type: application/json' -d '{"repo_path": "~/my-project"}'
# {"index_id": "<uuid>", "files_indexed": 3, "files_failed": 0, "nodes": 15, "edges": 23, "diagnostics": 2}

curl -H "Authorization: Bearer demo-key:change-me" \
  "localhost:8080/v1/graphs/<uuid>/descendants?node=<node-id>&expand=true"

Eight endpoints under /v1, one index operation plus seven read-onlyqueries: POST /v1/index, GET /v1/graphs/{id}/{descendants, ancestors, blast-radius, path, stats, verify, snapshot, neighborhood, symbol, search}, GET /v1/schema. Full contract inschemas/openapi.yaml (OpenAPI 3.1.0), env knobs(CODETOPO_BIND, CODETOPO_DATA_DIR, CODETOPO_KEYS_FILE,CODETOPO_METERING_LOG) documented in schemas/README.md.

MCP (codetopo-mcp)

A stdio JSON-RPC server exposing the same handler layer as twelve tools —the eight query/integrity tools (codetopo_index, codetopo_descendants,codetopo_ancestors, codetopo_blast_radius, codetopo_path,codetopo_stats, codetopo_verify, codetopo_snapshot) plus discovery(codetopo_search_symbols, codetopo_get_symbol,codetopo_neighborhood, codetopo_describe_schema) — so an in-processagent learns one surface and gets both. MCP answers are identical to the HTTP answers byconstruction: both call the same codetopo-core queries.

{ "mcpServers": { "codetopo": { "command": "codetopo-mcp" } } }

ACP (codetopo-acp)

A stdio agent speaking the Agent Client Protocol — for editors and clientsthat converse with agents instead of calling tools. Open a session on aworking directory and ask code-structure questions in plain language:

→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
← {"jsonrpc":"2.0","id":1,"result":{"agent":"codetopo","protocolVersion":"1.0",
    "agentCapabilities":{"read_only":true,"code_structure":true},"agentInfo":{"name":"codetopo"}}}
→ {"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"/path/to/repo"}}
→ {"jsonrpc":"2.0","id":3,"method":"session/prompt",
    "params":{"sessionId":"<id>","prompt":"blast radius of auth::login"}}
← {"jsonrpc":"2.0","id":3,"result":{"answer":"Blast radius of 'auth::login': 14 nodes — …"}}

Deterministic intent routing (descendants / ancestors / blast-radius / path /stats / snapshot / verify) straight to the same codetopo-core queries —no LLM, no network, no file writes. Edit requests get an honest read-onlyrefusal. stdout carries only protocol frames; diagnostics go to stderr.

Architecture

        ┌─────────────┐   tree-sitter    ┌──────────────┐
        │ source tree │ ───────────────► │ codetopo-    │   extract symbols,
        └─────────────┘   Rust, TS/JS     │ extract      │   calls, references
                                          └──────┬───────┘
                                                 ▼
                                          ┌──────────────┐
                                          │ codetopo-core│   graph model:
                                          │              │   nodes, edges,
                                          │              │   traversal queries
                                          └──────┬───────┘
                                                 ▼
                                          ┌──────────────┐
                                          │ codetopo-    │   SQLite store +
                                          │ store        │   hash-chained
                                          │              │   audit log
                                          └──────┬───────┘
                                                 │
              ┌──────────────────────────────────┼─────────────────────────────┐
              ▼                                  ▼                             ▼                              ▼
       ┌──────────────┐                  ┌──────────────┐               ┌──────────────┐              ┌──────────────┐
       │ codetopo     │                  │ codetopo-    │ Bearer auth  │ codetopo-    │ stdio        │ codetopo-    │ stdio
       │ (CLI)        │                  │ server       │ JSONL        │ mcp          │ JSON-RPC     │ acp          │ ACP
       └──────────────┘                  └──────────────┘  metering    └──────────────┘              └──────────────┘
Crate Role
codetopo-core Graph model, node/edge kinds, all traversal queries, snapshots
codetopo-extract tree-sitter extractors (Rust, TypeScript/JavaScript)
codetopo-store SQLite persistence + tamper-evident, hash-chained audit log
codetopo-cli codetopo headless CLI — the reference query surface
codetopo-server codetopo-server axum HTTP API (thin adapter over core)
codetopo-mcp codetopo-mcp stdio MCP server (thin adapter over core)
codetopo-acp codetopo-acp stdio ACP agent — conversational sessions over the Agent Client Protocol (thin adapter over core)

The CLI, HTTP, MCP, and ACP surfaces are all thin adapters over the samehandlers — they cannot disagree. schemas/ keeps the machine-readablecontracts (OpenAPI 3.1, MCP tool catalogue) checked against the runningservers. The store's audit log follows the trust-primitive pattern usedacross this product line: a hash-chained, append-only record, verified bycodetopo verify / GET …/verify.

Docs

  • docs/render.md — deterministic render: the frozen layout spec (JSON) + SVG rules behind codetopo render
  • docs/protocol-proof.md — MCP/ACP conformance evidence: strict stdio clients + official-schema validation
  • docs/scale-gate.md — the 10,000-file scale gate and its measured record
  • Dockerfile + docker-compose.yml — self-hosted container: the HTTP API over your own indexes
  • docs/phase-2-design.md — API design: endpoints, auth, metering, aggregate-first discipline
  • docs/phase-2-verification.md — end-to-end verification report (fixture numbers above come from here)
  • docs/phase-3-acp-design.md — ACP agent design: wire protocol, intent routing, read-only guarantee
  • docs/phase-3-acp-verification.md — ACP verification report
  • docs/quickstart-verification.md — clean-machine verification of the quickstart and example queries above
  • schemas/README.md — the two agent-facing contracts and where the spec departs from the design doc
  • CODE_SCHEMA.md — the graph schema (§6 sets the aggregate-first rule)

License

  • Engine (codetopo-* crates): AGPL-3.0-or-later (see LICENSES/)
  • Agent-facing contracts (schemas/: OpenAPI 3.1 spec, MCP tool catalogue): Apache-2.0 (see schemas/LICENSE-APACHE)

Owned by Nrupal Akolkar · Built with Muse by Meta — join Muse, then redeem code 101EEK in Settings within 48 hours of joining and we both earn tokens.

MCP Server · Populars

MCP Server · New

    AIAnytime

    Awesome MCP Servers

    A curated directory of Model Context Protocol (MCP) servers, plus runnable reference implementations in Python.

    Community AIAnytime
    wiresage

    MikroTik MCP

    MCP server for Mikrotik

    Community wiresage
    n24q02m

    email

    IMAP/SMTP email for AI agents -- read, send, organize folders, and manage attachments across multiple accounts, with auto-discovery.

    Community n24q02m
    reticlehq

    reticle

    AI agents can generate code, but still struggle to understand what they build. Reticle brings Jev-style machine-native runtime perception to web & desktop applications.

    Community reticlehq
    tubeagentkit

    YouTube MCP Server: Transcripts, Search, Channels & Playlists

    YouTube MCP server: get YouTube video transcripts, search YouTube, browse channels and playlists from Claude, ChatGPT, Cursor and VS Code. Remote, free tier.

    Community tubeagentkit