opencode MCP(Model Context Protocol)配置手册
什么是 MCP
MCP(Model Context Protocol)是一种开放协议,允许外部服务以标准化方式向 LLM 暴露工具(Tool)、提示词(Prompt)和资源(Resource)。opencode 作为 MCP 客户端,可连接任意 MCP 服务器,将其提供的工具直接注入到 LLM 上下文中。
配置位置
MCP 服务器在 opencode.json / opencode.jsonc 的 mcp 字段中配置:
kotlin
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"<服务器名称>": { /* McpLocalConfig 或 McpRemoteConfig */ }
}
}
配置文件查找顺序(项目级优先):
| 优先级 | 路径 |
|---|---|
| 1 | <project>/opencode.json |
| 2 | <project>/opencode.jsonc |
| 3 | <project>/.opencode/opencode.json |
| 4 | <project>/.opencode/opencode.jsonc |
| 5 | ~/.config/opencode/opencode.json(全局) |
服务器类型
opencode 支持两种 MCP 服务器类型:
local --- 本地进程(stdio)
通过子进程 stdin/stdout 通信,适合本地命令行工具。
json
{
"mcp": {
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
"environment": {
"NODE_ENV": "production"
},
"enabled": true,
"timeout": 10000
}
}
}
字段说明:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
type |
"local" |
✓ | --- | 固定值 |
command |
string[] |
✓ | --- | 启动命令及参数,第一个元素为可执行文件 |
environment |
Record<string, string> |
--- | --- | 注入到子进程的额外环境变量(会合并 process.env) |
enabled |
boolean |
--- | true |
设为 false 则跳过启动 |
timeout |
number(ms) |
--- | 30000 |
单次请求超时时间 |
remote --- 远程服务器(HTTP / SSE)
通过 HTTP 协议连接,优先尝试 StreamableHTTP,回退到 SSE。
json
{
"mcp": {
"my-api": {
"type": "remote",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer <token>"
},
"enabled": true,
"timeout": 15000
}
}
}
字段说明:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
type |
"remote" |
✓ | --- | 固定值 |
url |
string |
✓ | --- | MCP 服务器 URL |
headers |
Record<string, string> |
--- | --- | 随每次请求发送的 HTTP 头(如 API Key) |
oauth |
`McpOAuthConfig \ | false` | --- | 自动检测 |
enabled |
boolean |
--- | true |
设为 false 则跳过连接 |
timeout |
number(ms) |
--- | 30000 |
单次请求超时时间 |
OAuth 认证(remote 专属)
远程服务器默认启用 OAuth 自动检测。若服务器返回 401,opencode 会触发 OAuth 流程。
OAuth 配置字段(oauth 对象)
| 字段 | 类型 | 说明 |
|---|---|---|
clientId |
string |
预注册的 OAuth Client ID;不提供时尝试动态注册(RFC 7591) |
clientSecret |
string |
OAuth Client Secret(部分服务器需要) |
scope |
string |
请求的 OAuth scope,空格分隔 |
redirectUri |
string |
回调地址,默认 http://127.0.0.1:19876/mcp/oauth/callback |
禁用 OAuth
json
{
"mcp": {
"my-api": {
"type": "remote",
"url": "https://example.com/mcp",
"oauth": false
}
}
}
OAuth 完整示例
json
{
"mcp": {
"my-oauth-server": {
"type": "remote",
"url": "https://example.com/mcp",
"oauth": {
"clientId": "my-client-id",
"clientSecret": "my-client-secret",
"scope": "read write",
"redirectUri": "http://127.0.0.1:19876/mcp/oauth/callback"
}
}
}
}
禁用已配置的服务器
两种方式均可:
json
// 方式一:在配置对象中设置 enabled: false
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem"],
"enabled": false
}
// 方式二:简化写法(legacy)
"filesystem": { "enabled": false }
全局超时配置
在 experimental 字段中可设置全局 MCP 超时,优先级低于各服务器的 timeout 字段:
json
{
"experimental": {
"mcp_timeout": 30000
}
}
| 配置 | 优先级 |
|---|---|
单个服务器 timeout 字段 |
高 |
experimental.mcp_timeout |
中 |
| 内置默认值(30000ms) | 低 |
CLI 管理命令
ini
# 添加 MCP 服务器(交互式)
opencode mcp add
# 列出所有已配置服务器及状态
opencode mcp list
# OAuth 认证(交互式)
opencode mcp auth [name]
# 查看 OAuth 认证状态列表
opencode mcp auth list
# 登出(清除 OAuth 凭证)
opencode mcp logout [name]
# 调试 OAuth 连接
opencode mcp debug <name>
服务器连接状态
| 状态 | 说明 |
|---|---|
connected |
已成功连接 |
disabled |
enabled: false,跳过启动 |
failed |
连接失败,附带错误信息 |
needs_auth |
需要完成 OAuth 认证(运行 opencode mcp auth <name>) |
needs_client_registration |
服务器不支持动态注册,需在 oauth.clientId 中提供预注册 ID |
工具命名规则
MCP 工具注册到 LLM 时,名称为:
xml
<sanitized_server_name>_<sanitized_tool_name>
其中 sanitize 规则:所有非 [a-zA-Z0-9_-] 字符替换为 _。
例如:服务器名 my-server、工具名 list_files → LLM 看到的工具名为 my_server_list_files。
传输协议优先级(remote 类型)
连接远程服务器时,opencode 按以下顺序尝试:
- StreamableHTTP (
@modelcontextprotocol/sdk/client/streamableHttp) - SSE (
@modelcontextprotocol/sdk/client/sse)
任一方式连接成功即停止。若服务器返回 401,则进入 OAuth 流程,不再尝试其他传输方式。
OAuth Token 存储
OAuth 凭证(access token、refresh token、client info)存储在本地文件系统,路径由 McpAuth 管理(位于 XDG 数据目录)。Token 过期后可通过 opencode mcp auth <name> 重新认证,或 opencode mcp logout <name> 清除。
完整配置示例
kotlin
{
"$schema": "https://opencode.ai/config.json",
"experimental": {
"mcp_timeout": 30000
},
"mcp": {
// 本地 stdio 服务器
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
"environment": {
"NODE_ENV": "production"
},
"timeout": 10000
},
// 本地 opencode 内置服务器
"opencode-tools": {
"type": "local",
"command": ["opencode", "x", "@modelcontextprotocol/server-github"],
"environment": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxx"
}
},
// 远程服务器,使用 API Key 认证
"my-api": {
"type": "remote",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer sk-xxx",
"X-Custom-Header": "value"
},
"oauth": false
},
// 远程服务器,使用 OAuth 动态注册
"oauth-server": {
"type": "remote",
"url": "https://oauth.example.com/mcp"
},
// 远程服务器,使用预注册 OAuth Client
"oauth-server-manual": {
"type": "remote",
"url": "https://secure.example.com/mcp",
"oauth": {
"clientId": "my-client-id",
"clientSecret": "my-secret",
"scope": "tools:read tools:write"
}
},
// 已禁用的服务器
"disabled-server": {
"type": "local",
"command": ["some-mcp-server"],
"enabled": false
}
}
}
MCP 工具注入到 LLM 的完整流程
MCP 服务器本质上是一个工具提供方 。opencode 启动时连接 MCP 服务器、拉取工具列表,每次调用 LLM 时把这些工具和内置工具(bash、read、edit 等)合并在一起发给模型。模型决定调用哪个工具,opencode 把请求转发给 MCP 服务器执行,把结果返回给模型。
vbscript
opencode 启动
└─ 连接每个 MCP Server,拉取工具列表,缓存在内存
用户发消息
└─ 合并工具:内置工具 + 所有 MCP 工具
└─ 连同系统提示、对话历史一起发给 LLM
LLM 响应(决定调用某工具)
└─ opencode 拦截工具调用
├─ 触发 tool.execute.before 插件钩子
├─ 权限确认
├─ 转发给 MCP Server 执行
├─ 触发 tool.execute.after 插件钩子
└─ 将结果写入对话历史
再次调用 LLM(携带工具结果)
└─ LLM 生成最终回复,或继续调用下一个工具
示例 1:工具命名规则
MCP 工具注入 LLM 时,名称改为 服务器名_工具名,非字母数字字符统一替换为 _。
配置两个 MCP 服务器:
perl
{
"mcp": {
"fs": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
},
"my-github": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-github"]
}
}
}
LLM 实际看到的工具列表(内置 + 两个 MCP 服务器):
| 来源 | LLM 看到的工具名 |
|---|---|
| 内置 | bash、read、edit、glob、... |
MCP fs |
fs_read_file、fs_write_file、fs_list_directory、... |
MCP my-github |
my_github_create_issue、my_github_list_prs、... |
LLM 无法区分哪些是内置工具、哪些是 MCP 工具,它只看到一张扁平工具列表。
LLM 实际收到的请求体(Anthropic Claude 格式):
json
"tools": [
{
"name": "bash",
"description": "Run a bash command",
"input_schema": { "type": "object", "properties": { "command": { "type": "string" } } }
},
{
"name": "fs_list_directory",
"description": "List directory contents",
"input_schema": { "type": "object", "properties": { "path": { "type": "string" } } }
},
{
"name": "fs_read_file",
"description": "Read file contents",
"input_schema": { "type": "object", "properties": { "path": { "type": "string" } } }
},
{
"name": "my_github_list_prs",
"description": "List pull requests",
"input_schema": { "type": "object", "properties": { "repo": { "type": "string" } } }
}
]
示例 2:一次完整的工具调用
场景: 用户问"列出 /tmp 目录下的文件"
lua
用户消息
"列出 /tmp 目录下的文件"
│
▼
发给 LLM(携带完整工具列表)
tools: [bash, read, edit, fs_read_file, fs_list_directory, ...]
│
▼
LLM 决策:选择 fs_list_directory
调用参数:{ "path": "/tmp" }
│
▼
opencode 拦截执行
1. 触发插件钩子 tool.execute.before
2. 弹出权限确认(或自动通过)
3. 转发给 MCP filesystem 服务器执行
4. 服务器返回:
content: [{ type: "text", text: "a.txt\nb.txt\nc.log" }]
5. 触发插件钩子 tool.execute.after
6. 写入对话历史(part.type="tool", state.output="a.txt\nb.txt\nc.log")
│
▼
再次发给 LLM(携带工具结果)
│
▼
LLM 最终回复
"/tmp 目录下有 3 个文件:a.txt、b.txt、c.log"
示例 3:多工具协作
场景: 用户问"查 GitHub 上最新的 PR,把标题写入 /tmp/prs.txt"
swift
LLM 第一轮:调用 my_github_list_prs
→ MCP github 服务器返回 PR 列表
→ 结果追加到对话历史
LLM 第二轮:调用 fs_write_file
参数:{ "path": "/tmp/prs.txt", "content": "PR #123: Fix bug\nPR #124: Add feature" }
→ MCP filesystem 服务器写入文件
→ 结果追加到对话历史
LLM 第三轮:生成最终回复
"已将 2 条 PR 标题写入 /tmp/prs.txt"
每一轮的工具结果都会附在下次发给 LLM 的对话历史里,LLM 可以跨工具、跨轮次串联信息。
工具返回结果类型
MCP 服务器返回的内容分三种类型,opencode 均支持:
| 返回类型 | 说明 | LLM 如何使用 |
|---|---|---|
text |
纯文本 | 直接作为工具输出读取 |
image |
base64 图片 | 以图片附件形式附加到消息 |
resource |
文件/二进制资源 | 文本部分直接读取,二进制以附件形式附加 |
工具列表热更新
MCP 服务器可以在运行中主动推送 tools/list_changed 通知。opencode 收到后立即重新拉取工具列表,下一次 LLM 调用自动使用新列表,无需重启。
相关源码位置
| 文件 | 说明 |
|---|---|
packages/opencode/src/config/mcp.ts |
Local / Remote / OAuth 类型定义 |
packages/opencode/src/mcp/index.ts |
MCP 服务:连接、工具注册、OAuth 流程 |
packages/opencode/src/mcp/auth.ts |
OAuth Token 持久化存储 |
packages/opencode/src/mcp/oauth-provider.ts |
OAuth Provider 实现 |
packages/opencode/src/mcp/oauth-callback.ts |
OAuth 回调服务器(本地 HTTP) |
packages/opencode/src/cli/cmd/mcp.ts |
CLI 命令:opencode mcp add/list/auth/logout/debug |