npx skills add https://github.com/hhopkins95/ai-systems --skill 'OpenCode SDK Development'使用 OpenCode SDK 创建自定义工具和插件的指南。
OpenCode 为 SDK 开发提供了两个主要包:
| 包 | 用途 |
|---|---|
@opencode-ai/sdk | 用于与 OpenCode 服务器交互的客户端 SDK(会话、消息、文件) |
@opencode-ai/plugin | 用于创建具有模式验证的自定义工具的插件系统 |
自定义工具扩展了 OpenCode 的功能。工具是从以下位置自动发现的 TypeScript/JavaScript 文件:
.opencode/tool/~/.config/opencode/tool/文件名将成为工具名称。
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "工具功能的简要描述",
args: {
paramName: tool.schema.string().describe("参数描述")
},
async execute(args, context) {
// context 提供:sessionID, messageID, agent, abort
return "返回给 AI 的结果字符串"
}
})
使用 tool.schema(基于 Zod)进行参数验证:
args: {
// 带描述的字符串
query: tool.schema.string().describe("搜索查询"),
// 可选字符串
path: tool.schema.string().optional().describe("文件路径"),
// 带约束的数字
limit: tool.schema.number().min(1).max(100).default(10).describe("最大结果数"),
// 枚举/字面量联合类型
format: tool.schema.enum(["json", "text"]).describe("输出格式"),
// 布尔值
recursive: tool.schema.boolean().default(false).describe("递归搜索")
}
execute 函数接收一个上下文对象:
type ToolContext = {
sessionID: string // 当前会话 ID
messageID: string // 当前消息 ID
agent: string // 当前代理标识符
abort: AbortSignal // 用于取消操作的信号
}
import { tool } from "@opencode-ai/plugin"
import { $ } from "bun"
export default tool({
description: "搜索匹配指定模式的文件",
args: {
pattern: tool.schema.string().describe("要匹配的 Glob 模式"),
directory: tool.schema.string().default(".").describe("要搜索的目录")
},
async execute({ pattern, directory }) {
const result = await $`find ${directory} -name "${pattern}"`.text()
return result || "未找到文件"
}
})
插件提供了更全面的集成,包含事件处理、身份验证和工具修改的钩子。
import type { Plugin } from "@opencode-ai/plugin"
const plugin: Plugin = async (input) => {
const { client, project, directory, worktree, $ } = input
return {
// 自定义工具
tool: {
myTool: tool({ /* 定义 */ })
},
// 事件钩子
event: async ({ event }) => { /* 处理事件 */ },
// 配置钩子
config: async (config) => { /* 修改配置 */ },
// 消息钩子
"chat.message": async (input, output) => { /* 修改消息 */ },
// 工具执行钩子
"tool.execute.before": async (input, output) => { /* 预处理 */ },
"tool.execute.after": async (input, output) => { /* 后处理 */ }
}
}
export default plugin
| 钩子 | 用途 |
|---|---|
event | 处理来自服务器的实时事件 |
config | 加载时修改配置 |
tool | 注册自定义工具 |
auth | 自定义身份验证提供者 |
chat.message | 发送前修改消息 |
chat.params | 修改 LLM 参数(temperature, topP) |
permission.ask |
SDK 客户端提供了对 OpenCode 功能的编程式访问。
import { createOpencode, createOpencodeClient } from "@opencode-ai/sdk"
// 同时创建客户端和服务器
const { client, server } = await createOpencode({
hostname: "127.0.0.1",
port: 4096,
timeout: 5000
})
// 或者仅创建客户端
const client = createOpencodeClient({
baseUrl: "http://127.0.0.1:4096"
})
| 分类 | 方法 |
|---|---|
client.session | list, create, get, delete, prompt, messages, fork, share |
client.project | list, current |
client.file | list, read, status |
client.find | text, files, symbols |
client.tool | ids, list |
client.event | subscribe (SSE 流式传输) |
// 列出会话
const { data: sessions } = await client.session.list()
// 创建会话
const { data: session } = await client.session.create()
// 发送提示
const { data: response } = await client.session.prompt({
path: { id: sessionId },
body: {
parts: [{ type: "text", text: "您的消息内容" }]
}
})
// 获取消息
const { data: messages } = await client.session.messages({
path: { id: sessionId }
})
const result = await client.event.subscribe()
for await (const event of result.events) {
console.log("事件:", event.type, event.data)
}
# 安装 SDK
npm install @opencode-ai/sdk
# 安装插件包(用于工具)
npm install @opencode-ai/plugin
需要 TypeScript >= 4.9。
| 位置 | 范围 |
|---|---|
.opencode/tool/*.ts | 项目特定工具 |
~/.config/opencode/tool/*.ts | 适用于所有项目的全局工具 |
多个导出会创建多个工具:filename_exportname。
context.abortimport { tool } from "@opencode-ai/plugin"
import { $ } from "bun"
export default tool({
description: "运行 Python 分析脚本",
args: {
file: tool.schema.string().describe("要分析的文件")
},
async execute({ file }) {
return await $`python3 analyze.py ${file}`.text()
}
})
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "获取当前会话信息",
args: {},
async execute(args, context) {
return JSON.stringify({
session: context.sessionID,
message: context.messageID,
agent: context.agent
}, null, 2)
}
})
工具未出现:
.opencode/tool/ 或 ~/.config/opencode/tool/模式错误:
.optional()执行错误:
execute 是否返回一个字符串详细的 API 文档:
references/sdk-api.md - 完整的 SDK 客户端 API 参考references/plugin-api.md - 完整的插件钩子和类型examples/ 目录中的工作示例:
examples/basic-tool.ts - 简单的工具实现examples/full-plugin.ts - 包含钩子的完整插件每周安装量
–
代码仓库
首次出现
–
安全审计
Guide for creating custom tools and plugins using the OpenCode SDK.
OpenCode provides two main packages for SDK development:
| Package | Purpose |
|---|---|
@opencode-ai/sdk | Client SDK for interacting with OpenCode server (sessions, messages, files) |
@opencode-ai/plugin | Plugin system for creating custom tools with schema validation |
Custom tools extend OpenCode's capabilities. Tools are TypeScript/JavaScript files auto-discovered from:
.opencode/tool/ in project directory~/.config/opencode/tool/广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 处理权限请求 |
tool.execute.before | 预处理工具参数 |
tool.execute.after | 后处理工具输出 |
client.mcp | status, add |
client.tui | appendPrompt, submitPrompt, showToast |
The filename becomes the tool name.
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "Brief description of what the tool does",
args: {
paramName: tool.schema.string().describe("Parameter description")
},
async execute(args, context) {
// context provides: sessionID, messageID, agent, abort
return "Result string returned to the AI"
}
})
Use tool.schema (which is Zod) for argument validation:
args: {
// String with description
query: tool.schema.string().describe("Search query"),
// Optional string
path: tool.schema.string().optional().describe("File path"),
// Number with constraints
limit: tool.schema.number().min(1).max(100).default(10).describe("Max results"),
// Enum/literal union
format: tool.schema.enum(["json", "text"]).describe("Output format"),
// Boolean
recursive: tool.schema.boolean().default(false).describe("Search recursively")
}
The execute function receives a context object:
type ToolContext = {
sessionID: string // Current session ID
messageID: string // Current message ID
agent: string // Current agent identifier
abort: AbortSignal // Signal for cancellation
}
import { tool } from "@opencode-ai/plugin"
import { $ } from "bun"
export default tool({
description: "Search for files matching a pattern",
args: {
pattern: tool.schema.string().describe("Glob pattern to match"),
directory: tool.schema.string().default(".").describe("Directory to search")
},
async execute({ pattern, directory }) {
const result = await $`find ${directory} -name "${pattern}"`.text()
return result || "No files found"
}
})
Plugins provide more comprehensive integrations with hooks for events, authentication, and tool modification.
import type { Plugin } from "@opencode-ai/plugin"
const plugin: Plugin = async (input) => {
const { client, project, directory, worktree, $ } = input
return {
// Custom tools
tool: {
myTool: tool({ /* definition */ })
},
// Event hooks
event: async ({ event }) => { /* handle events */ },
// Configuration hooks
config: async (config) => { /* modify config */ },
// Message hooks
"chat.message": async (input, output) => { /* modify messages */ },
// Tool execution hooks
"tool.execute.before": async (input, output) => { /* pre-processing */ },
"tool.execute.after": async (input, output) => { /* post-processing */ }
}
}
export default plugin
| Hook | Purpose |
|---|---|
event | Handle real-time events from server |
config | Modify configuration on load |
tool | Register custom tools |
auth | Custom authentication providers |
chat.message | Modify messages before sending |
chat.params | Modify LLM parameters (temperature, topP) |
permission.ask | Handle permission requests |
tool.execute.before | Pre-process tool arguments |
tool.execute.after | Post-process tool output |
The SDK client provides programmatic access to OpenCode functionality.
import { createOpencode, createOpencodeClient } from "@opencode-ai/sdk"
// Create both client and server
const { client, server } = await createOpencode({
hostname: "127.0.0.1",
port: 4096,
timeout: 5000
})
// Or just the client
const client = createOpencodeClient({
baseUrl: "http://127.0.0.1:4096"
})
| Category | Methods |
|---|---|
client.session | list, create, get, delete, prompt, messages, fork, share |
client.project | list, current |
client.file | list, read, status |
client.find | text, files, symbols |
client.tool | ids, list |
client.event | subscribe (SSE streaming) |
client.mcp | status, add |
client.tui | appendPrompt, submitPrompt, showToast |
// List sessions
const { data: sessions } = await client.session.list()
// Create session
const { data: session } = await client.session.create()
// Send prompt
const { data: response } = await client.session.prompt({
path: { id: sessionId },
body: {
parts: [{ type: "text", text: "Your message here" }]
}
})
// Get messages
const { data: messages } = await client.session.messages({
path: { id: sessionId }
})
const result = await client.event.subscribe()
for await (const event of result.events) {
console.log("Event:", event.type, event.data)
}
# Install SDK
npm install @opencode-ai/sdk
# Install plugin package (for tools)
npm install @opencode-ai/plugin
Requires TypeScript >= 4.9.
| Location | Scope |
|---|---|
.opencode/tool/*.ts | Project-specific tools |
~/.config/opencode/tool/*.ts | Global tools for all projects |
Multiple exports create multiple tools: filename_exportname.
context.abort for long-running operationsimport { tool } from "@opencode-ai/plugin"
import { $ } from "bun"
export default tool({
description: "Run Python analysis script",
args: {
file: tool.schema.string().describe("File to analyze")
},
async execute({ file }) {
return await $`python3 analyze.py ${file}`.text()
}
})
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "Get current session info",
args: {},
async execute(args, context) {
return JSON.stringify({
session: context.sessionID,
message: context.messageID,
agent: context.agent
}, null, 2)
}
})
Tool not appearing:
.opencode/tool/ or ~/.config/opencode/tool/Schema errors:
.optional()Execution errors:
execute returns a stringFor detailed API documentation:
references/sdk-api.md - Complete SDK client API referencereferences/plugin-api.md - Full plugin hooks and typesWorking examples in examples/:
examples/basic-tool.ts - Simple tool implementationexamples/full-plugin.ts - Complete plugin with hooksWeekly Installs
–
Repository
First Seen
–
Security Audits
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
147,400 周安装
色彩可访问性指南:WCAG对比度标准、色盲模拟与最佳实践
212 周安装
AgentOps技能转换器 - 一键将技能转换为Codex、Cursor等AI平台格式
212 周安装
Agile Skill Build:快速创建和扩展ace-skills的自动化工具,提升AI技能开发效率
1 周安装
LLM评估工具lm-evaluation-harness使用指南:HuggingFace模型基准测试与性能分析
212 周安装
Agently TriggerFlow 状态与资源管理:runtime_data、flow_data 和运行时资源详解
1 周安装
Agently Tools 工具系统详解:Python 代理工具注册、循环控制与内置工具使用
1 周安装