feat(tunnel): MCP read-only server tunnel mode (VA-26) #22
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/mcp-readonly-va-26"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
USAGE_MCP=8tunnel mode (crates/meshagent/src/host/mcp.rs) that exposes the agent's read-only host inventory to MCP (Model Context Protocol) clients reached through the rendezvous tunnel.meshagent-mcpcrate carries a transport-agnostic JSON-RPC 2.0 server (handshake,tools/list,tools/call+notifications/progress,ping) speaking the current MCP spec revision (2025-11-25).DENYLISTED_TOOL_NAMES+verify_read_onlyrefuse to serve a registry that carries any destructive tool (exec,file_write,power_reboot, ...). Lifted in v2 (VA-27) behind amutating-toolsfeature + the consent layer.osinfo,cpuinfo,sysinfo,disks,users,process_list,dir_list,file_read,file_stat,services_list,packages_list,listen_ports,net_interfaces,dns_lookup,tcp_probe,time_status,log_tail(streaming).log_taildemonstratesnotifications/progress: one progress event per line addressed at the caller's_meta.progressToken, with the full result still returned so non-subscribing clients see complete output.Deviations from the issue body
rmcp(Anthropic's official Rust MCP SDK). I deferred that to v2. None of rmcp 1.7's built-in transports (stdio, Streamable HTTP) line up with the channel-backed tunnel transport without a duplex adapter, and the hand-rolled JSON-RPC is ~300 lines that we can swap for rmcp once the v2 consent layer forces typed schemas. Captured in the file-level doc onmeshagent-mcp/src/lib.rs.Acceptance criteria status
meshagent-mcpcrate compiles cleanly;cargo clippy --workspace --all-targets -- --deny warningspasses.TunnelMode::Mcp(USAGE_MCP = 8) routed inhost/tunnel.rs.log_tailemits MCP progress notifications and terminates cleanly on tunnel close (verified bymcp_tunnel_log_tail_emits_progress_notifications).tools/listenumeration, and round-tripsosinfo+process_list+file_read(mcp_tunnel_serves_initialize_list_and_tool_calls).registry_passes_read_only_checkinhost::mcpenumerates the live registry and trips if any denylisted name appears.Test plan
cargo build --workspacecargo test --workspace(260 lib + 7 handshake + 2 mcp_tunnel + 19 wsproxy + 24 tcpforward + 10 mcp + ...; all green)cargo clippy --workspace --all-targets -- --deny warningscargo fmt --all --check