MESH ONLINECODENAME:
v0.34

Wrap an MCP Server

The fastest way to put a capability on the mesh is to wrap a tool you already have. net-mesh wrap spawns an existing stdio MCP server, reads its tool list, announces each tool as a discoverable Net capability, and translates incoming mesh calls back into MCP tools/call — all without the Net core ever learning that MCP exists.

net-mesh wrap publishes tools from an existing MCP server as Net capabilities. Net and MCP explains where the bridge fits.

Prerequisite: a mesh to join

net-mesh wrap builds a real mesh node under your identity and joins the mesh via a peer — so it needs at least one reachable node to join. You provide that peer's address, Noise public key, and pre-shared key:

text
--node-addr <ip:port>   --node-pubkey <hex>   --psk-hex <psk>

There is no one-command net up yet: the bootstrap peer is a running mesh node you stand up via the SDK (MeshBuilder) or an existing daemon. If you just want to see the wrap → discover → invoke loop end-to-end today, the self-contained two-node path is the SDK harness in Discover and Invoke; this page is the operator command for federating a tool onto a mesh that already exists.

Wrap a server

text
net-mesh wrap github \
  --node-addr 203.0.113.7:4433 --node-pubkey 0x<peer-hex> --psk-hex <psk> \
  --identity ./operator.toml \
  --env GITHUB_TOKEN=ghp_xxx \
  -- npx -y @modelcontextprotocol/server-github
  • github is a short label for this wrapped server (shown in output; not a tool id).
  • Everything after -- is the stdio MCP server command to spawn.
  • --identity is your operator identity file (seed_hex = "..."). Owner-only scoping keys on it, so use a stable identity, not an ephemeral key.
  • --env KEY=VALUE (repeatable) sets environment for the child server. These stay in the child process on this machine and never transit the mesh — this is how credentials stay local. The one deliberate exception, for remote/HTTP destinations that only speak bearer auth, is opt-in, deny-by-default credential forwarding; a wrapped stdio server like this one never forwards.

net-mesh wrap is long-running. It emits a wrapped event (the served + skipped tools, the announced visibility/scope, and any widened origins), then a tools_changed event whenever the server's tool set changes, and a server_exited event when it stops — at which point the capabilities are withdrawn from the mesh.

Owner-only by default

Every wrapped tool is announced as visible to the mesh but invocable only by the same root identity — the owner. Discovery is not authorization: other nodes can see and describe the capability, but a call from outside the owner scope is rejected at the wrapper, verified against the AEAD-authenticated caller origin.

To widen who may invoke, admit specific caller origins explicitly:

text
net-mesh wrap github --allow 0x<caller-origin> --allow 0x<other-origin> \
  --node-addr <peer> --node-pubkey <hex> --psk-hex <psk> \
  -- npx -y @modelcontextprotocol/server-github

--allow widens the local enforcement beyond the owner; the announced scope label stays the owner identity, so consumers read the reported allowed_origins to know who may actually invoke. There is no flag that grants blanket mesh-wide invocation — widening is always an explicit, per-origin decision.

Credential status

net-mesh wrap classifies each wrapped tool's credential exposure automatically. You can override:

  • --credentialed — force status to credentialed (upward; always allowed).
  • --no-credentials --force — force status to none (downward; requires --force to confirm you really mean it).

Credential status flows into the descriptor a consumer sees, and into the consent gate on the demand side (Expose Net as MCP): anything credentialed is search/describe-only until a human approves it.

Limits of the mcp_bridge tier

Wrapped tools carry compat_tier: "mcp_bridge" and are request/response only — no streams, no migration, no artifacts. Use a native capability (Discover and Invoke) when the operation needs Net streams, typed task state, artifact transfer, or migration.

Embedding it (library)

The CLI is a thin frontend over the bridge library's public surface: net_mcp::wrap::ServerPublisher::publish_server spawns and publishes the server, returning a PublicationHandle you refresh() on tool changes and withdraw() to reverse. A publisher is scoped to one Mesh and merges every publication it makes into the node's single announcement, so one process can publish several MCP servers (with distinct tool ids) and withdraw them independently. The end-to-end path is demonstrated in adapters/mcp/tests/wrap_end_to_end.rs.