模型: claude-opus-4-6 (anthropic/claude-opus-4-6)
生成日期: 2026-02-17
前面三节我们深入分析了 MCP 的协议概念、Client 实现和 OAuth 认证。本节回到用户视角,看看如何在 OpenCode 中配置 MCP Server,以及 Resource 模型的数据结构。
8.4.1 mcpServers 配置项结构
OpenCode 的 MCP 配置通过 opencode.json(项目级)或全局配置文件中的 mcp 字段定义。配置系统使用 Zod 进行严格的类型验证。
本地 MCP Server 配置(McpLocal)
// config/config.ts
export const McpLocal = z.object({
type: z.literal("local"), // 类型标识
command: z.string().array(), // 命令和参数数组
environment: z.record(z.string(), z.string()).optional(), // 环境变量
enabled: z.boolean().optional(), // 是否启用(默认 true)
timeout: z.number().int().positive().optional(), // 超时时间(毫秒)
}).strict()
一个典型的本地 MCP Server 配置示例:
{
"mcp": {
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
"environment": {
"NODE_ENV": "production"
},
"timeout": 10000
}
}
}
配置字段解析:
连接和请求的超时时间(毫秒),默认 30,000ms
command 字段使用数组格式而非字符串,这避免了 shell 注入的安全风险,也使得带空格的路径能被正确处理。OpenCode 在启动本地 MCP Server 时会解构这个数组:
远程 MCP Server 配置(McpRemote)
远程 MCP Server 的配置示例:
远程服务器的 URL(StreamableHTTP/SSE 端点)
自定义 HTTP 请求头(用于 API Key 等认证)
OAuth 配置,false 表示禁用 OAuth
OAuth 配置(McpOAuth)
OAuth 配置有三种使用模式:
自动发现模式(默认):不提供 oauth 字段或提供空对象 {}。OpenCode 在连接远程 Server 时会自动检测是否需要 OAuth,并尝试动态客户端注册。
预注册客户端模式:提供 clientId(以及可选的 clientSecret)。适用于已在授权服务器上注册过客户端的场景。
禁用模式:设置 oauth: false。适用于不需要 OAuth 的远程 Server(如使用 API Key 或无认证的服务)。
源码中的处理逻辑:
Discriminated Union 的类型安全
Mcp 类型是 McpLocal 和 McpRemote 的可辨识联合:
这意味着 Zod 在解析配置时会根据 type 字段自动选择正确的验证模式——type: "local" 的配置不会被要求提供 url 字段,而 type: "remote" 的配置不会被要求提供 command 字段。如果提供了错误的字段组合,Zod 会给出精确的类型错误提示。
辅助函数 isMcpConfigured() 用于运行时类型守卫:
除了为每个 MCP Server 单独设置 timeout 之外,OpenCode 还提供了一个全局的实验性配置项:
优先级为:MCP Server 自身的 timeout > 全局 experimental.mcp_timeout > 默认值(30,000ms)。
8.4.2 MCP Resource 模型
在 8.1 节中我们提到,MCP 的三种核心原语之一是 Resource(资源)。OpenCode 使用 Zod 定义了 Resource 的数据模型:
Resource 的 URI 遵循标准的 URI 格式,允许 MCP Server 用任意的 scheme 来标识资源。例如:
file:///path/to/document.md —— 文件资源
https://api.example.com/data —— API 端点
client 字段记录了这个资源来自哪个 MCP Server,用于后续的 readResource() 调用时路由到正确的客户端。
Resource 的获取与读取
Resource 的命名同样使用了前缀策略(ServerName:ResourceName)来避免冲突。
以下是几种常见的 MCP 配置场景:
场景 1:本地文件系统工具
场景 2:需要 API Key 的远程服务
场景 3:需要 OAuth 的远程服务
场景 4:临时禁用某个 MCP Server
将 enabled 设为 false 可以保留配置但不建立连接,避免不必要的资源消耗。这比删除配置更加方便,因为启用时只需改回 true。
本节小结
OpenCode 的 MCP 配置系统通过 Zod 的 Discriminated Union 实现了类型安全的验证——type: "local" 和 type: "remote" 两种配置模式各自有不同的必填字段。本地配置的核心是 command 数组(避免 shell 注入),远程配置的核心是 url 和 oauth(支持自动发现、预注册和禁用三种模式)。超时时间支持 Server 级、全局级和默认值三层优先级。Resource 模型使用 URI 作为标识符,通过 client 字段关联到具体的 MCP Server。
第 8 章总结
本章从协议概念到源码实现,完整地剖析了 OpenCode 的 MCP 系统。MCP(Model Context Protocol)为 OpenCode 提供了连接外部工具生态的标准化桥梁,其核心价值在于将工具的实现与 AI 应用完全解耦。OpenCode 的 MCP 实现包括四个关键模块:
mcp/index.ts(935 行):MCP 客户端核心,管理连接、状态机和工具转换。
mcp/auth.ts(133 行):OAuth 凭据的安全存储,支持 URL 绑定验证。
mcp/oauth-provider.ts(155 行):实现 MCP SDK 的 OAuth 接口,支持动态客户端注册和 PKCE。
mcp/oauth-callback.ts(201 行):本地 HTTP 回调服务器,带 CSRF 防护和竞态条件处理。
从工程角度看,MCP 模块展示了许多值得学习的设计模式:传输层的降级策略(StreamableHTTP → SSE)、连接状态的五态状态机、OAuth 安全的多层防护(PKCE + State + URL 绑定)、以及先注册回调再打开浏览器的竞态条件处理。这些细节虽然在源码中可能只是几行代码的差异,但它们代表了对安全性和健壮性的深思熟虑,是区分"能用"和"可靠"之间的关键。