swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authormain <main@swarm.moe>2026-03-19 15:49:41 -0400
committermain <main@swarm.moe>2026-03-19 15:49:41 -0400
commitfa1bd32800b65aab31ea732dd240261b4047522c (patch)
tree2fd08af6f36b8beb3c7c941990becc1a0a091d62 /README.md
downloadadequate-rust-mcp-fa1bd32800b65aab31ea732dd240261b4047522c.zip
Release adequate-rust-mcp 1.0.0v1.0.0
Diffstat (limited to 'README.md')
-rw-r--r--README.md221
1 files changed, 221 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..640056e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,221 @@
+# 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:
+
+```bash
+cargo run -p adequate-rust-mcp
+```
+
+To launch the disposable worker directly:
+
+```bash
+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:
+
+```toml
+[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:
+
+```bash
+python3 qa_checklist.py
+```
+
+The literal step list lives in `docs/qa-checklist.md`.