rustlavel-mcp 0.5.3

Rustlavel Model Context Protocol support: server, client, stdio and HTTP transports
Documentation

rustlavel-mcp: the Model Context Protocol, both directions.

An application uses this crate to be an MCP server — handing an agent its own features as tools and resources — and to be an MCP client, using servers somebody else wrote. Both halves speak JSON-RPC 2.0 written from scratch on [rustlavel_core::Json]; there is no MCP SDK underneath.

Serving

Registrations go in one place, and a transport is chosen at the edge:

fn mcp() -> Server {
    Server::new("shop", env!("CARGO_PKG_VERSION"))
        .instructions("Use `orders.total` before quoting a refund.")
        .tool(Tool::new(
            "orders.total",
            "Total value of one customer's orders",
            Schema::object().integer("customer_id", "Which customer"),
            |args: Json| async move { Ok(Json::from(total_for(&args))) },
        ))
}

// Over HTTP, as part of the application:
App::new().plugin(Mcp::new(mcp()))

// Or over stdio, for a desktop client that launches the binary:
stdio::serve_stdio(Arc::new(mcp())).await?

Consuming

let mut client = McpClient::spawn("some-mcp-server", &[])?;
client.initialize().await?;
for tool in client.list_tools().await? {
    println!("{}: {}", tool.name, tool.description);
}

What the design insists on

  • Schemas are built, not typed. A tool declares its input through [Schema], and the same declaration is what an agent reads and what the server enforces — the two cannot drift apart.
  • Arguments are untrusted. They arrive from a language model. Every tools/call is validated against the declared schema before any application code runs.
  • A tool cannot take the process down. Handlers run inside a panic guard; a panic becomes an isError result the agent can read.
  • Every call is instrumented. tools/call dispatches an mcp.call event — tool, duration, outcome — so Telescope can show it.