ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

opencode-cli-mcp MCP 服务说明文档:用 FastAPI 暴露 CLI 能力的 HTTP API 实践

opencode-cli-mcp MCP 服务说明文档:用 FastAPI 暴露 CLI 能力的 HTTP API 实践

1. 先把问题摆清楚:CLI 好用但不好“被调用”

opencode-cli-mcp 这个项目解决的是一个很具体的痛点:opencode CLI 本身能力不错,能跑 agent、能管会话、能查提供商状态,但它是个命令行工具,你只能在终端里敲。一旦你想让别的程序、别的客户端、甚至一个网页仪表板去调用它,就卡住了——CLI 没有天然的 HTTP 入口,MCP 客户端又只认标准协议。

所以这个项目的定位是“桥”:把 opencode CLI 的 HTTP API 封装成 MCP 工具,同时用 FastAPI 做一层后端桥接,再配一个 Web 仪表板做能力内省。架构上分三段,客户端(MCP hosts)连 opencode-cli-mcp(基于 FastMCP 3.2),它再通过 HTTP 打到本机的opencode serve(默认 4096 端口)。端口分配也很清晰:前端 Vite 跑 10950,后端 FastAPI 跑 10951,opencode serve 占 4096。

适合谁?三类人最对口。第一类是想通过 MCP 协议调用 opencode CLI 功能的开发者,比如你在 Claude Code、Cline 这类 MCP 兼容客户端里想直接触发 agent 运行。第二类是要管理 AI 代理会话和工作流的团队,需要列出会话、导出记录、给运行中的会话发消息。第三类是打算把 opencode 集成进自有系统、或者监控代理集群健康状态的人。

我试过把这套东西接到统一 Key 通道上跑,最大的感受是:桥接层本身不难,难的是配置项对不上、端口打架、以及 MCP 客户端那边 Base URL 和 Key 填错导致的 401。这篇就按“能跟做”的路子写,从环境准备到配置片段到验证请求,把调用链路完整跑通。核心检索词先记住:opencode-cli-mcp 是一个把 CLI 能力封装为 MCP 工具和 HTTP API 的桥接服务,FastAPI 负责后端桥接,MCP 负责协议暴露。

2. 前置准备:TaoToken 统一 Key 与 opencode 环境

在动 FastAPI 之前,先把两件事办妥:opencode CLI 装好,统一 Key 通道配好。很多人一上来就 clone 仓库跑uv sync,结果opencode serve起不来,报找不到命令,就是因为 CLI 没装。

opencode CLI 的安装很直接,Node 18+ 环境下:

npm i -g opencode-ai opencode --version

能打印版本号就说明 CLI 就位。接着是 Python 侧,项目要求 Python 3.12+ 配 uv,uv 现在基本是 Python 项目管理的标配,装完uv sync会自动拉依赖。

然后是 Key 通道。opencode-cli-mcp 本身不绑定某一家模型服务,它通过 opencode 的提供商配置去调 LLM。这里我建议用 TaoToken 的统一 Key 通道,好处是一个 Key 走多家模型,省得在 opencode 里配一堆 provider。你可以在模型对话页先确认要用的模型 ID,再去 API Keys 页面生成 Key。地址分别是:

  • 模型对话(确认模型 ID):https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model_chat
  • API Keys(生成 Key):https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api_keys

生成 Key 后,opencode 侧的配置要写清楚三件套:Base URL、Key、Model ID。Base URL 用https://taotoken.net/api(注意这个不带 UTM,是纯 API 端点)。opencode 的提供商配置一般放在用户配置目录下,形如~/.config/opencode/opencode.json(Windows 在%USERPROFILE%\.config\opencode\)。一个可用的片段长这样:

{ "provider": { "taotoken": { "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "https://taotoken.net/api", "apiKey": "sk-你的Key" }, "models": { "gpt-4o-mini": {} } } } }

这里有个坑要提前说:baseURL末尾不要多加/v1,TaoToken 的 API 端点已经带了版本路径语义,多写一层会导致 404。Model ID 必须和模型对话页里列出的完全一致,大小写、连字符都不能错,否则 opencode 启动时会报 provider 初始化失败。

环境就绪的判断标准是:opencode serve能单独起来并监听 4096。你可以先手动跑一下:

opencode serve --port 4096

看到监听日志后再 Ctrl+C,说明 CLI 和 provider 配置都没问题。这一步别省,后面 FastAPI 桥接报的很多错,根子都在这里。

3. 可复制配置:FastAPI 桥接与 MCP 服务片段

这一节是重点,给出能直接抄的配置。先把仓库拉下来:

git clone <repository> cd opencode-cli-mcp uv sync

项目结构里,opencode_cli_mcp/server.py是 MCP server(stdio 传输),api/main.py是 FastAPI 后端(10951),web_sota是前端。启动方式有两种,一键脚本.\start.ps1(PowerShell 环境),或者分开跑:

uv run -m opencode_cli_mcp.server uv run -m api.main cd web_sota && npm run dev

分开跑的好处是排障时能看清是哪一层挂了。MCP server 走 stdio,不占端口;FastAPI 占 10951;前端占 10950。

接下来是 MCP 客户端侧的配置。如果你用的是 Claude Code 这类支持 MCP 的客户端,需要在它的 MCP 配置文件里登记这个 server。以 Claude Code 的settings.json风格为例,片段如下:

{ "mcpServers": { "opencode-cli-mcp": { "command": "uv", "args": [ "--directory", "/绝对路径/opencode-cli-mcp", "run", "-m", "opencode_cli_mcp.server" ], "env": { "OPENCODE_BASE_URL": "http://127.0.0.1:4096", "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "sk-你的Key" } } } }

三件套在这里的体现:TAOTOKEN_BASE_URL是 Base URL,TAOTOKEN_API_KEY是 Key,Model ID 则在 opencode 的 provider 配置里指定(上一节的models字段)。MCP 客户端本身不直接认 Model ID,它只负责把工具调用转发给 MCP server,真正选模型的是 opencode。

如果你用的是 Cline 的 MCP 配置,格式类似但字段名略有差异,核心还是 command + args + env 三块。Codex 那边如果是auth.json风格,则要把 Key 写进认证文件,Base URL 写进 provider 配置,Model ID 写进请求参数——这三件套缺一个就会在调用时报认证失败或模型不存在。

FastAPI 后端这边,api/main.py默认读环境变量,你也可以在项目根目录放一个.env:

OPENCODE_BASE_URL=http://127.0.0.1:4096 API_PORT=10951 TAOTOKEN_BASE_URL=https://taotoken.net/api TAOTOKEN_API_KEY=sk-你的Key

注意OPENCODE_BASE_URL指向的是本机opencode serve,不是 TaoToken。这两个 URL 别搞混:一个是 CLI 桥接目标,一个是模型服务端点。踩过的坑里,有一半是把这两个填反了,结果 FastAPI 起来后所有工具调用都超时。

配置写完后,启动顺序建议是:先opencode serve,再 FastAPI 后端,最后 MCP server 或前端。顺序反了会出现后端连不上 4096 的报错。

4. 验证请求:从健康检查到跑通一次 agent

配置对不对,靠请求验证。第一步先打 FastAPI 的健康检查,确认后端活着:

curl -s http://127.0.0.1:10951/health

正常返回类似{"status":"ok"}。如果连不上,说明api.main没起来或者端口被占,先lsof -i :10951查一下。

第二步验证 opencode serve 可达。FastAPI 有个能力内省接口,会去探 4096:

curl -s http://127.0.0.1:10951/api/opencode/status

返回里应该能看到 opencode 的版本和运行状态。这一步失败,八成是opencode serve没起或者OPENCODE_BASE_URL写错。

第三步,跑一次真正的 agent 调用。MCP 工具名是opencode_run_agent,通过 FastAPI 桥接时对应的 HTTP 路径大致是:

curl -s -X POST http://127.0.0.1:10951/api/opencode/run-agent \ -H "Content-Type: application/json" \ -d '{ "prompt": "用一句话解释什么是 MCP 协议", "model": "gpt-4o-mini" }'

成功的话返回里会有 agent 的输出文本和会话 ID。拿到会话 ID 后,可以接着验证会话管理链路:

curl -s http://127.0.0.1:10951/api/opencode/sessions curl -s http://127.0.0.1:10951/api/opencode/sessions/<session_id>/messages

前者列出活动会话,后者拉取该会话的消息记录。再试导出:

curl -s http://127.0.0.1:10951/api/opencode/sessions/<session_id>/export

返回 JSON 就是完整会话。这一串下来,opencode_run_agent、opencode_list_sessions、opencode_get_messages、opencode_export_session四个核心工具就都验证过了。

如果你是在 MCP 客户端里验证,直接在对话里让客户端调用opencode_server_status,能返回健康状态就说明 stdio 链路通了。再让它调opencode_list_providers,返回里应该能看到你在 opencode 里配的taotoken提供商。这一步很关键——它证明 MCP server 读到了 opencode 的 provider 配置,Model ID 也在其中。

实测下来,最容易出问题的是 agent 调用那一步。如果返回里choices字段为空或者报模型不存在,回去核对 Model ID 是否和模型对话页一致;如果报 401,核对TAOTOKEN_API_KEY有没有多余空格、是不是复制时截断了。

5. 常见报错排查:401、proxy failed、choices 为空

排障这节按真实报错来对。第一个高频错误是 401:

Error: 401 Unauthorized - invalid api key

原因基本三种:Key 复制时带了换行或空格、Key 已失效、或者 Base URL 填成了带 UTM 的页面地址而不是https://taotoken.net/api。排查方法是用 curl 直接打模型端点:

curl -s https://taotoken.net/api/v1/models \ -H "Authorization: Bearer sk-你的Key"

能列出模型说明 Key 和 Base URL 都对,问题就在 opencode 或 MCP 配置的传递环节。注意Authorization头的Bearer后面是一个空格,别漏。

第二个错误是本地代理失败:

local proxy failed: connect ECONNREFUSED 127.0.0.1:4096

这是 FastAPI 或 MCP server 连不上opencode serve。先确认 4096 在监听:lsof -i :4096或netstat -ano | findstr 4096。没监听就手动起opencode serve --port 4096。如果监听正常还报这个,检查OPENCODE_BASE_URL是不是写成了localhost而服务只绑了127.0.0.1,两者在某些系统上不等价,统一用127.0.0.1最稳。

第三个错误是返回结构里choices读不到:

TypeError: Cannot read properties of undefined (reading 'choices')

这通常发生在 agent 调用返回了错误对象而不是标准响应时。根因多半是上游模型服务返回了非 200,但桥接层没做错误透传,直接把 body 当成功响应解析。排查时先看原始返回:

curl -s -X POST http://127.0.0.1:10951/api/opencode/run-agent \ -H "Content-Type: application/json" \ -d '{"prompt":"test","model":"gpt-4o-mini"}' | jq .

如果 body 里有error字段,按 error 内容去查——模型不存在就改 Model ID,配额问题就看 Key 的额度。桥接层这层建议在api/main.py里加一段判断:响应状态非 200 时直接抛带 body 的异常,别往下走解析。

第四个是 OAuth 相关报错,出现在某些 MCP 客户端首次连接时:

OAuth callback failed: redirect_uri mismatch

opencode-cli-mcp 走的是 stdio 传输,本身不涉及 OAuth,这个错一般来自客户端侧的认证流程配置。检查客户端的回调地址是否和它自己文档里要求的一致,别手动改端口。stdio 模式下不需要额外开回调端口,如果你看到这个错,先确认客户端是不是误配成了 HTTP 传输模式。

第五个是端口冲突,10950/10951/4096 任一被占都会导致启动失败。统一用lsof -i :端口定位,杀掉占用进程再起。前端 10950 被占时 Vite 会自动换端口,但后端不会,所以后端冲突要手动处理。

把这些错误对照表贴在这,方便你快速定位:

报错关键词大概率原因首查项
401 UnauthorizedKey 错误或 Base URL 错Key 空格、URL 是否/api
ECONNREFUSED 4096opencode serve 未起4096 监听状态
reading 'choices'上游返回错误被当成功原始 body 的 error 字段
OAuth redirect_uri客户端传输模式配错是否误用 HTTP 模式
端口占用10950/10951/4096 冲突lsof 定位进程

6. 把链路固定下来:接入文档与长期编码方案

跑通一次不算完,要把这套链路固定成日常可用的形态。我的做法是分两条线:一条是接入文档沉淀,一条是长期编码场景的方案选型。

接入文档这条线,重点是把三件套写死在文档里,别靠记忆。Base URL 统一https://taotoken.net/api,Key 走环境变量不写进代码,Model ID 单独列一张表跟模型对话页同步。文档入口在这:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc 。把 opencode 的 provider 片段、MCP 客户端的 settings 片段、FastAPI 的.env片段三份都贴进去,新人照着抄就能起。

长期编码和 Agent 场景,如果调用量大、需要稳定配额和更完整的模型覆盖,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding_plan 。它适合把 opencode-cli-mcp 这种桥接服务长期挂在后台、持续跑 agent 会话的用法,比按次调 API 更好做成本预估。

还有一个实操细节:MCP server 走 stdio,意味着它和客户端是父子进程关系,客户端退出 server 就没了。如果你想让 FastAPI 后端常驻、MCP 按需拉起,就把两者分开部署——FastAPI 用 systemd 或 pm2 常驻,MCP server 交给客户端管理生命周期。这样前端仪表板随时能看状态,MCP 调用也不受客户端重启影响。

最后留一个我常用的自检脚本,每次改完配置跑一遍,三秒定位问题在哪层:

#!/usr/bin/env bash set -e echo "1. opencode serve:"; curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:4096/health || true echo "2. FastAPI:"; curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:10951/health || true echo "3. TaoToken Key:"; curl -s -o /dev/null -w "%{http_code}\n" https://taotoken.net/api/v1/models -H "Authorization: Bearer $TAOTOKEN_API_KEY" || true

三个 200 就说明链路全通,哪个不是 200 就回对应小节查。这套流程跑顺之后,opencode-cli-mcp 的调用链路基本不会再给你添乱。

返回列表