- Notifications
You must be signed in to change notification settings - Fork10
A high-performance, asynchronous toolkit for building MCP servers and clients in Rust.
License
rust-mcp-stack/rust-mcp-sdk
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A high-performance, asynchronous toolkit for building MCP servers and clients.Focus on your app's logic whilerust-mcp-sdk takes care of the rest!
rust-mcp-sdk provides the necessary components for developing both servers and clients in the MCP ecosystem.Leveraging therust-mcp-schema crate simplifies the process of building robust and reliable MCP servers and clients, ensuring consistency and minimizing errors in data handling and message processing.
rust-mcp-sdk supports all three official versions of the MCP protocol.By default, it uses the2025-06-18 version, but earlier versions can be enabled via Cargo features.
This project currently supports following transports:
- stdio (Standard Input/Output)
- sse (Server-Sent Events).
🚀 Therust-mcp-sdk includes a lightweightAxum based server that handles all core functionality seamlessly. Switching betweenstdio
andsse
is straightforward, requiring minimal code changes. The server is designed to efficiently handle multiple concurrent client connections and offers built-in support for SSL.
- Usage Examples
- Cargo features
- Choosing Between Standard and Core Handlers traits
- Projects using Rust MCP SDK
- Contributing
- Development
- License
Create a MCP server with atool
that will print aHello World!
message:
#[tokio::main]asyncfnmain() ->SdkResult<()>{// STEP 1: Define server details and capabilitieslet server_details =InitializeResult{// server name and versionserver_info:Implementation{name:"Hello World MCP Server".to_string(),version:"0.1.0".to_string(),title:Some("Hello World MCP Server".to_string()),},capabilities:ServerCapabilities{// indicates that server support mcp toolstools:Some(ServerCapabilitiesTools{list_changed:None}), ..Default::default()// Using default values for other fields},meta:None,instructions:Some("server instructions...".to_string()),protocol_version:LATEST_PROTOCOL_VERSION.to_string(),};// STEP 2: create a std transport with default optionslet transport =StdioTransport::new(TransportOptions::default())?;// STEP 3: instantiate our custom handler for handling MCP messageslet handler =MyServerHandler{};// STEP 4: create a MCP serverlet server:ServerRuntime = server_runtime::create_server(server_details, transport, handler);// STEP 5: Start the server server.start().await}
See hello-world-mcp-server example running inMCP Inspector :
Creating an MCP server inrust-mcp-sdk
with thesse
transport allows multiple clients to connect simultaneously with no additional setup.Simply create a Hyper Server usinghyper_server::create_server()
and pass in the same handler and transform options.
// STEP 1: Define server details and capabilitieslet server_details =InitializeResult{// server name and versionserver_info:Implementation{name:"Hello World MCP Server".to_string(),version:"0.1.0".to_string(),title:Some("Hello World MCP Server".to_string()),},capabilities:ServerCapabilities{// indicates that server support mcp toolstools:Some(ServerCapabilitiesTools{list_changed:None}), ..Default::default()// Using default values for other fields},meta:None,instructions:Some("server instructions...".to_string()),protocol_version:LATEST_PROTOCOL_VERSION.to_string(),};// STEP 2: instantiate our custom handler for handling MCP messageslet handler =MyServerHandler{};// STEP 3: instantiate HyperServer, providing `server_details` , `handler` and HyperServerOptionslet server = hyper_server::create_server( server_details, handler,HyperServerOptions{host:"127.0.0.1".to_string(), ..Default::default()},);// STEP 4: Start the serverserver.start().await?;Ok(())
The implementation ofMyServerHandler
is the same regardless of the transport used and could be as simple as the following:
// STEP 1: Define a rust_mcp_schema::Tool ( we need one with no parameters for this example)#[mcp_tool(name ="say_hello_world", description ="Prints\"Hello World!\" message")]#[derive(Debug,Deserialize,Serialize,JsonSchema)]pubstructSayHelloTool{}// STEP 2: Implement ServerHandler trait for a custom handler// For this example , we only need handle_list_tools_request() and handle_call_tool_request() methods.pubstructMyServerHandler;#[async_trait]implServerHandlerforMyServerHandler{// Handle ListToolsRequest, return list of available tools as ListToolsResultasyncfnhandle_list_tools_request(&self,request:ListToolsRequest,runtime:&dynMcpServer) ->Result<ListToolsResult,RpcError>{Ok(ListToolsResult{tools:vec![SayHelloTool::tool()],meta:None,next_cursor:None,})}/// Handles requests to call a specific tool.asyncfnhandle_call_tool_request(&self,request:CallToolRequest,runtime:&dynMcpServer,) ->Result<CallToolResult,CallToolError>{if request.tool_name() ==SayHelloTool::tool_name(){Ok(CallToolResult::text_content(vec![TextContent::from("Hello World!".to_string())]))}else{Err(CallToolError::unknown_tool(request.tool_name().to_string()))}}}
👉 For a more detailed example of aHello World MCP Server that supports multiple tools and provides more type-safe handling ofCallToolRequest
, check out:examples/hello-world-mcp-server
See hello-world-server-sse example running inMCP Inspector :
Create an MCP client that starts the@modelcontextprotocol/server-everything server, displays the server's name, version, and list of tools, then uses the add tool provided by the server to sum 120 and 28, printing the result.
// STEP 1: Custom Handler to handle incoming MCP MessagespubstructMyClientHandler;#[async_trait]implClientHandlerforMyClientHandler{// To check out a list of all the methods in the trait that you can override, take a look at https://github.com/rust-mcp-stack/rust-mcp-sdk/blob/main/crates/rust-mcp-sdk/src/mcp_handlers/mcp_client_handler.rs}#[tokio::main]asyncfnmain() ->SdkResult<()>{// Step2 : Define client details and capabilitieslet client_details:InitializeRequestParams =InitializeRequestParams{capabilities:ClientCapabilities::default(),client_info:Implementation{name:"simple-rust-mcp-client".into(),version:"0.1.0".into(),},protocol_version:LATEST_PROTOCOL_VERSION.into(),};// Step3 : Create a transport, with options to launch @modelcontextprotocol/server-everything MCP Serverlet transport =StdioTransport::create_with_server_launch("npx",vec!["-y".to_string(),"@modelcontextprotocol/server-everything".to_string()],None,TransportOptions::default())?;// STEP 4: instantiate our custom handler for handling MCP messageslet handler =MyClientHandler{};// STEP 5: create a MCP clientlet client = client_runtime::create_client(client_details, transport, handler);// STEP 6: start the MCP client client.clone().start().await?;// STEP 7: use client methods to communicate with the MCP Server as you wish// Retrieve and display the list of tools available on the serverlet server_version = client.server_version().unwrap();let tools = client.list_tools(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());});println!("Call\"add\" tool with 100 and 28 ...");// Create a `Map<String, Value>` to represent the tool parameterslet params =json!({"a":100,"b":28}).as_object().unwrap().clone();let request =CallToolRequestParams{name:"add".to_string(),arguments:Some(params)};// invoke the toollet result = client.call_tool(request).await?;println!("{}",result.content.first().unwrap().as_text_content()?.text);Ok(())}
Here is the output :
your results may vary slightly depending on the version of the MCP Server in use when you run it.
Creating an MCP client using therust-mcp-sdk
with the SSE transport is almost identical, with one exception atstep 3
. Instead of creating aStdioTransport
, you simply create aClientSseTransport
. The rest of the code remains the same:
- let transport = StdioTransport::create_with_server_launch(- "npx",- vec![ "-y".to_string(), "@modelcontextprotocol/server-everything".to_string()],- None, TransportOptions::default()-)?;+ let transport = ClientSseTransport::new(MCP_SERVER_URL, ClientSseTransportOptions::default())?;
If you are looking for a step-by-step tutorial on how to get started withrust-mcp-sdk
, please see :Getting Started MCP Server
Therust-mcp-sdk
crate provides several features that can be enabled or disabled. By default, all features are enabled to ensure maximum functionality, but you can customize which ones to include based on your project's requirements.
server
: Activates MCP server capabilities inrust-mcp-sdk
, providing modules and APIs for building and managing MCP servers.client
: Activates MCP client capabilities, offering modules and APIs for client development and communicating with MCP servers.hyper-server
: This feature enables thesse transport for MCP servers, supporting multiple simultaneous client connections out of the box.ssl
: This feature enables TLS/SSL support for thesse transport when used with thehyper-server
.macros
: Provides procedural macros for simplifying the creation and manipulation of MCP Tool structures.
2025_06_18
: Activates MCP Protocol version 2025-06-18 (enabled by default)2025_03_26
: Activates MCP Protocol version 2025-03-262024_11_05
: Activates MCP Protocol version 2024-11-05
Note: MCP protocol versions are mutually exclusive—only one can be active at any given time.
When you add rust-mcp-sdk as a dependency without specifying any features, all features are included, with the latest MCP Protocol version enabled by default:
[dependencies]rust-mcp-sdk ="0.2.0"
If you only need the MCP Server functionality, you can disable the default features and explicitly enable the server feature. Add the following to your Cargo.toml:
[dependencies]rust-mcp-sdk = {version ="0.2.0",default-features =false,features = ["server","macros"] }
Optionally addhyper-server
forsse transport, andssl
feature for tls/ssl support of thehyper-server
If you only need the MCP Client functionality, you can disable the default features and explicitly enable the client feature.Add the following to your Cargo.toml:
[dependencies]rust-mcp-sdk = {version ="0.2.0",default-features =false,features = ["client","2024_11_05"] }
Learn when to use themcp_*_handler
traits versus the lower-levelmcp_*_handler_core
traits for both server and client implementations. This section helps you decide based on your project's need for simplicity versus fine-grained control.
rust-mcp-sdk provides two type of handler traits that you can chose from:
ServerHandler: This is the recommended trait for your MCP project, offering a default implementation for all types of MCP messages. It includes predefined implementations within the trait, such as handling initialization or responding to ping requests, so you only need to override and customize the handler functions relevant to your specific needs.Refer toexamples/hello-world-mcp-server/src/handler.rs for an example.
ServerHandlerCore: If you need more control over MCP messages, consider using
ServerHandlerCore
. It offers three primary methods to manage the three MCP message types:request
,notification
, anderror
. While still providing type-safe objects in these methods, it allows you to determine how to handle each message based on its type and parameters.Refer toexamples/hello-world-mcp-server-core/src/handler.rs for an example.
👉 Note: Depending on whether you chooseServerHandler
orServerHandlerCore
, you must use thecreate_server()
function from the appropriate module:
For
ServerHandler
:- Use
server_runtime::create_server()
for servers with stdio transport - Use
hyper_server::create_server()
for servers with sse transport
- Use
For
ServerHandlerCore
:- Use
server_runtime_core::create_server()
for servers with stdio transport - Use
hyper_server_core::create_server()
for servers with sse transport
- Use
The same principles outlined above apply to the client-side handlers,ClientHandler
andClientHandlerCore
.
Use
client_runtime::create_client()
when working withClientHandler
Use
client_runtime_core::create_client()
when working withClientHandlerCore
Both functions create an MCP client instance.
Check out the corresponding examples at:examples/simple-mcp-client andexamples/simple-mcp-client-core.
Below is a list of projects that utilize therust-mcp-sdk
, showcasing their name, description, and links to their repositories or project pages.
Name | Description | Link | |
---|---|---|---|
![]() | Rust MCP Filesystem | Fast, async MCP server enabling high-performance, modern filesystem operations with advanced features. | GitHub |
![]() | MCP Discovery | A lightweight command-line tool for discovering and documenting MCP Server capabilities. | GitHub |
mistral.rs | Blazingly fast LLM inference. | GitHub | |
moon | moon is a repository management, organization, orchestration, and notification tool for the web ecosystem, written in Rust. | GitHub | |
Ruskel | Ruskel produces a syntactically correct, single-page skeleton of a crate's public API. | GitHub |
We welcome everyone who wishes to contribute! Please refer to thecontributing guidelines for more details.
Check out ourdevelopment guide for instructions on setting up, building, testing, formatting, and trying out example projects.
All contributions, including issues and pull requests, must followRust's Code of Conduct.
Unless explicitly stated otherwise, any contribution you submit for inclusion in rust-mcp-sdk is provided under the terms of the MIT License, without any additional conditions or restrictions.
Check out ourdevelopment guide for instructions on setting up, building, testing, formatting, and trying out example projects.
This project is licensed under the MIT License. see theLICENSE file for details.
About
A high-performance, asynchronous toolkit for building MCP servers and clients in Rust.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors7
Uh oh!
There was an error while loading.Please reload this page.