|
1 | 1 | # MCP Transport (stdio) Implementation Plan |
2 | 2 |
|
3 | | -> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. |
| 3 | +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if available) or superpowers:executing-plans to implement this plan. Steps use markdown checkboxes for tracking. |
4 | 4 |
|
5 | 5 | **Goal:** Add MCP client support (stdio transport) so LoopForge can load an `mcp-servers.json`, expose MCP tools to the model, and route tool calls/resources/prompts through MCP. |
6 | 6 |
|
7 | 7 | **Architecture:** Session-scoped MCP config is stored in runtime KV. Toolset owns MCP transports and exposes namespaced tool definitions (`mcp_<server>__<tool>`) plus wrapper tools for resources/prompts. |
8 | 8 |
|
9 | 9 | **Tech Stack:** Rust, tokio, serde_json, newline-delimited JSON-RPC over stdio. |
10 | 10 |
|
| 11 | +**Execution Status (2026-04-07):** Completed and merged on `main` (initial landing: `f33803e`; follow-up hardening and coverage included up to `0609812`). |
| 12 | + |
| 13 | +**Re-Verification (2026-04-07):** |
| 14 | +- `cargo test -p loopforge-cli --locked cli::tests -q` ✅ |
| 15 | +- `cargo test -p rexos-tools --locked mcp -q` ✅ |
| 16 | +- `cargo test -p rexos-tools --locked -q` ✅ |
| 17 | +- `cargo test -p rexos --locked agent_loop -q` ✅ |
| 18 | +- `python3 -m mkdocs build --strict` ✅ |
| 19 | +- `make check` ✅ |
| 20 | + |
11 | 21 | --- |
12 | 22 |
|
13 | 23 | ## Chunk 1: CLI + session storage plumbing |
|
20 | 30 | - Modify: `crates/rexos-runtime/src/session_skills/storage.rs` |
21 | 31 | - Test: `crates/loopforge-cli/src/cli/tests.rs` (CLI parse) |
22 | 32 |
|
23 | | -- [ ] **Step 1: Add `--mcp-config` to `loopforge agent run`** |
| 33 | +- [x] **Step 1: Add `--mcp-config` to `loopforge agent run`** |
24 | 34 | - Add `mcp_config: Option<PathBuf>` argument. |
25 | 35 |
|
26 | | -- [ ] **Step 2: CLI reads JSON file and stores content for the session** |
| 36 | +- [x] **Step 2: CLI reads JSON file and stores content for the session** |
27 | 37 | - Read file bytes, parse JSON for validity, store normalized string in runtime session KV. |
28 | 38 |
|
29 | | -- [ ] **Step 3: Add runtime APIs** |
| 39 | +- [x] **Step 3: Add runtime APIs** |
30 | 40 | - `set_session_mcp_config(session_id, raw_json)` |
31 | 41 | - `load_session_mcp_config(session_id) -> Option<String>` |
32 | 42 |
|
33 | | -- [ ] **Step 4: Update CLI tests** |
| 43 | +- [x] **Step 4: Update CLI tests** |
34 | 44 | - Ensure the new flag parses. |
35 | 45 |
|
36 | | -- [ ] **Step 5: Run focused tests** |
| 46 | +- [x] **Step 5: Run focused tests** |
37 | 47 | - Run: `cargo test -p loopforge-cli cli::tests -q` |
38 | 48 | - Expected: PASS |
39 | 49 |
|
|
51 | 61 | - Create: `crates/rexos-tools/src/mcp/types.rs` |
52 | 62 | - Test: `crates/rexos-tools/src/mcp/tests.rs` |
53 | 63 |
|
54 | | -- [ ] **Step 1: Define config types** |
| 64 | +- [x] **Step 1: Define config types** |
55 | 65 | - `McpServersConfig { servers: BTreeMap<String, McpServerConfig> }` |
56 | 66 | - `McpServerConfig { command, args, env, cwd }` |
57 | 67 |
|
58 | | -- [ ] **Step 2: Implement JSON-RPC client helper** |
| 68 | +- [x] **Step 2: Implement JSON-RPC client helper** |
59 | 69 | - `send_request(method, params) -> Result<Value>` |
60 | 70 | - background read loop, oneshot per id, timeout support. |
61 | 71 |
|
62 | | -- [ ] **Step 3: Implement stdio transport** |
| 72 | +- [x] **Step 3: Implement stdio transport** |
63 | 73 | - spawn child, newline-delimited JSON, capture stderr tail on failure. |
64 | 74 |
|
65 | | -- [ ] **Step 4: Implement MCP handshake** |
| 75 | +- [x] **Step 4: Implement MCP handshake** |
66 | 76 | - `initialize` then `initialized` notification. |
67 | 77 |
|
68 | | -- [ ] **Step 5: Unit tests for JSON-RPC routing** |
| 78 | +- [x] **Step 5: Unit tests for JSON-RPC routing** |
69 | 79 | - use a minimal in-process “fake transport” (or spawn stub binary) to validate request/response matching. |
70 | 80 |
|
71 | | -- [ ] **Step 6: Run focused tests** |
| 81 | +- [x] **Step 6: Run focused tests** |
72 | 82 | - Run: `cargo test -p rexos-tools mcp -q` |
73 | 83 | - Expected: PASS |
74 | 84 |
|
|
92 | 102 | - Create: `crates/rexos-tools/src/dispatch/mcp/mod.rs` |
93 | 103 | - Test: `crates/rexos-tools/src/tests/compat.rs` (definitions include MCP wrappers when enabled) |
94 | 104 |
|
95 | | -- [ ] **Step 1: Add MCP wrapper tool defs** |
| 105 | +- [x] **Step 1: Add MCP wrapper tool defs** |
96 | 106 | - `mcp_resources_list`, `mcp_resources_read`, `mcp_prompts_list`, `mcp_prompts_get`, `mcp_servers_list` |
97 | 107 |
|
98 | | -- [ ] **Step 2: Extend Toolset with optional MCP hub** |
| 108 | +- [x] **Step 2: Extend Toolset with optional MCP hub** |
99 | 109 | - On build: parse raw JSON from runtime, initialize servers, list tools. |
100 | 110 |
|
101 | | -- [ ] **Step 3: Flatten remote MCP tools into `ToolDefinition`s** |
| 111 | +- [x] **Step 3: Flatten remote MCP tools into `ToolDefinition`s** |
102 | 112 | - name: `mcp_<server>__<tool>` |
103 | 113 | - parameters: remote `inputSchema` (default `{ "type": "object" }`) |
104 | 114 |
|
105 | | -- [ ] **Step 4: Add dispatch routing** |
| 115 | +- [x] **Step 4: Add dispatch routing** |
106 | 116 | - New domain `ToolCallDomain::Mcp` and route calls to MCP hub. |
107 | 117 |
|
108 | | -- [ ] **Step 5: Run focused tests** |
| 118 | +- [x] **Step 5: Run focused tests** |
109 | 119 | - Run: `cargo test -p rexos-tools -q` |
110 | 120 | - Expected: PASS |
111 | 121 |
|
|
120 | 130 | - Modify: `crates/rexos-runtime/src/session_skills/storage.rs` |
121 | 131 | - Test: `crates/rexos/tests/agent_loop.rs` (add a small case with MCP stub) |
122 | 132 |
|
123 | | -- [ ] **Step 1: Load session MCP config in `run_session`** |
| 133 | +- [x] **Step 1: Load session MCP config in `run_session`** |
124 | 134 | - If present, build Toolset with MCP enabled. |
125 | 135 |
|
126 | | -- [ ] **Step 2: Ensure tool defs include MCP tools** |
| 136 | +- [x] **Step 2: Ensure tool defs include MCP tools** |
127 | 137 | - Toolset initializes MCP before `tool_defs` is computed. |
128 | 138 |
|
129 | | -- [ ] **Step 3: Add an integration-ish test** |
| 139 | +- [x] **Step 3: Add an integration-ish test** |
130 | 140 | - Spawn MCP stdio stub, configure via `--mcp-config`-equivalent session KV, verify a tool call succeeds. |
131 | 141 |
|
132 | | -- [ ] **Step 4: Run runtime tests** |
| 142 | +- [x] **Step 4: Run runtime tests** |
133 | 143 | - Run: `cargo test -p rexos agent_loop -q` |
134 | 144 | - Expected: PASS |
135 | 145 |
|
|
143 | 153 | - Modify: `docs-site/blog/mcp-integration-guide.md` |
144 | 154 | - Modify: `docs-site/reference/config.md` (optional: mention session flag, not TOML) |
145 | 155 |
|
146 | | -- [ ] **Step 1: Update MCP blog to match real CLI** |
| 156 | +- [x] **Step 1: Update MCP blog to match real CLI** |
147 | 157 | - Keep `--mcp-config` example, remove commands that do not exist (`config add-mcp-server`). |
148 | 158 |
|
149 | | -- [ ] **Step 2: Verify docs build** |
| 159 | +- [x] **Step 2: Verify docs build** |
150 | 160 | - Run: `python3 -m mkdocs build --strict` |
151 | 161 | - Expected: PASS |
152 | 162 |
|
153 | 163 | ### Task 6: Full verification |
154 | 164 |
|
155 | | -- [ ] **Step 1: Run full checks** |
| 165 | +- [x] **Step 1: Run full checks** |
156 | 166 | - Run: `make check` |
157 | 167 | - Expected: PASS |
0 commit comments