Skip to content

paiml/rust-mcp-sdk

Repository files navigation

PMCP - Pragmatic Model Context Protocol

CI Quality Gate Coverage Crates.io Documentation License: MIT Rust 1.82+ MCP Compatible

A high-quality Rust implementation of the Model Context Protocol (MCP) SDK, maintaining full compatibility with the TypeScript SDK while leveraging Rust's performance and safety guarantees.

Code Name: Angel Rust

🎉 Version 1.0.0 - Production Ready!

  • Full TypeScript SDK v1.17.2+ Compatibility: 100% protocol compatibility verified
  • 🎯 Procedural Macros: Simplified tool/prompt/resource definitions with #[tool] macro
  • 🌍 WASM/Browser Support: Run MCP clients directly in web browsers
  • SIMD Optimizations: 10-50x performance improvements for JSON parsing
  • 🔍 Fuzzing Infrastructure: Comprehensive fuzz testing for protocol robustness
  • 📚 Advanced Documentation: Complete protocol compatibility guide
  • 🧪 Integration Tests: TypeScript SDK interoperability testing
  • 🚀 Performance: 16x faster than TypeScript SDK, 50x lower memory usage

Core Features

  • 🚀 Full Protocol Support: Complete implementation of MCP specification v1.0
  • 🔄 Multiple Transports: stdio, HTTP/SSE, and WebSocket with auto-reconnection
  • 🛡️ Type Safety: Compile-time protocol validation
  • Zero-Copy Parsing: Efficient message handling with SIMD acceleration
  • 🔐 Built-in Auth: OAuth 2.0, OIDC discovery, and bearer token support
  • 🤖 LLM Sampling: Native support for model sampling operations
  • 🔌 Middleware System: Request/response interceptors for custom logic
  • 🔁 Retry Logic: Built-in exponential backoff for resilient connections
  • 📦 Message Batching: Efficient notification grouping and debouncing
  • 📬 Resource Subscriptions: Real-time resource change notifications
  • Request Cancellation: Full async cancellation support with CancellationToken
  • 🌐 WebSocket Server: Complete server-side WebSocket transport implementation
  • 📁 Roots Management: Directory/URI registration and management
  • 📊 Comprehensive Testing: Property tests, fuzzing, and integration tests
  • 🏗️ Quality First: Zero technical debt, no unwraps in production code

Installation

Add to your Cargo.toml:

[dependencies]
pmcp = "1.0"

Examples

The SDK includes comprehensive examples for all major features:

# Client initialization and connection
cargo run --example 01_client_initialize

# Basic server with tools
cargo run --example 02_server_basic

# Client tool usage
cargo run --example 03_client_tools

# Server with resources
cargo run --example 04_server_resources

# Client resource access
cargo run --example 05_client_resources

# Server with prompts
cargo run --example 06_server_prompts

# Client prompts usage
cargo run --example 07_client_prompts

# Logging
cargo run --example 08_logging

# Authentication (OAuth, Bearer tokens)
cargo run --example 09_authentication

# Progress notifications
cargo run --example 10_progress_notifications

# Request cancellation
cargo run --example 11_request_cancellation

# Error handling patterns
cargo run --example 12_error_handling

# WebSocket transport
cargo run --example 13_websocket_transport

# LLM sampling operations
cargo run --example 14_sampling_llm

# Middleware and interceptors
cargo run --example 15_middleware

# OAuth server with authentication
cargo run --example 16_oauth_server

# Completable prompts
cargo run --example 17_completable_prompts

# Resource watching with file system monitoring
cargo run --example 18_resource_watcher

# Input elicitation
cargo run --example 19_elicit_input

# OIDC discovery and authentication
cargo run --example 20_oidc_discovery

# Procedural macros for tools
cargo run --example 21_macro_tools --features macros

See the examples directory for detailed documentation.

What's New in v1.0 (In Development)

🎯 Procedural Macros

  • #[tool] attribute for automatic tool handler generation
  • #[tool_router] for collecting tools from impl blocks
  • Automatic JSON schema generation from Rust types
  • 70% reduction in boilerplate code

🌍 WASM Support

  • Full WebAssembly support for browser environments
  • WebSocket transport for WASM clients
  • Cross-platform runtime abstraction
  • Interactive browser example with modern UI
  • TypeScript definitions for seamless integration

🚀 Enhanced Developer Experience

  • Type-safe parameter handling with compile-time validation
  • Automatic error conversion and handling
  • Improved documentation with 200+ examples
  • Property-based testing for all new features

What's New in v0.6.6

🔐 OIDC Discovery Support

  • Full OpenID Connect discovery implementation
  • Automatic retry on CORS/network errors
  • Token exchange with explicit JSON accept headers
  • Comprehensive auth client module

🔒 Transport Response Isolation

  • Unique transport IDs prevent cross-transport response routing
  • Enhanced protocol safety for multiple concurrent connections
  • Request-response correlation per transport instance

📚 Enhanced Documentation

  • 135+ doctests with real-world examples
  • Complete property test coverage
  • New OIDC discovery example (example 20)

What's New in v0.2.0

🆕 WebSocket Transport with Auto-Reconnection

Full WebSocket support with automatic reconnection, exponential backoff, and keepalive ping/pong.

🆕 HTTP/SSE Transport

HTTP transport with Server-Sent Events for real-time notifications and long-polling support.

🆕 LLM Sampling Support

Native support for model sampling operations with the createMessage API:

let result = client.create_message(CreateMessageRequest {
    messages: vec![SamplingMessage {
        role: Role::User,
        content: Content::Text { text: "Hello!".to_string() },
    }],
    ..Default::default()
}).await?;

🆕 Middleware System

Powerful middleware chain for request/response processing:

use pmcp::{MiddlewareChain, LoggingMiddleware, AuthMiddleware};

let mut chain = MiddlewareChain::new();
chain.add(Arc::new(LoggingMiddleware::default()));
chain.add(Arc::new(AuthMiddleware::new("token".to_string())));

🆕 Message Batching & Debouncing

Optimize notification delivery with batching and debouncing:

use pmcp::{MessageBatcher, BatchingConfig};

let batcher = MessageBatcher::new(BatchingConfig {
    max_batch_size: 10,
    max_wait_time: Duration::from_millis(100),
    ..Default::default()
});

Quick Start

Client Example

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

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create client with stdio transport
    let transport = StdioTransport::new();
    let mut client = Client::new(transport);
    
    // Initialize connection
    let server_info = client.initialize(ClientCapabilities::default()).await?;
    println!("Connected to: {}", server_info.server_info.name);
    
    // List available tools
    let tools = client.list_tools(None).await?;
    for tool in tools.tools {
        println!("Tool: {} - {:?}", tool.name, tool.description);
    }
    
    // Call a tool
    let result = client.call_tool("get-weather", serde_json::json!({
        "location": "San Francisco"
    })).await?;
    
    Ok(())
}

Server Example

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

struct WeatherTool;

#[async_trait]
impl ToolHandler for WeatherTool {
    async fn handle(&self, args: Value) -> pmcp::Result<Value> {
        let location = args["location"].as_str()
            .ok_or_else(|| pmcp::Error::validation("location required"))?;
        
        // Implement weather fetching logic
        Ok(serde_json::json!({
            "temperature": 72,
            "condition": "sunny",
            "location": location
        }))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let server = Server::builder()
        .name("weather-server")
        .version("1.0.0")
        .capabilities(ServerCapabilities::tools_only())
        .tool("get-weather", WeatherTool)
        .build()?;
    
    // Run with stdio transport
    server.run_stdio().await?;
    Ok(())
}

Transport Options

stdio (Default)

let transport = StdioTransport::new();

HTTP/SSE

use pmcp::{HttpTransport, HttpConfig};

let config = HttpConfig {
    base_url: "http://localhost:8080".parse()?,
    sse_endpoint: Some("/events".to_string()),
    ..Default::default()
};
let transport = HttpTransport::new(config);

WebSocket

use pmcp::{WebSocketTransport, WebSocketConfig};

let config = WebSocketConfig {
    url: "ws://localhost:8080".parse()?,
    auto_reconnect: true,
    ..Default::default()
};
let transport = WebSocketTransport::new(config);

Development

Prerequisites

  • Rust 1.80.0 or later
  • Git

Setup

# Clone the repository
git clone https://github.com/paiml/rust-pmcp
cd rust-pmcp

# Install development tools
make setup

# Run quality checks
make quality-gate

Quality Standards

This project maintains pmat-level quality standards:

  • Zero Technical Debt: Production-ready with no technical debt
  • No unwrap(): All errors handled explicitly
  • 100% Documentation: Every public API documented
  • Property Testing: Comprehensive invariant testing
  • Benchmarks: Performance regression prevention

Testing

# Run all tests
make test-all

# Run property tests (slower, more thorough)
make test-property

# Generate coverage report
make coverage

# Run mutation tests
make mutants

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Ensure all quality checks pass (make quality-gate)
  4. Commit your changes (following conventional commits)
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Architecture

pmcp/
├── src/
│   ├── client/          # Client implementation
│   ├── server/          # Server implementation
│   ├── shared/          # Shared transport/protocol code
│   ├── types/           # Protocol type definitions
│   └── utils/           # Utility functions
├── tests/
│   ├── integration/     # Integration tests
│   └── property/        # Property-based tests
├── benches/             # Performance benchmarks
└── examples/            # Example implementations

Compatibility

Feature TypeScript SDK Rust SDK
Protocol Versions 2024-10-07+ 2024-10-07+
Transports stdio, SSE, WebSocket stdio, SSE, WebSocket
Authentication OAuth 2.0, Bearer OAuth 2.0, Bearer
Tools
Prompts
Resources
Sampling

Performance

Benchmarks show 10x improvement over TypeScript SDK:

  • Message parsing: < 1μs
  • Round-trip latency: < 100μs (stdio)
  • Memory usage: < 10MB baseline

Run benchmarks:

make bench

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments