Skip to main content

Crate pmcp

Crate pmcp 

Source
Expand description

§pmcp

High-quality Rust SDK for the Model Context Protocol (MCP), providing both client and server implementations with full TypeScript SDK compatibility, multiple transport options (stdio, HTTP streaming, WebSocket), and built-in authentication support.

pmcp is designed as a zero-compromise production SDK: every feature is behind an explicit cargo feature flag so downstream builds stay lean, every public API ships with a doctest that runs under cargo test --doc, and the transport layer is interchangeable so the same Server handles stdio for local assistants, HTTP streaming for cloud deployments, and WebSocket for browser clients without rewriting your handlers.

The crate is organized around three primitives that mirror the MCP specification: tools (callable functions with typed arguments and structured output), prompts (parameterized templates with auto-generated argument schemas), and resources (URI-addressable content with optional change notifications). Builder APIs wire your handlers to each primitive, and the #[mcp_tool], #[mcp_prompt], and #[mcp_server] attribute macros (behind the macros feature) eliminate the per-handler boilerplate entirely by deriving schemas from your Rust types.

§Quick Start

Add pmcp to Cargo.toml with the features you need. The full meta-feature turns everything on for prototyping; production builds should cherry-pick individual features to keep compile time and binary size under control.

[dependencies]
pmcp = { version = "2.3", features = ["full"] }
tokio = { version = "1.46", features = ["full"] }

§Client Example

Connect to an MCP server over stdio, initialize the session, and enumerate the tools that server exposes. This is the minimum end-to-end client flow — wire it into your own assistant or test harness as-is, then layer on tool calls and prompt fetches as your use case grows.

use pmcp::{Client, StdioTransport, ClientCapabilities};

// Create a client with stdio transport
let transport = StdioTransport::new();
let mut client = Client::new(transport);

// Initialize the connection
let server_info = client.initialize(ClientCapabilities::default()).await?;

// List available tools
let tools = client.list_tools(None).await?;

§Server Example

Expose a single tool backed by a custom ToolHandler implementation and run it over stdio. The same Server::builder() chain works with any transport; just call a different run_* method or hand the server to the pmcp::axum::router helper behind the streamable-http feature.

use pmcp::{Server, ServerCapabilities, ToolHandler};
use async_trait::async_trait;
use serde_json::Value;

struct MyTool;

#[async_trait]
impl ToolHandler for MyTool {
    async fn handle(&self, args: Value, _extra: pmcp::RequestHandlerExtra) -> Result<Value, pmcp::Error> {
        Ok(serde_json::json!({"result": "success"}))
    }
}

let server = Server::builder()
    .name("my-server")
    .version("1.0.0")
    .capabilities(ServerCapabilities::default())
    .tool("my-tool", MyTool)
    .build()?;

// Run with stdio transport
server.run_stdio().await?;

§Cargo Features

pmcp uses cargo features to keep the default build minimal and to let you opt into exactly the transports, integrations, and helpers you need. The table below documents every user-facing feature, what it gives you, and what it pulls into your dependency tree so you can weigh capability against binary size before turning a flag on.

FeatureDescriptionEnables
defaultEnabled by default; structured logging via tracing-subscribertracing-subscriber
fullEverything below — single switch for prototyping and testsAll individual features listed below
compositionCompose multiple MCP servers into one streamable-HTTP endpoint(via streamable-http)
httpHTTP transport primitives (Hyper server)hyper, hyper-util, bytes
http-clientAsync HTTP client (reqwest, rustls backend)reqwest
jwt-authJWT-based authentication helpersjsonwebtoken + http-client
loggingStructured logging via the tracing ecosystemtracing-subscriber
macrosAttribute proc macros (#[mcp_tool], #[mcp_server], #[mcp_prompt])pmcp-macros, schemars
mcp-appsChatGPT Apps / MCP-UI / SEP-1865 interactive UI typesUI types (code-only, no extra deps)
oauthOAuth 2.0 CLI helper for local token flowswebbrowser, dirs, rand + http-client
rayonParallel iterator support for batch operationsrayon
resource-watcherFile-system watcher for MCP resource notificationsnotify, glob-match
schema-generationGenerate JSON Schema from Rust typesschemars
simdSIMD-optimized JSON parsing (code-only, uses target-feature detection)SIMD JSON parsing (no extra deps)
sseServer-Sent Events streaming transportbytes + http-client
streamable-httpHTTP streaming transport with SSE and Axum integrationhyper, hyper-util, hyper-rustls, rustls, axum, tower, tower-http, futures-util, bytes
validationJSON Schema and struct-level validationjsonschema, garde
websocketWebSocket transport via tokio-tungstenitetokio-tungstenite

§Choosing features

Most deployments need one transport plus optional auth and validation. A Cloudflare Workers or Lambda HTTP server typically wants streamable-http + jwt-auth + validation + macros; a desktop assistant that speaks stdio only needs the defaults plus macros and schema-generation; a browser-facing server wants websocket + validation. Turn on full during local prototyping and narrow the list before you ship.

§Transport notes

Feature flags divide cleanly along transport lines. http gives you the raw Hyper primitives for custom server wiring; streamable-http layers Axum, Tower middleware, and SSE framing on top for the common case of a production HTTP MCP endpoint (DNS rebinding protection, CORS, security headers are all built in). sse is a lighter-weight option when you only need server-push streaming without the full Axum router. websocket is native tungstenite for long-lived browser-facing connections. composition lets you merge several Server instances under one streamable-http endpoint so a single process can publish tools from multiple subsystems without per-subsystem HTTP plumbing.

§Authentication notes

jwt-auth and oauth are additive: jwt-auth validates incoming bearer tokens against a JWKS or static key, and oauth ships a desktop CLI flow that obtains and refreshes tokens for clients. Both sit on top of http-client (reqwest) which you can also enable on its own for plain outbound HTTP calls from handlers.

§Learn More

§License

MIT

Re-exports§

pub use client::Client;
pub use client::ClientBuilder;
pub use client::ToolCallResponse;
pub use error::Error;
pub use error::ErrorCode;
pub use error::Result;
pub use server::cancellation::RequestHandlerExtra;Non-WebAssembly
pub use server::task_store::InMemoryTaskStore;Non-WebAssembly
pub use server::task_store::StoreConfig;Non-WebAssembly
pub use server::task_store::TaskStore;Non-WebAssembly
pub use server::task_store::TaskStoreError;Non-WebAssembly
pub use server::auth;Non-WebAssembly
pub use server::limits::PayloadLimits;Non-WebAssembly
pub use server::simple_prompt::SimplePrompt;Non-WebAssembly
pub use server::simple_prompt::SyncPrompt;Non-WebAssembly
pub use server::simple_resources::DynamicResourceHandler;Non-WebAssembly
pub use server::simple_resources::ResourceCollection;Non-WebAssembly
pub use server::simple_resources::StaticResource;Non-WebAssembly
pub use server::simple_tool::SimpleTool;Non-WebAssembly
pub use server::simple_tool::SyncTool;Non-WebAssembly
pub use server::state::State;Non-WebAssembly
pub use server::typed_prompt::TypedPrompt;Non-WebAssembly
pub use server::typed_tool::SimpleToolExt;Non-WebAssembly
pub use server::typed_tool::SyncToolExt;Non-WebAssembly
pub use server::typed_tool::TypedSyncTool;Non-WebAssembly
pub use server::typed_tool::TypedTool;Non-WebAssembly
pub use server::typed_tool::TypedToolWithOutput;Non-WebAssembly
pub use server::ui::UIResourceBuilder;Non-WebAssembly
pub use server::McpServer;Non-WebAssembly
pub use server::PromptHandler;Non-WebAssembly
pub use server::ResourceHandler;Non-WebAssembly
pub use server::SamplingHandler;Non-WebAssembly
pub use server::Server;Non-WebAssembly
pub use server::ServerBuilder;Non-WebAssembly
pub use server::ToolHandler;Non-WebAssembly
pub use shared::StdioTransport;Non-WebAssembly
pub use shared::peer::PeerHandle;Non-WebAssembly
pub use server::tower_layers::AllowedOrigins;streamable-http
pub use server::tower_layers::DnsRebindingLayer;streamable-http
pub use server::tower_layers::SecurityHeadersLayer;streamable-http
pub use shared::batch::BatchRequest;
pub use shared::batch::BatchResponse;
pub use shared::uri_template::UriTemplate;
pub use shared::AuthMiddleware;
pub use shared::LoggingMiddleware;
pub use shared::Middleware;
pub use shared::MiddlewareChain;
pub use shared::RetryMiddleware;
pub use shared::Transport;
pub use shared::WebSocketConfig;websocket and non-WebAssembly
pub use shared::WebSocketTransport;websocket and non-WebAssembly
pub use shared::HttpConfig;http and non-WebAssembly
pub use shared::HttpTransport;http and non-WebAssembly
pub use types::AuthInfo;
pub use types::AuthScheme;
pub use types::CallToolRequest;
pub use types::CallToolResult;
pub use types::ClientCapabilities;
pub use types::ClientNotification;
pub use types::ClientRequest;
pub use types::CompleteRequest;
pub use types::CompleteResult;
pub use types::CompletionArgument;
pub use types::CompletionReference;
pub use types::Content;
pub use types::CreateMessageParams;
pub use types::CreateMessageResult;
pub use types::GetPromptResult;
pub use types::Implementation;
pub use types::IncludeContext;
pub use types::ListResourcesResult;
pub use types::ListToolsResult;
pub use types::LoggingLevel;
pub use types::ModelPreferences;
pub use types::ProgressNotification;
pub use types::ProgressToken;
pub use types::PromptMessage;
pub use types::ProtocolVersion;
pub use types::ReadResourceResult;
pub use types::RequestId;
pub use types::ResourceInfo;
pub use types::Role;
pub use types::RootsCapabilities;
pub use types::SamplingCapabilities;
pub use types::SamplingMessage;
pub use types::ServerCapabilities;
pub use types::ServerNotification;
pub use types::ServerRequest;
pub use types::TokenUsage;
pub use types::ToolCapabilities;
pub use types::ToolInfo;
pub use types::UIMimeType;
pub use types::UIResource;
pub use types::UIResourceContents;
pub use types::CallToolResult as ToolResult;
pub use utils::BatchingConfig;Non-WebAssembly
pub use utils::DebouncingConfig;Non-WebAssembly
pub use utils::MessageBatcher;Non-WebAssembly
pub use utils::MessageDebouncer;Non-WebAssembly
pub use types::protocol::version::negotiate_protocol_version;
pub use types::protocol::version::DEFAULT_PROTOCOL_VERSION;
pub use types::protocol::version::LATEST_PROTOCOL_VERSION;
pub use types::protocol::version::SUPPORTED_PROTOCOL_VERSIONS;

Modules§

assets
Platform-agnostic asset loading for MCP servers.
axumstreamable-http
Axum Router convenience API for secure MCP server hosting.
client
MCP client implementation.
compositioncomposition
MCP Server Composition
error
Error types for the MCP SDK.
runtime
Runtime abstraction layer for platform-independent async execution
secrets
Runtime secret access for MCP servers.
server
MCP server implementation.
shared
Shared components used by both client and server.
simdsimd
SIMD optimizations for PMCP performance-critical operations Provides vectorized implementations of JSON parsing and string operations
types
Core protocol types for MCP.
utils
Utility modules for the MCP SDK.

Macros§

context_or_new
Macro to get current context or create new one.
debug_correlated
Log debug with correlation.
error_correlated
Log error with correlation.
info_correlated
Log info with correlation.
log_correlated
Helper macros for correlated logging.
warn_correlated
Log warning with correlation.
with_context
Macro to run code with request context.

Constants§

DEFAULT_REQUEST_TIMEOUT_MS
Default request timeout in milliseconds

Functions§

log
Server-side logging function (placeholder for examples).

Attribute Macros§

async_trait
mcp_promptmacros
Defines a prompt handler with automatic argument schema generation.
mcp_servermacros
Collects #[mcp_tool] and #[mcp_prompt] methods from an impl block and generates handlers plus bulk registration.
mcp_toolmacros
Defines an MCP tool with automatic schema generation and state injection.