Skip to main content

Crate plugin_mcp

Crate plugin_mcp 

Source
Expand description

An MCP client Plugin: it connects a prompt to one remote MCP server over Streamable HTTP and offers that server’s tools as ordinary tools.

A Host installs PACKAGE once per server, under the server’s name lowercased in ASCII, so the tools of a server named wg21-papers are wg21-papers/<tool>. The Plugin has no prelude, so declaring it, as in plugins: [wg21-papers], only makes it required.

The Host passes the server’s entry from an mcp.json file as the configuration. A remote entry has url and optional headers, and a type of "sse", the legacy transport, is refused. A local entry has command, with optional args, env, and cwd. This Plugin recognizes that shape and refuses it at install with local MCP servers (command) are not supported yet, so the Host installs it as unavailable. Other type values and unknown fields are ignored, because the format is defined outside this repository.

String values in an entry may use ${env:NAME}, which an unset variable refuses naming NAME, and ${userHome}. Any other ${...} form passes through unchanged. headers may not set accept, Mcp-Session-Id, or Last-Event-Id, which the client owns.

Install does no I/O. It reads the Host’s runtime from the Plugin contract’s [runvil_plugin::TOKIO_RUNTIME] service and starts one background task on it, which connects, runs the handshake, and lists every page of tools within two minutes. The Plugin’s ready waits for that task, so a run sees the tools of a server that is still starting. A server that fails to start is unavailable to each run that starts while it is down, with the reason, and the Plugin keeps trying in the background, waiting 1 second after the first failure and doubling up to a minute, so a later run offers its tools once it answers. A server that is ready stays ready, and a later failure shows as a transport error on the call.

A tool whose name, lowercased in ASCII, is not a valid tool id, or that repeats an earlier tool’s id after lowercasing, is dropped with a warning. A tool’s description is its description, else its title, else its name, and its parameters are its inputSchema.

A call sends tools/call with the tool’s original name and waits up to five minutes. Text blocks and embedded text resources come back joined with blank lines. An image, audio, or binary resource becomes a placeholder such as [image omitted: image/png], a resource link becomes [resource: <uri>], and a result with no blocks but with structuredContent gives that JSON. A result marked isError is a backend error with the server’s text, and a transport failure or the deadline is a transport error. Dropping a call sends the server notifications/cancelled for its request.

The client declares no capabilities, because an optional extension would make GitHub’s remote server answer with interactive forms this Plugin cannot show. Its HTTP client refuses redirects, which keeps the configured headers off any other server.

§Invariants

  • May depend on: runvil-plugin, shared-* crates, and outside libraries. cargo test -p build-xtask enforces the Plugin family’s allow-list. Only PACKAGE is public.
  • Every output is untrusted.
  • No reason, log line, Debug output, or error names an env or headers value. They may name keys.
  • It runs on the Host’s runtime, read through the contract’s TOKIO_RUNTIME service, and construct does no I/O.
  • It starts no process: a local entry is refused at construct.
  • Dropping a call tells the server to drop the request.

Constants§

PACKAGE
The Plugin’s label, which a Host adds to its package registry.