codebase-cartographer

codebase-cartographer

Maps a local Python repository into an AST-backed symbol graph and performs verified multi-file refactors, enabling scope-aware renaming, moving, and deletion of symbols with safety checks.

Category
Visit Server

README

Codebase Cartographer

An MCP server that maps a local Python repository into an AST-backed symbol graph and performs verified multi-file refactors on it.

Most coding agents refactor by grepping for a string and rewriting what they find. That approach cannot tell a call to compute() apart from a local variable that happens to be named compute, and it has no idea which twelve files break when you rename it. This server gives the model a real index instead: scope-resolved references, an import graph, and a two-phase edit protocol that refuses to write anything it cannot verify.

What it does

Maps. Walks the repository (honouring .gitignore), parses every module, and builds a symbol table of functions, classes, methods, and module-level variables, plus the import graph between modules.

Resolves. Finds references using real scope analysis — the LEGB chain, global and nonlocal declarations, comprehension scopes, walrus bindings, and the rule that class bodies are invisible to nested functions. A local variable that shadows a module-level symbol is not a reference to it, and the tool knows the difference.

Refactors. Renames, moves, and deletes symbols across every file that touches them — rewriting from x import y, import x + x.y attribute access, as aliases, and __all__ entries. Nothing is written until you apply a plan you have seen the diff for.

Safety model

Refactoring is two-phase, and the first phase never touches disk.

  1. plan_rename_symbol / plan_move_symbol / plan_delete_symbol return a plan id, a unified diff, and a list of warnings. Every touched file's content hash is recorded.
  2. apply_plan re-checks those hashes (aborting if anything changed on disk since planning), builds the new content for every file, re-parses each one, and refuses to write if any file would end up unparseable. Originals are copied to .cartographer-backups/<plan_id>/. A failure mid-write rolls every file back.

Further guardrails: paths outside the mapped root are rejected; renaming a method requires an explicit allow_heuristic=true because attribute matching cannot be resolved without type inference; deleting a symbol that still has references is refused unless forced.

What it cannot see

Static analysis has a hard edge, and the tool is built to say where that edge is rather than to pretend it isn't there.

find_dynamic_references reports string literals matching a symbol name — getattr(mod, "compute"), plugin registries, dotted settings strings, entry-point tables — and detects imports of underscore-prefixed native modules. Those warnings are attached to every refactor plan.

This matters concretely. Renaming JSONDecodeError in a copy of the stdlib json package rewrites all 19 Python references correctly and still breaks the package, because the _json C accelerator resolves that name at runtime through the C API. No pure-Python analysis can follow that. The tool flags the native accelerator import and tells you to check by hand.

Also invisible: from x import * re-exports (reported as a warning), runtime monkey-patching, and references from other languages or config files.

Tools

Tool Purpose
map_repository Scan a directory and build the index. Call this first, and again after applying.
repository_overview Stats, packages, import cycles, most-depended-on modules.
list_modules Indexed modules, filterable by dotted prefix.
file_outline One file's imports and definitions.
search_symbols Find definitions by substring, kind, or module prefix.
get_symbol_source Full source of one definition, with docstring and decorators.
find_references Every scope-resolved use of a symbol.
find_dynamic_references String literals and native imports that static analysis can't follow.
dependency_graph Internal import edges, whole-graph or one module's neighbourhood.
impact_of_change Transitive dependents — the blast radius of editing a module.
find_dead_code Module-level definitions with no discoverable references.
plan_rename_symbol Plan a repository-wide rename. Writes nothing.
plan_move_symbol Plan moving a definition to another module. Writes nothing.
plan_delete_symbol Plan removing a definition and its __all__ entry. Writes nothing.
preview_plan Re-render a pending plan's diff.
list_plans / discard_plan Inspect or drop pending plans.
apply_plan Commit a plan, with hash checks, syntax validation, and backups.

Install

pip install -e .

Register it with an MCP client:

{
  "mcpServers": {
    "codebase-cartographer": {
      "command": "python",
      "args": ["-m", "cartographer"],
      "env": { "CARTOGRAPHER_ROOT": "/path/to/your/repo" }
    }
  }
}

CARTOGRAPHER_ROOT is only the default for map_repository; the tool takes an explicit root argument too.

A typical session

map_repository(root="~/work/service")
  -> 412 files, 1 import cycle, 38k LOC

impact_of_change(module="service.auth.tokens")
  -> 23 transitive dependents

find_references(qualname="service.auth.tokens.decode_jwt")
  -> 31 references across 12 files

find_dynamic_references(name="decode_jwt")
  -> 1 string literal in service/registry.py:44   <- read this before proceeding

plan_rename_symbol(qualname="service.auth.tokens.decode_jwt", new_name="decode_access_token")
  -> plan 9f2a1c: 31 edits across 12 files, with diff

apply_plan(plan_id="9f2a1c")
  -> written, backed up to .cartographer-backups/9f2a1c/

Development

pip install -e ".[dev]"
pytest

65 tests cover scope resolution (shadowing, global, comprehensions, class-body visibility), reference finding across every import style, rename/move/delete correctness, generated-import style, and the apply-phase guarantees: stale-file detection, syntax validation, and rollback.

The suite's strongest check is that the tool refactors its own source — renaming a function across the implementation and the tests, and moving one between modules — after which the full suite still passes against the rewritten copy.

Requirements

Python 3.10+ (uses ast.alias position attributes). Python source only.

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured