OpenCode LSP 与 ACP 文档
LSP — 语言服务器协议
是什么
LSP(Language Server Protocol)是 OpenCode 与各编程语言的语言服务器之间的集成层。启用后,AI 在读写代码时能获取真实的语言信息:
- 诊断:语法错误、类型错误、lint 警告
- 悬停信息:类型签名、文档注释
- 定义跳转:找到符号定义位置
- 引用查找:找到所有引用位置
- 符号导航:文档级 / 工作区级符号列表
- 调用层次:函数的调用者与被调用者
AI 在编辑文件后会自动收集诊断信息,并在下一轮对话中将错误作为上下文反馈给自己,实现"写代码 → 看报错 → 修复"的闭环。
LSP 配置
在项目根目录的 opencode.json 中配置:
全局开关
{ "lsp": true } // 启用所有内置语言服务器(默认)
{ "lsp": false } // 完全禁用 LSP
精细配置
{
"lsp": {
"<服务器ID>": {
"command": ["可执行文件", "参数..."],
"extensions": [".ts", ".tsx"],
"disabled": false,
"env": { "环境变量": "值" },
"initialization": { "LSP初始化选项": "值" }
}
}
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
command | string[] | 自定义服务器必填 | 启动命令,如 ["typescript-language-server", "--stdio"] |
extensions | string[] | 自定义服务器必填 | 触发该服务器的文件扩展名 |
disabled | boolean | 否 | 设为 true 禁用此服务器(不删除配置) |
env | Record<string, string> | 否 | 注入到服务器进程的环境变量 |
initialization | Record<string, any> | 否 | LSP initializationOptions,传给服务器的初始化参数 |
注意: 内置服务器(如
typescript、pyright)不需要填extensions,已预配置。自定义服务器必须填写extensions。
配置示例
{
"lsp": {
"typescript": {
"initialization": {
"preferences": {
"importModuleSpecifier": "relative"
}
}
},
"pyright": {
"disabled": true
},
"my-custom-lsp": {
"command": ["my-lsp-server", "--stdio"],
"extensions": [".myext"],
"env": { "LSP_LOG": "debug" }
}
}
}
内置语言服务器
OpenCode 内置 50+ 语言服务器,按语言/生态分类:
主流语言
| 服务器 ID | 语言 | 文件扩展名 | 根目录检测文件 |
|---|---|---|---|
typescript | TypeScript / JavaScript | .ts .tsx .js .jsx .mjs .cjs | package-lock.json bun.lockb yarn.lock |
deno | Deno | .ts .tsx .js .jsx | deno.json deno.jsonc |
pyright | Python | .py .pyi | pyproject.toml requirements.txt Pipfile |
ty | Python(实验性) | .py .pyi | pyproject.toml ty.toml |
gopls | Go | .go | go.mod go.sum go.work |
rust-analyzer | Rust | .rs | Cargo.toml Cargo.lock |
clangd | C / C++ | .c .cpp .cc .h .hpp | compile_commands.json |
jdtls | Java | .java | pom.xml build.gradle |
kotlin-ls | Kotlin | .kt .kts | build.gradle.kts pom.xml |
csharp | C# | .cs .csx | .sln .csproj global.json |
ruby-lsp | Ruby | .rb .rake .gemspec | Gemfile |
swift / sourcekit-lsp | Swift | .swift | Package.swift |
dart | Dart | .dart | pubspec.yaml |
前端框架
| 服务器 ID | 语言/框架 | 文件扩展名 |
|---|---|---|
vue | Vue | .vue |
svelte | Svelte | .svelte |
astro | Astro | .astro |
biome | HTML / CSS / JSON | .ts .tsx .js .json .css .html |
eslint | ESLint | .ts .tsx .js .jsx .vue |
oxlint | Oxlint | .ts .tsx .js .json .astro |
其他语言
| 服务器 ID | 语言 |
|---|---|
php-intelephense | PHP |
prisma | Prisma Schema |
yaml-ls | YAML |
lua-ls | Lua |
bash | Bash / Shell |
terraform | Terraform |
texlab | LaTeX |
dockerfile | Dockerfile |
gleam | Gleam |
clojure-lsp | Clojure |
nixd | Nix |
tinymist | Typst |
haskell-language-server | Haskell |
julials | Julia |
elixir-ls | Elixir |
zls | Zig |
ocaml-lsp | OCaml |
运行时工作原理
文件被 AI 读写
│
▼
lsp.touchFile(filePath)
│
▼
按扩展名找到匹配的服务器
│
▼
(首次访问)在项目根目录启动服务器进程
│
▼
发送 textDocument/didOpen 或 didChange
│
├─ 等待推送诊断(textDocument/publishDiagnostics)
└─ 或主动拉取诊断(textDocument/diagnostic)
│
▼
返回合并、去重后的诊断信息
│
▼
AI 将错误作为上下文,决定是否修复
关键行为:
- 服务器进程懒启动:首次访问该类型文件时才启动,不提前占用资源
- 同一根目录下同一语言的服务器只启动一个进程,多个文件共享
- 诊断更新有 150ms 防抖,避免频繁触发
- 等待诊断超时:文档级 5 秒,工作区级 10 秒
诊断信息收集
诊断数据由所有活跃服务器合并,去除重复项(相同代码 + 级别 + 消息 + 位置视为重复)。
诊断级别:
| 级别 | 说明 |
|---|---|
error | 编译/类型错误 |
warning | 潜在问题、不推荐用法 |
information | 提示信息 |
hint | 优化建议 |
自动安装: 部分服务器首次使用时会自动下载安装(如 gopls、pyright、clangd)。若不希望自动安装,设置环境变量:
export OPENCODE_DISABLE_LSP_DOWNLOAD=1
ACP — Agent 通信协议
ACP 是什么
ACP(Agent Client Protocol)是一个标准化的 Agent 通信协议(agentclientprotocol.com/),基于 JSON-RPC 规范,允许 IDE、工具或其他客户端与 OpenCode 的 AI 能力进行程序化交互。
简单理解: 如果说 MCP 是"给 AI 提供工具",那 ACP 就是"给外部客户端提供 AI"。外部程序通过 ACP 协议向 OpenCode 发起对话请求,获取 AI 响应。
典型场景:
- IDE(如 Zed)通过 ACP 将 OpenCode 作为 AI 后端
- CI/CD 系统通过 ACP 自动化代码审查
- 自定义工具通过 ACP 调用 OpenCode 的 Agent 能力
启动方式
# 在当前目录启动 ACP 服务器(JSON-RPC over stdio)
opencode acp
# 指定工作目录
opencode acp --cwd /path/to/project
ACP 服务器通过**标准输入输出(stdio)**通信,遵循 JSON-RPC 2.0 协议。客户端启动 OpenCode 进程后,直接向其 stdin 写入请求,从 stdout 读取响应。
协议能力
OpenCode ACP 服务器声明的能力:
{
"protocolVersion": 1,
"agentCapabilities": {
"loadSession": true,
"mcpCapabilities": { "http": true, "sse": true },
"promptCapabilities": { "embeddedContext": true, "image": true },
"sessionCapabilities": { "fork": {}, "list": {}, "resume": {} }
}
}
支持的方法
初始化
| 方法 | 说明 |
|---|---|
initialize | 握手,返回协议版本和能力声明 |
会话管理
| 方法 | 说明 |
|---|---|
newSession | 创建新会话,可携带 MCP 服务器配置 |
loadSession | 加载已有会话,重放历史消息 |
listSessions | 列出所有会话(按时间戳分页) |
unstable_forkSession | 从当前会话创建分支 |
unstable_resumeSession | 恢复暂停的会话 |
对话
| 方法 | 说明 |
|---|---|
prompt | 发送用户消息,获取 AI 响应 |
cancel | 取消正在执行的响应 |
配置
| 方法 | 说明 |
|---|---|
unstable_setSessionModel | 切换模型(如 anthropic/claude-3-opus) |
setSessionMode | 切换 Agent 模式(plan / build / general 等) |
setSessionConfigOption | 通用配置项更改 |
会话管理
会话状态
每个 ACP 会话维护以下状态:
{
"id": "会话唯一 ID",
"cwd": "/path/to/project",
"mcpServers": [],
"createdAt": "2024-01-01T00:00:00Z",
"model": {
"providerID": "anthropic",
"modelID": "claude-3-7-sonnet"
},
"modeId": "build"
}
创建会话时配置 MCP 服务器
新建会话时可以附带 MCP 服务器配置:
远程 MCP:
{
"type": "remote",
"url": "https://my-mcp-server.com/sse",
"headers": { "Authorization": "Bearer TOKEN" }
}
本地 MCP:
{
"type": "local",
"command": ["node", "/path/to/mcp-server.js"],
"environment": { "API_KEY": "value" }
}
prompt 支持的内容块类型
发送消息时支持多种内容类型:
| 类型 | 说明 |
|---|---|
text | 纯文本 |
image | Base64 编码图片(含 MIME 类型) |
resource_link | 文件路径或 URI |
resource | 嵌入式资源(文本或二进制) |
工具调用上报
AI 执行工具时,ACP 服务器将工具状态实时推送给客户端:
| 工具类型 | ACP Kind | 典型工具 |
|---|---|---|
| 命令执行 | execute | bash |
| 文件修改 | edit | edit patch write |
| 文件读取 | read | read |
| 代码搜索 | search | grep glob |
| HTTP 请求 | fetch | webfetch |
| 其他 | other | — |
工具进度:pending → in_progress → completed / error
Token 用量追踪
每次 prompt 完成后,ACP 服务器返回 token 用量:
{
"used": 12500,
"size": 200000,
"cost": { "amount": 0.0375, "currency": "USD" }
}
集成示例
JetBrains 系列 IDE
适用于所有 JetBrains 产品:IntelliJ IDEA、PyCharm、WebStorm、GoLand、Rider、CLion、DataGrip、RubyMine 等。
前提条件:
- JetBrains AI Assistant 插件已安装并激活(需要 JetBrains AI 订阅)
- OpenCode 已安装
第一步:找到 opencode 的绝对路径
JetBrains 的 acp.json 要求填写绝对路径,不支持依赖 $PATH。
which opencode
# 示例输出:/usr/local/bin/opencode
# 或:/opt/homebrew/bin/opencode(macOS Homebrew)
# 或:/home/yourname/.local/bin/opencode(Linux)
第二步:找到 acp.json 配置文件位置
acp.json 位于 JetBrains IDE 的配置目录,按操作系统和产品不同而不同:
| 操作系统 | 路径 |
|---|---|
| macOS | ~/Library/Application Support/JetBrains/<Product><Version>/acp.json |
| Linux | ~/.config/JetBrains/<Product><Version>/acp.json |
| Windows | %APPDATA%\JetBrains<Product><Version>\acp.json |
<Product><Version> 示例:IntelliJIdea2025.1、PyCharm2025.1、WebStorm2025.1、GoLand2025.1
也可以在 IDE 内直接打开:Settings → Tools → AI Assistant → Agent Servers → Open acp.json
第三步:编辑 acp.json
{
"agent_servers": {
"OpenCode": {
"command": "/usr/local/bin/opencode",
"args": ["acp"]
}
}
}
将 command 替换为第一步得到的实际绝对路径。
第四步:在 IDE 中使用
- 打开 AI Assistant 面板(右侧工具栏或菜单 View → Tool Windows → AI Assistant)
- 在聊天面板顶部找到 Agent 选择器(下拉菜单)
- 选择 OpenCode
- 开始对话,OpenCode 会在当前项目目录下启动
常见问题:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| Agent 列表中没有 OpenCode | acp.json 路径或格式错误 | 检查 JSON 格式,重启 IDE |
| 启动失败 | command 使用了相对路径或别名 | 必须使用 which opencode 得到的绝对路径 |
| 无法连接 | OpenCode 未登录 | 终端执行 opencode auth login |
| 功能异常 | AI Assistant 插件版本过旧 | 更新至最新版插件 |
指定工作目录(可选):
默认使用 IDE 当前打开的项目目录。若需要固定工作目录:
{
"agent_servers": {
"OpenCode": {
"command": "/usr/local/bin/opencode",
"args": ["acp", "--cwd", "/path/to/your/project"]
}
}
}
Zed 编辑器
在 ~/.config/zed/settings.json 中添加:
{
"agent_servers": {
"OpenCode": {
"command": "opencode",
"args": ["acp"]
}
}
}
通过命令面板执行 agent: new thread 打开对话。也可在 keymap.json 中绑定快捷键:
[ { "bindings": { "cmd-alt-o": [ "agent::NewExternalAgentThread", { "agent": { "custom": { "name": "OpenCode", "command": { "command": "opencode", "args": ["acp"] }
}
}
}
]
}
}
]
自定义客户端(伪代码)
import { ACPClient } from "@agentclientprotocol/sdk"
// 启动 opencode acp 子进程
const client = new ACPClient({ command: "opencode", args: ["acp"] })
// 初始化握手
await client.initialize()
// 创建会话
const { sessionId } = await client.newSession({ cwd: process.cwd() })
// 发送消息
const response = await client.prompt({
sessionId,
content: [{ type: "text", text: "帮我审查这段代码" }]
})
console.log(response.content)
源码位置
LSP
| 功能 | 文件 |
|---|---|
| 配置 Schema | packages/opencode/src/config/lsp.ts |
| 主服务(核心逻辑) | packages/opencode/src/lsp/lsp.ts |
| 客户端实现 | packages/opencode/src/lsp/client.ts |
| 内置服务器定义(50+) | packages/opencode/src/lsp/server.ts |
| 诊断工具函数 | packages/opencode/src/lsp/diagnostic.ts |
| 语言 ID 映射(120+) | packages/opencode/src/lsp/language.ts |
ACP
| 功能 | 文件 |
|---|---|
| Agent 实现(核心) | packages/opencode/src/acp/agent.ts |
| 会话状态管理 | packages/opencode/src/acp/session.ts |
| 类型定义 | packages/opencode/src/acp/types.ts |
| 服务器入口 | packages/opencode/src/acp/server.ts |