Skip to main content

Batho MCP Server

The Batho MCP (Model Context Protocol) server exposes your codebase's structural intelligence to AI agents. Instead of agents issuing dozens of grep and read calls to understand your code, they query pre-built Arrow IPC artifacts with sub-millisecond latency and minimal token consumption.

What It Does​

CapabilityDescription
Zero-copy readsMemory-mapped Arrow IPC — no database, no parsing at query time
Dual-outputCompact markdown for the model (34–38% fewer tokens) + structured JSON for programmatic use
20 tools total (16 default)13 read-only + 3 destructive (default) + 4 admin (opt-in). See Tool Matrix below.
Tool gatingSecure-by-default: 4 admin tools disabled. Enable via batho.yaml, --enable-tool flag, or allowlist. See Tool Gating.
File watcher engineOptional per-repo filesystem monitoring with debounced auto-patching. Enable via add_repo(watch=true). See File Watcher.
Relationship filteringsymbol_roles, confidence_threshold, and relation_direction filters on graph_query, trace_path, search_entities. See Tools Reference.
Community detectionGreedy modularity clustering (networkx) produces architectural summaries at build time
Multi-repo registryRegister multiple repos via add_repo tool — one MCP config entry serves all repos. Registry v3 schema with stable IDs, status tracking, and auto-migration.
Incremental updatesAfter batho patch, the server serves the latest generation — no restart needed
Token budgeting25K token default with automatic truncation and pagination hints

Architecture​

Architecture diagram showing the MCP data flow: source code is built by batho build into Arrow IPC artifacts, the MCP server reads a registry of repos, and serves queries to AI agents over stdio. Agents can add/remove repos via the registry.

Tool Matrix​

Default-Enabled Tools (16)​

ToolPurposeKey Parameters
list_reposList all registered repos with artifact status and entity counts—
add_repoRegister a repository in the MCP registryname, path, watch, debounce_ms
remove_repoRemove a repository from the registryname
graph_overviewHigh-level codebase summary: entity counts, relationship breakdown, communities, ambiguous edge countrepo, response_format, max_tokens
graph_queryFiltered graph query with file/type/name/role/confidence/direction filtersrepo, file_path, entity_types, relation_types, symbol_roles, confidence_threshold, relation_direction, name_pattern, limit, offset
get_entityDetailed info for a single entity including relationshipsentity_id, repo, include_source
trace_pathShortest path between two entities via BFS with role/confidence/direction filterssource_entity_id, target_entity_id, repo, max_depth, relation_types, symbol_roles, confidence_threshold, relation_direction
get_file_graphAll entities and relationships within a filefile_path, repo, include_cross_file_refs
file_connectivityFile-level dependency connectivity in both directions with external-reference summaryfile_path, repo, direction, include_external, min_confidence
search_entitiesSubstring/regex search across entity names with optional role filterquery, repo, entity_types, symbol_roles, limit
get_deltaIncremental changes from the latest patch runrepo, run_id, change_kind, file_path
batho_statusArtifact and watcher status for one or all repos (read-only)repo
batho_list_runsList patch/build run IDs for a repo (read-only)repo, limit
batho_diffQuery node-level changes across runs, entities, or files (read-only)repo, run_id, entity_id, file_path, since
batho_patchRun an incremental patch on an existing artifact (destructive)repo, max_file_size_kb, graph_backend
batho_fixRun integrity verification and repair (destructive)repo, deep, dry_run, target, phase, parallel

Admin Tools (4, disabled by default)​

ToolPurposeKey Parameters
batho_buildRun a full index build (destructive — deletes artifact)repo, full, max_workers, max_file_size_kb, graph_backend
batho_exportExport a JSON view or Pack artifact (destructive — writes files)repo, view, output, index_id, filter_pattern, category, token_budget, json_mode, include_relationships
batho_loadUnpack a transport artifact ZIP (destructive — overwrites artifact)artifact_path, repo, force
batho_gcRun garbage collection and maintenance (destructive — may delete runs)repo, subcommand, run_uuid, older_than

How It Works​

  1. Build — Run batho build --root /path/to/repo to create Arrow IPC artifacts in .batho/artifact/
  2. Start — Run batho mcp to start the stdio-based MCP server (auto-loads ~/.batho/mcp-repos.json)
  3. Connect — Your AI agent (Claude Desktop, Cursor, Windsurf) connects via MCP protocol — one-time config
  4. Register — The agent calls add_repo(name, path) to register repos in the registry
  5. Query — The agent calls tools with repo="name" to explore specific repos without reading raw files

The server reads artifacts using zero-copy memory-mapped I/O. No database process, no network calls, no file parsing at query time. Each tool returns dual output: markdown content for the model and JSON structuredContent for programmatic consumers.

Tool Gating​

Batho uses a secure-by-default tool registration model. Of the 20 total tools, 4 administrative tools are disabled by default to keep the agent's tool surface focused on retrieval and diagnostics:

Disabled by default (Tier-3 admin tools):

  • batho_build — full rebuild (deletes artifact)
  • batho_export — writes export files to disk
  • batho_load — overwrites artifact directory
  • batho_gc — may delete old run artifacts

Enabling Admin Tools​

Option 1: batho.yaml (blocklist)

mcp:
tools:
disabled: [] # Enable all tools (empty blocklist)
# Or selectively: disabled: ["batho_gc"] # keep gc disabled, enable others

Option 2: batho.yaml (allowlist)

mcp:
tools:
enabled: ["graph_overview", "graph_query", "batho_build"] # ONLY these register

When enabled is set, it takes precedence over disabled — only the allowlisted tools register.

Option 3: CLI flag

batho mcp --enable-tool batho_build --enable-tool batho_export

Why Secure-by-Default?​

Admin tools can delete artifacts, overwrite files, or trigger expensive builds. In agent-driven workflows, an AI accidentally calling batho_build --full could wipe a carefully maintained artifact. The default-disabled set ensures agents can only read and diagnose until you explicitly grant write/destructive permissions.

File Watcher Engine​

Batho includes an optional file watcher engine (BathoWatcherEngine) that monitors registered repositories for filesystem changes and automatically triggers batho patch runs after a configurable debounce period.

Enabling the Watcher​

Enable per-repo at registration time:

add_repo(name="myapp", path="/projects/myapp", watch=true, debounce_ms=2000)
ParameterDefaultDescription
watchfalseEnable filesystem monitoring for this repo
debounce_ms2000Milliseconds to wait after last change before patching

How It Works​

  1. Monitor: watchdog observes the repo root (respecting .gitignore and Batho's ignore spec)
  2. Debounce: Rapid changes (e.g., a multi-file refactor) are batched — the patch only runs after debounce_ms of quiescence
  3. Patch: A batho patch run is triggered automatically, producing a new artifact generation
  4. Serve: All connected MCP server processes auto-detect the new generation on their next tool call — no restart needed

Watcher Status​

Check watcher state via batho_status:

batho_status(repo="myapp")

Returns watcher state (active/inactive), pending change count, last patch trigger time, and debounce timer status.

When to Use​

  • Active development: Keep the watcher on so the graph stays fresh as you edit
  • CI/CD: Leave the watcher off — let your pipeline control build/patch timing
  • Read-only analysis: Leave the watcher off — no need for auto-updates if the codebase is static

Registry v3 Schema​

The repo registry (~/.batho/mcp-repos.json) uses a v3 schema with rich metadata per entry:

FieldTypeDescription
idstring (uuid4 hex)Stable identifier generated on add (used by dashboards and build lifecycle)
namestringRepo name (unique key in registry)
pathstringAbsolute path to repository root
modelocal | githubRepo mode (default: local)
branchstring | nullTracked branch (optional)
statusnot_indexed | indexing | ready | stale | errorArtifact status, derived from on-disk state
last_built_atstring (ISO 8601) | nullTimestamp of last successful build
created_atstring (ISO 8601)When the entry was added
watchboolWhether the file watcher is active for this repo
debounce_msintDebounce interval for file watch events
max_file_size_kbint | nullMax file size override for this repo

Auto-Migration​

Older registry entries (v2) are automatically migrated on load:

  • Stable id fields are generated (uuid4)
  • status is derived from the on-disk artifact (ready if artifact exists, not_indexed otherwise)
  • last_built_at is inferred from the latest run's completed_at timestamp
  • The migration is persisted to disk so IDs remain stable across processes

Next Steps​