A concise, production-ready Model Context Protocol (MCP) server implementation in Rust that demonstrates best practices for building MCP tools with dual transport support.
cargo run --release
# Server starts on http://localhost:8080/mcp- Simple Tools – Add integers and echo messages with structured JSON responses
- Type Safe – Built with Rust's type system and
rmcpmacros for compile-time safety - Dual Transport – Support for both stdio JSON-RPC and HTTP streaming
- Well Documented – Clear examples and comprehensive documentation
- Observable – Structured logging via
tracingwith proper stderr output
- Rust 1.75+ (tested on 1.90+)
- Cargo (included with Rust)
- Platform: macOS, Linux, or Windows
src/
├── main.rs # Transport layer and runtime configuration
├── models.rs # CLI arguments and data schemas
└── server.rs # MCP server implementation and tool handlers
# Start server with HTTP transport on port 8080
cargo run --release
# or explicitly
cargo run --release -- --stdio false🔗 Endpoint: http://localhost:8080/mcp
# Start server with stdio transport for MCP clients
cargo run --release -- --stdio trueThe server reads JSON-RPC messages from STDIN and writes responses to STDOUT, making it compatible with MCP-compliant clients like Claude Desktop and Cursor.
lsof -ti:8080 | xargs kill -9 # macOS/Linux
| Tool | Description | Input Schema | Output Schema |
|---|---|---|---|
add |
Add two integers | { "a": i32, "b": i32 } |
{ "result": i32, "operation": "a + b" } |
echo |
Echo a message back | { "message": string } |
{ "message": "Echo: <input>" } |
All responses are wrapped with rmcp::handler::server::wrapper::Json, providing
structured content with JSON Schema metadata for clients.
# HTTP API example
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "add",
"arguments": {"a": 5, "b": 3}
}
}'- Logging: Structured logging via
tracingto stderr (preserves stdout for JSON-RPC) - HTTP Mode: Startup logs include bound address and transport details
- Error Handling: Comprehensive error reporting with
McpErrortypes
# Enable debug logging
RUST_LOG=debug cargo run --release-
Define Models - Add request/response types in
models.rs:#[derive(Deserialize, schemars::JsonSchema)] struct MyRequest { /* fields */ }
-
Implement Tool - Add
#[tool]method inserver.rs:#[tool(name = "my_tool", description = "My custom tool")] async fn my_tool(&self, params: Parameters<MyRequest>) -> Result<Json<MyResponse>, McpError> { // Implementation }
-
Return Structured Results - Always return
Result<Json<_>, McpError> -
Format & Lint - Run
cargo fmt && cargo clippyto maintain code quality
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"simple-mcp": {
"command": "cargo",
"args": ["run", "--release", "--", "--stdio", "true"],
"cwd": "/absolute/path/to/simple-mcp"
}
}
}or
{
"mcpServers": {
"simple-mcp": {
"url": "http://localhost:8080/mcp",
}
}
}- Open Settings → Features → MCP
- Add new server with command:
cargo run --release -- --stdio true
npx @modelcontextprotocol/inspector cargo run --release -- --stdio true- Building MCP in Rust Guide - Comprehensive tutorial
- MCP Specification - Official protocol docs
- rmcp Documentation - Rust implementation details
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is currently unlicensed. Feel free to adapt it internally; add an explicit license file before distributing externally.
Built with ❤️ using Rust and the Model Context Protocol