tmcp 0.2.0

Complete, ergonomic implementation of the Model Context Protocol (MCP)
Documentation

tmcp

A complete Rust implementation of the Model Context Protocol (MCP), providing both client and server capabilities for building AI-integrated applications.

Overview

tmcp offers an ergonomic API for implementing MCP servers and clients with support for tools, resources, and prompts. The library uses async/await patterns with Tokio and provides procedural macros to eliminate boilerplate.

Features

  • Derive Macros: Simple #[mcp_server] attribute for automatic implementation
  • Multiple Transports: TCP, HTTP (with SSE), and stdio support
  • Type Safety: Strongly typed protocol messages with serde
  • Async-First: Built on Tokio for high-performance async I/O

Quick Example

use serde::{Deserialize, Serialize};
use tmcp::{mcp_server, schema::*, schemars, tool, Result, Server, ServerCtx};

#[derive(Default)]
struct WeatherServer;

// Tool input schema is automatically derived from the struct using serde and schemars.
#[derive(Debug, Serialize, Deserialize, schemars::JsonSchema)]
struct WeatherParams {
    city: String,
}

// The mcp_server macro generates the necessary boilerplate to expose methods as MCP tools.
#[mcp_server]
impl WeatherServer {
    // The doc comment becomes the tool's description in the MCP schema.
    #[tool]
    /// Get current weather for a city
    async fn get_weather(&self, _ctx: &ServerCtx, params: WeatherParams) -> Result<CallToolResult> {
        // Simulate weather API call
        let temperature = 22.5;
        let conditions = "Partly cloudy";

        Ok(CallToolResult::new().with_text_content(format!(
            "Weather in {}: {}°C, {}",
            params.city, temperature, conditions
        )))
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    let server = Server::default().with_connection(WeatherServer::default);
    server.serve_stdio().await?;
    Ok(())
}

Transport Options

  • TCP: server.listen_tcp("127.0.0.1:3000")
  • HTTP: server.listen_http("127.0.0.1:3000") (uses SSE for server->client)
  • Stdio: server.listen_stdio() for subprocess integration