code-analyze-mcp
Native agent tools (regex search, path matching, file reading) handle targeted lookups well.aptu-coder handles the mechanical, non-AI work: mapping directory structure, extracting symbols, and tracing call graphs. Offloading this to a dedicated tool reduces token usage and speeds up coding with better accuracy.
Benchmarks
Auth migration task on Claude Code against Django (Python) source tree. Full methodology.
Mode | Sonnet 4.6 | Haiku 4.5 |
MCP | 112k tokens, $0.39 | 406k tokens, $0.42 |
Native | 276k tokens, $0.95 | 473k tokens, $0.53 |
Savings | 59% fewer tokens, 59% cheaper | 14% fewer tokens, 21% cheaper |
AeroDyn integration audit task on Claude Code against OpenFAST (Fortran) source tree. Full methodology.
Mode | Sonnet 4.6 | Haiku 4.5 |
MCP | 472k tokens, $1.65 | 687k tokens, $0.72 |
Native | 877k tokens, $2.85 | 2162k tokens, $2.21 |
Savings | 46% fewer tokens, 42% cheaper | 68% fewer tokens, 68% cheaper |
Related MCP server: CodeGraphMCPServer
Overview
aptu-coder is a Model Context Protocol server that gives AI agents precise structural context about a codebase: directory trees, symbol definitions, and call graphs, without reading raw files. It supports 18 languages (see Supported Languages) and integrates with any MCP-compatible orchestrator.
Supported Languages
All languages are enabled by default. Disable individual languages at compile time via Cargo feature flags.
Language | Extensions | Feature flag |
Astro |
| always-on (regex via TypeScript frontmatter extractor) |
C/C++ |
|
|
C# |
|
|
CSS |
|
|
Fortran |
|
|
Go |
|
|
HTML |
|
|
Java |
|
|
JavaScript |
|
|
JSON |
| always-on (regex; first-level key extraction) |
Kotlin |
|
|
Markdown |
|
|
Python |
|
|
Rust |
|
|
TOML |
| always-on (regex; section header extraction) |
TSX |
|
|
TypeScript |
|
|
YAML |
|
|
Installation
Homebrew (macOS and Linux)
brew install clouatre-labs/tap/aptu-coderUpdate: brew upgrade aptu-coder
cargo-binstall (no Rust required)
cargo binstall aptu-codercargo install (requires Rust toolchain)
cargo install aptu-coderQuick Start
Build from source
cargo build --releaseThe binary is at target/release/aptu-coder.
Configure MCP Client
Two transports are available. Streamable HTTP is recommended when using orchestrators that spawn delegates (e.g. goose coder): a single server process is shared across the orchestrator and all agents, eliminating extension-drift that occurs when each stdio subprocess gets its own isolated instance.
Streamable HTTP (recommended for multi-agent setups)
With Homebrew, one command starts the server on login and keeps it running:
brew services start aptu-coderThe Homebrew formula starts the server on port 49200 by default. Then add the extension once to ~/.config/goose/config.yaml:
extensions:
aptu-coder:
type: streamable_http
uri: http://127.0.0.1:49200/mcp
name: aptu-coder
timeout: 300Or for Claude Code:
claude mcp add --transport http aptu-coder http://127.0.0.1:49200/mcpTo use a different port, set APTU_CODER_PORT before restarting:
APTU_CODER_PORT=4000 brew services restart aptu-coderTo start directly without brew services:
aptu-coder --port 49200
# or equivalently
APTU_CODER_PORT=49200 aptu-coderstdio (single-client use)
Suitable when only one process needs the server. The client owns the process lifecycle and spawns it automatically:
claude mcp add --transport stdio aptu-coder -- aptu-coderOr add manually to .mcp.json at your project root (shared with your team via version control):
{
"mcpServers": {
"aptu-coder": {
"command": "aptu-coder",
"args": []
}
}
}Tools
All optional parameters may be omitted. Shared optional parameters for analyze_directory, analyze_file, and analyze_symbol:
Parameter | Type | Default | Description |
| boolean | auto | Compact output; auto-triggers above 50K chars |
| string | -- | Pagination cursor from a previous response's |
| integer | 100 | Items per page |
Tool | Purpose | Languages |
| Directory tree with LOC, function, and class counts; respects | all |
| Functions, classes, and imports with signatures and line ranges; returns graceful fallback (line count, file head, no AST) for unsupported extensions | all |
| Lightweight function and import index (~75% smaller than | all |
| Call graph for a named symbol across a directory; callers, callees, call depth | all |
| Create or overwrite a file; creates parent directories | any file |
| Replace a unique exact text block; errors if zero or multiple matches; empty | all |
| Run a shell command; returns stdout, stderr, exit code; output capped and filtered; optional | any |
Tool parameters, constraints, and examples are available via your MCP client's tool inspector or tools/list response.
Output Management
For large codebases, several mechanisms prevent context overflow.
Pagination
analyze_file and analyze_symbol append a NEXT_CURSOR: line when output is truncated. Pass the token back as cursor to fetch the next page. summary=true and cursor are mutually exclusive; passing both returns an error.
# Response ends with:
NEXT_CURSOR: eyJvZmZzZXQiOjUwfQ==
# Fetch next page:
analyze_symbol path: /my/project symbol: my_function cursor: eyJvZmZzZXQiOjUwfQ==exec_command output caps
exec_command applies three independent byte-level caps to prevent large command outputs from flooding the context:
Stream | Cap | Behavior |
stdout | 30,000 chars | Tail-preserving; keeps the last 30k chars |
stderr | 10,000 chars | Tail-preserving; errors appear at the end |
combined | 50,000 chars | Safety net after interleaving |
The 30k stdout cap is data-driven: analysis of 27,981 observed exec_command calls shows only 0.33% exceed this limit. When any cap fires, output_truncated: true is set in the response and recorded in the JSONL metrics.
drain_timeout_secs controls how long the server waits after the child exits for any background subprocess still holding the pipe open. Default is 500 ms (0 or omitted). Negative values return INVALID_PARAMS. When the drain window expires before the pipe closes, output_truncated: true is set.
exec_command output filters
A built-in filter table suppresses per-file noise from chatty CLI tools before output reaches the model. Filters apply to stdout, stderr, and interleaved output on success only; raw output is always preserved on failure.
Command | Behavior |
| Strips diff-stat noise (pipe bars, |
| Strips |
| Strips |
| Caps at 20 lines |
| Caps at 20 lines |
| Strips patch hunks ( |
| Strips GPG signing and gitleaks hook output; caps at 10 lines; empty output replaced with |
| Strips ANSI escape sequences; caps at 100 lines; empty output replaced with |
| Strips gitleaks hook output; caps at 5 lines; empty output replaced with |
| Strips |
| Strips |
Project-local rules can be added in .aptu/filters.toml. Parse errors and unrecognized schema_version values (version != 1) fall back to the built-in table with a logged warning; no crash occurs. When a filter fires, filter_applied in structuredContent identifies which rule matched.
Non-Interactive Pipelines
In single-pass subagent sessions, prompt caches are written but never reused. Benchmarks showed MCP responses writing ~2x more to cache than native-only workflows, adding cost with no quality gain. Set DISABLE_PROMPT_CACHING=1 (or DISABLE_PROMPT_CACHING_HAIKU=1 for Haiku-specific pipelines) to avoid this overhead.
The server's own instructions expose a 4-step recommended workflow for unknown repositories: survey the repo root with analyze_directory at max_depth=2, drill into the source package, run analyze_module on key files for a function/import index (or analyze_file when signatures and types are needed), then use analyze_symbol to trace call graphs. MCP clients that surface server instructions will present this workflow automatically to the agent.
Environment Variables
Cache and runtime
Variable | Default | Description |
|
| LRU cache size for directory-analysis results. |
|
| Directory for the L2 on-disk call-graph cache used by |
| unset | Set to |
|
| LRU cache size for |
|
| TTL in seconds for |
|
| LRU cache size for file-analysis results. |
| unset | Absolute path for a one-shot JSONL metrics export on shutdown. |
| unset | Port for streamable HTTP mode. Equivalent to |
| unset | Tool subset: |
| unset | Shell for |
Telemetry
Variable | Default | Description |
| unset | Set to |
| unset | Set to |
| unset | OTLP HTTP endpoint URL (e.g., |
| unset | Reserved per OTel GenAI conventions; aptu-coder does not implement this -- bounded parameters are recorded as span attributes instead. |
|
| Base directory for daily-rotated JSONL metrics files ( |
Observability
The server emits two parallel, independent telemetry streams.
JSONL metrics (always-on) are written daily-rotated to $XDG_DATA_HOME/aptu-coder/ (fallback: ~/.local/share/aptu-coder/) regardless of configuration. Each record captures tool name, duration, output size, and result status. Files are retained for 30 days. See docs/OBSERVABILITY.md for the full schema.
OpenTelemetry export (opt-in) is enabled when OTEL_EXPORTER_OTLP_ENDPOINT is set to an OTLP HTTP endpoint URL. When set, the server initializes OpenTelemetry trace, log, and meter providers and exports asynchronously via OTLP/HTTP. When unset, noop providers are used with zero runtime overhead.
Each tool invocation is wrapped in a span carrying OpenTelemetry GenAI semantic attributes (gen_ai.system, gen_ai.operation.name, gen_ai.tool.name). W3C Trace Context is extracted from the MCP _meta field on each call, allowing MCP clients to propagate their trace context so tool spans appear as children in a distributed trace.
For the span attribute policy, the never-record list, and details on what is instrumented, see OBSERVABILITY.md at the repository root.
Documentation
AGENTS.md - Contributor reference: project structure, commands, rmcp footguns, tool parameter constraints
ARCHITECTURE.md - Design goals, module map, data flow, language handler system, caching strategy
CONTRIBUTING.md - Development workflow, commit conventions, PR checklist
DESIGN-GUIDE.md - Design decisions, rationale, and replication guide for building high-performance MCP servers
MCP Best Practices - Best practices for agentic loops, orchestration patterns, MCP tool design, memory management, and safety controls
OBSERVABILITY.md - Metrics schema, JSONL format, and retention policy
ROADMAP.md - Development history and future direction
SECURITY.md - Security policy and vulnerability reporting
License
Apache-2.0. See LICENSE for details.
This server cannot be installed
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/clouatre-labs/aptu-coder'
If you have feedback or need assistance with the MCP directory API, please join our Discord server