Model Context Protocol (MCP) Rust SDK
⚠️ Warning: This SDK is currently a work in progress and is not ready for production use.
A Rust implementation of the Model Context Protocol (MCP), designed for seamless communication between AI models and their runtime environments.
THIS IS BASED ON https://github.com/Derek-X-Wang/mcp-rust-sdk.
Getting Started
-
Get the MCP server you want.
- ex:
uvx create-mcp-server. - make sure you set it up, so cd into it and
uv sync --dev --all-extras
- ex:
-
Look at
src/main.rs.
let client = new
.directory
.arg
.arg
.implementation
.spawn_and_initialize
.await?;
- Modify directory and args to point to your server.
The core SDK is based on https://github.com/Derek-X-Wang/mcp-rust-sdk.
I added some convenience methods and a builder pattern to simplify connecting to MCP servers that follow the MCP specification.
Also did some big debugging on the client side. STDIO had a lot of issues at first, so fixed those.
This is intended to be upstreamed when I have the time.
The main modifications are:
- Some more types
- Ergonomics
- Fuckton of error handling/debugging
- STDIO focused. Don't handle websockets at all
enjoy!
Key Features:
- Core MCP Protocol Support: Implements the core MCP protocol, allowing you to initialize, list resources, read resources, and call tools from MCP-compatible servers.
- Transport Flexibility: Uses
stdiotransport by default, making it simple to spawn and connect to a subprocess MCP server. You can also implement custom transports for other communication methods. - Typed Convenience Methods: Offers typed return values and helper functions (e.g.,
list_resources(),call_tool()) so you don't have to manually serialize and deserialize JSON. - Builder Pattern for Initialization: A
ClientBuilderstreamlines the process of starting a server, setting capabilities, and initializing the connection. - Extensible and Composable: The SDK is designed to be easily integrated with your own Rust code and adapted for custom use cases.
Table of Contents
Usage
Spawning the Server
You can either:
- Manually start the server: Start it in one terminal and pipe output to/from your client.
- Use the builder to spawn automatically: The
ClientBuilderallows you to spawn a subprocess server easily, attaching to itsstdinandstdout.
Example:
use ClientBuilder;
use Result;
async
Initializing the Client
The ClientBuilder automatically calls initialize() for you. If you want more control, you can manually initialize the Client by creating a transport and calling initialize() yourself:
use ;
use ;
use Result;
async
Typed Convenience Methods
The Client provides typed methods to interact with the server:
list_resources() -> Result<ListResourcesResult, Error>call_tool(name, arguments) -> Result<CallToolResult, Error>read_resource(uri) -> Result<ReadResourceResult, Error>
This spares you the hassle of manually constructing JSON requests and parsing raw JSON responses.
For example:
let resources = client.list_resources.await?;
println!;
let tool_result = client.call_tool.await?;
println!;
let read_result = client.read_resource.await?;
println!;
Advanced Topics
-
Custom Transports:
If you don't want to usestdio, implement theTransporttrait yourself. This lets you connect over TCP, WebSockets, or any other medium. -
Custom Deserialization Logic:
If the server's output doesn't exactly match MCP or you need more control, implement customDeserializelogic for certain responses. -
Error Handling:
TheErrortype included is flexible. Integrate it withanyhowor your own error types for robust error handling strategies.
Contributing
Contributions are welcome! Please open an issue or submit a PR if you have improvements, bug fixes, or new features to propose.
- Fork the repo
- Create a new branch
- Add your changes and tests
- Submit a Pull Request
License
This project is licensed under the MIT License. See LICENSE for details.