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.
| Feature | Description | Enables |
|---|---|---|
default | Enabled by default; structured logging via tracing-subscriber | tracing-subscriber |
full | Everything below — single switch for prototyping and tests | All individual features listed below |
composition | Compose multiple MCP servers into one streamable-HTTP endpoint | (via streamable-http) |
http | HTTP transport primitives (Hyper server) | hyper, hyper-util, bytes |
http-client | Async HTTP client (reqwest, rustls backend) | reqwest |
jwt-auth | JWT-based authentication helpers | jsonwebtoken + http-client |
logging | Structured logging via the tracing ecosystem | tracing-subscriber |
macros | Attribute proc macros (#[mcp_tool], #[mcp_server], #[mcp_prompt]) | pmcp-macros, schemars |
mcp-apps | ChatGPT Apps / MCP-UI / SEP-1865 interactive UI types | UI types (code-only, no extra deps) |
oauth | OAuth 2.0 CLI helper for local token flows | webbrowser, dirs, rand + http-client |
rayon | Parallel iterator support for batch operations | rayon |
resource-watcher | File-system watcher for MCP resource notifications | notify, glob-match |
schema-generation | Generate JSON Schema from Rust types | schemars |
simd | SIMD-optimized JSON parsing (code-only, uses target-feature detection) | SIMD JSON parsing (no extra deps) |
sse | Server-Sent Events streaming transport | bytes + http-client |
streamable-http | HTTP streaming transport with SSE and Axum integration | hyper, hyper-util, hyper-rustls, rustls, axum, tower, tower-http, futures-util, bytes |
validation | JSON Schema and struct-level validation | jsonschema, garde |
websocket | WebSocket transport via tokio-tungstenite | tokio-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
- API docs: https://docs.rs/pmcp
- Book: https://paiml.github.io/pmcp/book/ — architecture, transport selection, OAuth flows, and deployment recipes.
- Course: https://paiml.github.io/pmcp/course/ — hands-on exercises covering tools, prompts, resources, and the full MCP protocol lifecycle.
- Repository: https://github.com/paiml/rust-mcp-sdk — issues, PRs, changelog, and examples directory with dozens of runnable MCP servers.
- TypeScript parity: pmcp tracks the reference TypeScript MCP SDK closely; wire-level messages are compatible, so a pmcp server works with any TypeScript client and vice versa.
§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-httppub use server::tower_layers::DnsRebindingLayer;streamable-httppub use server::tower_layers::SecurityHeadersLayer;streamable-httppub 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;websocketand non-WebAssemblypub use shared::WebSocketTransport;websocketand non-WebAssemblypub use shared::HttpConfig;httpand non-WebAssemblypub use shared::HttpTransport;httpand non-WebAssemblypub 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.
- axum
streamable-http - Axum Router convenience API for secure MCP server hosting.
- client
- MCP client implementation.
- composition
composition - 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.
- simd
simd - 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_
prompt macros - Defines a prompt handler with automatic argument schema generation.
- mcp_
server macros - Collects
#[mcp_tool]and#[mcp_prompt]methods from an impl block and generates handlers plus bulk registration. - mcp_
tool macros - Defines an MCP tool with automatic schema generation and state injection.