8.4 MCP 配置

模型: 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
    }
  }
}

配置字段解析:

字段
类型
说明

type

"local"

标识为本地 MCP Server

command

string[]

启动命令,第一个元素为可执行文件,其余为参数

environment

Record<string, string>

额外的环境变量(会叠加到当前进程的环境变量上)

enabled

boolean

是否启用,false 时不会尝试连接

timeout

number

连接和请求的超时时间(毫秒),默认 30,000ms

command 字段使用数组格式而非字符串,这避免了 shell 注入的安全风险,也使得带空格的路径能被正确处理。OpenCode 在启动本地 MCP Server 时会解构这个数组:

远程 MCP Server 配置(McpRemote)

远程 MCP Server 的配置示例:

字段
类型
说明

type

"remote"

标识为远程 MCP Server

url

string

远程服务器的 URL(StreamableHTTP/SSE 端点)

headers

Record<string, string>

自定义 HTTP 请求头(用于 API Key 等认证)

oauth

McpOAuth | false

OAuth 配置,false 表示禁用 OAuth

enabled

boolean

是否启用

timeout

number

超时时间(毫秒)

OAuth 配置(McpOAuth)

OAuth 配置有三种使用模式:

  1. 自动发现模式(默认):不提供 oauth 字段或提供空对象 {}。OpenCode 在连接远程 Server 时会自动检测是否需要 OAuth,并尝试动态客户端注册。

  2. 预注册客户端模式:提供 clientId(以及可选的 clientSecret)。适用于已在授权服务器上注册过客户端的场景。

  3. 禁用模式:设置 oauth: false。适用于不需要 OAuth 的远程 Server(如使用 API Key 或无认证的服务)。

源码中的处理逻辑:

Discriminated Union 的类型安全

Mcp 类型是 McpLocalMcpRemote 的可辨识联合:

这意味着 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 —— 文件资源

  • db://users/123 —— 数据库记录

  • 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 注入),远程配置的核心是 urloauth(支持自动发现、预注册和禁用三种模式)。超时时间支持 Server 级、全局级和默认值三层优先级。Resource 模型使用 URI 作为标识符,通过 client 字段关联到具体的 MCP Server。


第 8 章总结

本章从协议概念到源码实现,完整地剖析了 OpenCode 的 MCP 系统。MCP(Model Context Protocol)为 OpenCode 提供了连接外部工具生态的标准化桥梁,其核心价值在于将工具的实现与 AI 应用完全解耦。OpenCode 的 MCP 实现包括四个关键模块:

  1. mcp/index.ts(935 行):MCP 客户端核心,管理连接、状态机和工具转换。

  2. mcp/auth.ts(133 行):OAuth 凭据的安全存储,支持 URL 绑定验证。

  3. mcp/oauth-provider.ts(155 行):实现 MCP SDK 的 OAuth 接口,支持动态客户端注册和 PKCE。

  4. mcp/oauth-callback.ts(201 行):本地 HTTP 回调服务器,带 CSRF 防护和竞态条件处理。

从工程角度看,MCP 模块展示了许多值得学习的设计模式:传输层的降级策略(StreamableHTTP → SSE)、连接状态的五态状态机、OAuth 安全的多层防护(PKCE + State + URL 绑定)、以及先注册回调再打开浏览器的竞态条件处理。这些细节虽然在源码中可能只是几行代码的差异,但它们代表了对安全性和健壮性的深思熟虑,是区分"能用"和"可靠"之间的关键。

Last updated