MCP 2025-03-26 新规范解读:OAuth认证、远程连接与Tool Annotations
🧢
MCP(Model Context Protocol)协议自 2024 年 11 月由 Anthropic 首次发布以来,已经历多次重大迭代。2025-03-26 版本是迄今为止变动最大的一次更新,它从认证安全、传输架构、工具元数据三个维度对协议进行了全面升级。如果你正在构建或维护 MCP Server,这次更新值得你认真对待。
本文将深入解读这些变更的技术细节和设计动机,并提供可运行的代码示例帮助你快速落地。
核心要点
•
OAuth 2.1 强制升级:废弃隐式授权流,强制 PKCE + HTTPS,支持动态客户端注册
•
Streamable HTTP 取代 SSE:单端点设计替代双通道架构,支持双向通信和断线恢复
•
Tool Annotations:为每个工具声明行为元数据(只读/破坏性/幂等/开放域),驱动智能权限控制
•
JSON-RPC 批处理:协议级强制支持,大幅降低网络开销
•
会话管理:Mcp-Session-Id 头实现有状态连接和断点续传
•
生态爆发:Claude、ChatGPT、VS Code、Cursor 等主流平台全面支持
MCP 规范演进时间线
MCP 协议自诞生以来经历了四个重要版本:
#IzfoonsiObgx text { white-space: pre; }#IzfoonsiObgx .fb0 { stroke: var(--N900-FG, 0.15); }#IzfoonsiObgx .fb0 {stroke: rgba(31,35,41, 0.15)}#IzfoonsiObgx .fx0 { stroke-miterlimit: 10; }#IzfoonsiObgx .fx0 {stroke-miterlimit: 10}#IzfoonsiObgx .fa1 { fill: rgb(187, 191, 196); }#IzfoonsiObgx .fa1 {fill: rgb(187, 191, 196)}#IzfoonsiObgx .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#IzfoonsiObgx .fx1 {font-style: normal}#IzfoonsiObgx .fx2 { text-anchor: middle; }#IzfoonsiObgx .fx2 {text-anchor: middle}#IzfoonsiObgx .fx3 { dominant-baseline: central; }#IzfoonsiObgx .fx3 {dominant-baseline: central}#IzfoonsiObgx .fx4 { stroke: none; }#IzfoonsiObgx .fx4 {stroke: none}#IzfoonsiObgx .fc0 { fill: var(--text-caption); }#IzfoonsiObgx .fc0 {fill: #646a73}#IzfoonsiObgx .fa2 { fill: var(--text-link-disabled); }#IzfoonsiObgx .fa2 {fill: rgb(187, 191, 196)}#IzfoonsiObgx .fa3 { fill: rgb(246, 248, 250); }#IzfoonsiObgx .fa3 {fill: rgb(246, 248, 250)}#IzfoonsiObgx .fx5 { font: 400 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#IzfoonsiObgx .fx5 {font-style: normal}#IzfoonsiObgx .fx6 { text-anchor: start; }#IzfoonsiObgx .fx6 {text-anchor: start}#IzfoonsiObgx .fx7 { dominant-baseline: alphabetic; }#IzfoonsiObgx .fx7 {dominant-baseline: alphabetic}#IzfoonsiObgx .fc1 { fill: rgb(51, 51, 51); }#IzfoonsiObgx .fc1 {fill: rgb(51, 51, 51)}#IzfoonsiObgx .fx8 { font: 700 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#IzfoonsiObgx .fx8 {font-style: normal}#IzfoonsiObgx .fb1 { fill: var(--N900-FG, 0.15); }#IzfoonsiObgx .fb1 {fill: rgba(31,35,41, 0.15)}#IzfoonsiObgx .fb2 { fill: rgb(225, 228, 232); }#IzfoonsiObgx .fb2 {fill: rgb(225, 228, 232)}#IzfoonsiObgx .fa4 { fill: var(--bg-body); }#IzfoonsiObgx .fa4 {fill: #fff}ABC12345版本发布日期2024年11月2025年3月2025年6月2025年11月核心变更初始版本,定义 Tools/Resources/Prompts 三大原语,HTTP+SSE 传输OAuth 2.1、Streamable HTTP、Tool Annotations、JSON-RPC 批处理Elicitation(服务端请求用户输入)、安全最佳实践文档、结构化输出进一步安全增强、协议稳定性改进2024/11/52025/3/262025/6/182025/11/25
其中 2025-03-26 版本是最具里程碑意义的一次迭代,它将 MCP 从"本地开发工具协议"推向了"企业级生产就绪协议"的新阶段。
如果你还不熟悉 MCP 的基础概念,建议先阅读 MCP 协议深度解析 了解核心架构。
OAuth 2.1 认证授权框架
为什么 MCP 需要认证?
在 MCP 的初始版本中,Server 大多通过 stdio 在本地运行,本地进程天然拥有当前用户的权限,无需额外认证。然而,当 MCP Server 走向远程部署,认证就成了不可回避的问题:
•
权限隔离:不同用户访问不同数据,远程 Server 必须识别调用者身份
•
工具安全:具有破坏性的工具(如数据库删除)不能被未授权的 AI Agent 随意调用
•
合规要求:企业环境中对 API 访问的审计追溯是基本要求
OAuth 2.0 到 2.1 的关键升级
MCP 2025-03-26 版本直接采用了 OAuth 2.1 标准,相比旧版 OAuth 2.0 有三个核心变化:
#WGcSnqVLbxbi text { white-space: pre; }#WGcSnqVLbxbi .fb0 { stroke: var(--N900-FG, 0.15); }#WGcSnqVLbxbi .fb0 {stroke: rgba(31,35,41, 0.15)}#WGcSnqVLbxbi .fx0 { stroke-miterlimit: 10; }#WGcSnqVLbxbi .fx0 {stroke-miterlimit: 10}#WGcSnqVLbxbi .fa1 { fill: rgb(187, 191, 196); }#WGcSnqVLbxbi .fa1 {fill: rgb(187, 191, 196)}#WGcSnqVLbxbi .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#WGcSnqVLbxbi .fx1 {font-style: normal}#WGcSnqVLbxbi .fx2 { text-anchor: middle; }#WGcSnqVLbxbi .fx2 {text-anchor: middle}#WGcSnqVLbxbi .fx3 { dominant-baseline: central; }#WGcSnqVLbxbi .fx3 {dominant-baseline: central}#WGcSnqVLbxbi .fx4 { stroke: none; }#WGcSnqVLbxbi .fx4 {stroke: none}#WGcSnqVLbxbi .fc0 { fill: var(--text-caption); }#WGcSnqVLbxbi .fc0 {fill: #646a73}#WGcSnqVLbxbi .fa2 { fill: var(--text-link-disabled); }#WGcSnqVLbxbi .fa2 {fill: rgb(187, 191, 196)}#WGcSnqVLbxbi .fa3 { fill: rgb(246, 248, 250); }#WGcSnqVLbxbi .fa3 {fill: rgb(246, 248, 250)}#WGcSnqVLbxbi .fx5 { font: 400 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#WGcSnqVLbxbi .fx5 {font-style: normal}#WGcSnqVLbxbi .fx6 { text-anchor: start; }#WGcSnqVLbxbi .fx6 {text-anchor: start}#WGcSnqVLbxbi .fx7 { dominant-baseline: alphabetic; }#WGcSnqVLbxbi .fx7 {dominant-baseline: alphabetic}#WGcSnqVLbxbi .fc1 { fill: rgb(51, 51, 51); }#WGcSnqVLbxbi .fc1 {fill: rgb(51, 51, 51)}#WGcSnqVLbxbi .fx8 { font: 700 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#WGcSnqVLbxbi .fx8 {font-style: normal}#WGcSnqVLbxbi .fb1 { fill: var(--N900-FG, 0.15); }#WGcSnqVLbxbi .fb1 {fill: rgba(31,35,41, 0.15)}#WGcSnqVLbxbi .fb2 { fill: rgb(225, 228, 232); }#WGcSnqVLbxbi .fb2 {fill: rgb(225, 228, 232)}#WGcSnqVLbxbi .fa4 { fill: var(--bg-body); }#WGcSnqVLbxbi .fa4 {fill: #fff}ABC1234变更项隐式授权流PKCEHTTPSOAuth 2.0支持可选推荐OAuth 2.1完全废弃强制要求强制要求
**PKCE(Proof Key for Code Exchange)**是这次升级的核心。它通过密码学挑战-应答机制,彻底消除了授权码在传输过程中被截获的中间人攻击风险。
OAuth 认证流程
以下是 MCP 中 OAuth 2.1 + PKCE 的完整授权流程:

动态客户端注册
MCP 规范要求支持 RFC 7591 动态客户端注册,这意味着 MCP Client 不需要预先在 Server 端手动配置——连接时自动注册即可获得凭证。这对 AI 工具生态尤为重要:
代码块
JSON
POST /register HTTP/1.1
Content-Type: application/json
{"client_name": "My AI Assistant","redirect_uris": ["http://localhost:3000/callback"\],"grant\_types": ["authorization_code"],"token_endpoint_auth_method": "none"}
响应中返回 client_id,后续授权流程使用该 ID 进行身份标识。
Node.js 实现:带 OAuth 认证的 MCP Server
下面演示如何用 Node.js 构建一个符合 2025-03-26 规范的 MCP Server,集成 OAuth 2.1 认证。如果你在调试过程中需要检查 JWT Token 的结构,可以使用 JWT 生成与解析工具。
代码块
JavaScript
import express from 'express';
import crypto from 'crypto';
import jwt from 'jsonwebtoken';
const app = express();
app.use(express.json());
// --- OAuth 2.1 端点 ---// 授权服务器元数据发现
app.get('/.well-known/oauth-authorization-server', (req, res) => {
res.json({
issuer: 'https://mcp.example.com',
authorization_endpoint: 'https://mcp.example.com/authorize',
token_endpoint: 'https://mcp.example.com/token',
registration_endpoint: 'https://mcp.example.com/register',
response_types_supported: ['code'],
code_challenge_methods_supported: ['S256'],
grant_types_supported: ['authorization_code', 'refresh_token']
Python 实现:OAuth PKCE 客户端
代码块
Python
import hashlib
import base64
import os
import httpx
class MCPOAuthClient:
def __init__(self, server_url: str):
self.server_url = server_url
self.client_id = Noneself.access_token = Noneasync def discover(self):
"""发现授权服务器元数据"""async with httpx.AsyncClient() as client:
resp = await client.get(
f"{self.server_url}/.well-known/oauth-authorization-server"
)
return resp.json()
Streamable HTTP:传输层架构革新
从双端点到单端点
旧版 MCP(2024-11-05)采用 HTTP+SSE 双通道方案:GET /sse 建立 Server→Client 的推送通道,POST /message 接收 Client→Server 的 JSON-RPC 请求。这种设计存在明显的工程痛点——如果你曾经实现过这套方案(参考 用 Go 从零实现 SSE 传输层),你一定对双连接管理的复杂性深有体会。
2025-03-26 版本引入 Streamable HTTP 彻底重构了传输层:
核心工作机制
Streamable HTTP 的智能之处在于协议协商——Client 通过 Accept 头声明自己的能力,Server 据此选择响应方式:
代码块
HTTP
Server 可以选择两种响应策略:
策略 1:简单 JSON 响应(短任务)
代码块
HTTP
HTTP/1.1 200 OK
Content-Type: application/json
{"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "done"}]}}
策略 2:SSE 流式响应(长任务)
代码块
HTTP
会话管理与断线恢复
新增的 Mcp-Session-Id HTTP 头为长任务场景带来了关键的可靠性保障。当网络断开后重新连接时,Client 携带之前的 Session ID 和 Last-Event-ID,Server 可以从断点恢复而无需重新初始化:
代码块
JavaScript
// 客户端断线重连逻辑async function reconnect(sessionId, lastEventId) {
const response = await fetch('/mcp', {
method: 'GET',
headers: {
关于高并发场景下的连接管理策略,可以参考 高并发 MCP Gateway 架构设计。
Tool Annotations:工具行为元数据
为什么需要 Tool Annotations?
在 MCP 初始版本中,工具只有 name、description 和 inputSchema 三个字段。Client(或 LLM)只能通过文本描述来"猜测"一个工具会做什么——这在涉及破坏性操作时非常危险。
2025-03-26 版本引入 Tool Annotations 机制,允许 Server 为每个工具声明结构化的行为元数据:
代码块
TypeScript
interface ToolAnnotations {
title?: string; // 语义化标题(UI展示用)readOnlyHint?: boolean; // 是否只读(默认 false)destructiveHint?: boolean; // 是否有破坏性(默认 true)idempotentHint?: boolean; // 是否幂等(默认 false)openWorldHint?: boolean; // 是否与外部交互(默认 true)
}
四个 Hint 字段详解
重要提示:所有 Hint 字段都是"建议性"的,Client 不应将其作为安全控制的唯一依据。实际的权限校验必须由 Server 端的 RBAC 引擎执行。
实际应用示例
代码块
JSON
{"tools": [{"name": "query_database","description": "Execute a read-only SQL query","inputSchema": {"type": "object","properties": {"sql": { "type": "string" }}},"annotations": {"title": "Database Query","readOnlyHint": true,"destructiveHint": false,"idempotentHint": true,"openWorldHint": false}},{"name": "delete_user","description": "Permanently delete a user account","inputSchema": {"type": "object","properties": {"user_id": { "type": "string" }}},"annotations": {"title": "Delete User Account","readOnlyHint": false,"destructiveHint": true,"idempotentHint": false,"openWorldHint": false}},{"name": "send_email","description": "Send an email to the specified recipient","inputSchema": {"type": "object","properties": {"to": { "type": "string" },"subject": { "type": "string" },"body": { "type": "string" }}},"annotations": {"title": "Send Email","readOnlyHint": false,"destructiveHint": false,"idempotentHint": false,"openWorldHint": true}}]}
Client 可以基于这些 Annotations 实现智能化的 UI 交互——例如,对 destructiveHint: true 的工具自动弹出二次确认对话框,对 readOnlyHint: true 的工具跳过确认直接执行。这与 Function Calling 和 Tool Use 的安全理念一脉相承。
JSON-RPC 批处理与进度通知
协议级批处理支持
2025-03-26 版本明确规定:所有 MCP 实现必须支持 JSON-RPC 2.0 批处理规范。这意味着 Client 可以在单个 HTTP 请求中发送多个 JSON-RPC 调用,大幅减少网络开销。
代码块
JSON
[{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "analyze_text", "arguments": {"text": "hello"}}},{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "translate", "arguments": {"text": "hello", "target": "zh"}}},{"jsonrpc": "2.0", "method": "notifications/initialized"}]
批处理的性能优势非常显著:
增强的进度通知
新版进度通知增加了 message 字段,支持语义化的状态描述:
代码块
JSON
{"jsonrpc": "2.0","method": "notifications/progress","params": {"progressToken": "task_123","progress": 65,"total": 100,"message": "数据清洗中:已处理 12000/20000 条记录"}}
这让用户界面可以展示更有意义的进度信息,而不仅仅是一个百分比数字。
生态支持与 MCP Registry
主流平台支持现状
截至 2026 年,MCP 协议已获得全面的生态支持:
GitHub MCP Registry
2025 年 9 月,GitHub 上线了官方 MCP Registry 预览版——这是 MCP Server 的"应用商店",为生态系统提供了一个中心化的发现与分发平台:
•
权威索引:公开 MCP Server 的单一可信数据源
•
社区驱动:由 Anthropic、GitHub、Microsoft 等核心贡献者维护
•
客户端集成:VS Code 等工具可以直接从 Registry 安装 MCP Server
•
质量保证:提供 Server 的信誉评分和安全审计信息
对于 Server 开发者而言,将你的 MCP Server 发布到 Registry 可以显著提升可发现性。你可以通过 JSON 格式化工具 来检查和美化你的 Registry 配置文件。
从旧版迁移到新规范
迁移检查清单
如果你正在维护基于 2024-11-05 版本的 MCP Server,以下是迁移到 2025-03-26 版本的完整路线:
第 1 步:传输层升级(优先级最高)
代码块
JavaScript
// ❌ 旧版:双端点 HTTP+SSE
app.get('/sse', handleSSE);
app.post('/message', handleMessage);
// ✅ 新版:单端点 Streamable HTTP
app.post('/mcp', handleStreamableHTTP);
app.get('/mcp', handleSSEStream); // 可选:用于服务端主动推送
第 2 步:实现 OAuth 2.1 认证
代码块
JavaScript
// 新增元数据发现端点
app.get('/.well-known/oauth-authorization-server', (req, res) => {
res.json({ /* 授权服务器配置 */ });
});
第 3 步:添加 Tool Annotations
代码块
JavaScript
// ❌ 旧版:仅有基础描述
{ name: 'delete_file', description: 'Delete a file' }
// ✅ 新版:包含行为元数据
{
name: 'delete_file',
description: 'Delete a file',
annotations: {
title: 'Delete File',
readOnlyHint: false,
第 4 步:支持 JSON-RPC 批处理和会话管理
代码块
JavaScript
app.post('/mcp', (req, res) => {
// 处理 Mcp-Session-Idconst sessionId = req.headers['mcp-session-id'] || generateSessionId();
res.setHeader('Mcp-Session-Id', sessionId);
// 支持批处理if (Array.isArray(req.body)) {
const results = req.body.map(msg => processMessage(msg, sessionId));
return res.json(results.filter(Boolean));
}
// 单消息处理const result = processMessage(req.body, sessionId);
result ? res.json(result) : res.status(202).end();
向后兼容性建议
MCP 规范建议 Server 在过渡期间同时支持新旧传输方式,通过请求头进行版本协商。旧版 Client 发送的请求会自动被路由到兼容模式。关于 MCP 协议的高阶实战技巧,可以参考 MCP 协议高阶实战指南。
总结
MCP 2025-03-26 版本标志着协议从"可用"迈向"可靠"的关键一步。OAuth 2.1 解决了远程部署的认证难题,Streamable HTTP 简化了传输架构,Tool Annotations 让工具调用更加安全可控。对于正在构建 AI 应用的开发者而言,及时跟进这些规范变更,将帮助你构建更安全、更高效、更易维护的 MCP 集成方案。