使用说明
MCP认证演示
模型上下文协议(MCP)授权流的概念验证实现,其特征是:
- MCP服务器 (
server/)公开动态客户端注册(DCR)、OAuth授权/令牌端点以及由承载令牌保护的基于SSE的MCP传输。 - MCP客户端 (
client/)它通过DCR自动进行自我注册,执行OAuth流,缓存凭据/令牌,并连接到服务器以使用经过身份验证的工具。
先决条件
- Node.js≥18
- npm
框架和关键版本
| 库/工具 | 版本 | 角色/基本原理 |
|---|---|---|
| 快速 | ^5.1.0 |
轻量级HTTP框架,用于快速连接OAuth端点和SSE传输。v5为我们提供了开箱即用的异步处理程序支持。 |
| @模型上下文协议/sdk | ^1.22.0 |
提供规范的MCP服务器+客户端实现和传输助手,这样我们就可以在不重建协议栈的情况下保持规范合规性。 |
| 萨德 | ^3.25.76 |
DCR/OAuth有效载荷和工具模式的运行时验证;明确错误消息。 |
| TypeScript | ^5.9.3 |
确保跨服务器和客户端的严格键入,以提高身份验证流的安全性。 |
| TSX | ^4.20.6 |
用于本地开发脚本的零配置TS/ESM运行器(dev:server, dev:client). |
安装
npm install
运行服务器
npm run dev:server
默认值:
- 基本URL:
http://localhost:3333 - 自动注册两个工具:
whoami:返回调用者的MCP上下文。read-secret:返回受保护的秘密,需要secret.read范围。
环境变量(可选):
| 变量 | 描述 | 默认值 |
|---|---|---|
PORT |
服务器端口 | 3333 |
PUBLIC_BASE_URL |
外部基础URL(用于元数据+OAuth响应) | http://localhost:${PORT} |
SERVER_SECRET |
返回的值 read-secret |
demo-mcp-secret |
DEMO_USER_ID / DEMO_USER_NAME |
授权过程中使用的模拟用户身份 | demo-user / Demo User |
运行客户端
npm run dev:client
发生了什么:
- 支票
.mcp-auth/clients.json对于每个基本URL的现有注册。如果缺失/无效,请通过以下方式注册新客户端/dcr/register. - 在中查找有效的缓存访问令牌
.mcp-auth/tokens.json。如果过期或丢失,则运行OAuth授权+令牌交换流(使用prompt=auto以及手动重定向处理,因此不需要浏览器交互)。 - 通过以下方式连接到MCP服务器
SSEClientTransport,列出工具、调用whoami,然后呼叫read-secret(如果范围可用)。
CLI会自动从过时的客户端注册中恢复(例如,如果服务器重新启动并忘记了以前的客户端ID)。
客户端环境变量:
| 变量 | 描述 | 默认值 |
|---|---|---|
SERVER_BASE_URL |
MCP服务器的基本URL | http://localhost:3333 |
CLIENT_REDIRECT_URI |
重定向OAuth期间使用的URI | http://localhost:4321/callback |
CLIENT_SCOPES |
DCR/OAuth期间请求的范围 | mcp:invoke secret.read |
CLIENT_STORAGE_DIR |
缓存凭据的根目录 | ${PWD}/.mcp-auth |
CLIENT_STORAGE_PATH |
覆盖缓存客户端注册的路径 | ${CLIENT_STORAGE_DIR}/clients.json |
TOKEN_STORAGE_PATH |
覆盖缓存令牌的路径 | ${CLIENT_STORAGE_DIR}/tokens.json |
TOKEN_LEEWAY_MS |
重用缓存令牌之前的过期余地 | 60000 (1分钟) |
⚠️ .mcp-auth/ 被git忽略;删除它以强制进行新的注册和令牌。
通过curl/Postman进行手动测试
如果需要,您可以手动驱动每个步骤:
- 动态条件响应:
POST /dcr/register使用JSON有效载荷进行接收client_id+client_secret. - 授权:
GET /oauth/authorize?client_id=...&response_type=code&prompt=auto...并检查要捕获的重定向URLcode. - 代币交换:
POST /oauth/token(表格编码)带有授权码。 - 主控程序:使用
access_token在Authorization: Bearer ...要调用的标头GET /mcp(成立苏格兰和南方能源公司)以及POST /mcp/messages?sessionId=...用于JSON-RPC请求。
测试指导
仅服务器检查
- 健康+元数据
curl http://localhost:3333/healthz curl http://localhost:3333/.well-known/oauth-authorization-server - DCR验证
curl http://localhost:3333/dcr/register \ -H "Content-Type: application/json" \ -d '{"client_name":"curl-test","redirect_uris":["http://localhost:9999/callback"],"scope":"mcp:invoke"}' - OAuth流(手动)
- 击打
/oauth/authorize?client_id=...&response_type=code&prompt=auto... - 交换代码通过
/oauth/token.
- 击打
- 受保护的MCP端点
GET /mcp和POST /mcp/messages使用承载令牌确保授权中间件正常工作。
仅限客户检查
- 清除缓存:
rm -rf .mcp-auth - 跑
npm run dev:client- 验证它是否注册、授权和打印工具响应。
- 再次运行以确认缓存的客户端+令牌重用。
- (可选)删除
.mcp-auth/clients.json仅用于确认重新注册处理。
完整的端到端测试
npm run dev:server- 在另一个终端中:
npm run dev:client - 确认日志显示工具列表,
whoami,以及read-secret输出。 - (可选)使用已发布的命令通过curl/Postman驱动其他工具调用
access_token.
回购结构
server/
auth.ts # In-memory DCR + OAuth storage + bearer middleware
index.ts # Express app exposing OAuth + MCP endpoints/tools
client/
app.ts # CLI entry point
config.ts # Configuration & environment defaults
dcr.ts # Client registration logic
oauth.ts # Authorization-code flow
tokenManager.ts # Token caching & refresh heuristics
mcp.ts # SSE client transport & demo tool invocations
storage.ts # File-based persistence helpers
utils/ # Logging + HTTP helpers
未来的增强功能
- 用于任意工具调用的交互式CLI命令。
- 基于浏览器的OAuth,带有PKCE和嵌入式环回回调服务器。
- 持久刷新令牌/长期会话。
- 涵盖整个DCR的自动化测试→ OAuth→ MCP往返。
您可以随意调整范围、添加新工具或将客户端指向远程托管的MCP服务器,以尝试企业风格的部署。
