Skip to main content

SDK

The OpenCode SDK provides a programmatic interface for building custom integrations, plugins, tools, and automation workflows. It is published as an npm package and can be used in Node.js projects to extend or control OpenCode behavior.

Installation

npm install opencode-ai
# or
yarn add opencode-ai
# or
pnpm add opencode-ai

Custom Tools

Custom tools allow you to define project-specific functions that the AI agent can invoke. Tools are registered in your OpenCode configuration and implemented as JavaScript/TypeScript modules.

import { tool } from 'opencode-ai/sdk';

export const weatherTool = tool({
name: 'get_weather',
description: 'Get the current weather for a location',
parameters: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City and state or country'
}
},
required: ['location']
},
execute: async ({ location }) => {
const response = await fetch(
`https://api.weather.example/v1/current?q=${encodeURIComponent(location)}`
);
return response.json();
}
});

Register custom tools in your project configuration:

{
"tool": ["./tools/weather.mjs"]
}

Each tool file should export an array of tool definitions or a single tool definition. Tools receive structured arguments and return results that the agent can interpret.

Plugins

Plugins extend OpenCode with hooks, custom tools, middleware, and lifecycle callbacks. The SDK exports a plugin API for building and publishing plugins.

import { definePlugin } from 'opencode-ai/sdk';

export default definePlugin({
name: 'my-custom-plugin',
version: '1.0.0',
hooks: {
'tool.execute.before': async ({ tool, args }) => {
console.log(`Executing tool: ${tool.name}`, args);
},
'tool.execute.after': async ({ tool, result }) => {
console.log(`Tool ${tool.name} completed`, result);
}
},
tools: [myCustomTool]
});

See the Plugins page for detailed plugin authoring guidance.

Tool Execution Hooks

The SDK exposes lifecycle hooks that fire before and after tool execution. These hooks are useful for logging, auditing, transforming arguments, or modifying results.

{
hooks: {
'tool.execute.before': async ({ tool, args, session }) => {
// Validate or transform arguments before execution
return args;
},
'tool.execute.after': async ({ tool, args, result, session }) => {
// Log results, send telemetry, or transform output
return result;
}
}
}

Hooks can be async and may optionally return modified data. If a before hook throws, the tool execution is aborted.

Session Management API

The SDK provides APIs to manage sessions programmatically, useful for building custom frontends or automation scripts.

import { SessionManager } from 'opencode-ai/sdk';

const manager = new SessionManager();

// Create a new session
const session = await manager.create({
agent: 'build',
model: 'anthropic/claude-sonnet-4'
});

// Send a message
const response = await session.send('Explain how dependency injection works');

// Stream response
for await (const chunk of session.sendStream('Write a React component')) {
process.stdout.write(chunk.text);
}

// List all sessions
const sessions = await manager.list();

// Resume a session
const resumed = await manager.resume(sessionId);

Provider Integration API

Register custom LLM providers through the SDK. This is useful for connecting internal model endpoints or proprietary APIs.

import { defineProvider } from 'opencode-ai/sdk';

export const myProvider = defineProvider({
id: 'my-corp',
name: 'My Corp Models',
models: async () => {
const res = await fetch('https://api.my-corp.example/models');
return res.json();
},
complete: async ({ model, messages, options }) => {
const res = await fetch('https://api.my-corp.example/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${options.apiKey}`
},
body: JSON.stringify({ model, messages, ...options })
});
return res.json();
},
stream: async function* ({ model, messages, options }) {
const res = await fetch('https://api.my-corp.example/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${options.apiKey}`
},
body: JSON.stringify({ model, messages, stream: true, ...options })
});
const reader = res.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
yield JSON.parse(new TextDecoder().decode(value));
}
}
});

Agent Creation API

Define and configure agents programmatically. This is useful for creating specialized assistants that can be invoked from your own application.

import { defineAgent } from 'opencode-ai/sdk';

const codeReviewAgent = defineAgent({
name: 'code-reviewer',
mode: 'plan',
model: 'anthropic/claude-sonnet-4',
system: 'You are a senior engineer reviewing code changes. Focus on security, performance, and maintainability.',
tools: ['read_file', 'search_files', 'run_command'],
temperature: 0.2,
maxSteps: 20
});

// Use the agent programmatically
const review = await codeReviewAgent.run({
task: 'Review the changes in src/components/Button.tsx',
context: { repo: 'my-project', branch: 'feature/button-fix' }
});

SDK Reference

The full SDK is exported from the opencode-ai package:

import {
tool,
definePlugin,
defineProvider,
defineAgent,
SessionManager,
ToolExecutionContext,
HookRegistry,
type Tool,
type Plugin,
type Provider,
type Agent,
type Session,
type Message,
type ToolResult
} from 'opencode-ai/sdk';

Refer to the npm package documentation for the complete API surface and TypeScript type definitions.

Patterns and Best Practices

  • Tool isolation: Each tool should perform a single, well-defined operation. Avoid tools that mix concerns.
  • Error handling: Tools should return structured error objects rather than throwing. This lets the agent decide how to recover.
  • Stateless hooks: Hook handlers should be idempotent and avoid side effects outside of logging or telemetry.
  • Authentication: Use environment variables for secrets. Never hardcode API keys in tool or plugin code.
  • Versioning: Publish plugins and provider integrations with semantic versioning. Document breaking changes clearly.