Summary
Implement the MCP (Model Context Protocol) server that exposes 29 RemoteClaw-specific tools to CLI subprocess agents. This is the C2 component — the mechanism by which CLI agents (Claude, Gemini, Codex, OpenCode) can interact with RemoteClaw's sessions, messaging, cron, and gateway systems.
Architecture
Lifecycle Model
ChannelBridge (gateway process)
|
| 1. Builds McpServerConfig, passes via AgentExecuteParams.mcpServers
| 2. Spawns CLI subprocess (runtime handles config format internally)
v
CLI Agent (claude/gemini/codex/opencode)
|
| 3. Reads MCP config, spawns MCP server as child
v
remoteclaw-mcp-server (stdio subprocess of CLI agent)
|
| 4. Connects to gateway via WebSocket RPC
| 5. Handles MCP tool calls by invoking gateway RPCs
| 6. Appends side effects to temp file (NDJSON)
v
Gateway WebSocket RPC (existing infrastructure)
Per-invocation: Each CLI subprocess invocation gets a fresh MCP server. The MCP server starts when the CLI agent spawns it, dies when the CLI agent exits. Clean isolation, no cross-session state.
Transport: Stdio — the only transport supported by all 4 CLIs.
Per-Runtime Config Generation (already implemented)
Per-runtime MCP config generation is already implemented in each runtime's *McpConfigManager class (from ClaudeCliRuntime (#8)–015):
| Runtime |
Mechanism |
Implemented In |
| Claude |
Inline JSON via --mcp-config flag |
runtimes/claude.ts |
| Gemini |
Merge-restore .gemini/settings.json |
GeminiMcpConfigManager |
| Codex |
TOML serialization into config.toml |
CodexMcpConfigManager |
| OpenCode |
Merge-restore opencode.json |
OpenCodeMcpConfigManager |
All runtimes accept a uniform McpServerConfig via AgentExecuteParams.mcpServers and handle format translation internally. MCP server (#30) only needs to define the McpServerConfig shape that ChannelBridge passes (env vars for gateway URL, token, session key, side effects path, channel info).
Configuration (environment variables)
The MCP server receives its context via environment variables set by ChannelBridge:
| Variable |
Purpose |
REMOTECLAW_GATEWAY_URL |
Gateway WebSocket URL (e.g., ws://127.0.0.1:18789) |
REMOTECLAW_GATEWAY_TOKEN |
Gateway auth token |
REMOTECLAW_SESSION_KEY |
Current session key |
REMOTECLAW_SIDE_EFFECTS_FILE |
Temp file path for side effects NDJSON |
REMOTECLAW_CHANNEL |
Originating channel (e.g., telegram) |
REMOTECLAW_ACCOUNT_ID |
Originating account ID |
REMOTECLAW_TO |
Originating delivery target |
REMOTECLAW_THREAD_ID |
Originating thread/topic ID |
Tool Inventory (29 tools)
Session Management (7 tools)
| MCP Tool Name |
Source |
Parameters |
Side Effect? |
sessions_list |
sessions-list-tool.ts |
filter?, limit? |
No |
sessions_history |
sessions-history-tool.ts |
sessionKey, limit? |
No |
sessions_send |
sessions-send-tool.ts |
sessionKey/label, message, timeout? |
Yes (messaging) |
sessions_spawn |
sessions-spawn-tool.ts |
agentId?, channel?, prompt |
No |
session_status |
session-status-tool.ts |
(current session info) |
No |
agents_list |
agents-list-tool.ts |
(list configured agents) |
No |
subagents |
subagents-tool.ts |
action, params |
No |
Channel Messaging (10 tools)
| MCP Tool Name |
Source Action |
Parameters |
Side Effect? |
message_send |
message:send |
target, message, media? |
Yes |
message_reply |
message:reply |
message, replyToId? |
Yes |
message_thread_reply |
message:thread-reply |
message, threadId |
Yes |
message_broadcast |
message:broadcast |
targets[], message |
Yes |
message_react |
message:react |
emoji, messageId |
No |
message_delete |
message:delete |
messageId |
No |
message_send_attachment |
message:sendAttachment |
target, file, caption? |
Yes |
message_send_with_effect |
message:sendWithEffect |
target, message, effectId |
Yes |
message_pin |
message:pin |
messageId |
No |
message_read |
message:readMessages |
channelId, limit? |
No |
Cron Scheduling (7 tools)
| MCP Tool Name |
Source Action |
Parameters |
Side Effect? |
cron_status |
cron:status |
(overview) |
No |
cron_list |
cron:list |
filter? |
No |
cron_add |
cron:add |
job spec |
Yes (cronAdds) |
cron_update |
cron:update |
jobId, updates |
No |
cron_remove |
cron:remove |
jobId |
No |
cron_run |
cron:run |
jobId |
No |
cron_runs |
cron:runs |
jobId?, limit? |
No |
Gateway Admin (5 tools)
| MCP Tool Name |
Source Action |
Parameters |
gateway_restart |
gateway:restart |
(none) |
gateway_config_get |
gateway:config.get |
key? |
gateway_config_apply |
gateway:config.apply |
config |
gateway_config_patch |
gateway:config.patch |
patches |
gateway_config_schema |
gateway:config.schema |
(none) |
NOT Exposed (middleware boundary principle)
| Tool |
Reason |
web_search, web_fetch |
CLI agents have native equivalents |
browser, image, tts |
CLI agents have native equivalents or MCP-based |
canvas, nodes |
Requires rendering/pairing layer |
memory_search, memory_get |
Deferred to v0.2.0 |
Side Effects Protocol
File-based NDJSON protocol for tracking MCP messaging side effects:
{"type":"message_sent","tool":"message","provider":"telegram","to":"group:123","text":"Hello","mediaUrl":null,"ts":1708905600000}
{"type":"cron_added","jobId":"job-xyz","ts":1708905602000}
Why file-based: ChannelBridge creates a temp file path; the MCP server appends side effects as NDJSON lines. After CLI subprocess exits, ChannelBridge reads the file. Robust even if MCP server crashes (partial file is valid NDJSON).
Side effect recording tools:
- Messaging:
message_send, message_reply, message_thread_reply, message_broadcast, message_send_attachment, message_send_with_effect, sessions_send → recordMessageSent()
- Cron:
cron_add → recordCronAdd()
No race condition: CLI agent blocks on MCP tool responses, so the sequence is always: CLI sends request → MCP processes + writes side effect → MCP responds → CLI continues. When CLI exits, all side effects are on disk.
Tool Policy Integration
The MCP server applies the same tool policy pipeline as the existing /tools/invoke HTTP endpoint:
- Tool allowlisting/denylisting is respected
- Per-agent, per-channel, per-group policies apply
- Subagent tool restrictions are enforced
At startup, the MCP server loads config, resolves policies, and only registers allowed tools.
Implementation Approach
New Files
| File |
Purpose |
Est. Lines |
src/middleware/mcp-server.ts |
MCP server entry point + stdio transport setup |
~80 |
src/middleware/mcp-tools.ts |
Tool registration (schema generation from existing tool schemas) |
~150 |
src/middleware/mcp-handlers/session.ts |
Session tool handlers (7 tools) |
~100 |
src/middleware/mcp-handlers/message.ts |
Message tool handlers (10 tools) |
~150 |
src/middleware/mcp-handlers/cron.ts |
Cron tool handlers (7 tools) |
~100 |
src/middleware/mcp-handlers/gateway.ts |
Gateway admin tool handlers (5 tools) |
~75 |
src/middleware/mcp-side-effects.ts |
Side effects collector (NDJSON writer) + reader |
~100 |
Modified Files
| File |
Change |
src/middleware/types.ts |
May need minor additions for MCP-related types |
Test Files
| File |
Coverage |
src/middleware/mcp-side-effects.test.ts |
Side effects writer + reader |
src/middleware/mcp-tools.test.ts |
Tool registration, schema generation |
src/middleware/mcp-handlers/*.test.ts |
Tool handler invocation (mock gateway RPC) |
Estimated total: ~755 LoC (not counting tests) + ~500 LoC tests
(Reduced from original ~1,180 estimate — per-runtime config generation (~425 LoC) already exists in ClaudeCliRuntime (#8)–015.)
Tool Implementations
Each MCP tool handler is a thin adapter layer that:
- Receives MCP tool input (JSON Schema-validated by MCP SDK)
- Translates to a
callGatewayTool() RPC call (using existing gateway RPC infrastructure)
- Records side effects (for messaging and cron tools)
- Returns MCP-formatted result
The tool handlers wrap existing src/agents/tools/ code — specifically sessions, messaging, cron, and gateway tools. They do NOT wrap the pi-embedded tools (web, browser, image, TTS) being gutted in M3.
Key Dependencies
| What |
Status |
@modelcontextprotocol/sdk |
npm dependency to add |
AgentRuntime interface (PR #4) |
Done |
McpServerConfig type (PR #4) |
Done — already in types.ts |
McpSideEffects type (PR #4) |
Done — already in types.ts |
| Per-runtime MCP config (ClaudeCliRuntime (#8)–015) |
Done — *McpConfigManager classes |
Existing src/agents/tools/ |
Upstream code, wrapping only |
Acceptance Criteria
Summary
Implement the MCP (Model Context Protocol) server that exposes 29 RemoteClaw-specific tools to CLI subprocess agents. This is the C2 component — the mechanism by which CLI agents (Claude, Gemini, Codex, OpenCode) can interact with RemoteClaw's sessions, messaging, cron, and gateway systems.
Architecture
Lifecycle Model
Per-invocation: Each CLI subprocess invocation gets a fresh MCP server. The MCP server starts when the CLI agent spawns it, dies when the CLI agent exits. Clean isolation, no cross-session state.
Transport: Stdio — the only transport supported by all 4 CLIs.
Per-Runtime Config Generation (already implemented)
Per-runtime MCP config generation is already implemented in each runtime's
*McpConfigManagerclass (from ClaudeCliRuntime (#8)–015):--mcp-configflagruntimes/claude.ts.gemini/settings.jsonGeminiMcpConfigManagerconfig.tomlCodexMcpConfigManageropencode.jsonOpenCodeMcpConfigManagerAll runtimes accept a uniform
McpServerConfigviaAgentExecuteParams.mcpServersand handle format translation internally. MCP server (#30) only needs to define theMcpServerConfigshape that ChannelBridge passes (env vars for gateway URL, token, session key, side effects path, channel info).Configuration (environment variables)
The MCP server receives its context via environment variables set by ChannelBridge:
REMOTECLAW_GATEWAY_URLws://127.0.0.1:18789)REMOTECLAW_GATEWAY_TOKENREMOTECLAW_SESSION_KEYREMOTECLAW_SIDE_EFFECTS_FILEREMOTECLAW_CHANNELtelegram)REMOTECLAW_ACCOUNT_IDREMOTECLAW_TOREMOTECLAW_THREAD_IDTool Inventory (29 tools)
Session Management (7 tools)
sessions_listsessions-list-tool.tssessions_historysessions-history-tool.tssessions_sendsessions-send-tool.tssessions_spawnsessions-spawn-tool.tssession_statussession-status-tool.tsagents_listagents-list-tool.tssubagentssubagents-tool.tsChannel Messaging (10 tools)
message_sendmessage_replymessage_thread_replymessage_broadcastmessage_reactmessage_deletemessage_send_attachmentmessage_send_with_effectmessage_pinmessage_readCron Scheduling (7 tools)
cron_statuscron_listcron_addcron_updatecron_removecron_runcron_runsGateway Admin (5 tools)
gateway_restartgateway_config_getgateway_config_applygateway_config_patchgateway_config_schemaNOT Exposed (middleware boundary principle)
web_search,web_fetchbrowser,image,ttscanvas,nodesmemory_search,memory_getSide Effects Protocol
File-based NDJSON protocol for tracking MCP messaging side effects:
{"type":"message_sent","tool":"message","provider":"telegram","to":"group:123","text":"Hello","mediaUrl":null,"ts":1708905600000} {"type":"cron_added","jobId":"job-xyz","ts":1708905602000}Why file-based: ChannelBridge creates a temp file path; the MCP server appends side effects as NDJSON lines. After CLI subprocess exits, ChannelBridge reads the file. Robust even if MCP server crashes (partial file is valid NDJSON).
Side effect recording tools:
message_send,message_reply,message_thread_reply,message_broadcast,message_send_attachment,message_send_with_effect,sessions_send→recordMessageSent()cron_add→recordCronAdd()No race condition: CLI agent blocks on MCP tool responses, so the sequence is always: CLI sends request → MCP processes + writes side effect → MCP responds → CLI continues. When CLI exits, all side effects are on disk.
Tool Policy Integration
The MCP server applies the same tool policy pipeline as the existing
/tools/invokeHTTP endpoint:At startup, the MCP server loads config, resolves policies, and only registers allowed tools.
Implementation Approach
New Files
src/middleware/mcp-server.tssrc/middleware/mcp-tools.tssrc/middleware/mcp-handlers/session.tssrc/middleware/mcp-handlers/message.tssrc/middleware/mcp-handlers/cron.tssrc/middleware/mcp-handlers/gateway.tssrc/middleware/mcp-side-effects.tsModified Files
src/middleware/types.tsTest Files
src/middleware/mcp-side-effects.test.tssrc/middleware/mcp-tools.test.tssrc/middleware/mcp-handlers/*.test.tsEstimated total: ~755 LoC (not counting tests) + ~500 LoC tests
(Reduced from original ~1,180 estimate — per-runtime config generation (~425 LoC) already exists in ClaudeCliRuntime (#8)–015.)
Tool Implementations
Each MCP tool handler is a thin adapter layer that:
callGatewayTool()RPC call (using existing gateway RPC infrastructure)The tool handlers wrap existing
src/agents/tools/code — specifically sessions, messaging, cron, and gateway tools. They do NOT wrap the pi-embedded tools (web, browser, image, TTS) being gutted in M3.Key Dependencies
@modelcontextprotocol/sdkAgentRuntimeinterface (PR #4)McpServerConfigtype (PR #4)types.tsMcpSideEffectstype (PR #4)types.ts*McpConfigManagerclassessrc/agents/tools/Acceptance Criteria
src/middleware/mcp-server.ts(and supporting files) expose 29 RemoteClaw-specific tools via MCPMcpSideEffectsCollectorconsumptionsrc/agents/tools/code (thin adapter layer)pnpm buildpasses