AgentStack
MCP verified MIT Self-run

Rust Mcp Sdk

mcp-rust-mcp-stack-rust-mcp-sdk · by rust-mcp-stack

A high-performance, asynchronous toolkit for building MCP servers and clients in Rust.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add mcp-rust-mcp-stack-rust-mcp-sdk

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Rust Mcp Sdk? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Rust MCP SDK

[](https://crates.io/crates/rust-mcp-sdk) [](https://docs.rs/rust-mcp-sdk) [ ](examples/hello-world-mcp-server-stdio)

A high-performance, asynchronous Rust toolkit for building MCP servers and clients.

This SDK fully implements the latest MCP protocol version (2025-11-25) and passes 100% of official MCP conformance tests.

rust-mcp-sdk provides the necessary components for developing both servers and clients in the MCP ecosystem. It leverages the rust-mcp-schema crate for type-safe schema objects and includes powerful procedural macros for tools and user input elicitation.

Focus on your application logic , rust-mcp-sdk handles the protocol, transports, and the rest!

⚠ Upgrading from v0.9.x

v0.10.0 includes breaking changes compared to v0.9.x. If you are upgrading, please review the migration guide.

Key Features

  • ✅ Latest MCP protocol specification supported: 2025-11-25
  • 100% MCP Conformance - passes all official client (254/254) and server (40/40) conformance tests
  • ✅ Transports:Stdio, Streamable HTTP, and backward-compatible SSE support
  • ✅ Framework Agnostic: Seamless Axum, Actix, and BYO Server integrations
  • ✅ Multi-client concurrency
  • ✅ DNS Rebinding Protection
  • ✅ Resumability
  • ✅ MCP Tasks support
  • ✅ Batch Messages
  • ✅ Streaming & non-streaming JSON response
  • ✅ Message Observer (Telemetry & Monitoring)
  • ✅ HTTP Health Checks (for load balancers & container orchestration)
  • ✅ OAuth Authentication for MCP Servers
  • ✅ [Remote Oauth Provider](crates/rust-mcp-sdk/src/auth/authprovider/remoteauth_provider.rs) (for any provider with DCR support)
  • Keycloak Provider (via [rust-mcp-extra](crates/rust-mcp-extra/README.md#keycloak))
  • WorkOS Authkit Provider (via [rust-mcp-extra](crates/rust-mcp-extra/README.md#workos-authkit))
  • Scalekit Authkit Provider (via [rust-mcp-extra](crates/rust-mcp-extra/README.md#scalekit))
  • ✅ OAuth Authentication for MCP Clients (metadata discovery, DCR, PKCE, token refresh, pluggable storage)

⚠️ Project is currently under development and should be used at your own risk.

Table of Contents

  • [Quick Start](#quick-start)
  • [Minimal MCP Server (Stdio)](#minimal-mcp-server-stdio)
  • [Minimal MCP Server (Streamable HTTP)](#minimal-mcp-server-streamable-http)
  • [Minimal MCP Client (Stdio)](#minimal-mcp-client-stdio)
  • [Usage Examples](#usage-examples)
  • [Macros](#macros)
  • [mcptool](#mcptool)
  • [toolbox](#-toolbox)
  • [mcpelicit](#-mcpelicit)
  • [mcpresource](#-mcpresource)
  • [mcpresourcetemplate](#-mcpresourcetemplate)
  • [mcpicon](#-mcpicon)
  • [Authentication](#authentication)
  • [RemoteAuthProvider](#remoteauthprovider)
  • [OAuthProxy](#oauthproxy)
  • [HTTP Server Backends (Axum & Actix)](#http-server-backends-axum--actix)
  • [Axum Backend (rust-mcp-axum)](#axum-backend-rust-mcp-axum)
  • [Actix-web Backend (rust-mcp-actix)](#actix-web-backend-rust-mcp-actix)
  • [BYO-server: Embed MCP in your existing app](#byo-server-embed-mcp-in-your-existing-app)
  • [AxumServerOptions](#axumserveroptions)
  • [ActixServerOptions](#actixserveroptions)
  • [Security Considerations](#security-considerations)
  • [Cargo features](#cargo-features)
  • [Available Features](#available-features)
  • [Default Features](#default-features)
  • [Using Only the server Features](#using-only-the-server-features)
  • [Using Only the client Features](#using-only-the-client-features)
  • [Handler Traits](#handlers-traits)
  • [Choosing Between ServerHandler and ServerHandlerCore](#choosing-between-serverhandler-and-serverhandlercore)
  • [Choosing Between ClientHandler and ClientHandlerCore](#choosing-between-clienthandler-and-clienthandlercore)
  • [Message Observer (Telemetry & Monitoring)](#message-observer-telemetry--monitoring)
  • [Health Check Endpoint](#health-check-endpoint)
  • [Projects using Rust MCP SDK](#projects-using-rust-mcp-sdk)
  • [Contributing](#contributing)
  • [Development](#development)
  • [License](#license)

Quick Start

Add to your Cargo.toml:

[dependencies]
rust-mcp-sdk = "0.9.0"  # Check crates.io for the latest version

Minimal MCP Server (Stdio)

use async_trait::async_trait;
use rust_mcp_sdk::{*,error::SdkResult,macros,mcp_server::{server_runtime, ServerHandler},schema::*,};

// Define a mcp tool
#[macros::mcp_tool(name = "say_hello", description = "returns \"Hello from Rust MCP SDK!\" message ")]
#[derive(Debug, ::serde::Deserialize, ::serde::Serialize, macros::JsonSchema)]
pub struct SayHelloTool {}

// define a custom handler
#[derive(Default)]
struct HelloHandler;

// implement ServerHandler
#[async_trait]
impl ServerHandler for HelloHandler {
    // Handles requests to list available tools.
    async fn handle_list_tools_request(
        &self,
        _request: Option,
        _runtime: std::sync::Arc,
    ) -> std::result::Result {
        Ok(ListToolsResult {
            tools: vec![SayHelloTool::tool()],
            meta: None,
            next_cursor: None,
        })
    }
    // Handles requests to call a specific tool.
    async fn handle_call_tool_request(&self,
        params: CallToolRequestParams,
        _runtime: std::sync::Arc,
    ) -> std::result::Result {
        if params.name == "say_hello" {
            Ok(CallToolResult::text_content(vec!["Hello from Rust MCP SDK!".into()]))
        } else {
            Err(CallToolError::unknown_tool(params.name))
        }
    }
}

#[tokio::main]
async fn main() -> SdkResult {
    // Define server details and capabilities
    let server_info = InitializeResult {
        server_info: Implementation {
            name: "hello-rust-mcp".into(),
            version: "0.1.0".into(),
            title: Some("Hello World MCP Server".into()),
            description: Some("A minimal Rust MCP server".into()),
            icons: vec![mcp_icon!(src = "https://raw.githubusercontent.com/rust-mcp-stack/rust-mcp-sdk/main/assets/rust-mcp-icon.png",
                mime_type = "image/png",
                sizes = ["128x128"],
                theme = "light")],
            website_url: Some("https://github.com/rust-mcp-stack/rust-mcp-sdk".into()),
        },
        capabilities: ServerCapabilities { tools: Some(ServerCapabilitiesTools { list_changed: None }), ..Default::default() },
        protocol_version: ProtocolVersion::V2025_11_25.into(),
        instructions: None,
        meta:None
    };

    let transport = StdioTransport::new(TransportOptions::default())?;
    let handler = HelloHandler::default().to_mcp_server_handler();
    let server = server_runtime::create_server(server_info, transport, handler);
    server.start().await
}

HTTP Server Backends (Axum & Actix)

Creating a Streamable HTTP MCP server in rust-mcp-sdk allows multiple clients to connect simultaneously with no additional setup. The setup is nearly identical to the stdio example — the only difference is which HTTP backend crate you install and which function you call to create the server.

💡 If backward compatibility with older SSE-only clients is required, both backends support enabling SSE transport by setting sse_support to true in their respective options (it defaults to true).

Axum Backend (rust-mcp-axum)

Add rust-mcp-axum to your dependencies and use create_axum_server() with AxumServerOptions.

use async_trait::async_trait;
use rust_mcp_axum::{create_axum_server, AxumServerOptions};
use rust_mcp_sdk::{*,error::SdkResult,event_store::InMemoryEventStore,macros,
    mcp_server::ServerHandler,schema::*,
};

// ... (define SayHelloTool and HelloHandler as shown above)

#[tokio::main]
async fn main() -> SdkResult {
    let server_info = InitializeResult { /* ... */ };

    let handler = HelloHandler::default().to_mcp_server_handler();
    let server = create_axum_server(
        server_info,
        handler,
        AxumServerOptions {
            host: "127.0.0.1".to_string(),
            event_store: Some(std::sync::Arc::new(InMemoryEventStore::default())), // enable resumability
            ..Default::default()
        },
    );
    server.start().await?;
    Ok(())
}

Actix-web Backend (rust-mcp-actix)

Add rust-mcp-actix to your dependencies and use create_actix_server() with ActixServerOptions.

use rust_mcp_actix::{create_actix_server, ActixServerOptions};
use rust_mcp_sdk::{*,error::SdkResult,event_store::InMemoryEventStore,
    mcp_server::ServerHandler,schema::*,
};

// ... (define SayHelloTool and HelloHandler as shown above)

#[tokio::main]
async fn main() -> SdkResult {
    let server_info = InitializeResult { /* ... */ };

    let handler = HelloHandler::default().to_mcp_server_handler();
    let server = create_actix_server(
        server_info,
        handler,
        ActixServerOptions {
            host: "127.0.0.1".to_string(),
            event_store: Some(std::sync::Arc::new(InMemoryEventStore::default())), // enable resumability
            ..Default::default()
        },
    );
    server.start().await?;
    Ok(())
}

BYO-server: Embed MCP in your Existing App

Both backends support a BYO-server (Bring Your Own Server) mode, letting you mount MCP endpoints onto a router or app you already control — no need to hand over the server lifecycle.

| Backend | Function | Docs | |---|---|---| | Axum | mcp_routes(state, &mount_opts, http_handler) | [rust-mcp-axum README](crates/rust-mcp-axum/README.md) | | Actix-web | mcp_scope(state, http_handler, &mount_opts) | [rust-mcp-actix README](crates/rust-mcp-actix/README.md) |

Both functions take a pre-built McpAppState and McpMountOptions, and produce routes/scopes you can merge directly into your existing router.

👉 See [examples/byo-server.rs](crates/rust-mcp-axum/examples/byo-server.rs) (Axum) and [examples/byo-server.rs](crates/rust-mcp-actix/examples/byo-server.rs) (Actix) for working examples.

Custom HTTP Framework Integrations

While we provide native Axum and Actix integrations, the SDK is completely framework-agnostic. If you are using a different HTTP framework (like Rocket, Salvo, or Warp), you can build a custom integration by adapting your framework's native Request/Response types to the SDK's core HTTP handling logic.

👉 See the [Custom HTTP Framework Integration Guide](../../doc/custom-http-framework-integration.md) for architectural details and implementation steps.

AxumServerOptions

Axum server is highly customizable through AxumServerOptions:

let server = create_axum_server(
    server_details,
    handler.to_mcp_server_handler(),
    AxumServerOptions {
        host: "127.0.0.1".to_string(),
        port: 8080,
        event_store: Some(Arc::new(InMemoryEventStore::default())), // enable resumability
        task_store: Some(Arc::new(InMemoryTaskStore::new(None))),   // server MCP tasks
        auth: Some(Arc::new(auth_provider)),                        // enable authentication
        health_endpoint: Some("/health".into()),                    // health check
        sse_support: true,                                          // backward-compat SSE
        ..Default::default()
    },
);
server.start().await?;

📝 Refer to AxumServerOptions or the [rust-mcp-axum README](crates/rust-mcp-axum/README.md) for a complete field reference.

ActixServerOptions

ActixServerOptions mirrors AxumServerOptions field-for-field:

let server = create_actix_server(
    server_details,
    handler.to_mcp_server_handler(),
    ActixServerOptions {
        host: "127.0.0.1".to_string(),
        port: 8080,
        event_store: Some(Arc::new(InMemoryEventStore::default())), // enable resumability
        task_store: Some(Arc::new(InMemoryTaskStore::new(None))),   // server MCP tasks
        auth: Some(Arc::new(auth_provider)),                        // enable authentication
        health_endpoint: Some("/health".into()),                    // health check
        sse_support: true,                                          // backward-compat SSE
        ..Default::default()
    },
);
server.start().await?;

📝 Refer to ActixServerOptions or the [rust-mcp-actix README](crates/rust-mcp-actix/README.md) for a complete field reference.

Following is implementation of an MCP client that starts the @modelcontextprotocol/server-everything server, displays the server's name, version, and list of tools provided by the server.

use async_trait::async_trait;
use rust_mcp_sdk::{*, error::SdkResult,
    mcp_client::{client_runtime, ClientHandler},
    schema::*,
};

// Custom Handler to handle incoming MCP Messages
pub struct MyClientHandler;
#[async_trait]
impl ClientHandler for MyClientHandler {
    // To see all the trait methods you can override,
    // check out:
    // https://github.com/rust-mcp-stack/rust-mcp-sdk/blob/main/crates/rust-mcp-sdk/src/mcp_handlers/mcp_client_handler.rs
}

#[tokio::main]
async fn main() -> SdkResult {
    // Client details and capabilities
    let client_details: InitializeRequestParams = InitializeRequestParams {
        capabilities: ClientCapabilities::default(),
        client_info: Implementation {
            name: "simple-rust-mcp-client".into(),
            version: "0.1.0".into(),
            description: None,
            icons: vec![],
            title: None,
            website_url: None,
        },
        protocol_version: ProtocolVersion::V2025_11_25.into(),
        meta: None,
    };

    //  Create a transport, with options to launch @modelcontextprotocol/server-everything MCP Server
    let transport = StdioTransport::create_with_server_launch(
        "npx",vec!["-y".to_string(),"@modelcontextprotocol/server-everything@latest".to_string()],
        None,
        TransportOptions::default(),
    )?;

    // instantiate our custom handler for handling MCP messages
    let handler = MyClientHandler {};

    // Create and start the MCP client
    let client = client_runtime::create_client(client_details, transport, handler);    
    client.clone().start().await?;

    // use client methods to communicate with the MCP Server as you wish:

    let server_version = client.server_version().unwrap();    
    
    // Retrieve and display the list of tools available on the server
    let tools = client.request_tool_list(None).await?.tools;
    println!( "List of tools for {}@{}",server_version.name, server_version.version);
    tools.iter().enumerate().for_each(|(tool_index, tool)| {
        println!("  {}. {} : {}", tool_index + 1, tool.name, tool.description.clone().unwrap_or_default());
    });

    client.shut_down().await?;
    Ok(())
}

Usage Examples

👉 For more examples (stdio, Streamable HTTP, clients, auth, etc.), see the examples/ directory.

👉 If you are looking for a step-by-step tutorial on how to get started with rust-mcp-sdk , please see : [Getting Started MCP Server](https://github.com/rust-mcp-stack/rust-mcp-sdk/tree/main/doc/getting-starte

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.