freshcrate
Skin:/
Home > RAG & Memory > rust-sdk

rust-sdk

The official Rust SDK for the Model Context Protocol

Why this rank:Strong adoptionRecent releaseHealthy release cadence

Description

The official Rust SDK for the Model Context Protocol

README

RMCP

Crates.io Version docs.rs CI License

An official Rust Model Context Protocol SDK implementation with tokio async runtime.

Migrating to 1.x? See the migration guide for breaking changes and upgrade instructions.

This repository contains the following crates:

  • rmcp: The core crate providing the RMCP protocol implementation - see rmcp
  • rmcp-macros: A procedural macro crate for generating RMCP tool implementations - see rmcp-macros

For the full MCP specification, see modelcontextprotocol.io.

Table of Contents

Usage

Import the crate

rmcp = { version = "0.16.0", features = ["server"] }
## or dev channel
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main" }

Third Dependencies

Basic dependencies:

Build a Client

Start a client
use rmcp::{ServiceExt, transport::{TokioChildProcess, ConfigureCommandExt}};
use tokio::process::Command;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ().serve(TokioChildProcess::new(Command::new("npx").configure(|cmd| {
        cmd.arg("-y").arg("@modelcontextprotocol/server-everything");
    }))?).await?;
    Ok(())
}

Build a Server

Build a transport
use tokio::io::{stdin, stdout};
let transport = (stdin(), stdout());
Build a service

You can easily build a service by using ServerHandler or ClientHandler.

let service = common::counter::Counter::new();
Start the server
// this call will finish the initialization process
let server = service.serve(transport).await?;
Interact with the server

Once the server is initialized, you can send requests or notifications:

// request
let roots = server.list_roots().await?;

// or send notification
server.notify_cancelled(...).await?;
Waiting for service shutdown
let quit_reason = server.waiting().await?;
// or cancel it
let quit_reason = server.cancel().await?;

Tools

Tools let servers expose callable functions to clients. Each tool has a name, description, and a JSON Schema for its parameters. Clients discover tools via list_tools and invoke them via call_tool.

MCP Spec: Tools

Server-side

The #[tool], #[tool_router], and #[tool_handler] macros handle all the wiring. For a tools-only server you can use #[tool_router(server_handler)] to skip the separate ServerHandler impl:

use rmcp::{handler::server::wrapper::Parameters, schemars, tool, tool_router, ServiceExt, transport::stdio};

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct AddParams {
    a: i32,
    b: i32,
}

#[derive(Clone)]
struct Calculator;

#[tool_router(server_handler)]
impl Calculator {
    #[tool(description = "Add two numbers")]
    fn add(&self, Parameters(AddParams { a, b }): Parameters<AddParams>) -> String {
        (a + b).to_string()
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let service = Calculator.serve(stdio()).await?;
    service.waiting().await?;
    Ok(())
}

When you need custom server metadata or multiple capabilities (tools + prompts), use explicit #[tool_handler]:

use rmcp::{handler::server::wrapper::Parameters, schemars, tool, tool_router, tool_handler, ServerHandler, ServiceExt};

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct AddParams {
    a: i32,
    b: i32,
}

#[derive(Clone)]
struct Calculator;

#[tool_router]
impl Calculator {
    #[tool(description = "Add two numbers")]
    fn add(&self, Parameters(AddParams { a, b }): Parameters<AddParams>) -> String {
        (a + b).to_string()
    }
}

#[tool_handler(name = "calculator", version = "1.0.0", instructions = "A simple calculator")]
impl ServerHandler for Calculator {}

See crates/rmcp-macros for full macro documentation.

Client-side

use rmcp::model::CallToolRequestParams;

// List all tools
let tools = client.list_all_tools().await?;

// Call a tool by name
let result = client.call_tool(CallToolRequestParams::new("add")).await?;

Example: examples/servers/src/common/calculator.rs (server), examples/servers/src/calculator_stdio.rs (stdio runner)


Resources

Resources let servers expose data (files, database records, API responses) that clients can read. Each resource is identified by a URI and returns content as text or binary (base64-encoded) data. Resource templates allow servers to declare URI patterns with dynamic parameters.

MCP Spec: Resources

Server-side

Implement list_resources(), read_resource(), and optionally list_resource_templates() on the ServerHandler trait. Enable the resources capability in get_info().

use rmcp::{
    ErrorData as McpError, RoleServer, ServerHandler, ServiceExt,
    model::*,
    service::RequestContext,
    transport::stdio,
};
use serde_json::json;

#[derive(Clone)]
struct MyServer;

impl ServerHandler for MyServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder()
                .enable_resources()
                .build(),
            ..Default::default()
        }
    }

    async fn list_resources(
        &self,
        _request: Option<PaginatedRequestParams>,
        _context: RequestContext<RoleServer>,
    ) -> Result<ListResourcesResult, McpError> {
        Ok(ListResourcesResult {
            resources: vec![
                RawResource::new("file:///config.json", "config").no_annotation(),
                RawResource::new("memo://insights", "insights").no_annotation(),
            ],
            next_cursor: None,
            meta: None,
        })
    }

    async fn read_resource(
        &self,
        request: ReadResourceRequestParams,
        _context: RequestContext<RoleServer>,
    ) -> Result<ReadResourceResult, McpError> {
        match request.uri.as_str() {
            "file:///config.json" => Ok(ReadResourceResult {
                contents: vec![ResourceContents::text(r#"{"key": "value"}"#, &request.uri)],
            }),
            "memo://insights" => Ok(ReadResourceResult {
                contents: vec![ResourceContents::text("Analysis results...", &request.uri)],
            }),
            _ => Err(McpError::resource_not_found(
                "resource_not_found",
                Some(json!({ "uri": request.uri })),
            )),
        }
    }

    async fn list_resource_templates(
        &self,
        _request: Option<PaginatedRequestParams>,
        _context: RequestContext<RoleServer>,
    ) -> Result<ListResourceTemplatesResult, McpError> {
        Ok(ListResourceTemplatesResult {
            resource_templates: vec![],
            next_cursor: None,
            meta: None,
        })
    }
}

Client-side

use rmcp::model::{ReadResourceRequestParams};

// List all resources (handles pagination automatically)
let resources = client.list_all_resources().await?;

// Read a specific resource by URI
let result = client.read_resource(ReadResourceRequestParams {
    meta: None,
    uri: "file:///config.json".into(),
}).await?;

// List resource templates
let templates = client.list_all_resource_templates().await?;

Notifications

Servers can notify clients when the resource list changes or when a specific resource is updated:

// Notify that the resource list has changed (clients should re-fetch)
context.peer.notify_resource_list_changed().await?;

// Notify that a specific resource was updated
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
    uri: "file:///config.json".into(),
}).await?;

Clients handle these via ClientHandler:

impl ClientHandler for MyClient {
    async fn on_resource_list_changed(
        &self,
        _context: NotificationContext<RoleClient>,
    ) {
        // Re-fetch the resource list
    }

    async fn on_resource_updated(
        &self,
        params: ResourceUpdatedNotificationParam,
        _context: NotificationContext<RoleClient>,
    ) {
        // Re-read the updated resource at params.uri
    }
}

Example: examples/servers/src/common/counter.rs (server), examples/clients/src/everything_stdio.rs (client)


Prompts

Prompts are reusable message templates that servers expose to clients. They accept typed arguments and return conversation messages. The #[prompt] macro handles argument validation and routing automatically.

MCP Spec: Prompts

Server-side

Use the #[prompt_router], #[prompt], and #[prompt_handler] macros to define prompts declaratively. Arguments are defined as structs deriving JsonSchema.

use rmcp::{
    ErrorData as McpError, RoleServer, ServerHandler, ServiceExt,
    handler::server::{router::prompt::PromptRouter, wrapper::Parameters},
    model::*,
    prompt, prompt_handler, prompt_router,
    schemars::JsonSchema,
    service::RequestContext,
    transport::stdio,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CodeReviewArgs {
    #[schemars(description = "Programming language of the code")]
    pub language: String,
    #[schemars(description = "Focus areas for the review")]
    pub focus_areas: Option<Vec<String>>,
}

#[derive(Clone)]
pub struct MyServer {
    prompt_router: PromptRouter<Self>,
}

#[prompt_router]
impl MyServer {
    fn new() -> Self {
        Self { prompt_router: Self::prompt_router() }
    }

    /// Simple prompt without parameters
    #[prompt(name = "greeting", description = "A simple greeting")]
    async fn greeting(&self) -> Vec<PromptMessage> {
        vec![PromptMessage::new_text(
            PromptMessageRole::User,
            "Hello! How can you help me today?",
        )]
    }

    /// Prompt with typed arguments
    #[prompt(name = "code_review", description = "Review code in a given language")]
    async fn code_review(
        &self,
        Parameters(args): Parameters<CodeReviewArgs>,
    ) -> Result<GetPromptResult, McpError> {
        let focus = args.focus_areas
            .unwrap_or_else(|| vec!["correctness".into()]);

        Ok(GetPromptResult {
            description: Some(format!("Code review for {}", args.language)),
            messages: vec![
                PromptMessage::new_text(
                    PromptMessageRole::User,
                    format!("Review my {} code. Focus on: {}", args.language, focus.join(", ")),
                ),
            ],
        })
    }
}

#[prompt_handler]
impl ServerHandler for MyServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder().enable_prompts().build(),
            ..Default::default()
        }
    }
}

Prompt functions support several return types:

  • Vec<PromptMessage> -- simple message list
  • GetPromptResult -- messages with an optional description
  • Result<T, McpError> -- either of the above, with error handling

Client-side

use rmcp::model::GetPromptRequestParams;

// List all prompts
let prompts = client.list_all_prompts().await?;

// Get a prompt with arguments
let result = client.get_prompt(GetPromptRequestParams {
    meta: None,
    name: "code_review".into(),
    arguments: Some(rmcp::object!({
        "language": "Rust",
        "focus_areas": ["performance", "safety"]
    })),
}).await?;

Notifications

// Server: notify that available prompts have changed
context.peer.notify_prompt_list_changed().await?;

Example: examples/servers/src/prompt_stdio.rs (server), examples/clients/src/everything_stdio.rs (client)


Sampling

Sampling flips the usual direction: the server asks the client to run an LLM completion. The server sends a create_message request, the client processes it through its LLM, and returns the result.

MCP Spec: Sampling

Server-side (requesting sampling)

Access the client's sampling capability through context.peer.create_message():

use rmcp::model::*;

// Inside a ServerHandler method (e.g., call_tool):
let response = context.peer.create_message(CreateMessageRequestParams {
    meta: None,
    task: None,
    messages: vec![SamplingMessage::user_text("Explain this error: connection refused")],
    model_preferences: Some(ModelPreferences {
        hints: Some(vec![ModelHint { name: Some("claude".into()) }]),
        cost_priority: Some(0.3),
        speed_priority: Some(0.8),
        intelligence_priority: Some(0.7),
    }),
    system_prompt: Some("You are a helpful assistant.".into()),
    include_context: Some(ContextInclusion::None),
    temperature: Some(0.7),
    max_tokens: 150,
    stop_sequences: None,
    metadata: None,
    tools: None,
    tool_choice: None,
}).await?;

// Extract the response text
let text = response.message.content
    .first()
    .and_then(|c| c.as_text())
    .map(|t| &t.text);

Client-side (handling sampling)

On the client side, implement ClientHandler::create_message(). This is where you'd call your actual LLM:

use rmcp::{ClientHandler, model::*, service::{RequestContext, RoleClient}};

#[derive(Clone, Default)]
struct MyClient;

impl ClientHandler for MyClient {
    async fn create_message(
        &self,
        params: CreateMessageRequestParams,
        _context: RequestContext<RoleClient>,
    ) -> Result<CreateMessageResult, ErrorData> {
        // Forward to your LLM, or return a mock response:
        let response_text = call_your_llm(&params.messages).await;

        Ok(CreateMessageResult {
            message: SamplingMessage::assistant_text(response_text),
            model: "my-model".into(),
            stop_reason: Some(CreateMessageResult::STOP_REASON_END_TURN.into()),
        })
    }
}

Example: examples/servers/src/sampling_stdio.rs (server), examples/clients/src/sampling_stdio.rs (client)


Roots

Roots tell servers which directories or projects the client is working in. A root is a URI (typically file://) pointing to a workspace or repository. Servers can query roots to know where to look for files and how to scope their work.

MCP Spec: Roots

Server-side

Ask the client for its root list, and handle change notifications:

use rmcp::{ServerHandler, model::*, service::{NotificationContext, RoleServer}};

impl ServerHandler for MyServer {
    // Query the client for its roots
    async fn call_tool(
        &self,
        request: CallToolRequestParams,
        context: RequestContext<RoleServer>,
    ) -> Result<CallToolResult, ErrorData> {
        let roots = context.peer.list_roots().await?;
        // Use roots.roots to understand workspace boundaries
        // ...
    }

    // Called when the client's root list changes
    async fn on_roots_list_changed(
        &self,
        _context: NotificationContext<RoleServer>,
    ) {
        // Re-fetch roots to stay current
    }
}

Client-side

Clients declare roots capability and implement list_roots():

use rmcp::{ClientHandler, model::*};

impl ClientHandler for MyClient {
    async fn list_roots(
        &self,
        _context: RequestContext<RoleClient>,
    ) -> Result<ListRootsResult, ErrorData> {
        Ok(ListRootsResult {
            roots: vec![
                Root {
                    uri: "file:///home/user/project".into(),
                    name: Some("My Project".into()),
                },
            ],
        })
    }
}

Clients notify the server when roots change:

// After adding or removing a workspace root:
client.notify_roots_list_changed().await?;

Logging

Servers can send structured log messages to clients. The client sets a minimum severity level, and the server sends messages through the peer notification interface.

MCP Spec: Logging

Server-side

Enable the logging capability, handle level changes from the client, and send log messages via the peer:

use rmcp::{ServerHandler, model::*, service::RequestContext};

impl ServerHandler for MyServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder()
                .enable_logging()
                .build(),
            ..Default::default()
        }
    }

    // Client sets the minimum log level
    async fn set_level(
        &self,
        request: SetLevelRequestParams,
        _context: RequestContext<RoleServer>,
    ) -> Result<(), ErrorData> {
        // Store request.level and filter future log messages accordingly
        Ok(())
    }
}

// Send a log message from any handler with access to the peer:
context.peer.notify_logging_message(LoggingMessageNotificationParam {
    level: LoggingLevel::Info,
    logger: Some("my-server".into()),
    data: serde_json::json!({
        "message": "Processing completed",
        "items_processed": 42
    }),
}).await?;

Available log levels (from least to most severe): Debug, Info, Notice, Warning, Error, Critical, Alert, Emergency.

Client-side

Clients handle incoming log messages via ClientHandler:

impl ClientHandler for MyClient {
    async fn on_logging_message(
        &self,
        params: LoggingMessageNotificationParam,
        _context: NotificationContext<RoleClient>,
    ) {
        println!("[{}] {}: {}", params.level,
            params.logger.unwrap_or_default(), params.data);
    }
}

Clients can also set the server's log level:

client.set_level(SetLevelRequestParams {
    level: LoggingLevel::Warning,
    meta: None,
}).await?;

Completions

Completions give auto-completion suggestions for prompt or resource template arguments. As a user fills in arguments, the client can ask the server for suggestions based on what's already been entered.

MCP Spec: Completions

Server-side

Enable the completions capability and implement the complete() handler. Use request.context to inspect previously filled arguments:

use rmcp::{ErrorData as McpError, ServerHandler, model::*, service::RequestContext, RoleServer};

impl ServerHandler for MyServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder()
                .enable_completions()
                .enable_prompts()
                .build(),
            ..Default::default()
        }
    }

    async fn complete(
        &self,
        request: CompleteRequestParams,
        _context: RequestContext<RoleServer>,
    ) -> Result<CompleteResult, McpError> {
        let values = match &request.r#ref {
            Reference::Prompt(prompt_ref) if prompt_ref.name == "sql_query" => {
                match request.argument.name.as_str() {
                    "operation" => vec!["SELECT", "INSERT", "UPDATE", "DELETE"],
                    "table" => vec!["users", "orders", "products"],
                    "columns" => {
                        // Adapt suggestions based on previously filled arguments
                        if let Some(ctx) = &request.context {
                            if let Some(op) = ctx.get_argument("operation") {
                                match op.to_uppercase().as_str() {
                                    "SELECT" | "UPDATE" => {
                                        vec!["id", "name", "email", "created_at"]
                                    }
                                    _ => vec![],
                                }
                            } else { vec![] }
                        } else { vec![] }
                    }
                    _ => vec![],
                }
            }
            _ => vec![],
        };

        // Filter by the user's partial input
        let filtered: Vec<String> = values.into_iter()
            .map(String::from)
            .filter(|v| v.to_lowercase().contains(&request.argument.value.to_lowercase()))
            .collect();

        Ok(CompleteResult {
            completion: CompletionInfo {
                values: filtered,
                total: None,
                has_more: Some(false),
            },
        })
    }
}

Client-side

use rmcp::model::*;

let result = client.complete(CompleteRequestParams {
    meta: None,
    r#ref: Reference::Prompt(PromptReference {
        name: "sql_query".into(),
    }),
    argument: ArgumentInfo {
        name: "operation".into(),
        value: "SEL".into(),
    },
    context: None,
}).await?;

// result.completion.values contains suggestions like ["SELECT"]

Example: examples/servers/src/completion_stdio.rs


Notifications

Notifications are fire-and-forget messages -- no response is expected. They cover progress updates, cancellation, and lifecycle events. Both sides can send and receive them.

MCP Spec: Notifications

Progress notifications

Servers can report progress during long-running operations:

use rmcp::model::*;

// Inside a tool handler:
for i in 0..total_items {
    process_item(i).await;

    context.peer.notify_progress(ProgressNotificationParam {
        progress_token: ProgressToken(NumberOrString::Number(i as i64)),
        progress: i as f64,
        total: Some(total_items as f64),
        message: Some(format!("Processing item {}/{}", i + 1, total_items)),
    }).await?;
}

Cancellation

Either side can cancel an in-progress request:

// Send a cancellation
context.peer.notify_cancelled(CancelledNotificationParam {
    request_id: the_request_id,
    reason: Some("User requested cancellation".into()),
}).await?;

Handle cancellation in ServerHandler or ClientHandler:

impl ServerHandler for MyServer {
    async fn on_cancelled(
        &self,
        params: CancelledNotificationParam,
        _context: NotificationContext<RoleServer>,
    ) {
        // Abort work for params.request_id
    }
}

Initialized notification

Clients send initialized after the handshake completes:

// Sent automatically by rmcp during the serve() handshake.
// Servers handle it via:
impl ServerHandler for MyServer {
    async fn on_initialized(
        &self,
        _context: NotificationContext<RoleServer>,
    ) {
        // Server is ready to receive requests
    }
}

List-changed notifications

When available tools, prompts, or resources change, tell the client:

context.peer.notify_tool_list_changed().await?;
context.peer.notify_prompt_list_changed().await?;
context.peer.notify_resource_list_changed().await?;

Example: examples/servers/src/common/progress_demo.rs


Subscriptions

Clients can subscribe to specific resources. When a subscribed resource changes, the server sends a notification and the client can re-read it.

MCP Spec: Resources - Subscriptions

Server-side

Enable subscriptions in the resources capability and implement the subscribe() / unsubscribe() handlers:

use rmcp::{ErrorData as McpError, ServerHandler, model::*, service::RequestContext, RoleServer};
use std::sync::Arc;
use tokio::sync::Mutex;
use std::collections::HashSet;

#[derive(Clone)]
struct MyServer {
    subscriptions: Arc<Mutex<HashSet<String>>>,
}

impl ServerHandler for MyServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo {
            capabilities: ServerCapabilities::builder()
                .enable_resources()
                .enable_resources_subscribe()
                .build(),
            ..Default::default()
        }
    }

    async fn subscribe(
        &self,
        request: SubscribeRequestParams,
        _context: RequestContext<RoleServer>,
    ) -> Result<(), McpError> {
        self.subscriptions.lock().await.insert(request.uri);
        Ok(())
    }

    async fn unsubscribe(
        &self,
        request: UnsubscribeRequestParams,
        _context: RequestContext<RoleServer>,
    ) -> Result<(), McpError> {
        self.subscriptions.lock().await.remove(&request.uri);
        Ok(())
    }
}

When a subscribed resource changes, notify the client:

// Check if the resource has subscribers, then notify
context.peer.notify_resource_updated(ResourceUpdatedNotificationParam {
    uri: "file:///config.json".into(),
}).await?;

Client-side

use rmcp::model::*;

// Subscribe to updates for a resource
client.subscribe(SubscribeRequestParams {
    meta: None,
    uri: "file:///config.json".into(),
}).await?;

// Unsubscribe when no longer needed
client.unsubscribe(UnsubscribeRequestParams {
    meta: None,
    uri: "file:///config.json".into(),
}).await?;

Handle update notifications in ClientHandler:

impl ClientHandler for MyClient {
    async fn on_resource_updated(
        &self,
        params: ResourceUpdatedNotificationParam,
        _context: NotificationContext<RoleClient>,
    ) {
        // Re-read the resource at params.uri
    }
}

Examples

See examples.

OAuth Support

See Oauth_support for details.

Related Resources

Related Projects

Extending rmcp

Built with rmcp

  • goose - An open-source, extensible AI agent that goes beyond code suggestions
  • apollo-mcp-server - MCP server that connects AI agents to GraphQL APIs via Apollo GraphOS
  • rustfs-mcp - High-performance MCP server providing S3-compatible object storage operations for AI/LLM integration
  • containerd-mcp-server - A containerd-based MCP server implementation
  • rmcp-openapi-server - High-performance MCP server that exposes OpenAPI definition endpoints as MCP tools
  • nvim-mcp - A MCP server to interact with Neovim
  • terminator - AI-powered desktop automation MCP server with cross-platform support and >95% success rate
  • stakpak-agent - Security-hardened terminal agent for DevOps with MCP over mTLS, streaming, secret tokenization, and async task management
  • video-transcriber-mcp-rs - High-performance MCP server for transcribing videos from 1000+ platforms using whisper.cpp
  • NexusCore MCP - Advanced malware analysis & dynamic instrumentation MCP server with Frida integration and stealth unpacking capabilities
  • spreadsheet-mcp - Token-efficient MCP server for spreadsheet analysis with automatic region detection, recalculation, screenshot, and editing support for LLM agents
  • hyper-mcp - A fast, secure MCP server that extends its capabilities through WebAssembly (WASM) plugins
  • rudof-mcp - RDF validation and data processing MCP server with ShEx/SHACL validation, SPARQL queries, and format conversion. Supports stdio and streamable HTTP transports with full MCP capabilities (tools, prompts, resources, logging, completions, tasks)
  • McpMux - Desktop app to configure MCP servers once at McpMux, connect every AI client (Cursor, Claude Desktop, VS Code, Windsurf) through a single encrypted local gateway with Spaces for project organization, FeatureSets to switch toolsets per client, and a built-in server registry

Development

Tips for Contributors

See docs/CONTRIBUTE.MD to get some tips for contributing.

Using Dev Container

If you want to use dev container, see docs/DEVCONTAINER.md for instructions on using Dev Container for development.

Release History

VersionChangesUrgencyDate
rmcp-v1.7.0### Added - add task-based stdio examples ([#839](https://github.com/modelcontextprotocol/rust-sdk/pull/839)) ### Fixed - *(rmcp)* flatten Resource variant of PromptMessageContent ([#843](https://github.com/modelcontextprotocol/rust-sdk/pull/843)) - reply -32700 on stdio parse errors instead of closing ([#833](https://github.com/modelcontextprotocol/rust-sdk/pull/833)) ### Other - *(rmcp)* remove dependency on chrono default features ([#829](https://github.com/modelcontextprotocol/rust-sdk/High5/13/2026
rmcp-v1.6.0### Added - *(http)* log Host/Origin rejections ([#826](https://github.com/modelcontextprotocol/rust-sdk/pull/826)) - *(http)* add Origin header validation ([#823](https://github.com/modelcontextprotocol/rust-sdk/pull/823)) - *(router)* support runtime disabling of tools ([#809](https://github.com/modelcontextprotocol/rust-sdk/pull/809)) - optional session store (resumabillity support) ([#775](https://github.com/modelcontextprotocol/rust-sdk/pull/775)) ### Fixed - add init_timeout for streamaHigh5/1/2026
rmcp-v1.5.0### Added - *(transport)* add constructors for non_exhaustive error types ([#806](https://github.com/modelcontextprotocol/rust-sdk/pull/806)) - add 2025-11-25 protocol version support ([#802](https://github.com/modelcontextprotocol/rust-sdk/pull/802)) ### Fixed - treat resource metadata JSON parse failure as soft error ([#810](https://github.com/modelcontextprotocol/rust-sdk/pull/810)) - include http_request_id in request-wise priming event IDs ([#799](https://github.com/modelcontextprotocol/High4/16/2026
rmcp-macros-v1.5.0### Fixed - *(macros)* respect `local` feature in `#[prompt]` macro โ€” omit `+ Send` bound ([#803](https://github.com/modelcontextprotocol/rust-sdk/pull/803))High4/16/2026
rmcp-v1.4.0### Added - add Default and constructors to ServerSseMessage ([#794](https://github.com/modelcontextprotocol/rust-sdk/pull/794)) - add meta to elicitation results ([#792](https://github.com/modelcontextprotocol/rust-sdk/pull/792)) - *(macros)* auto-generate get_info and default router ([#785](https://github.com/modelcontextprotocol/rust-sdk/pull/785)) - *(transport)* add which_command for cross-platform executable resolution ([#774](https://github.com/modelcontextprotocol/rust-sdk/pull/774)) - High4/10/2026
rmcp-macros-v1.4.0### Added - *(macros)* auto-generate get_info and default router ([#785](https://github.com/modelcontextprotocol/rust-sdk/pull/785))Medium4/10/2026
rmcp-v1.3.0### Added - *(transport)* add Unix domain socket client for streamable HTTP ([#749](https://github.com/modelcontextprotocol/rust-sdk/pull/749)) - *(auth)* implement SEP-2207 OIDC-flavored refresh token guidance ([#676](https://github.com/modelcontextprotocol/rust-sdk/pull/676)) - add configuration for transparent session re-init ([#760](https://github.com/modelcontextprotocol/rust-sdk/pull/760)) - add local feature for !Send tool handler support ([#740](https://github.com/modelcontextprotocol/rMedium3/26/2026
rmcp-macros-v1.3.0### Added - add local feature for !Send tool handler support ([#740](https://github.com/modelcontextprotocol/rust-sdk/pull/740)) ### Other - fix all clippy warnings across workspace ([#746](https://github.com/modelcontextprotocol/rust-sdk/pull/746))Medium3/26/2026
rmcp-v1.2.0### Added - add missing constructors for non-exhaustive model types ([#739](https://github.com/modelcontextprotocol/rust-sdk/pull/739)) - include granted scopes in OAuth refresh token request ([#731](https://github.com/modelcontextprotocol/rust-sdk/pull/731)) ### Fixed - handle ping requests sent before initialize handshake ([#745](https://github.com/modelcontextprotocol/rust-sdk/pull/745)) - allow deserializing notifications without params field ([#729](https://github.com/modelcontextprotocoLow3/11/2026
rmcp-macros-v1.2.0### Fixed - *(rmcp-macros)* use re-exported serde_json path in task_handler ([#735](https://github.com/modelcontextprotocol/rust-sdk/pull/735))Low3/11/2026
rmcp-v1.1.1### Fixed - accept logging/setLevel and ping before initialized notification ([#730](https://github.com/modelcontextprotocol/rust-sdk/pull/730))Low3/9/2026
rmcp-macros-v1.1.1### Fixed - *(rmcp-macros)* replace deprecated *Param type aliases with *Params ([#727](https://github.com/modelcontextprotocol/rust-sdk/pull/727))Low3/9/2026
rmcp-v1.1.0### Added - implement OAuth 2.0 Client Credentials flow ([#707](https://github.com/modelcontextprotocol/rust-sdk/pull/707)) ### Other - add McpMux to Built with rmcp section ([#717](https://github.com/modelcontextprotocol/rust-sdk/pull/717))Low3/4/2026
rmcp-macros-v1.1.0### Other - add McpMux to Built with rmcp section ([#717](https://github.com/modelcontextprotocol/rust-sdk/pull/717))Low3/4/2026
rmcp-v1.0.0### Fixed - *(auth)* pass WWW-Authenticate scopes to DCR registration request ([#705](https://github.com/modelcontextprotocol/rust-sdk/pull/705)) - api ergonomics follow-up ([#720](https://github.com/modelcontextprotocol/rust-sdk/pull/720)) - *(streamable-http)* map stale session 401 to status-aware error ([#709](https://github.com/modelcontextprotocol/rust-sdk/pull/709))Low3/3/2026
rmcp-macros-v1.0.0### Fixed - api ergonomics follow-up ([#720](https://github.com/modelcontextprotocol/rust-sdk/pull/720))Low3/3/2026
rmcp-v1.0.0-alpha### Added - docs update ([#718](https://github.com/modelcontextprotocol/rust-sdk/pull/718)) - *(auth)* [**breaking**] support returning extra fields from token exchange ([#700](https://github.com/modelcontextprotocol/rust-sdk/pull/700)) ### Fixed - downgrade logging of message to `TRACE` to avoid spamming logs ([#699](https://github.com/modelcontextprotocol/rust-sdk/pull/699)) ### Other - add #[non_exhaustive] and mutation methods to improve compatibility ([#715](https://github.com/modelconLow3/3/2026
rmcp-macros-v1.0.0-alpha### Added - docs update ([#718](https://github.com/modelcontextprotocol/rust-sdk/pull/718)) ### Other - add #[non_exhaustive] and mutation methods to improve compatibility ([#715](https://github.com/modelcontextprotocol/rust-sdk/pull/715))Low3/3/2026
rmcp-v0.17.0### Added - *(streamable-http)* add json_response option for stateless server mode ([#683](https://github.com/modelcontextprotocol/rust-sdk/pull/683)) - mcp sdk conformance ([#687](https://github.com/modelcontextprotocol/rust-sdk/pull/687)) - add default value support to string, number, and integer schemas ([#686](https://github.com/modelcontextprotocol/rust-sdk/pull/686)) - add trait-based tool declaration ([#677](https://github.com/modelcontextprotocol/rust-sdk/pull/677)) - send and validate Low2/27/2026
rmcp-macros-v0.17.0### Added - add trait-based tool declaration ([#677](https://github.com/modelcontextprotocol/rust-sdk/pull/677)) ### Other - add prose documentation for core features to meet conformance ([#702](https://github.com/modelcontextprotocol/rust-sdk/pull/702))Low2/27/2026
rmcp-v0.16.0### Added - add support for custom HTTP headers in StreamableHttpClient ([#655](https://github.com/modelcontextprotocol/rust-sdk/pull/655)) - *(auth)* add token_endpoint_auth_method to OAuthClientConfig ([#648](https://github.com/modelcontextprotocol/rust-sdk/pull/648)) ### Fixed - remove unnecessary doc-cfg ([#661](https://github.com/modelcontextprotocol/rust-sdk/pull/661)) - duplicate meta serialization ([#662](https://github.com/modelcontextprotocol/rust-sdk/pull/662)) - sort list_all() ouLow2/17/2026
rmcp-macros-v0.16.0### Fixed - align task response types with MCP spec ([#658](https://github.com/modelcontextprotocol/rust-sdk/pull/658)) ### Other - include LICENSE in final crate tarball ([#657](https://github.com/modelcontextprotocol/rust-sdk/pull/657)) - add rudof-mcp to MCP servers list ([#645](https://github.com/modelcontextprotocol/rust-sdk/pull/645))Low2/17/2026
rmcp-v0.15.0### Added - *(elicitation)* add support URL elicitation. SEP-1036 ([#605](https://github.com/modelcontextprotocol/rust-sdk/pull/605)) - enforce SEP-1577 MUST requirements for sampling with tools ([#646](https://github.com/modelcontextprotocol/rust-sdk/pull/646)) - add native-tls as an optional TLS backend ([#631](https://github.com/modelcontextprotocol/rust-sdk/pull/631)) - *(capabilities)* add extensions field for SEP-1724 ([#643](https://github.com/modelcontextprotocol/rust-sdk/pull/643)) ##Low2/10/2026
rmcp-macros-v0.15.0### Fixed - *(tasks)* avoid dropping completed task results during collection ([#639](https://github.com/modelcontextprotocol/rust-sdk/pull/639)) - *(tasks)* expose `execution.taskSupport` on tools ([#635](https://github.com/modelcontextprotocol/rust-sdk/pull/635))Low2/10/2026
rmcp-v0.14.0### Fixed - *(tasks)* #626 model task capabilities correctly ([#627](https://github.com/modelcontextprotocol/rust-sdk/pull/627)) - don't treat non-success HTTP codes as transport errors ([#618](https://github.com/modelcontextprotocol/rust-sdk/pull/618)) ### Other - show README content on docs.rs ([#583](https://github.com/modelcontextprotocol/rust-sdk/pull/583)) - added hyper-mcp to the list of built with rmcp ([#621](https://github.com/modelcontextprotocol/rust-sdk/pull/621)) - Implement SEPLow1/23/2026
rmcp-macros-v0.14.0### Other - show README content on docs.rs ([#583](https://github.com/modelcontextprotocol/rust-sdk/pull/583)) - added hyper-mcp to the list of built with rmcp ([#621](https://github.com/modelcontextprotocol/rust-sdk/pull/621)) - Implement SEP-1319: Decouple Request Payload from RPC Methods ([#617](https://github.com/modelcontextprotocol/rust-sdk/pull/617))Low1/23/2026
rmcp-v0.13.0### Added - provide blanket implementations for ClientHandler and ServerHandler traits ([#609](https://github.com/modelcontextprotocol/rust-sdk/pull/609)) - *(service)* add close() method for graceful connection shutdown ([#588](https://github.com/modelcontextprotocol/rust-sdk/pull/588)) - *(auth)* add StateStore trait for pluggable OAuth state storage ([#614](https://github.com/modelcontextprotocol/rust-sdk/pull/614)) - *(elicitation)* implement SEP-1330 Elicitation Enum Schema Improvements ([Low1/15/2026
rmcp-macros-v0.13.0### Added - *(task)* add task support (SEP-1686) ([#536](https://github.com/modelcontextprotocol/rust-sdk/pull/536)) ### Fixed - *(docs)* add spreadsheet-mcp to Built with rmcp ([#582](https://github.com/modelcontextprotocol/rust-sdk/pull/582)) ### Other - update README external links ([#603](https://github.com/modelcontextprotocol/rust-sdk/pull/603)) - clarity and formatting ([#602](https://github.com/modelcontextprotocol/rust-sdk/pull/602))Low1/15/2026
rmcp-v0.12.0### Added - add support for custom requests ([#590](https://github.com/modelcontextprotocol/rust-sdk/pull/590)) - add support for custom server notifications ([#580](https://github.com/modelcontextprotocol/rust-sdk/pull/580)) ### Fixed - update process-wrap to v9.0 ([#586](https://github.com/modelcontextprotocol/rust-sdk/pull/586)) - *(oauth)* rfc8414 should judement the response_types ([#485](https://github.com/modelcontextprotocol/rust-sdk/pull/485)) ### Other - Add SEP-991 (CIMD) supportLow12/18/2025
rmcp-macros-v0.12.0### Other - merge cached_schema_for_type into schema_for_type ([#581](https://github.com/modelcontextprotocol/rust-sdk/pull/581)) - Add NexusCore MCP to project list ([#573](https://github.com/modelcontextprotocol/rust-sdk/pull/573)) - *(deps)* update darling requirement from 0.21 to 0.23 ([#574](https://github.com/modelcontextprotocol/rust-sdk/pull/574))Low12/18/2025
rmcp-v0.11.0### Added - *(meta)* add _meta field to prompts, resources and paginated result ([#558](https://github.com/modelcontextprotocol/rust-sdk/pull/558)) - [**breaking**] remove SSE transport support ([#562](https://github.com/modelcontextprotocol/rust-sdk/pull/562)) ### Fixed - *(streamable-http)* gracefully shutdown while client connected ([#494](https://github.com/modelcontextprotocol/rust-sdk/pull/494)) ### Other - Implements outputSchema validation ([#566](https://github.com/modelcontextprotLow12/8/2025
rmcp-macros-v0.11.0### Added - *(meta)* add _meta field to prompts, resources and paginated result ([#558](https://github.com/modelcontextprotocol/rust-sdk/pull/558)) ### Other - Implements outputSchema validation ([#566](https://github.com/modelcontextprotocol/rust-sdk/pull/566)) - add video-transcriber-mcp-rs to projects built with rmcp ([#565](https://github.com/modelcontextprotocol/rust-sdk/pull/565))Low12/8/2025
rmcp-v0.10.0### Added - add support for custom client notifications ([#556](https://github.com/modelcontextprotocol/rust-sdk/pull/556)) ### Other - replace paste with pastey for macros feature ([#564](https://github.com/modelcontextprotocol/rust-sdk/pull/564))Low12/1/2025
rmcp-macros-v0.10.0### Fixed - *(shemars)* use JSON Schema 2020-12 as Default Dialect ([#549](https://github.com/modelcontextprotocol/rust-sdk/pull/549))Low12/1/2025
rmcp-v0.9.1### Added - *(streamable-http)* support both SSE and JSON response formats ([#540](https://github.com/modelcontextprotocol/rust-sdk/pull/540)) ### Fixed - don't block on creating the SSE stream ([#553](https://github.com/modelcontextprotocol/rust-sdk/pull/553)) - *(shemars)* use JSON Schema 2020-12 as Default Dialect ([#549](https://github.com/modelcontextprotocol/rust-sdk/pull/549)) - *(oauth)* let OAuth discovery skip to next well-known URL candidate on JSON parse error. ([#545](https://gitLow11/24/2025
rmcp-macros-v0.9.1### Fixed - *(shemars)* use JSON Schema 2020-12 as Default Dialect ([#549](https://github.com/modelcontextprotocol/rust-sdk/pull/549))Low11/24/2025
rmcp-v0.9.0### Added - *(auth)* implement CredentialStore trait ([#542](https://github.com/modelcontextprotocol/rust-sdk/pull/542)) - *(tool)* add _meta to tool definitions ([#534](https://github.com/modelcontextprotocol/rust-sdk/pull/534))Low11/17/2025
rmcp-macros-v0.9.0### Added - *(tool)* add _meta to tool definitions ([#534](https://github.com/modelcontextprotocol/rust-sdk/pull/534))Low11/17/2025
rmcp-v0.8.5### Fixed - *(oauth)* respect oauth-protected-resource discovery ([#511](https://github.com/modelcontextprotocol/rust-sdk/pull/511))Low11/5/2025
rmcp-macros-v0.8.5### Fixed - *(doc)* add stakpak-agent to Built with rmcp section ([#500](https://github.com/modelcontextprotocol/rust-sdk/pull/500))Low11/5/2025
rmcp-v0.8.4### Fixed - *(oauth)* fix oauth credential refresh ([#509](https://github.com/modelcontextprotocol/rust-sdk/pull/509)) - do not manually construct fallback authorization metadata ([#507](https://github.com/modelcontextprotocol/rust-sdk/pull/507)) - *(doc)* add stakpak-agent to Built with rmcp section ([#500](https://github.com/modelcontextprotocol/rust-sdk/pull/500))Low11/4/2025
rmcp-macros-v0.8.4### Fixed - *(doc)* add stakpak-agent to Built with rmcp section ([#500](https://github.com/modelcontextprotocol/rust-sdk/pull/500))Low11/4/2025
rmcp-v0.8.3### Fixed - accept 204 in addition to 202 on initialize ([#497](https://github.com/modelcontextprotocol/rust-sdk/pull/497))Low10/22/2025
rmcp-macros-v0.8.3### Other - *(macro)* fix visibility attribute's usage of handler macro ([#481](https://github.com/modelcontextprotocol/rust-sdk/pull/481)) - bump crate version in README.md ([#471](https://github.com/modelcontextprotocol/rust-sdk/pull/471))Low10/22/2025
rmcp-v0.8.2### Added - add type-safe elicitation schema support ([#465](https://github.com/modelcontextprotocol/rust-sdk/pull/465)) ([#466](https://github.com/modelcontextprotocol/rust-sdk/pull/466)) - *(SEP-973)* following change Icon.sizes from string to string array ([#479](https://github.com/modelcontextprotocol/rust-sdk/pull/479)) ### Fixed - *(oauth)* three oauth discovery and registration issues ([#489](https://github.com/modelcontextprotocol/rust-sdk/pull/489)) - *(oauth)* dynamic client registrLow10/21/2025
rmcp-macros-v0.8.2### Other - *(macro)* fix visibility attribute's usage of handler macro ([#481](https://github.com/modelcontextprotocol/rust-sdk/pull/481)) - bump crate version in README.md ([#471](https://github.com/modelcontextprotocol/rust-sdk/pull/471))Low10/21/2025
rmcp-v0.8.1### Fixed - *(oauth)* pass bearer token to all streamable http requests ([#476](https://github.com/modelcontextprotocol/rust-sdk/pull/476)) - fix spellcheck on intentional typo in CHANGELOG ([#470](https://github.com/modelcontextprotocol/rust-sdk/pull/470))Low10/7/2025
rmcp-macros-v0.8.1### Fixed - generate default schema for tools with no params ([#446](https://github.com/modelcontextprotocol/rust-sdk/pull/446))Low10/7/2025
rmcp-v0.8.0### Added - allow clients to override client_name ([#469](https://github.com/modelcontextprotocol/rust-sdk/pull/469)) ### Fixed - *(oauth)* support suffixed and preffixed well-knonw paths ([#459](https://github.com/modelcontextprotocol/rust-sdk/pull/459)) - generate default schema for tools with no params ([#446](https://github.com/modelcontextprotocol/rust-sdk/pull/446)) ### Other - bump to rust 1.90.0 ([#453](https://github.com/modelcontextprotocol/rust-sdk/pull/453))Low10/4/2025
rmcp-macros-v0.8.0### Fixed - generate default schema for tools with no params ([#446](https://github.com/modelcontextprotocol/rust-sdk/pull/446))Low10/4/2025
rmcp-v0.7.0### Fixed - return auth errors ([#451](https://github.com/modelcontextprotocol/rust-sdk/pull/451)) - *(oauth)* do not treat empty secret as valid for public clients ([#443](https://github.com/modelcontextprotocol/rust-sdk/pull/443)) - *(clippy)* add doc comment for generated tool attr fn ([#439](https://github.com/modelcontextprotocol/rust-sdk/pull/439)) - *(oauth)* require CSRF token as part of the OAuth authorization flow. ([#435](https://github.com/modelcontextprotocol/rust-sdk/pull/435)) #Low9/24/2025
rmcp-macros-v0.7.0### Fixed - *(macros)* support #[doc = include_str!(...)] for macros ([#444](https://github.com/modelcontextprotocol/rust-sdk/pull/444)) - *(clippy)* add doc comment for generated tool attr fn ([#439](https://github.com/modelcontextprotocol/rust-sdk/pull/439)) ### Other - *(root)* Add Terminator to Built with rmcp section ([#437](https://github.com/modelcontextprotocol/rust-sdk/pull/437))Low9/24/2025

Dependencies & License Audit

Loading dependencies...

Similar Packages

spiceaiA portable accelerated SQL query, search, and LLM-inference engine, written in Rust, for data-grounded AI apps and agents.v2.0.0
pdf_oxideThe fastest PDF library for Python and Rust. Text extraction, image extraction, markdown conversion, PDF creation & editing. 0.8ms mean, 5ร— faster than industry leaders, 100% pass rate on 3,830 PDFs. v0.3.57
edgequakeEdegQuake ๐ŸŒ‹ High-performance GraphRAG inspired from LightRag written in Rust; Transform documents into intelligent knowledge graphs for superior retrieval and generationv0.12.6
swiftideFast, streaming indexing, query, and agentic LLM applications in Rustv0.32.1
alefGenerate fully-typed, lint-clean language bindings for Rust libraries across 11 languagesv0.23.18

More from modelcontextprotocol

python-sdkThe official Python SDK for Model Context Protocol servers and clients
typescript-sdkThe official TypeScript SDK for Model Context Protocol servers and clients
modelcontextprotocolSpecification andย documentation for the Model Context Protocol
registryA community driven registry service for Model Context Protocol (MCP) servers.

More in RAG & Memory

vllmA high-throughput and memory-efficient inference and serving engine for LLMs
spiceaiA portable accelerated SQL query, search, and LLM-inference engine, written in Rust, for data-grounded AI apps and agents.
awesome-opensource-aiCurated list of the best truly open-source AI projects, models, tools, and infrastructure.
antflyNo description