本节摘要:serve 模式是 OpenCode「连接一切」的枢纽——它把内核暴露成一个无头 HTTP 服务器,让别的程序(Web、桌面、第三方客户端、别的 Agent)都能通过 HTTP 调用它。本节讲清 serve 模式:它启动时有哪些配置(端口、主机、CORS、密码),自带哪些「加分项」能力(OpenAPI 文档、WebSocket、服务器推送事件、局域网发现),以及它为什么是「多客户端共用一个内核」的关键。
serve 模式就是把 OpenCode 内核起成一个 HTTP 服务。没有 TUI、没有界面,只有一个监听端口的服务,任何 HTTP 客户端都能调它的 API。
opencode serve │ ▼ 起一个 HTTP 服务(默认 127.0.0.1:某端口) │ ▼ 任何 HTTP 客户端可调 ├─ Web 浏览器(前端页面调它) ├─ 桌面应用(渲染进程调它) ├─ 第三方脚本 └─ 别的 Agent
这是「多客户端共用一个内核」的关键——一个 serve 实例,多个客户端连。OpenWork 的服务端就是基于这个机制托管的(OpenWork 教程第 5 章)。
serve 命令的几个关键配置项:
| 配置 | 默认 | 说明 |
|---|---|---|
port |
0(随机) |
监听端口;0 表示先试 4096,失败用随机空闲端口 |
hostname |
127.0.0.1 |
监听地址;127.0.0.1 只本机,0.0.0.0 全网络 |
cors |
[] |
允许的跨域来源列表 |
mdns |
false |
是否在局域网发布服务(便于发现) |
| 密码 | 可选 | 设了密码才安全;不设会打印「不安全」警告 |
几个值得注意的细节:
0(系统分配)。如果你要固定端口,显式指定。127.0.0.1 意味着只有本机能连。如果你要让局域网别的机器连,要么改 0.0.0.0,要么开 mdns(开了 mdns 会自动改成 0.0.0.0)。⚠️ 最危险的配置:
hostname 0.0.0.0+ 不设密码 + 公网机器 = 灾难。任何人都能用你的内核。要么别暴露到公网,要么设密码。
serve 模式不只是「能调 API」,它自带几个让集成更顺的能力:
服务自动生成 OpenAPI 规范,提供文档端点(如 /doc 或 /openapi.json)。这意味着你可以用任何 OpenAPI 工具(文档查看器、代码生成器、Postman)来探索和调用它的 API。这也是第 13 章「客户端契约 codegen」的基础——客户端是从这份 OpenAPI 规范生成的。
某些实时交互(如嵌入式终端)用 WebSocket。serve 模式支持 WebSocket 升级路由,专门用于终端连接这种需要双向实时通信的场景。
事件订阅用 SSE(text/event-stream),让客户端能实时收到内核发出的事件(如会话进展、工具调用)。这是「实时性」的一种实现——客户端订阅事件流,内核有事件就推。
开了 mdns 后,服务会在局域网发布自己(默认域名类似 opencode.local),局域网内的别的设备能「发现」它,不用记 IP 端口。这对「在团队内共享一个内核实例」很方便。
💡 mdns 自动改主机:开 mdns 后,如果你没显式设 hostname,它会自动改成
0.0.0.0(否则局域网发现不了)。这是个贴心的默认,但也意味着「暴露到网络」——配合密码用。
serve 模式最大的价值是多客户端共用。一个 serve 实例跑着,多个客户端同时连:
一个 serve 实例(内核) ├─◄ Web 浏览器(前端调 API) ├─◄ 桌面应用(渲染进程调 API) └─◄ 第三方脚本
这带来了几种典型用法:
serve 模式和下一节的嵌入式 SDK 都解决「让别的程序用内核」,但方式不同:
| serve 模式 | 嵌入式 SDK | |
|---|---|---|
| 通信方式 | HTTP(网络或本地回环) | 进程内内存调用 |
| 进程关系 | 独立进程 | 同进程 |
| 跨进程/跨机器 | 支持 | 不支持(同进程) |
| 性能 | 有 HTTP 开销 | 几乎零开销 |
跨进程或跨机器用 serve,同进程用 SDK。这是选型原则。下一节详讲 SDK。
0.0.0.0 + 无密码 + 公网 = 灾难,务必设密码。serve 讲完了,下一节讲最巧妙的形态——嵌入式 SDK,它怎么在进程内复用内核。