Rust MCP服务器模板
使用Rust和Actix Web构建的生产就绪模型上下文协议(MCP)服务器模板。此模板为构建支持STDIO和HTTP传输模式的高性能MCP服务器提供了坚实的基础。
目录
概述
此模板按照模型上下文协议规范实现了一个完整的MCP服务器。它支持STDIO(用于MCP Inspector和本地开发)和HTTP传输模式,使其适用于开发和生产部署。
该服务器针对高流量场景进行了优化,包括连接池、资源限制和高效的JSON序列化。它包括内置的监控、健康检查和工具发现端点。
特性
核心功能
- 完整的MCP协议实施:完整的JSON-RPC 2.0支持,包括初始化、工具/列表和工具/调用方法
- 双重运输模式:STDIO用于MCP检查器兼容性,HTTP用于生产部署
- 模块化工具系统:将工具干净地分成单独的模块,便于维护
- 配置管理:通过YAML文件进行工具特定配置
- 错误处理:通过正确的JSON-RPC错误响应进行全面的错误处理
性能优化
- 连接池:实现高并发的自动连接管理
- 资源限制:可配置的连接、超时和速率限制
- 优化序列化:高效的JSON处理,分配最少
- 缓冲输入/输出:优化了stdio模式,具有8KB缓冲区以提高吞吐量
- CPU优化:基于CPU内核的自动工作线程扩展
生产特点
- 健康检查:内置
/health监控端点 - 指标端点:请求计数器和服务器统计信息
/metrics - 工具发现:服务器发送事件(SSE)端点位于
/sse用于实时工具发现 - 安全标头:XSS保护、帧选项和内容类型验证
- 优雅地关闭:服务器终止时进行适当的清理
建筑
项目结构
.
├── src/
│ ├── main.rs # Application entry point and transport mode selection
│ ├── core/
│ │ ├── mod.rs # Core module exports
│ │ ├── server.rs # MCP server implementation, HTTP/STDIO handlers
│ │ └── utils.rs # Configuration loading and utility functions
│ └── tools/
│ ├── mod.rs # Tool module exports
│ └── echo.rs # Example echo tool implementation
├── Cargo.toml # Rust dependencies and build configuration
├── kmcp.yaml # Tool configuration file
├── Dockerfile # Multi-stage Docker build for production
└── README.md # This file组件概述
main.rs:解析环境变量并选择适当传输模式(STDIO或HTTP)的入口点。
core/server.rs:包含MCP服务器实现,包括:
- JSON-RPC请求/响应结构
- 用于管理可用工具的工具注册表
- 使用Actix Web设置HTTP服务器
- 基于线路通信的STDIO服务器实现
- 用于初始化、工具/列表和工具/调用的请求处理程序
core/utils.rs:实用功能:
- 从YAML文件加载配置
- 访问工具特定配置
- 环境变量管理
工具/:包含工具实现的目录。每个工具都是一个单独的模块,用于导出 register 功能。
快速开始
先决条件
- Rust 1.70或更高版本(2021年版)
- Cargo(Rust包管理器)
安装
- 克隆或使用此模板作为项目的起点。
- 更新
Cargo.toml与您的项目详细信息:
[package]
name = "your-mcp-server"
version = "0.1.0"
authors = ["Your Name "]- 构建项目:
cargo build --release运行服务器
STDIO模式(默认)
STDIO模式用于MCP检查器和本地开发。服务器从stdin读取JSON-RPC请求,并将响应写入stdout。
# Run in STDIO mode
cargo run
# Or run the release binary
./target/release/mcp-serverHTTP模式
HTTP模式用于生产部署和web集成。
# Run in HTTP mode
MCP_TRANSPORT_MODE=http cargo run
# With custom host and port
MCP_TRANSPORT_MODE=http HOST=0.0.0.0 PORT=8080 cargo run与MCP检查器一起使用
- 构建发布二进制文件:
cargo build --release- 在MCP检查器中,配置:
- 传输类型: STDIO - 命令:二进制文件的完整路径(例如。, /path/to/target/release/mcp-server) - 参数:(留空) - 环境变量:(可选) - SERVER_NAME=mcp-server - SERVER_VERSION=0.1.0
- 点击 连接 以建立连接。
测试服务器
健康检查
curl http://localhost:3000/health预期响应:
{"status":"ok","service":"mcp-server"}MCP初始化
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'列出工具
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'调用工具
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":3,
"method":"tools/call",
"params":{
"name":"echo",
"arguments":{"message":"Hello, MCP!"}
}
}'配置
环境变量
可以使用以下环境变量配置服务器:
| 变量 | 描述 | 默认值 |
|---|---|---|
SERVER_NAME | MCP协议的服务器名称 | mcp-server |
SERVER_VERSION | 服务器版本字符串 | 0.1.0 |
MCP_TRANSPORT_MODE | 运输方式: stdio 或 http | stdio |
HOST | HTTP模式的绑定地址 | 0.0.0.0 |
PORT | HTTP模式的端口号 | 3000 |
WORKER_THREADS | 工作线程数(HTTP模式) | CPU计数(最多16个) |
工具配置
工具特定配置在中管理 kmcp.yaml:
name: mcp-server
framework: actix-web-rust
version: 0.1.0
description: Model Context Protocol server built with Rust
tools:
echo:
prefix: "Echo: "
weather:
api_key_env: "WEATHER_API_KEY"
base_url: "https://api.openweathermap.org/data/2.5"
timeout: 30工具中的访问配置:
use crate::core::utils;
let config = utils::get_tool_config("weather");
let api_key = utils::get_env_var(
config.get("api_key_env")
.and_then(|v| v.as_str())
.unwrap_or("WEATHER_API_KEY"),
""
);创建工具
刀具结构
每个工具都是作为一个单独的Rust模块实现的 src/tools/。该模块必须导出 register 将工具添加到注册表的函数。
示例工具实现
// src/tools/weather.rs
use crate::core::server::{MCPTool, ToolRegistry, ToolHandler};
use crate::core::utils;
use serde_json::Value;
/// Register the weather tool with the tool registry.
/// This function is called during server initialization.
pub fn register(registry: &mut ToolRegistry) {
// Define the tool metadata
let tool = MCPTool {
name: "weather".to_string(),
description: "Get current weather information for a location.".to_string(),
input_schema: serde_json::json!({
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or location identifier"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"default": "celsius",
"description": "Temperature units"
}
},
"required": ["location"]
}),
};
// Implement the tool handler
let handler: ToolHandler = Box::new(|args: Value| -> Result {
// Extract and validate parameters
let location = args.get("location")
.and_then(|v| v.as_str())
.ok_or_else(|| "Missing required parameter: location".to_string())?;
let units = args.get("units")
.and_then(|v| v.as_str())
.unwrap_or("celsius");
// Load tool configuration
let config = utils::get_tool_config("weather");
let api_key = utils::get_env_var(
config.get("api_key_env")
.and_then(|v| v.as_str())
.unwrap_or("WEATHER_API_KEY"),
""
);
if api_key.is_empty() {
return Err("Weather API key not configured".to_string());
}
// TODO: Implement actual API call
// For now, return a placeholder response
Ok(serde_json::json!({
"location": location,
"temperature": 22,
"units": units,
"condition": "sunny"
}))
});
// Register the tool
registry.register(tool, handler);
}注册工具
- 将工具模块添加到
src/tools/mod.rs:
pub mod echo;
pub mod weather; // Add your new tool- 在中注册该工具
src/core/server.rs:
pub fn initialize_tools() -> Arc {
let mut registry = ToolRegistry::new();
tools::echo::register(&mut registry);
tools::weather::register(&mut registry); // Register your tool
Arc::new(registry)
}工具处理程序最佳实践
- 参数验证:始终验证所需参数并返回明确的错误消息。
- 错误处理:使用
Result返回错误。错误字符串将被发送到客户端。 - 配置:使用
utils::get_tool_config()访问工具特定设置。 - 环境变量:使用
utils::get_env_var()用于API密钥等敏感数据。 - 演出:在高流量场景中,尽量减少分配并使用高效的数据结构。
API 参考
HTTP端点
GET/健康
用于监视和负载平衡器的健康检查端点。
答复:
{
"status": "ok",
"service": "mcp-server"
}GET/指标
服务器指标和请求统计。
答复:
{
"requests_total": 1234,
"status": "ok"
}GET/sse
用于工具发现的服务器发送事件终结点。返回工具信息流。
响应格式:
data: {"tools":[...],"count":1}
JavaScript示例:
const eventSource = new EventSource('http://localhost:3000/sse');
eventSource.onmessage = (e) => {
const data = JSON.parse(e.data);
console.log('Available tools:', data.tools);
};POST/mcp
主MCP JSON-RPC端点。接受JSON-RPC 2.0请求。
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "echo",
"arguments": {
"message": "Hello"
}
}
}答复:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"result\":\"Hello\"}"
}
],
"isError": false
}
}性能调整
构建优化
该项目包括积极的发布优化 Cargo.toml:
- 选择级别=3:最大优化
- lto=“薄”:链接时间优化以获得更好的性能
- 编码单位=1:更好的内联机会
- 恐慌=“中止”:较小的二进制大小
- strip=真:删除调试符号
使用以下内容构建:
cargo build --releaseHTTP服务器配置
HTTP服务器配置了以下限制( src/core/server.rs):
- 最大连接数:10000个并发连接
- 连接速率:每秒1000个连接
- 长连接:30秒
- 请求超时:30秒
- 断开连接超时:2秒
工作者线程
工作线程根据CPU计数(上限为16)自动设置。覆盖:
WORKER_THREADS=8 MCP_TRANSPORT_MODE=http cargo run --release资源使用情况
典型资源使用情况:
- 记忆:10-50MB基础(取决于工具数量)
- 中央处理器:使用工作线程进行扩展(建议每个CPU核1个)
- 网络:高效处理10000多个并发连接
监控
使用度量端点监控服务器性能:
# Watch metrics in real-time
watch -n 1 'curl -s http://localhost:3000/metrics | jq'部署
码头工人
构建图像
docker build -t mcp-server:latest .运行容器
# HTTP mode (default)
docker run -p 3000:3000 mcp-server:latest
# Stdio mode
docker run -i mcp-server:latest
# With custom configuration
docker run -p 3000:3000 \
-e WORKER_THREADS=8 \
-e PORT=8080 \
-e SERVER_NAME=my-mcp-server \
mcp-server:latestDocker Compose
version: '3.8'
services:
mcp-server:
build: .
ports:
- "3000:3000"
environment:
- MCP_TRANSPORT_MODE=http
- WORKER_THREADS=8
- PORT=3000
- SERVER_NAME=mcp-server
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
restart: unless-stopped系统化服务
创建 /etc/systemd/system/mcp-server.service:
[Unit]
Description=MCP Server
After=network.target
[Service]
Type=simple
User=mcpuser
WorkingDirectory=/opt/mcp-server
ExecStart=/opt/mcp-server/mcp-server
Environment="MCP_TRANSPORT_MODE=http"
Environment="PORT=3000"
Environment="WORKER_THREADS=8"
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target启用并启动:
sudo systemctl enable mcp-server
sudo systemctl start mcp-serverKubernetes
部署示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
spec:
replicas: 3
selector:
matchLabels:
app: mcp-server
template:
metadata:
labels:
app: mcp-server
spec:
containers:
- name: mcp-server
image: mcp-server:latest
ports:
- containerPort: 3000
env:
- name: MCP_TRANSPORT_MODE
value: "http"
- name: PORT
value: "3000"
- name: WORKER_THREADS
value: "8"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10发展
添加依赖关系
向添加依赖项 Cargo.toml:
[dependencies]
your-crate = "1.0"然后构建:
cargo build代码质量
格式代码:
cargo fmt棉绒编码:
cargo clippy使用更严格的lints跑步:
cargo clippy -- -W clippy::all -W clippy::pedantic测试
在工具模块中添加测试:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tool_handler() {
let args = serde_json::json!({"message": "test"});
// Test your handler
}
}运行测试:
cargo test调试
在调试模式下运行并记录:
RUST_LOG=debug cargo runMCP协议
协议版本
此服务器实现MCP协议版本 2024-11-05.
支持的方法
初始化
初始化MCP连接。返回服务器功能和信息。
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}答复:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "mcp-server",
"version": "0.1.0"
}
}
}工具/列表
列出所有可用工具。
请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}答复:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "echo",
"description": "Echo a message back to the client.",
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The message to echo"
}
},
"required": ["message"]
}
}
]
}
}工具/调用
使用提供的参数调用工具。
请求:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "echo",
"arguments": {
"message": "Hello, MCP!"
}
}
}响应(成功):
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "{\"result\":\"Hello, MCP!\"}"
}
],
"isError": false
}
}响应(错误):
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "Error: Missing required parameter: message"
}
],
"isError": true
}
}错误代码
服务器使用标准JSON-RPC 2.0错误代码:
-32700:解析错误(JSON无效)-32600:无效请求(格式错误的JSON-RPC)-32601:未找到方法-32602:无效参数-32603:内部错误
许可证
MIT许可证-有关详细信息,请参阅许可证文件。
贡献
- 分叉存储库
- 创建要素分支
- 进行更改
- 如果适用,添加测试
- 提交拉取请求
支持
有关问题和疑问,请在GitHub存储库上打开问题。
