最新n1n v2.0.1 正式上线!企业级大模型接口聚合平台 (LLM API Gateway),为您接入 500+ AI Models,价格低至 1 折, 立即尝试

本地与远程 MCP 服务端对比:模型上下文协议连接原理详解

作者
  • avatar
    姓名
    Nino
    职业
    Senior Tech Editor

模型上下文协议(Model Context Protocol,简称 MCP)已快速成为连接 AI 客户端(如 Claude Code、Cursor 或自定义大模型应用)与外部工具及数据源的开放标准。无论你是调用本地文件评估工具,还是与 Upwork、Notion、Todoist 等远程云服务交互,深入理解其底层的连接与认证机制,对于系统架构设计、安全加固及生产级扩展都至关重要。

在构建复杂 AI Agent 工作流或通过 n1n.ai 等高性能 API 聚合平台进行模型调度时,开发者通常需要在两种 MCP 传输模式之间做出选择:运行在本地宿主机器上的 本地服务端(stdio),以及部署在云端并通过授权校验的 远程服务端(HTTP/SSE + OAuth 2.0)。

本文结合实际测试数据与 MCP 官方规范,详细拆解这两种模式的通信协议、进程行为、鉴权握手以及令牌校验流程。


1. 本地 MCP 服务端:Stdio 传输与进程生命周期

本地 MCP 服务端作为宿主 AI 应用直接启动的子进程运行。双方通过标准输入(stdin)和标准输出(stdout)管道传输 JSON-RPC 消息进行通信。

+-----------------------+              +-----------------------+
|   宿主 AI 应用程序    |  --- stdin ->|   本地 MCP 服务端     |
|  (例如 Claude Code)   |  <- stdout --|     (子进程)          |
+-----------------------+              +-----------------------+

进程生命周期的实测分析

为了观察本地 MCP 服务端在实际运行中的表现,我们在 Claude Code(claude -p)运行本地工具服务端(如 doceval)时,以 250ms 为间隔对进程树进行了连续监控:

  1. 会话启动即初始化:当客户端会话建立时,宿主程序会立即将其配置的所有本地 MCP 服务端作为子进程启动——即使当前 Prompt 尚未调用任何工具。如果配置文件中定义了 3个本地服务端,系统会立刻创建 3个独立的子进程。
  2. 跨调用复用进程:在同一个会话中,后续的所有工具调用都会复用已启动的进程。在单次会话中连续调用 10次工具,服务端进程只会被创建 1次。
  3. 会话间隔离:每个独立的客户端会话都会启动属于自己的子进程集合。如果同时打开 3个运行 Claude Code 的终端窗口,系统将运行 3 份完全独立的本地服务端副本。
  4. 进程销毁与崩溃恢复:当客户端正常退出时,宿主程序会向子进程发送终止信号以完成清理。若对宿主程序执行强制杀进程(kill -9),子进程的 stdin 管道会立即关闭。符合规范的本地 MCP 服务端在检测到 stdin 的 EOF(文件结束符)后,会在 2秒内自动退出,避免产生孤儿进程。

本地模式下的密钥注入

根据 MCP 官方规范,本地 stdio 服务端不应使用 OAuth 2.0 等复杂授权流程。相反,敏感凭证与 API 密钥应通过宿主应用配置中的环境变量进行传递。

为了避免将明文密钥直接硬编码在磁盘配置文件中,主流客户端支持 shell 环境变量动态替换:

{
  "mcpServers": {
    "local-evaluator": {
      "command": "node",
      "args": ["/path/to/server.js"],
      "env": {
        "API_KEY": "${MY_CUSTOM_API_SECRET}"
      }
    }
  }
}

在运行时,宿主程序会自动读取当前 shell 中的 ${MY_CUSTOM_API_SECRET} 变量值并注入子进程的环境变量块中,既保障了安全,又无需繁琐的浏览器登录流程。


2. 远程 MCP 服务端:HTTP、OAuth 2.0 与 PKCE 握手

远程 MCP 服务端部署在公网 HTTPS 地址上(例如 ai.todoist.net 或 mcp.upwork.com/mcp)。由于远程接口暴露在公网上,必须采用严格的身份认证与授权机制。

+-------------+          +---------------+          +-------------------+
|   AI 客户端  |  ----->  |  MCP 服务端   |  ----->  |     授权服务器     |
| (Claude Code)|         |  (资源提供方)  |         | (OAuth 2.0 Provider)|
+-------------+          +---------------+          +-------------------+

与简单的静态 API Key 不同,MCP 规范要求远程服务端采用带有 PKCE(带密钥交换的验证码,RFC 7636)的 OAuth 2.0 授权机制。

远程连接的 9 步完整时序

以下是 AI 客户端连接远程 MCP 服务端(如 Upwork、Notion 或 Todoist)时的完整交互流程:

AI 客户端 (Claude Code)    MCP 服务端 (资源)      授权服务器 (OAuth)        浏览器 / 用户
        |                         |                        |                    |
  1. 未带 Token 发起请求 -------->|                        |                    |
        |<--- 返回 401 Unauthorized-|                        |                    |
        |     (包含元数据链接)     |                        |                    |
  2. 获取资源元数据 ------------->|                        |                    |
  3. 查询授权服务器端点 ---------------------------------->|                    |
  4. 解析 Client ID URL ---------------------------------->|                    |
  5. 生成 PKCE 随机串与哈希        |                        |                    |
  6. 在浏览器中打开登录页面 -------------------------------------------------------->| 用户登录授权
  7. 授权码重定向返回客户端 <-------------------------------------------------------| 同意授权
  8. 提交授权码与 PKCE 原始验证串 ------------------------->|                    |
        |<--- 返回 Access Token & Refresh Token -----------|                    |
  9. 存储 Token 并携带 Bearer 请求->|                        |                    |

步骤 1:无令牌探测(401 响应)

客户端首先在不携带 Bearer 令牌的情况下向远程 MCP 服务端发起请求。服务端返回 401 Unauthorized 响应,并在 WWW-Authenticate 响应头中提供公开元数据地址(例如 /.well-known/oauth-protected-resource)。

步骤 2:资源元数据发现

客户端请求该元数据文件,从中提取出规范的授权服务器地址。例如,Todoist 的 MCP 服务端(ai.todoist.net)指向的授权服务器为 todoist.com。

步骤 3:授权端点解析

客户端访问授权服务器的 /.well-known/oauth-authorization-server 文件,获取登录地址、Token 兑换地址、撤销地址以及支持的 PKCE 哈希算法(S256)。

步骤 4:基于 URL 的客户端身份标识

为避免每个开发者的本地机器都需要手动注册 App Secret,MCP 规范采用了客户端元数据 URL。Claude Code 使用统一的公开 URL 作为其 Client ID:https://claude.ai/oauth/claude-code-client-metadata。授权服务器会拉取该配置文件以确认客户端属性。由于本地 CLI 工具无法安全保存 App Secret,配置文件显式标明 "token_endpoint_auth_method": "none"。

步骤 5:生成 PKCE 密钥

由于客户端没有固定 App Secret,必须借助 PKCE 来证明“完成登录的程序就是发起登录的程序”。客户端在本地生成一个高熵随机字符串(Code Verifier),并计算其 SHA256 哈希值(Code Challenge)。

步骤 6:用户浏览器登录

客户端自动打开用户的默认浏览器,跳转至授权服务器的登录页面,URL 参数中包含:

  • client_id: https://claude.ai/oauth/claude-code-client-metadata
  • redirect_uri: http://localhost/callback
  • code_challenge: Base64URL(SHA256(Verifier))
  • code_challenge_method: S256
  • resource: 目标 MCP 服务端地址

用户直接在服务商官方页面输入账号密码。客户端完全无法接触用户的明文密码。

步骤 7:授权码回调

用户同意授权后,授权服务器将浏览器重定向至 http://localhost/callback?code=AUTH_CODE。客户端在本地监听的回调服务接收到该请求,并校验防重放状态。

步骤 8:Token 兑换

客户端向授权服务器的 Token 端点发送 POST 请求,提交:

  • 获取到的授权码(Authorization Code)
  • 步骤 5 中在本地保留的 Code Verifier 原始字符串

授权服务器对传入的 Verifier 进行哈希计算并与步骤 6 存留的 Challenge 进行比对。校验一致后,颁发 Access Token(短效访问令牌)和 Refresh Token(长效刷新令牌)。

步骤 9:Token 存储与请求携带

客户端将获得的令牌安全保存在本地仅限当前用户读写的文件中(例如 ~/.claude/.credentials.json)。在此之后,发往该 MCP 服务端的每个 HTTP 请求都会携带以下 Header: Authorization: Bearer <access_token>

在构建连接大语言模型与外部系统的高效桥梁时,接入如 n1n.ai 提供的多模型 API 服务,能够帮助开发者在统一管理底层模型调用的同时,保持上层工具链认证逻辑的高效与规范。


3. 远程 MCP 服务端如何校验访问令牌

当 Access Token 抵达远程 MCP 服务端后,服务端必须在执行任何工具逻辑前完成令牌合法性校验。校验方式主要分为以下两种策略:

不透明令牌(Opaque Token)与 JWT 签名校验对比

令牌机制数据结构校验方式网络开销撤销生效时效
不透明令牌随机字符串数据库查询或 RFC 7662 Introspection 接口请求每次请求都需要发起内部网络调用实时生效
签名 JWTHeader.Payload.Signature使用公钥(JWKS)进行本地密码学签名校验零额外网络开销依赖 Token 过期时间

JWT 本地验签代码实现逻辑

若 MCP 服务端接收的是 JWT 格式的令牌,可以通过公钥在本地完成快速验签:

import jwt
import requests

def verify_mcp_jwt(token_string, trusted_issuer_url):
    # 1. 解析 Header 获取 Key ID (kid)
    header = jwt.get_unverified_header(token_string)
    kid = header.get("kid")
    
    # 2. 仅从受信任的发号服务器拉取公钥集 (JWKS)
    jwks_url = f"{trusted_issuer_url}/.well-known/jwks.json"
    jwks = requests.get(jwks_url).json()
    
    # 3. 匹配对应的公钥
    public_key = get_public_key_by_kid(jwks, kid)
    
    # 4. 校验签名及标准 Claim(aud, exp, iss)
    decoded = jwt.decode(
        token_string,
        public_key,
        algorithms=["RS256"],
        audience="https://mcp.target-service.com",
        issuer=trusted_issuer_url
    )
    return decoded

安全专家建议:合规的 MCP 服务端必须仅从预先配置并信任的授权服务器 URL(iss)获取公钥,绝不能直接信任 JWT Header 内部声明的外部 URL 地址,以防范公钥伪造攻击。

协议演进:无状态(Sessionless)架构

在最新的 MCP 协议修订中(包括面向 2026年的标准演进),官方废弃了早期繁琐的 initialize 握手过程及 Mcp-Session-Id 请求头。

现在的远程 MCP 服务端完全基于 无状态 HTTP 运行。每个独立的 HTTP 请求都会完整携带协议版本、客户端能力声明及 Bearer 令牌。状态逻辑被彻底沉淀在两端:客户端本地的 Token 存储与授权服务器端的撤销记录。这种设计使得远程 MCP 服务端可以非常轻松地在负载均衡器后方实现水平扩展。

结合 n1n.ai 统一的大模型 API 聚合能力,开发者可以在横向扩展云端 Agent 架构的同时,保持高并发模型推理与远程工具调用的稳定连接。


4. 本地与远程 MCP 架构全面对比

维度本地 MCP 服务端 (Stdio)远程 MCP 服务端 (HTTP / OAuth)
传输层标准输入输出管道 (stdin/stdout)HTTPS / Server-Sent Events (SSE)
进程模式由 AI 客户端在本地作为子进程启动运行在远程云端服务器或容器中
鉴权机制环境变量注入 (${ENV_VAR})带有 PKCE (S256) 的 OAuth 2.0
凭证安全保存在本地环境或配置文件中账号密码仅保留在服务商侧;本地仅保存 Token
并发能力每个会话独占 1个子进程单服务端并发处理成千上万客户端连接
进程生命周期随父进程管道关闭(EOF)自动销毁无状态 / 无会话请求生命周期
适用场景本地文件操作、Git 管理、代码执行环境SaaS 软件集成 (Notion, Upwork, Jira, 数据库)

5. 安全分析与风险防御

在选择 MCP 服务端架构时,必须清晰评估不同传输模式的安全边界:

本地 MCP 的安全边界

  • 子进程权限隐患:本地 MCP 服务端继承了宿主用户的系统权限。若引入了存在安全漏洞的本地 MCP 模块,可能会被恶意利用执行任意 shell 命令或读取敏感文件。
  • 环境变量泄漏:将明文密钥直接写在配置文件中存在泄露风险。开发者在结合 n1n.ai 进行多模型调度与工具集成时,应始终坚持使用环境变量动态展开(${SECRET_KEY})的方式管理密钥。

远程 MCP 的安全边界

  • 签名密钥泄漏风险:若授权服务器的私钥泄漏(如历史上的 Storm-0558 安全事件),攻击者将能够伪造任意有效 Token。通过缩短 Access Token 的有效时长(如 15-60分钟)并建立完善的密钥轮换机制,可以有效规避该风险。
  • 令牌撤销机制:当 Access Token 过期或被用户主动撤销后,Refresh Token 兑换流程将失效,系统会强制要求重新登录,从而确保了风险窗口的可控性。

凭证流转与存储总结表

凭证要素生成方持有/管理方暴露等级
App ID URL客户端开发者公开可访问的元数据配置文件完全公开
PKCE VerifierAI 客户端登录流程中暂存于客户端内存临时代码级机密
授权码 (Auth Code)授权服务器浏览器重定向 URL 参数一次性有效
Access Token授权服务器客户端本地文件 (credentials.json)短效机密
Refresh Token授权服务器客户端本地及授权服务器数据库长效机密
用户密码用户仅保留在授权服务器侧严格保密
本地服务端密钥用户宿主系统环境变量 (env)本地局部机密

合理选择传输协议——用本地 stdio 解决高性能本地文件与系统交互,用远程 HTTP/OAuth 解决云端 SaaS 服务安全集成——是构建高可用、生产级 AI 应用的核心要义。

在 n1n.ai 获取免费 API 密钥。