MCP Hub
Back to servers

mcpkit

A robust Rust SDK implementing the latest MCP protocol (2025-11-25), providing macros and typestate builders to easily create servers with tools, resources, and various transport layers.

Stars
2
Tools
3
Updated
Jan 7, 2026
Validated
Feb 11, 2026

mcpkit

CI Crates.io Documentation License MSRV MCP Protocol

A Rust SDK for the Model Context Protocol (MCP) that simplifies server development through a unified #[mcp_server] macro.

Features

  • Unified #[mcp_server] macro for defining tools, resources, and prompts
  • Runtime-agnostic async support (Tokio, smol)
  • Typestate builders for compile-time validation of server configuration
  • Context-based error handling with McpError and .context() chains
  • MCP 2025-11-25 protocol including Tasks, Elicitation, and OAuth 2.1
  • Tower-compatible middleware via built-in Layer pattern

Why mcpkit?

mcpkit implements MCP 2025-11-25 — the latest protocol specification. As of December 2025, the official rmcp SDK documentation references protocol version 2024-11-05 (always verify current status). mcpkit supports the newest MCP features:

FeatureAdded InDescription
Tasks2025-11-25Long-running operations with progress tracking and cancellation
Elicitation2025-06-18Server-initiated requests for user input
OAuth 2.12025-03-26Modern authentication with mandatory PKCE
Tool Annotations2025-03-26readOnly, destructive, idempotent hints for tools
Structured Output2025-06-18Type-safe JSON responses with schema validation

See the detailed comparison for a full overview of Rust MCP SDK options.

Quick Start

Add the dependency to your Cargo.toml:

[dependencies]
mcpkit = "0.5"
tokio = { version = "1", features = ["full"] }
serde_json = "1"

Create a simple MCP server:

use mcpkit::prelude::*;
use mcpkit::transport::stdio::StdioTransport;

struct Calculator;

#[mcp_server(name = "calculator", version = "1.0.0")]
impl Calculator {
    #[tool(description = "Add two numbers")]
    async fn add(&self, a: f64, b: f64) -> ToolOutput {
        ToolOutput::text((a + b).to_string())
    }

    #[tool(description = "Multiply two numbers")]
    async fn multiply(&self, a: f64, b: f64) -> ToolOutput {
        ToolOutput::text((a * b).to_string())
    }
}

#[tokio::main]
async fn main() -> Result<(), McpError> {
    // Create transport - you choose the runtime!
    let transport = StdioTransport::new();

    // Build server with registered handlers
    let server = ServerBuilder::new(Calculator)
        .with_tools(Calculator)
        .build();

    // Serve on the transport
    server.serve(transport).await
}

Note: This SDK is runtime-agnostic. You provide the transport, which lets you use Tokio, smol, or any other async runtime. The examples use Tokio, but the SDK itself doesn't depend on any specific runtime.

mcpkit Highlights

FeatureDescription
ProtocolMCP 2025-11-25 (supports all 4 protocol versions)
MacroSingle #[mcp_server] with #[tool], #[resource], #[prompt]
ParametersExtracted directly from function signatures
ErrorsUnified McpError with .context() chains
Transportsstdio, WebSocket, HTTP/SSE, Unix sockets, gRPC, Windows pipes
MiddlewareBuilt-in Tower-compatible Layer system
RuntimeAgnostic (Tokio, smol)

For comparisons with other Rust MCP SDKs (rmcp, rust-mcp-sdk, mcp-protocol-sdk), see the detailed comparison.

Crate Structure

mcpkit/
├── mcpkit/                     # Facade crate (use this)
├── crates/
│   ├── mcpkit-core/            # Protocol types, traits
│   ├── mcpkit-transport/       # Transport abstractions
│   │   ├── stdio               # Standard I/O transport
│   │   ├── http                # Streamable HTTP transport
│   │   ├── websocket           # WebSocket transport
│   │   ├── grpc                # gRPC with bidirectional streaming
│   │   ├── unix                # Unix domain sockets
│   │   └── windows             # Windows named pipes
│   ├── mcpkit-server/          # Server implementation
│   ├── mcpkit-client/          # Client implementation
│   ├── mcpkit-macros/          # Procedural macros
│   ├── mcpkit-testing/         # Test utilities
│   ├── mcpkit-axum/            # Axum web framework integration
│   ├── mcpkit-actix/           # Actix-web framework integration
│   ├── mcpkit-rocket/          # Rocket web framework integration
│   └── mcpkit-warp/            # Warp web framework integration
└── examples/                   # Example servers

Examples

Minimal Server

use mcpkit::prelude::*;

struct MyServer;

#[mcp_server(name = "minimal", version = "1.0.0")]
impl MyServer {
    #[tool(description = "Say hello")]
    async fn hello(&self, name: Option<String>) -> ToolOutput {
        let name = name.unwrap_or_else(|| "World".to_string());
        ToolOutput::text(format!("Hello, {}!", name))
    }
}

With Resources

use mcpkit::prelude::*;

struct ConfigServer;

#[mcp_server(name = "config", version = "1.0.0")]
impl ConfigServer {
    #[resource(
        uri_pattern = "config://app/{key}",
        name = "Configuration",
        mime_type = "application/json"
    )]
    async fn get_config(&self, uri: &str) -> ResourceContents {
        ResourceContents::text(uri, r#"{"debug": true}"#)
    }
}

With Prompts

use mcpkit::prelude::*;

struct PromptServer;

#[mcp_server(name = "prompts", version = "1.0.0")]
impl PromptServer {
    #[prompt(description = "Review code for issues")]
    async fn code_review(&self, code: String, language: Option<String>) -> GetPromptResult {
        let lang = language.unwrap_or_else(|| "unknown".to_string());
        GetPromptResult {
            description: Some("Code review prompt".to_string()),
            messages: vec![
                PromptMessage::user(format!(
                    "Please review the following {} code:\n```{}\n{}```",
                    lang, lang, code
                ))
            ],
        }
    }
}

Transports

The SDK is runtime-agnostic. You choose the transport and the async runtime.

Standard I/O

use mcpkit_transport::stdio::StdioTransport;

let transport = StdioTransport::new();

HTTP (Streamable)

use mcpkit_transport::http::HttpTransport;

let transport = HttpTransport::new(HttpTransportConfig::new("http://localhost:8080"));

WebSocket

use mcpkit_transport::websocket::WebSocketTransport;

let transport = WebSocketTransport::new(WebSocketConfig::new("ws://localhost:9000"));

Unix Domain Socket (Unix only)

#[cfg(unix)]
use mcpkit_transport::unix::UnixTransport;

#[cfg(unix)]
let transport = UnixTransport::new("/tmp/mcp.sock");

gRPC

use mcpkit_transport::grpc::{GrpcTransport, GrpcConfig};

let config = GrpcConfig::new("http://localhost:50051");
let transport = GrpcTransport::connect(config).await?;

Windows Named Pipes (Windows only)

#[cfg(windows)]
use mcpkit_transport::windows::{NamedPipeTransport, NamedPipeConfig};

#[cfg(windows)]
let config = NamedPipeConfig::new(r"\\.\pipe\mcp-server");
let transport = NamedPipeTransport::connect(config).await?;

Middleware

use mcpkit_transport::stdio::StdioTransport;
use mcpkit_transport::middleware::{LoggingLayer, TimeoutLayer, LayerStack};
use std::time::Duration;
use log::Level;

let transport = StdioTransport::new();
let stack = LayerStack::new(transport)
    .with(LoggingLayer::new(Level::Debug))
    .with(TimeoutLayer::new(Duration::from_secs(30)));

Error Handling

use mcpkit::prelude::*;

fn process() -> Result<(), McpError> {
    let result = something_risky()
        .context("while processing request")?;
    Ok(())
}

Protocol Version

This SDK implements MCP protocol version 2025-11-25.

License

Licensed under either of:

at your option.

Documentation

Contributing

Contributions are welcome! Please read our Contributing Guide before submitting a Pull Request.

Security

For security issues, please see our Security Policy.

Reviews

No reviews yet

Sign in to write a review