使用 Rust、Axum 和 Shuttle 构建的完整的 模型上下文协议(MCP) 服务器。此模板提供了构建具有 OAuth 2.1 认证、数据库集成、AI 工具以及基于注册表的清晰架构的生产就绪 MCP 服务器所需的一切。
rig 包提供的 AI 功能该服务器实现了带有认证的完整 MCP 规范:
┌─────────────────┐ JSON-RPC 2.0 ┌─────────────────┐
│ MCP 客户端 │ ────────────────────▶│ Shuttle MCP │
│ (Claude 等) │ │ 服务器 │
│ │ ◄──── 工具 ─────────│ │
│ │ ◄── 资源 ───────────│ 🔐 OAuth 2.1 │
│ │ ◄─── 提示 ────────┬ │ 🗄️ PostgreSQL │
└─────────────────┘ │ 🤖 AI 工具 │
└─────────────────┘
initialize, notifications/initialized, exitRust - 从 rustup.rs 安装
Shuttle CLI - 推荐安装方式:
# Linux/macOS
curl -sSfL https://www.shuttle.dev/install | bash
# Windows (PowerShell)
# iwr https://www.shuttle.dev/install-win | iex
# 可选:使用 Cargo
# cargo install cargo-shuttle
Auth0 账户 - 免费账户在 auth0.com
Docker
git clone <this-repo-url>
cd mcp-server
# 在项目根目录创建 Secrets.toml
cat > Secrets.toml << EOF
AUTH0_DOMAIN = 'your-tenant.auth0.com'
AUTH0_CLIENT_ID = 'your-client-id'
AUTH0_CLIENT_SECRET = 'your-client-secret'
AUTH0_CALLBACK_URL = 'http://localhost:8000/auth/callback'
SESSION_JWT_SECRET = 'your-very-long-random-secret-key-at-least-32-chars'
OPENAI_API_KEY = 'sk-your-openai-api-key' # 可选
EOF
shuttle run
最简单的方法是使用官方的 MCP Inspector —— 一个专门为 MCP 开发设计的可视化测试工具。
MCP Inspector 提供了一个无需安装的完整测试界面:
# 直接测试 Shuttle 服务器
npx @modelcontextprotocol/inspector shuttle run
Inspector 提供了:
mcp.json 文件以进行客户端集成为了快速验证,你可以测试公共端点:
# 测试 MCP 端点(initialize 是公共的 - 不需要认证)
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "test-client", "version": "1.0.0"}
},
"id": 1
}'
# 测试认证流程(将重定向到 Auth0)
curl -I http://localhost:8000/auth/login
注意:测试受保护的 MCP 方法(工具、资源、提示)需要认证,这在 MCP Inspector 的内置认证支持下更容易处理。
shuttle login
shuttle deploy
注意:此部署尚未包含所需的密钥,因此不会完全工作。但是,我们需要部署 URL 来配置密钥——请参阅下一步。
在你的 Auth0 应用中:
https://your-mcp-server.shuttleapp.dev/auth/callbackhttps://your-mcp-server.shuttleapp.dev/# 更新 Secrets.toml
AUTH0_CALLBACK_URL = 'https://your-mcp-server.shuttleapp.dev/auth/callback'
# 保持其他密钥不变
shuttle deploy
| 端点 | 方法 | 描述 |
|---|---|---|
/.well-known/oauth-authorization-server | GET | OAuth 服务器元数据(RFC8414) |
/authorize | GET | 支持 PKCE 的授权端点 |
/token | POST | 获取访问令牌的端点 |
/register | POST | 动态客户端注册(RFC7591) |
/register 端点注册/authorize 启动带有 PKCE 的认证流程/token 交换代码以获取令牌此端点处理 OAuth 流程中的 Auth0 回调:
GET /auth/callback - 处理 Auth0 回调并将用户绑定到 OAuth 授权码POST /mcp - 主 MCP JSON-RPC 2.0 端点| 方法 | 认证 | 描述 |
|---|---|---|
initialize | ❌ 公共 | 交换能力和服务信息 |
notifications/initialized | ❌ 公共 | 完成 MCP 握手 |
tools/list | ✅ 必需 | 列出可用工具及其模式 |
tools/call | ✅ 必需 | 执行工具 |
resources/list | ✅ 必需 | 列出可用数据资源 |
resources/read | ✅ 必需 | 读取资源内容 |
prompts/list | ✅ 必需 | 列出可用提示模板 |
prompts/get | ✅ 必需 | 获取特定提示 |
| 工具 | 描述 | 参数 |
|---|---|---|
text_length | 获取字符数 | text: string |
text_transform | 转换文本大小写 | text: string, transform: enum |
text_search | 查找模式 | text: string, pattern: string |
timestamp | 获取当前 UTC 时间 | 无 |
ai_complete | 完成文本提示 | prompt: string |
ai_summarize | 摘要长文本 | text: string |
user_stats | 获取数据库统计信息 | 无 |
| 资源 | 描述 | 内容类型 |
|---|---|---|
user://stats | 数据库中的用户统计信息 | application/json |
| 提示 | 描述 | 参数 |
|---|---|---|
code_review | 生成代码审查提示 | code: string, language?: string |
explain_error | 生成错误解释提示 | error: string |
src/tools/ 中:// src/tools/my_tools.rs
pub fn calculate_fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => calculate_fibonacci(n - 1) + calculate_fibonacci(n - 2)
}
}
src/registries.rs):Tool {
name: "fibonacci",
description: "计算斐波那契数",
},
src/mcp.rs 的 handle_tool_call 函数中:"fibonacci" => {
let n = arguments.get("n").and_then(|v| v.as_u64()).unwrap_or(0) as u32;
let result = crate::tools::my_tools::calculate_fibonacci(n);
Ok(serde_json::json!({
"content": [{
"type": "text",
"text": format!("Fibonacci({}) = {}", n, result)
}]
}))
}
get_tool_schema 函数中:"fibonacci" => serde_json::json!({
"type": "object",
"properties": {
"n": {
"type": "integer",
"description": "斐波那契序列的位置",
"minimum": 0
}
},
"required": ["n"]
}),
src/registries.rs):Resource {
uri: "system://health",
name: "系统健康",
description: "当前系统健康指标",
mime_type: "application/json",
},
handle_resource_read 函数中 (src/mcp.rs):"system://health" => {
let health_data = serde_json::json!({
"status": "健康",
"uptime": "2小时30分钟",
"memory_usage": "45%"
});
Ok(serde_json::json!({
"contents": [{
"uri": uri,
"mimeType": resource.mime_type,
"text": serde_json::to_string_pretty(&health_data).unwrap()
}]
}))
}
src/registries.rs):Prompt {
name: "write_tests",
description: "为代码生成单元测试",
arguments: vec![
PromptArgument {
name: "code",
description: "要测试的代码",
required: true,
},
PromptArgument {
name: "framework",
description: "测试框架",
required: false,
},
],
},
handle_prompt_get 函数中 (src/mcp.rs):"write_tests" => {
let code = arguments.and_then(|args| args.get("code"))
.and_then(|v| v.as_str()).unwrap_or("// 没有提供代码");
let framework = arguments.and_then(|args| args.get("framework"))
.and_then(|v| v.as_str()).unwrap_or("jest");
Ok(serde_json::json!({
"messages": [{
"role": "user",
"content": {
"type": "text",
"text": format!("为这段代码编写 {} 单元测试:\n\n{}", framework, code)
}
}]
}))
}
src/
├── main.rs # 应用程序入口点和路由
├── auth/ # 认证系统
│ ├── mod.rs # 模块导出
│ ├── handlers.rs # OAuth 和会话处理器
│ ├── middleware.rs # 认证中间件和辅助函数
│ └── models.rs # 用户和认证数据模型
├── database.rs # 数据库初始化和迁移
├── mcp.rs # MCP JSON-RPC 协议实现
├── registries.rs # 工具、资源和提示的中央注册表
└── tools/ # 工具实现
├── mod.rs # 工具模块导出
├── ai.rs # OpenAI 集成工具
├── db.rs # 数据库查询工具
├── text.rs # 文本处理实用工具
└── utils.rs # 通用实用工具
migrations/ # 数据库迁移文件
本项目采用 MIT 许可证 - 详情见 LICENSE 文件。