Skip to content
create-opencode-plugin logo

Creating OpenCode Plugins

create-opencode-plugin

Create OpenCode plugins using the @opencode-ai/plugin SDK. Use for building custom tools, event hooks, auth providers, or tool execution interception. Use proactively when developing new plugins in .opencode/plugin/ or ~/.config/opencode/plugin/. Examples: - user: "Create a plugin to block dangerous commands" → implement tool execution before hook with blocking logic - user: "Add a custom tool for jira" → design tool schema and implementation using SDK context - user: "Show toast on file edit" → react to file edit events and display status message - user: "Build a custom auth provider" → implement auth flow for new model provider - user: "Intercept git commits" → add hook to validate commit messages before execution

SKILL.md

Full skill instructions

Creating OpenCode Plugins

<critical> Re-read this file periodically during plugin development to refresh context and ensure you're following the correct procedure. </​critical> <workflow>

Procedure Overview

StepActionRead
1Verify SDK referenceRun extract script
2Validate feasibilityThis file
3Design pluginreferences/​hooks.md, references/​hook-patterns.md, references/​CODING-TS.MD
4Implementreferences/​tool-helper.md (if custom tools)
5Add UI feedbackreferences/​toast-notifications.md, references/​ui-feedback.md (if needed)
6Testreferences/​testing.md
7Publishreferences/​publishing.md, references/​update-notifications.md (if npm)

Step 1: Verify SDK Reference (REQUIRED)

Before creating any plugin, MUST regenerate the API reference to ensure accuracy:

bun run .opencode/​skill/​create-opencode-plugin/​scripts/​extract-plugin-api.ts

This generates:

  • references/​hooks.md - All available hooks and signatures
  • references/​events.md - All event types and properties
  • references/​tool-helper.md - Tool creation patterns

Step 2: Validate Feasibility (REQUIRED)

MUST determine if the user's concept is achievable with available hooks.

Feasible as plugins:

  • Intercepting/​blocking tool calls
  • Reacting to events (file edits, session completion, etc.)
  • Adding custom tools for the LLM
  • Modifying LLM parameters (temperature, etc.)
  • Custom auth flows for providers
  • Customizing session compaction
  • Displaying status messages (toasts, inline)

NOT feasible (inform user):

  • Modifying TUI rendering or layout
  • Adding new built-in tools (requires OC source)
  • Changing core agent behavior/​prompts
  • Intercepting assistant responses mid-stream
  • Adding new keybinds or commands
  • Modifying internal file read/​write
  • Adding new permission types

If not feasible, MUST inform user clearly. Suggest:

  • OC core changes: contribute to packages/​opencode
  • MCP tools: use MCP server configuration
  • Simple automation: use shell scripts

Step 3: Design Plugin

READ: references/​hooks.md for available hooks, references/​hook-patterns.md for implementation patterns.

READ: references/​CODING-TS.MD for code architecture principles. MUST follow these design guidelines:

  • Modular structure: Split complex plugins into multiple focused files (types, utilities, hooks, tools)
  • Single purpose: Each function does ONE thing well
  • DRY: Extract common patterns into shared utilities immediately
  • Small files: Keep individual files under 150 lines - split into smaller modules as needed
  • No monoliths: MUST NOT put all plugin code in a single index.ts file

Plugin Locations

ScopePathUse Case
Project.opencode/​plugin/<name>/​index.tsTeam-shared, repo-specific
Global~/​.config/​opencode/​plugin/<name>/​index.tsPersonal, all projects

Basic Structure

import type { Plugin } from "@opencode-ai/​plugin"

export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  // Setup code runs once on load

  return {
    // Hook implementations - see references/​hook-patterns.md
  }
}

Context Parameters

ParameterTypeDescription
projectProjectCurrent project info (id, worktree, name)
clientSDK ClientOpenCode API client
$BunShellBun shell for commands
directorystringCurrent working directory
worktreestringGit worktree path

Step 4: Implement

READ: references/​hook-patterns.md for hook implementation examples.

READ: references/​tool-helper.md if adding custom tools (Zod schemas).

READ: references/​events.md if using event hook (event types/​properties).

READ: references/​examples.md for complete plugin examples.

ALWAYS READ: references/​CODING-TS.MD and follow modular design principles.

Plugin Structure (Non-Monolithic)

For complex plugins, MUST use a modular directory structure:

.opencode/​plugin/​my-plugin/
├── index.ts          # Entry point, exports Plugin
├── types.ts          # TypeScript types/​interfaces
├── utils.ts          # Shared utilities
├── hooks/            # Hook implementations
│   ├── event.ts
│   └── tool-execute.ts
└── tools/            # Custom tool definitions
    └── my-tool.ts

Example modular index.ts:

import type { Plugin } from "@opencode-ai/​plugin"
import { eventHooks } from "./​hooks/​event"
import { toolHooks } from "./​hooks/​tool-execute"
import { customTools } from "./​tools"

export const MyPlugin: Plugin = async ({ project, client }) => {
  return {
    ...eventHooks({ client }),
    ...toolHooks({ client }),
    tool: customTools,
  }
}

Keep each file under 150 lines. Split as complexity grows.

Common Mistakes

MistakeFix
Using client.registerTool()Use tool: { name: tool({...}) }
Wrong event property namesCheck references/​events.md
Sync event handlerMUST use async
Not throwing to blockthrow new Error() in tool.execute.before
Forgetting TypeScript typesimport type { Plugin } from "@opencode-ai/​plugin"

Step 5: Add UI Feedback (Optional)

Only if plugin needs user-visible notifications:

READ: references/​toast-notifications.md for transient alerts (brief popups)

READ: references/​ui-feedback.md for persistent inline status messages

Choose based on:

NeedUse
Brief alerts, warningsToast
Detailed stats, multi-lineInline message
Config validation errorsToast
Session completion noticeToast or inline

Step 6: Test

READ: references/​testing.md for full testing procedure.

Quick Test Steps

  1. Create test folder with opencode.json:

    {
      "plugin": ["file:///path/​to/​your/​plugin/​index.ts"],
    }
    
  2. Verify plugin loads:

    cd /​path/​to/​test-folder
    opencode run hi
    
  3. Test interactively:

    opencode
    
  4. SHOULD recommend specific tests based on hook type used.


Step 7: Publish (Optional)

READ: references/​publishing.md for npm publishing.

READ: references/​update-notifications.md for version update toasts (for users with pinned versions).

</​workflow>

<reference_summary>

Reference Files Summary

FilePurposeWhen to Read
hooks.mdHook signatures (auto-generated)Step 3-4
events.mdEvent types (auto-generated)Step 4 (if using events)
tool-helper.mdZod tool schemas (auto-generated)Step 4 (if custom tools)
hook-patterns.mdHook implementation examplesStep 3-4
CODING-TS.MDCode architecture principlesStep 3 (Design)
examples.mdComplete plugin examplesStep 4
toast-notifications.mdToast popup APIStep 5 (if toasts needed)
ui-feedback.mdInline message APIStep 5 (if inline needed)
testing.mdTesting procedureStep 6
publishing.mdnpm publishingStep 7
update-notifications.mdVersion toast patternStep 7 (for npm plugins)

</​reference_summary>