swarm repositories / source
aboutsummaryrefslogtreecommitdiff

adequate-rust-mcp

Industrial-grade, self-healing MCP server for rust-analyzer.

Dependency Note

This workspace currently consumes libmcp from the public swarm Git surface:

  • https://git.swarm.moe/libmcp.git

Cargo will fetch that dependency automatically on first build.

Crates

  • ra-mcp-domain: strict domain types and lifecycle algebra
  • ra-mcp-engine: resilient rust-analyzer transport + supervisor
  • adequate-rust-mcp: MCP stdio server exposing analysis tools

Guarantees

  • automatic recovery from broken pipes and dead workers
  • bounded request/startup deadlines
  • typed boundaries for lifecycle, faults, and source positions
  • fault-injection integration tests for restart behavior

Runtime Modes

  • default (adequate-rust-mcp): stable host process (Codex-facing stdio endpoint)
  • worker (adequate-rust-mcp --worker): actual MCP tool server process

The host supervises worker generations, drains pending requests with explicit JSON-RPC errors on worker loss, and automatically respawns.

Quick Start

From the workspace root:

cargo run -p adequate-rust-mcp

To launch the disposable worker directly:

cargo run -p adequate-rust-mcp -- --worker

Live Reload

Host mode watches the worker binary path for updates. On Unix it self-reexecs into the new binary and restores live session state before spawning the next worker generation; on other platforms it falls back to worker-only restart. It replays initialize and reconstructs notifications/initialized if needed so replacement workers come up fully live. In-flight requests are replayed across host/worker restarts with bounded at-least-once semantics, so transient rollout and recovery churn is hidden from clients by default.

Environment knobs:

  • ADEQUATE_MCP_WORKER_BINARY: worker binary path to execute/watch (default: current executable)
  • ADEQUATE_MCP_HOST_RELOAD_DEBOUNCE_MS: file-change debounce before reload (default: 250)
  • ADEQUATE_MCP_HOST_RESPAWN_FLOOR_MS: initial respawn backoff floor (default: 100)
  • ADEQUATE_MCP_HOST_RESPAWN_CEILING_MS: respawn backoff ceiling (default: 3000)
  • ADEQUATE_MCP_HOST_QUEUE_CAPACITY: max queued inbound frames while recovering (default: 512)
  • ADEQUATE_MCP_HOST_MAX_REPLAY_ATTEMPTS: replay budget per in-flight request before surfacing an error (default: 8)

Tool Surface

In addition to typed core tools (hover, definition, references, rename_symbol, diagnostics, clippy_diagnostics, fix_everything, health_snapshot, telemetry_snapshot), the server exposes advanced_lsp_request for editing-heavy and advanced rust-analyzer capabilities:

  • completions
  • completion/resolve
  • code actions + resolve
  • code lens + resolve
  • prepare rename
  • rename
  • execute command
  • formatting (document/range/on-type)
  • symbols + workspace symbol resolve
  • document links + resolve
  • colors + color presentation
  • linked editing range, inline value, moniker
  • document/workspace diagnostics
  • selection/folding/inlay hints + inlay resolve
  • semantic tokens (full/range/full-delta), call hierarchy, type hierarchy

hover, definition, references, health_snapshot, and telemetry_snapshot also default to line-oriented porcelain text with render=json opt-in.

diagnostics and clippy_diagnostics split detail from presentation:

  • mode: compact (default), full, or summary
  • render: porcelain (default line-oriented text) or json
  • default responses are model-friendly porcelain text in content
  • render=json exposes the structured payload and schema for programmatic consumers
  • empty definition/references/hover results may include an indexing note during early rust-analyzer warm-up when the empty result could be a false negative
  • transient early-startup unlinked-file / not part of any crate diagnostics are retried during the same warm-up window before surfacing to clients

One-Stop Autofix

fix_everything is the do-the-obvious thing button for agent loops. It runs, in order:

  • workspace formatter command (default: cargo fmt --all)
  • workspace clippy fix command (default: cargo clippy --fix --workspace --all-targets --all-features --allow-dirty --allow-staged)

The output is structured and model-friendly:

  • success: whether all steps exited with status 0
  • workspace_root: resolved workspace root path
  • steps: per-step command argv, exit code, and bounded stdout/stderr excerpts

Input Normalization

User-facing tool inputs are intentionally permissive and normalized at the boundary:

  • file_path accepts absolute paths, file:// URIs, and relative paths (resolved against workspace root)
  • position indices accept numeric strings and integer-like floats
  • 0 indices are normalized to 1 for one-indexed fields
  • alias spellings are accepted for common fields (filePath, lineNumber, character, newName, etc.)
  • advanced_lsp_request.method accepts snake_case, camelCase, kebab-case, and full LSP method paths
  • diagnostics.mode accepts compact (default), full (aliases: raw, verbose), or summary
  • diagnostics.render accepts porcelain (default; aliases: text, plain, plain_text) or json (alias: structured)
  • diagnostics.max_items and diagnostics.max_message_chars accept numeric strings and integer-like floats
  • diagnostics and clippy_diagnostics accept either a single file (file_path) or many files (file_paths/files/paths)
  • clippy_diagnostics accepts the same render controls as diagnostics
  • multi-file diagnostics preserve requested file order and return one fused diagnostics list
  • render=json compact diagnostics use descriptive field names (severity, file_path, start_line, etc.) and descriptive counters (error_count, total_count, ...)

Clippy Gate Integration

clippy_diagnostics runs cargo clippy and filters results to the requested file. Strictness lives in workspace lint configuration:

  • [workspace.lints.clippy] in Cargo.toml is the canonical policy (all + pedantic with explicit carve-outs)
  • ./check.py runs cargo clippy without inline lint flags, so commit-gate behavior is sourced from Cargo.toml

The MCP worker executes:

  • cargo clippy --workspace --all-targets --all-features --message-format=json

To override command shape (for example, alternate target selection), configure:

[workspace.metadata.adequate-rust-mcp]
format_command = ["cargo", "fmt", "--all"]
clippy_command = [
  "cargo",
  "clippy",
  "--workspace",
  "--all-targets",
  "--all-features",
  "--message-format=json",
]
fix_command = [
  "cargo",
  "clippy",
  "--fix",
  "--workspace",
  "--all-targets",
  "--all-features",
  "--allow-dirty",
  "--allow-staged",
]

Telemetry

Use telemetry_snapshot as first-line triage when the system slows down or starts flapping. It reports:

  • lifecycle state + generation
  • uptime
  • consecutive failures and restart count
  • total request counters (success, response error, transport fault, retries)
  • per-method counters and latency aggregates (last, avg, max)
  • last observed method-level error text
  • latest restart-triggering fault

Useful choke signatures:

  • rising transport_fault_count + restart_count: rust-analyzer process instability or I/O link failure
  • rising response_error_count with low restart count: semantic/query misuse or LSP-level request issues
  • high avg_latency_ms/max_latency_ms in one method: method-specific hot spot in large workspaces
  • non-zero consecutive_failures while state is recovering: active degradation loop

Host JSONL Telemetry (XDG State)

The host process also emits append-only JSONL telemetry for path-level heat/error analysis.

  • default path: $XDG_STATE_HOME/adequate-rust-mcp/telemetry.jsonl
  • fallback path: $HOME/.local/state/adequate-rust-mcp/telemetry.jsonl
  • snapshot cadence: ADEQUATE_MCP_TELEMETRY_SNAPSHOT_EVERY (default: 100)

Each tool call writes a tool_call event with:

  • repo_root
  • request_id
  • tool_name and optional lsp_method
  • path_hint (best-effort normalized path extraction)
  • latency_ms, replay_attempts
  • outcome (ok/error)
  • optional error_code, error_kind, error_message

Every N calls, and once on shutdown, the host writes hot_paths_snapshot with:

  • hottest_paths (highest request volume)
  • slowest_paths (highest average latency)
  • error_count per path

QA Checklist

For a lean live MCP smoke pass against this repo, run:

python3 qa_checklist.py

The literal step list lives in docs/qa-checklist.md.