| name | developing-opencode-meta |
| description | Build OpenCode plugins, agents, hooks, and tools. Use when creating, reviewing, or debugging OpenCode extensions. Covers plugin architecture, agent configuration, lifecycle hooks, custom tools, and distribution. Invoke PROACTIVELY when user mentions OpenCode plugins, agents, hooks, or wants to extend OpenCode functionality. |
1. Plugins are the extension mechanism Everything in OpenCode is extended through plugins. A plugin is a TypeScript function that returns configuration for agents, tools, hooks, and other features. Plugins can be distributed via npm.
2. Agents define AI behaviour
Agents are configured AI assistants with specific prompts, models, and tool access. OpenCode has two modes: primary (main agent) and subagent (delegated tasks). Agent prompts are full TypeScript strings, giving complete control.
3. Hooks intercept lifecycle events Hooks let plugins react to events like tool execution, session creation, context limits, and more. They enable features like auto-compaction, TDD enforcement, and context monitoring.
4. Tools extend agent capabilities Custom tools give agents new abilities. Tools are defined with Zod schemas for parameters and can access the plugin context for session management, file operations, etc.
5. Skills work differently in OpenCode OpenCode can load Claude Code skills, but also has its own skill system. Skills in OpenCode are simpler — markdown files that agents can invoke for domain knowledge.
- Plugin — Create a new plugin with agents, tools, or hooks
- Agent — Define a custom agent with specific behaviour
- Hook — Intercept lifecycle events for custom behaviour
- Tool — Add a new capability for agents to use
- Review — Audit an existing OpenCode plugin
Wait for response before proceeding.
After identifying the intent, read the relevant reference file and follow its guidance.
const MyPlugin: Plugin = async (ctx) => { return { tool: { /* custom tools / }, config: { agents: { / agent definitions / } }, event: async (input) => { / lifecycle events / }, "tool.execute.before": async (input, output) => { / pre-tool hook / }, "tool.execute.after": async (input, output) => { / post-tool hook */ }, } }
export default MyPlugin
**Agent Definition:**
```typescript
import type { AgentConfig } from "@opencode-ai/sdk"
const myAgent: AgentConfig = {
description: "What this agent does (shown in delegation UI)",
mode: "subagent", // or "primary"
model: "anthropic/claude-sonnet-4",
temperature: 0.1,
tools: { write: true, edit: true, bash: true },
prompt: `Full agent prompt here...`,
}
Custom Tool:
import { z } from "zod"
const myTool = {
description: "What this tool does",
parameters: z.object({
input: z.string().describe("Parameter description"),
}),
async execute(params, ctx) {
// Tool logic
return { result: "output" }
},
}
Key Hooks:
event— Session lifecycle (created, deleted, error)tool.execute.before— Modify tool args before executiontool.execute.after— Process tool resultsexperimental.session.compacting— Inject context into summarieschat.message— Intercept user messages
The plugin receives a context object with:
ctx.client— OpenCode client for session operationsctx.directory— Current working directoryctx.client.session.summarize()— Trigger context compaction
Agent Modes
| Mode | Purpose | Use Case |
|---|---|---|
primary |
Main conversation agent | Custom main agent replacing default |
subagent |
Delegated task executor | Specialized agents for specific work |
Tool Access Control
Agents can restrict tool access:
tools: {
write: true, // File writing
edit: true, // File editing
bash: true, // Shell commands
background_task: false, // Prevent sub-subagent spawning
}
Hook Execution Order
chat.message— User input receivedtool.execute.before— Before each tool call- Tool executes
tool.execute.after— After each tool callevent— Session events (async, not blocking)
Distribution
Plugins are distributed via npm:
# Install
bunx my-opencode-plugin install
# This registers in ~/.config/opencode/opencode.json
- Single default export (plugin function)
- No non-plugin exports from main index.ts
- Agents use appropriate mode (primary vs subagent)
- Hooks don't cause infinite loops
- Tools have clear Zod schemas with descriptions
- Distribution via npm with CLI installer