Skip to content
cccskills
FreePublished on GitHub

create-plugin

Create an OpenCode plugin for OpenWork with custom tools and hooks, which run code at specific events. The skill builds the plugin file and adds its entry to the project configuration.

OriginalShow the original description

Create an OpenCode plugin for OpenWork. Scaffolds the plugin file with the correct API shape, tool definitions, and hook registration. Use when the user asks to 'create a plugin', 'write a plugin', or 'make a plugin that does X'.

See how to install

Good for

  • Adding custom tools to OpenWork
  • Creating a plugin to save and list notes
  • Running custom code before or after tool execution
  • Adapting Anthropic plugin definitions for OpenCode

Files included (1)

  • SKILL.md5.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Skill: Create an OpenCode Plugin

Scaffold a working OpenCode plugin for use in OpenWork.

When to use

  • User asks "create a plugin that does X"
  • User asks "write a plugin" or "make a plugin"
  • User wants to extend OpenWork/OpenCode with custom tools

Plugin API

An OpenCode plugin is an async factory function that returns a hooks object.

File location

Plugins can live in:

  • Project: .opencode/plugins/my-plugin.ts (auto-discovered)
  • Global: ~/.config/opencode/plugins/my-plugin.ts
  • npm: published as a package, referenced in opencode.json plugin array
  • URL: file: or https: path in the plugin array

Minimal shape

import { z } from "zod";

export default async () => ({
  tool: {
    my_tool_name: {
      description: "What this tool does.",
      args: z.object({
        input: z.string().describe("The input parameter."),
      }).shape,   // NOTE: .shape, not the ZodObject itself
      async execute(args: { input: string }) {
        // Your logic here. Can use fetch(), fs, child_process, etc.
        return `Result: ${args.input}`;
      },
    },
  },
});

Key rules

  1. Export default an async function that returns the hooks object.
  2. Tool args use zodSchema.shape (a ZodRawShape), not the ZodObject.
  3. execute returns a string or { output: string; metadata?: Record<string, unknown> }.
  4. Tools are declared, not registered imperatively — return them in the hooks object.
  5. fetch() works — plugins run in-process inside the OpenCode runtime.
  6. process.env is accessible — use env vars for secrets/config.

Available hooks

{
  // Modify the system prompt
  "experimental.chat.system.transform": async (input, output: { system: string[] }) => {
    output.system.push("Extra instruction for the agent.");
  },

  // Define tools the agent can call
  tool: {
    tool_name: { description, args, execute },
  },

  // Run code before/after a tool executes
  "tool.execute.before": async ({ tool, args }) => { /* ... */ },
  "tool.execute.after": async ({ tool, args, result }) => { /* ... */ },

  // React to lifecycle events
  event: async ({ event }) => { /* ... */ },
}

Registering the plugin

Add to opencode.json:

{
  "plugin": [
    ".opencode/plugins/my-plugin.ts"
  ]
}

Or install from npm:

{
  "plugin": [
    "my-published-plugin"
  ]
}

Anthropic / Claude plugin compatibility

OpenCode plugins are NOT the same as Anthropic's plugin format. Key differences:

AspectOpenCode PluginAnthropic Plugin
Entry pointAsync factory functionManifest JSON
Tool argsZod schema .shapeJSON Schema
RuntimeIn-process (Bun/Node)Sandboxed container
Authprocess.envOAuth/API key in manifest
Distributionnpm / file path / URLAnthropic marketplace

To adapt an Anthropic plugin for OpenCode:

  1. Rewrite the tool definitions using Zod instead of JSON Schema.
  2. Move any auth from the manifest to env vars or opencode.json provider config.
  3. Export the async factory function instead of the manifest.
  4. HTTP-based Anthropic plugins can often be wrapped as MCP servers instead.

Example: plugin with multiple tools

import { z } from "zod";

export default async () => ({
  "experimental.chat.system.transform": async (_input: unknown, output: { system: string[] }) => {
    output.system.push("You have access to a note-taking system. Use save_note and list_notes.");
  },
  tool: {
    save_note: {
      description: "Save a note with a title and body.",
      args: z.object({
        title: z.string().describe("Note title"),
        body: z.string().describe("Note content"),
      }).shape,
      async execute(args: { title: string; body: string }) {
        const fs = await import("node:fs/promises");
        const path = `.opencode/notes/${args.title.replace(/[^a-zA-Z0-9-_]/g, "_")}.md`;
        await fs.mkdir(".opencode/notes", { recursive: true });
        await fs.writeFile(path, `# ${args.title}\n\n${args.body}\n`);
        return `Saved note: ${path}`;
      },
    },
    list_notes: {
      description: "List all saved notes.",
      args: {},
      async execute() {
        const fs = await import("node:fs/promises");
        try {
          const files = await fs.readdir(".opencode/notes");
          return files.filter(f => f.endsWith(".md")).join("\n") || "No notes yet.";
        } catch {
          return "No notes yet.";
        }
      },
    },
  },
});

Scaffold workflow

When the user describes what they want the plugin to do:

  1. Create .opencode/plugins/<name>.ts with the plugin code.
  2. Add it to opencode.json plugin array if not already present.
  3. Tell the user to restart their session for the plugin to load.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

add-a-feature

FreeSummary

Manage OpenWork feature releases with feature flags, switches that control access to new behavior. Register features before coding, release them by organization and deployment, prepare a global shutdown option, and remove temporary flags after rollout.

  • Registering a feature before implementation
  • Releasing a feature to selected organizations
  • Separating cloud and self-hosted availability
different-ai/openwork24.2KUpdated Oct 18, 2026

Connect OpenCode browser tools to a locally running OpenWork Electron app to inspect its UI, enter a task, and check the response. This skill supports exploration and debugging through CDP, Chrome's remote control protocol.

  • Connecting browser tools to a local Electron development app
  • Inspecting screen state during debugging
  • Entering a task in the composer and running it
different-ai/openwork24.2KUpdated Oct 18, 2026

Check added lines in a change for information identifying customers, prospects, partners, or outside individuals. Report locations and generic remediation without reproducing identities, and escalate cases where the information is already public.

  • Checking changes for customer and partner identities
  • Reviewing documents and test data for identifying details
  • Reporting disclosure locations without repeating identities
different-ai/openwork24.2KUpdated Oct 18, 2026

Connects supported AI clients, including Claude Code and Codex, to OpenWork through MCP, a protocol for accessing external tools. It guides account sign-in and verifies that tools for finding and running organization capabilities are available.

  • Connecting an AI client to OpenWork organization resources
  • Signing in and verifying available MCP tools
  • Switching organizations or troubleshooting authentication
different-ai/openwork24.2KUpdated Oct 18, 2026

Review an outside contributor’s pull request before running its code. Identify concealed behavior, obfuscated code, risky dependencies, and build hooks, with file locations and specific checks for maintainers to follow up.

  • Screening an outside contributor’s pull request before execution
  • Checking encoded code and unexplained network calls
  • Reviewing dependency changes and installation scripts
different-ai/openwork24.2KUpdated Oct 18, 2026

daytona

FreeSummary

Set up and troubleshoot Daytona sandbox environments, which provide isolated spaces for running applications. The skill covers CLI authentication, persistent desktop and server sandboxes, diagnostic logs, shared secrets storage, snapshot refreshes, and environment deletion.

  • Troubleshooting Daytona authentication and organization selection
  • Keeping an Electron or server sandbox available for debugging
  • Preparing shared secrets storage for sandboxes
different-ai/openwork24.2KUpdated Oct 18, 2026

See all skills by different-ai

Report a problem with this skill