OpenCode 为它的服务端推出了一个 TypeScript/JavaScript SDK,为开发者提供了一套类型安全、可直接在代码中操控 OpenCode 的编程接口。不管是构建第三方集成,还是想用脚本自动控制 OpenCode 的行为,这套 SDK 都提供了完整的工具链。如果对服务端的运作原理感兴趣,可以去查阅更深入的资料;想找灵感的话,社区里也有一些基于这个 SDK 做的项目可以参考。

下面就来拆解一下这个 SDK 能做什么,以及具体怎么用。

安装

第一步自然是安装。SDK 已经发布在 npm 上,用一行命令就能装好:

npm install @opencode-ai/sdk

创建客户端

SDK 的核心是 createOpencode 函数。调用它时,它会在后台启动一个 OpenCode 服务端,同时返回一个已经连好的客户端实例:

import { createOpencode } from "@opencode-ai/sdk"

const { client } = await createOpencode()

这么做的好处是,开发者不需要手动管理服务端进程,一切都在同一段代码里搞定。

可配置的选项

createOpencode 接受一个可选的配置对象,用来定制服务端的行为。可用的字段包括:

选项 类型 说明 默认值
hostname string 服务端主机名 127.0.0.1
port number 服务端口 4096
signal AbortSignal 用于取消操作的终止信号 undefined
timeout number 等待服务端启动的超时时间(毫秒) 5000
config Config 配置对象,可覆盖项目里的 opencode.json {}

通过 Config 微调

即使项目里已经有了 opencode.json 配置文件,也可以在代码中传入一个 config 字段,对模型等设置进行覆盖或补充。比如,可以把默认模型指定为某个 Claude 版本:

import { createOpencode } from "@opencode-ai/sdk"

const opencode = await createOpencode({
  hostname: "127.0.0.1",
  port: 4096,
  config: {
    model: "anthropic/claude-3-5-sonnet-20241022",
  },
})

console.log(`Server running at ${opencode.server.url}`)

opencode.server.close()

这里返回的 opencode.server 对象上有一个 close() 方法,可以在不需要的时候主动关闭服务端。

只连接客户端(不启动服务端)

如果已经有一个独立运行的 OpenCode 服务端,就不需要再次启动,只需要创建一个客户端连上去就好。SDK 为此提供了 createOpencodeClient 函数:

import { createOpencodeClient } from "@opencode-ai/sdk"

const client = createOpencodeClient({
  baseUrl: "http://localhost:4096",
})

这个函数接受的选项如下:

选项 类型 说明 默认值
baseUrl string 服务端 URL http://localhost:4096
fetch function 自定义 fetch 实现 globalThis.fetch
parseAs string 响应解析方式 auto
responseStyle string 返回风格:data 或 fields fields
throwOnError boolean 是否在出错时抛出异常 false

这样一来,即使服务器是由其他工具或进程启动的,也能轻松地用 SDK 与之交互。

类型定义

SDK 包里包含了所有 API 类型的 TypeScript 定义,直接从服务端的 OpenAPI 规范生成。需要的话,可以这样引入:

import type { Session, Message, Part } from "@opencode-ai/sdk"

所有类型都可以从 types 文件中找到,这让在 TypeScript 项目里使用时有完整的智能提示和编译时检查。

错误处理

SDK 在执行请求时可能会抛出错误,用 try/catch 可以捕获并处理它们:

try {
  await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
  console.error("Failed to get session:", (error as Error).message)
}

结构化输出

SDK 支持一种叫做“结构化输出”的功能:让模型按照预先定义好的 JSON Schema 返回严格校验过的 JSON 数据,而不是自由格式的文本。模型内部会使用一个 StructuredOutput 工具来确保输出符合要求。

基本用法

发送一次带格式要求的提示:

const result = await client.session.prompt({
  path: { id: sessionId },
  body: {
    parts: [{ type: "text", text: "Research Anthropic and provide company info" }],
    format: {
      type: "json_schema",
      schema: {
        type: "object",
        properties: {
          company: { type: "string", description: "Company name" },
          founded: { type: "number", description: "Year founded" },
          products: {
            type: "array",
            items: { type: "string" },
            description: "Main products",
          },
        },
        required: ["company", "founded"],
      },
    },
  },
})

// 从返回结果中取出结构化数据
console.log(result.data.info.structured_output)
// { company: "Anthropic", founded: 2021, products: ["Claude", "Claude API"] }

输出格式的类型

  • text(默认):标准文本响应,不做结构化。
  • json_schema:返回经过校验、符合 Schema 的 JSON。

JSON Schema 模式下需要提供的字段

字段 类型 说明
type ‘json_schema’ 必填,指明使用 JSON Schema 模式
schema object 必填,描述输出结构的 JSON Schema 对象
retryCount number 可选,校验重试次数,默认 2 次

错误处理

如果模型在所有重试后仍然没有产生合法的结构化输出,返回的结果里会包含一个 StructuredOutputError,可以这样检查:

if (result.data.info.error?.name === "StructuredOutputError") {
  console.error("Failed to produce structured output:", result.data.info.error.message)
  console.error("Attempts:", result.data.info.error.retries)
}

使用建议

  • 在 schema 的属性里填写清晰的描述,帮助模型理解该提取什么数据。
  • required 标记哪些字段必须出现。
  • 保持 schema 结构聚焦、不过于复杂,过于嵌套的定义可能让模型难以准确填充。
  • 根据复杂度调整 retryCount,简单结构可以少重试,复杂的可适当增加。

完整的 API 一览

SDK 将服务端的所有接口都包装成了类型安全的方法,按功能模块划分。

Global(全局)

  • global.health() — 检查服务端健康状态和版本号
const health = await client.global.health()
console.log(health.data.version)

App(应用)

  • app.log() — 写一条日志
  • app.agents() — 列出所有可用的代理
await client.app.log({
  body: {
    service: "my-app",
    level: "info",
    message: "Operation completed",
  },
})

const agents = await client.app.agents()

Project(项目)

  • project.list() — 列出所有项目
  • project.current() — 获取当前项目信息
const projects = await client.project.list()
const currentProject = await client.project.current()

Path(路径)

  • path.get() — 获取当前路径信息
const pathInfo = await client.path.get()

Config(配置)

  • config.get() — 获取配置信息
  • config.providers() — 列出所有提供者及其默认模型
const config = await client.config.get()
const { providers, default: defaults } = await client.config.providers()

Sessions(会话)

会话是 SDK 的核心功能,支持完整的生命周期管理:

方法 说明 返回
session.list() 列出所有会话 Session[]
session.get({ path }) 获取单个会话 Session
session.children({ path }) 列出子会话 Session[]
session.create({ body }) 创建新会话 Session
session.delete({ path }) 删除会话 boolean
session.update({ path, body }) 更新会话属性 Session
session.init({ path, body }) 分析应用并生成 AGENTS.md boolean
session.abort({ path }) 中止正在运行的会话 boolean
session.share({ path }) 分享会话 Session
session.unshare({ path }) 取消分享 Session
session.summarize({ path, body }) 对会话进行总结 boolean
session.messages({ path }) 列出会话中的所有消息 { info: Message, parts: Part[]}[]
session.message({ path }) 获取某条消息的详情 { info: Message, parts: Part[]}
session.prompt({ path, body }) 发送提示消息 body.noReply: true,返回 UserMessage(仅注入上下文);否则返回 AssistantMessage。支持 body.outputFormat 做结构化输出
session.command({ path, body }) 向会话发送命令 { info: AssistantMessage, parts: Part[]}
session.shell({ path, body }) 运行一个 shell 命令 AssistantMessage
session.revert({ path, body }) 回退一条消息 Session
session.unrevert({ path }) 恢复已回退的消息 Session
postSessionByIdPermissionsByPermissionId({ path, body }) 响应权限请求 boolean

几个常见的用法示例:

// 创建并管理会话
const session = await client.session.create({
  body: { title: "My session" },
})
const sessions = await client.session.list()

// 发送一个带模型的提示
const result = await client.session.prompt({
  path: { id: session.id },
  body: {
    model: { providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" },
    parts: [{ type: "text", text: "Hello!" }],
  },
})

// 仅注入上下文,不触发 AI 回复(插件场景常用)
await client.session.prompt({
  path: { id: session.id },
  body: {
    noReply: true,
    parts: [{ type: "text", text: "You are a helpful assistant." }],
  },
})

Files(文件)

提供文件搜索和读取能力:

方法 说明 返回
find.text({ query }) 在文件中搜索文本 包含路径、行号、偏移等信息的匹配对象数组
find.files({ query }) 按名称查找文件或目录 路径字符串数组
find.symbols({ query }) 查找工作区符号 Symbol[]
file.read({ query }) 读取文件内容 `{ type: “raw”
file.status({ query? }) 获取被跟踪文件的状态 File[]

其中 find.files 还支持一些可选的查询参数:type"file""directory")、directory(覆盖搜索根目录)、limit(1 到 200)。

// 文本搜索
const textResults = await client.find.text({
  query: { pattern: "function.*opencode" },
})

// 查找 .ts 文件
const files = await client.find.files({
  query: { query: "*.ts", type: "file" },
})

// 查找目录,限制返回数量
const directories = await client.find.files({
  query: { query: "packages", type: "directory", limit: 20 },
})

// 读取文件内容
const content = await client.file.read({
  query: { path: "src/index.ts" },
})

TUI(终端界面控制)

可以直接控制 OpenCode 的终端界面(TUI):

方法 说明
tui.appendPrompt({ body }) 在提示输入框中追加文本
tui.openHelp() 打开帮助对话框
tui.openSessions() 打开会话选择器
tui.openThemes() 打开主题选择器
tui.openModels() 打开模型选择器
tui.submitPrompt() 提交当前提示
tui.clearPrompt() 清空提示输入框
tui.executeCommand({ body }) 执行一个命令
tui.showToast({ body }) 显示一条提示通知

这些方法都返回 boolean,表示操作是否成功。

await client.tui.appendPrompt({
  body: { text: "Add this to prompt" },
})

await client.tui.showToast({
  body: { message: "Task completed", variant: "success" },
})

Auth(认证)

  • auth.set({ ... }) — 设置认证凭据,返回 boolean
await client.auth.set({
  path: { id: "anthropic" },
  body: { type: "api", key: "your-api-key" },
})

Events(事件)

  • event.subscribe() — 订阅服务端发送的实时事件流(Server-Sent Events)。
const events = await client.event.subscribe()
for await (const event of events.stream) {
  console.log("Event:", event.type, event.properties)
}

这样就能在代码里监听 OpenCode 内部发生的各种状态变化。


这套 SDK 把 OpenCode 的所有能力都暴露成了清晰的函数调用,无论是构建自动化脚本、开发插件,还是做更复杂的集成,都能直接在 TypeScript 里享受类型安全带来的便利。只要跟着这份指南动手试一试,就能很快用代码驾驭这个强大的 AI 编程助手了。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐