apomesh-substrate-mcp
apomesh-substrate-mcp is a substrate implementation plane: the
rmcp-backed adapter that turns an operator-configured
MCP server’s tools into first-class
substrate Tool instances. From the worker’s dispatch path, an MCP-backed
tool is indistinguishable from a native one — same Tool trait, same
ToolSandbox::execute wrap, same cancellation contract. This crate owns the
transport (how the substrate connects to an MCP server), the tool projection
(how a discovered MCP tool becomes a substrate Tool), and the sandboxed
lifecycle of a spawned server. Touch it for MCP transport mechanics: a new
transport variant, the connection pool’s lifecycle, or the discovered-tool
adapter.
Position in the workspace
Section titled “Position in the workspace”- Layer: substrate implementation plane. See Control & execution planes.
- Depends on:
apomesh-substrate-types only
(the
Tool/ToolSandbox/RuntimeLayerStoreports plus the agent/tenant/tool/cancellation vocabulary), and thermcptransport tree — stdio child-process always, streamable-HTTP behind themcp-httpfeature. - Consumed by:
apomesh-substrate, which pulls this
plane in behind its optional
mcpcargo feature and re-exports the surface flat throughapomesh_substrate::tool. Deployments that wire no MCP servers don’t compilermcpat all. The orchestrator and worker reach the plane only through that facade.
What it owns
Section titled “What it owns”- The transport vocabulary —
McpTransport, a closed enum ofStdio(the substrate spawns the server as a subprocess and speaks JSON-RPC over its pipes) andHttp(streamable-HTTP per the MCP 2025-11-25 spec, gated onmcp-http). One transport perMcpServerSpec. - The tool projection —
McpServerConnection::connectruns theinitializehandshake and caches thetools/listadvertisement;register_mcp_toolsbuilds oneMcpToolper discovered tool (filtered by the spec’s optionalpermitted_toolsallow-list), prefixing itsToolIdas<server>:<tool>for collision-free provenance.McpToolimplements the substrateTooltrait — surfacing the MCP-side name, description, and input schema, and routing dispatch through atools/callround-trip. - The sandboxed server lifecycle — a stdio server is spawned as a
long-lived sandboxed subprocess via
ToolSandbox::spawn_long_livedunder theSideEffectingToolpolicy; the connection holds the kill lifeline, so dropping it terminates the sandbox. HTTP servers are remote (no subprocess). - Per-tenant spec catalog + connection pool —
McpServerStore(a plugin trait with an in-memory adapter here; the Postgres adapter lives in the state-store crate) andMcpConnectionPool, which lazy-spawns, refcounts, and idle-evicts one connection per(tenant, server). - The runtime-layer adapter —
LocalDiskRuntimeLayerStoreplus thesubstrate_shipped_seedscatalog, which verify host-provisioned language runtimes for runtime-bound stdio servers (bind-mounted at/runtime/<id>).
It does not own server registration/admin or session-start admission
— the operator-facing list/register/update/remove/probe workflows and the
admit_session_mcp call live in the
orchestrator. It does not own
at-rest secret sealing — the secret-bearing transport fields (Stdio.env,
Http.auth_header) are sealed by
apomesh-state-store-postgres’s
PostgresMcpServerStore, never by this crate. And the worker-side delegate
stub (McpDelegateTool) lives in apomesh-substrate outside the mcp gate,
so the worker never compiles the rmcp transport tree.
Public surface
Section titled “Public surface”McpTransport— closed-enum transport selection:Stdio { command, args, env }|Http { url, auth_header }.McpServerSpec— per-server registration input (name, transport,ToolCategory, optional allow-list, optional runtime layer); the substrate mirror of config’sMcpServerConfig.register_mcp_tools— the worker-boot driver: connect each server, discover, and register itsMcpTools into aToolRegistry; a failing server is logged and skipped, never fatal.McpServerConnection— one live server connection;connectdoes the sandboxed handshake +tools/list,invoke_tooldoes the per-calltools/call.absorb_mcp_server— projects a legacyMcpServerSpeconto the one connector declaration. The per-tenantMcpServerStorethis crate used to own is gone: it was a second sealed secret home beside the one per-tenantCredentialStore, and the connector plane’s registry replaced it. A stored row’s inline credential values are lifted to names under the same move.McpConnectionPool— per-(tenant, server)lifecycle:acquire(lazy-spawn + refcount),probe(non-disruptive health check),evict_idle.LocalDiskRuntimeLayerStore+substrate_shipped_seeds— the runtime-layer adapter (verifies host-provisioned runtimes; does not download them) and its seed catalog.McpError— the closed failure vocabularies, mapped toToolErroron dispatch and to a gRPCStatusat the admin wire boundary.
In a running daemon the orchestrator holds an Arc<dyn McpServerStore> and an
Arc<McpConnectionPool>. An operator registers a server for their tenant
through the console’s MCP surface (or the equivalent admin RPC), which
upserts an McpServerSpec into the store. At session start,
create_session_workflow calls admit_session_mcp, which list_for_tenants
the registered specs and acquires a pooled connection per server —
lazy-spawning the sandboxed subprocess on first use. The discovered tools
project into the session’s tool set as McpTools, and the worker dispatches
them exactly like native tools: tier-validated, sandbox-wrapped, and
cancellable by future-drop. The MCP server process stays alive across
dispatches (one persistent transport); only the tools/call round-trip is
per-dispatch, and the pool tears down the subprocess once the connection has
been idle past its window.
Register and inspect servers from the operator console; transport-config secrets are sealed at rest by the Postgres store, never written in cleartext.
Related
Section titled “Related”- Concepts: Control & execution planes (the decide / route / execute split and sandbox-by-default), The credential plane (how the sealed transport secrets and the injected-secret boundary work).
- Reference:
apomesh-substrate-sandbox
(the
ToolSandboxthis plane spawns servers into), apomesh-substrate-tools (the native leaf tools MCP tools sit beside), apomesh-state-store-postgres (the sealingMcpServerStoreadapter), apomesh-orchestrator (the admin + admission workflows that drive the store and pool). - Operate: The operator console.