Skip to content

feat: add MCP server support - #44

Merged
ostepan8 merged 5 commits into
mainfrom
feat/mcp-client
Oct 5, 2026
Merged

ostepan8 merged 5 commits into
mainfrom
feat/mcp-client

Conversation

@ostepan8

@ostepan8 ostepan8 commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the M9 MCP client that rc-mcp reserved.

  • Config: an mcpServers block in settings.json, the same shape as Claude Code and Cursor, plus repeatable --mcp-config <file-or-json> and --strict-mcp-config for harnesses. ${VAR} and ${VAR:-default} expand from the environment, so secrets stay out of settings files. Project settings replace user settings per server, and null removes one.
  • Transports: stdio and streamable HTTP, through the official Rust SDK (rmcp 3.5, Apache-2.0, MSRV 1.88). TLS reuses the workspace's rustls + ring stack (reqwest-tls-no-provider), so no second crypto provider or C toolchain is added. Legacy SSE is refused with a message pointing to streamable HTTP.
  • Tools: each server tool is a normal Tool named mcp__<server>__<tool>, sanitized to the provider's 64-character [a-zA-Z0-9_-]. Tools run SerialWrite and get the usual tool-result cap.
  • Startup: all servers connect in parallel before the first request, so the tool set and the cached prefix stay fixed for the session.
  • Failures: a server that fails to start, times out, or exits mid-run never stops the session. Its tools return the error, startup prints a warning, and a stdio server's stderr goes to a tail buffer, never to the terminal.
  • Permissions: MCP tools ask in default and acceptEdits and are denied in plan, like Bash. Rules accept a full tool name or mcp__<server> for a whole server.
  • TUI: /mcp lists each server's state, transport, tools and last stderr line.
  • Docs: docs/CONFIGURATION.md, README, ARCHITECTURE and CHANGELOG.

Test plan

  • Unit tests: config parsing and ${VAR} expansion, wire names, schema normalization, result rendering, settings layering, permission rules.
  • Integration tests against a stdio fixture server (crates/rc-mcp/tests/fixture, a test-only bin): listing and calling, isError, a server crashing mid-call, a server failing at startup next to a healthy one, a missing binary, per-call timeout and cancellation.
  • cargo fmt --check, cargo +1.99.0 clippy --workspace --all-targets -D warnings, cargo test --workspace (585 passed), cargo +1.89.0 check for both workspaces.
  • Live: marathon -p ... --mcp-config mcp.json --strict-mcp-config on subconscious/glm-5.3-marathon. The model called mcp__fx__echo {"text": "marathon-mcp-ok"} and returned echo: marathon-mcp-ok.

🤖 Generated with Claude Code

ostepan8 and others added 5 commits October 5, 2026 16:38
Connect stdio and streamable HTTP MCP servers from the mcpServers settings
block or --mcp-config, and expose their tools as mcp__<server>__<tool>.
Servers start in parallel before the first request so the tool set stays
fixed; a server that fails or exits never stops the session. MCP tools ask
for confirmation by default, and /mcp lists server state and tools.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… redaction

- Project .sc/settings.json servers start only with --trust-project-mcp or a
  user-level trustedMcpProjects entry; untrusted values are never expanded.
- Stdio servers start with an env allowlist plus their own env.
- /mcp and errors show the config as written; substituted values are scrubbed.
- McpHub::shutdown closes connections and kills each server's process group
  or job; dropping the hub kills too.
- Docs: -p needs an allow rule; servers run outside the Bash sandbox.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- SIGINT/SIGTERM/SIGHUP (Ctrl-C, Ctrl-Break, console close on Windows) shut
  down every MCP server, restore the terminal and exit with 128+signal.
- Linux servers get PR_SET_PDEATHSIG=SIGKILL.
- Secrets are also scrubbed in percent-encoded form and line by line.
- Install the ring rustls provider before rmcp builds its HTTP client, which
  otherwise panicked on connect; a panicked connect now shows as failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…nal exit

- The fixture also serves stateless streamable HTTP; an integration test
  lists and calls tools over it with a configured Authorization header.
- Each graceful shutdown step now takes at most 1 s, and the signal path
  kills every process tree before exiting, whatever the graceful pass did.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@ostepan8
ostepan8 merged commit 94ca1f8 into main Oct 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant