说起来,最近一段时间AI编程助手确实火得不行。从自动补全到写单元测试,从解释代码到重构逻辑,大模型在软件开发流程里的存在感越来越强。不过,绝大部分这类工具都还停留在“插件”或者“聊天窗口”的形态——用户需要在IDE里点来点去,或者复制粘贴代码片段。有没有一种方式,可以让AI编程能力像真正的服务一样跑在后台,供各种客户端随时调用呢?

OpenCode给出的答案就是它的Server模式。

不是又一个聊天工具,而是一个真正的HTTP服务

很多人在第一次接触OpenCode时,以为它不过是一个跑在终端里的交互式界面(TUI)。确实,运行opencode命令会启动一个漂亮的终端界面,用户可以在里面和AI对话、让它改代码、看文件差异。但这只是OpenCode能力的冰山一角。实际上,每次运行OpenCode的时候,它会在背后悄悄启动一个HTTP服务器。那个TUI本身就是这个服务器的客户端——TUI里打的每一个字、发的每一条指令,都是通过HTTP请求送到服务器去处理的。

这种架构带来的好处很直接:开发者不再被限制在终端里。既然服务器暴露的是标准的HTTP接口,那就意味着任何能发HTTP请求的程序——不管是VS Code插件、浏览器扩展、还是自己写的脚本——都可以成为OpenCode的客户端。

独立运行:让服务不再依赖TUI

前面提到,默认情况下服务器随TUI一起启动。但OpenCode也允许单独把服务器跑起来,不附带任何界面。命令很简单:

opencode serve

执行这条命令后,一个独立的HTTP服务器就在后台开始监听了。默认的端口是4096,默认绑定的地址是127.0.0.1。当然,这些都可以调整:

  • --port 用来指定端口号,比如 --port 8080
  • --hostname 用来指定监听地址,比如 --hostname 0.0.0.0 让外部也能访问
  • --cors 用来设置允许的浏览器来源,可以多次使用这个参数添加多个域名,例如 --cors http://localhost:5173 --cors https://app.example.com
  • --mdns 是一个开关,开启后可以通过mDNS在网络里自动发现服务
  • --mdns-domain 则用来自定义mDNS的服务域名,默认是 opencode.local

安全保护:添加一道简单的密码锁

如果服务器需要暴露在网络上,安全自然是不能忽视的问题。OpenCode提供了一个很直接的方案——HTTP基本认证。只要在启动服务器前设置环境变量 OPENCODE_SERVER_PASSWORD,服务器就会要求客户端提供用户名和密码。用户名默认是 opencode,也可以通过 OPENCODE_SERVER_USERNAME 改成自己喜欢的值。

举个例子:

OPENCODE_SERVER_PASSWORD=my-secret-password opencode serve

这样一来,任何想访问这个服务的客户端都必须携带正确的认证信息。这个机制同时适用于 opencode serveopencode web 两种模式。

幕后原理:一个规范的开API设计

OpenCode的服务器遵循OpenAPI 3.1规范。这意味着它的所有接口都有明确的描述文档,可以方便地生成各种语言的SDK,也可以在Swagger这类工具里直接浏览和测试。

当服务器运行起来后,访问 http://<主机名>:<端口>/doc 就能看到这份规范文档。比如本地运行默认配置时,打开 http://localhost:4096/doc 就能看到一个HTML页面,里面列出了所有可用的端点、请求参数和响应格式。

与现有服务器连接:TUI也可以指定目标

有时候,用户已经有一个OpenCode服务器在跑了(比如通过 opencode serve 单独启动的),希望后面打开的TUI直接连到这个现有服务器,而不是再启动一个新的。这可以通过在启动TUI时指定 --hostname--port 来实现。

另外,服务器上有一个特别的 /tui 端点。这个端点允许外部程序通过服务器去驱动TUI界面——比如预先在输入框里填好一段文字,或者直接提交一个提示词。OpenCode的各种IDE插件正是利用这个机制,把编辑器和AI能力无缝衔接起来的。

细数那些实用的API

整个服务器暴露的API可以分成几个大的类别,每一个都对应着不同的使用场景。

全局与健康检查

最简单的接口是 /global/health,用来检查服务器是否活着,顺便返回版本号。响应内容类似 { healthy: true, version: "..." }。还有一个 /global/event 接口,通过SSE(Server-Sent Events)推送全局事件,适合需要实时监听服务器状态的场景。

项目管理

通过 /project 可以列出当前所有的项目,而 /project/current 则告诉调用方当前正在操作的是哪个项目。对于需要感知上下文的工具来说,这个信息至关重要。

文件系统与版本控制

/path 返回当前的工作路径,/vcs 则提供当前项目下的版本控制信息(比如Git分支、状态等)。

配置与模型提供商

/config 支持GET和PATCH两种方法,分别用来读取和更新配置。而 /config/providers 会列出所有可用的AI模型提供商以及它们对应的默认模型。更进一步,/provider 接口不仅能列出所有提供商,还能获取认证方式、发起OAuth授权流程、处理回调等。这对于需要动态切换模型或者接入私有API密钥的应用来说非常实用。

会话管理

会话是整个OpenCode的核心概念之一。一次对话、一次代码修改任务,通常都对应一个会话。API提供了完整的会话生命周期管理:

  • GET /session 列出所有会话
  • POST /session 创建新会话,创建时可以指定父会话ID和标题
  • GET /session/:id 获取某个会话的详情
  • DELETE /session/:id 删除一个会话及其所有数据
  • PATCH /session/:id 更新会话的标题等属性
  • GET /session/:id/children 获取某个会话的子会话(用于分支对话场景)
  • GET /session/:id/todo 获取会话的任务清单
  • POST /session/:id/fork 从某个消息位置派生出一个新会话
  • POST /session/:id/abort 强制中止正在运行的会话
  • POST /session/:id/share 分享会话,生成可分享的链接;DELETE /session/:id/share 取消分享
  • GET /session/:id/diff 获取会话产生的文件差异,可以指定从哪条消息开始计算
  • POST /session/:id/summarize 让AI总结整个会话的内容
  • POST /session/:id/revert 回退某条消息及其影响,POST /session/:id/unrevert 则用来恢复
  • POST /session/:id/permissions/:permissionID 用于响应权限请求(比如执行某个危险命令前需要用户确认)

消息交互

会话里的具体内容由消息组成。消息的API设计很灵活:

  • GET /session/:id/message 分页列出会话中的所有消息,可以指定limit参数
  • POST /session/:id/message 发送一条消息,然后同步等待AI的完整响应。请求体可以指定模型、代理(agent)、是否不需要回复、是否禁用工具等
  • GET /session/:id/message/:messageID 获取单条消息的详情
  • POST /session/:id/prompt_async 异步发送消息,服务器立即返回204状态码,响应结果通过事件流推送
  • POST /session/:id/command 执行一个斜杠命令(比如 /explain/fix
  • POST /session/:id/shell 直接执行一条shell命令,AI会解释执行结果

文件搜索与操作

OpenCode提供了几个非常好用的文件接口:

  • GET /find?pattern=<模式> 在项目文件中搜索文本,返回匹配的位置和内容片段
  • GET /find/file?query=<搜索词> 按文件名模糊搜索文件和目录,可以限制类型(只搜文件或只搜目录)、指定搜索根目录、限制结果数量
  • GET /find/symbol?query=<符号名> 在工作区中搜索符号(函数名、类名等)
  • GET /file?path=<路径> 列出某个目录下的文件和子目录
  • GET /file/content?path=<文件路径> 读取文件内容
  • GET /file/status 获取被版本控制跟踪的文件的状态

实验性的工具接口

OpenCode还暴露了两个实验性的工具相关接口:/experimental/tool/ids 列出所有可用的工具ID,而 /experimental/tool?provider=<提供商>&model=<模型> 则根据指定的模型返回对应的工具列表及其JSON Schema描述。这对于动态适配不同AI模型的能力很有帮助。

LSP、格式化器和MCP

现代编辑器离不开语言服务器协议(LSP)和代码格式化工具。OpenCode的API允许查询LSP服务器的运行状态(/lsp)、格式化器的状态(/formatter),以及MCP(Model Context Protocol)服务器的状态(/mcp)。更有意思的是,POST /mcp 接口可以在运行时动态添加MCP服务器——只要提供名称和配置即可。

代理与命令

/agent 接口列出所有可用的AI代理(不同的代理可能有不同的系统提示词和能力边界)。/command 则列出所有可执行的斜杠命令,方便客户端做自动补全或功能发现。

日志与TUI控制

调试时,POST /log 允许往OpenCode的日志系统里写入条目,需要指定服务名、日志级别、消息和可选的额外数据。

虽然TUI是一个独立的界面,但服务器也提供了一些控制TUI行为的接口:追加文本到提示框、打开帮助面板、打开会话选择器、切换主题、切换模型、提交当前提示词、清空提示框、执行命令、显示通知浮层等。这些接口让外部的客户端能够以编程方式操纵TUI的行为,实现更深度的集成。

另外还有一套控制请求机制:GET /tui/control/next 会阻塞等待下一个控制请求,然后通过 POST /tui/control/response 来响应。这种设计适合需要双向交互的场景。

认证与事件

/auth/:id 接口用于设置某个认证方式的凭证,请求体必须匹配对应提供商要求的schema。而 /event 则是一个SSE事件流端点,连接后第一个事件是 server.connected,后续会持续推送各种总线事件——比如消息完成、文件变更、权限请求等。

文档

最后当然不能忘了 /doc 本身。它返回一个包含完整OpenAPI规范的HTML页面,既是文档也是调试入口。

一个真实的使用场景

假设有人正在开发一个VS Code插件,希望在用户选中一段代码后,让OpenCode帮忙解释这段代码的逻辑。插件可以这样做:

  1. 检测到OpenCode服务器已经在本地运行(或者通过配置的地址访问)
  2. 先调用 GET /project/current 确认当前项目路径
  3. 调用 POST /session 创建一个新会话
  4. 再调用 POST /session/:id/message,发送一条消息:“请解释一下这段代码:\n\n[选中的代码]\n
  5. 从响应中拿到AI的解释,显示在插件界面中

整个过程不需要打开任何终端窗口,不需要手动复制粘贴。用户甚至不知道背后有一个OpenCode服务器在工作。

小结

OpenCode Server的设计思路其实很纯粹:把AI编程能力接口化、服务化。它不再是一个孤立的工具,而是一个可以嵌入到各种开发工作流中的基础设施。无论是构建一个定制化的AI代码助手,还是在CI流水线里加入自动代码审查步骤,或者只是简单地想用自己喜欢的编辑器来驱动OpenCode,这套HTTP API都提供了足够的可能性。

有兴趣的读者可以自己试试 opencode serve,然后打开浏览器访问 http://localhost:4096/doc,看看那个详细的API文档。也许下一个有趣的集成方案,就是从这次浏览开始的。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐