create-plugin skill
✓ VerifiedScaffold OpenCode plugins for iPolloWork with correct API shapes, tool definitions, and hook registrations.
- GitHub stars
- 7,451
- Files
- 1
- Last commit
- Nov 11, 2026
- License
- —
- Allowed tools
- —
What does the create-plugin skill do?
create-plugin is an agent skill. Scaffold OpenCode plugins for iPolloWork with correct API shapes, tool definitions, and hook registrations.
Summary generated from the skill's SKILL.md.
About the create-plugin skill
Scaffolding OpenCode plugins for iPolloWork is what this skill enables for developers looking to extend their runtime with custom tools and hooks. When an agent receives a request to create or write a plugin, it uses this skill to generate a TypeScript file containing an async factory function. This function produces a hooks object that defines tool behaviors, system prompt transformations, and lifecycle event reactions.
The skill ensures that the generated code follows specific requirements, such as using Zod schema shapes for tool arguments and returning strings or specific metadata objects from execution functions. It handles the structural setup for plugins located in project directories, global configuration folders, or external npm packages. By automating the creation of these files and providing the necessary registration steps for the opencode.json configuration, it helps developers implement in-process logic using standard Node or Bun capabilities like fetch and filesystem access.
What an agent can do with it
- 1Generate a new plugin fileCreate a TypeScript plugin file in the local project directory to add new capabilities to iPolloWork.
- 2Define custom agent toolsDevelop new tools with specific Zod argument shapes and execution logic for an agent to call.
- 3Modify system instructionsImplement a hook that injects extra instructions into the agent's system prompt.
- 4Register plugins in configurationUpdate the opencode.json file to ensure the newly created plugin is automatically discovered.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the create-plugin skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the create-plugin skill in Claude Code
~/.claude/skills/create-plugin/SKILL.md
$ npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin ~/.claude/skills/create-pluginInstall the create-plugin skill in Claude Code (project)
.claude/skills/create-plugin/SKILL.md
$ npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin .claude/skills/create-pluginInstall the create-plugin skill in Codex
~/.agents/skills/create-plugin/SKILL.md
$ npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin ~/.agents/skills/create-pluginInstall the create-plugin skill in Gemini CLI
~/.gemini/skills/create-plugin/SKILL.md
$ npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin ~/.gemini/skills/create-pluginInstall the create-plugin skill in Claude.ai
npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin create-plugin && zip -r create-plugin.zip create-plugin # claude.ai → Customize → Skills → + → Create skill → Upload a skill → create-plugin.zip
Automated checks
Ran Nov 14, 2026Full report →Passed our automated checks. That is not a security audit: read the scripts before you let an agent run them. How checks work
- Source repository linked and reachabledevin-axis/ipollowork/.opencode/skills/create-plugin is public and reachablegithub.com/devin-axis/ipollowork/tree/HEAD/.opencode/skills/ ↗Pass
- Open source license (OSI)No licenseFinding
- Commit or release in the last yearLast commit 2026-11-11github.com/devin-axis/ipollowork/commits ↗Pass
- No download-and-run or credential theft in scriptsNo scripts in the skill folderPass
- No hidden instructions in SKILL.mdNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/devin-axis/ipollowork/blob/HEAD/.opencode/skills/ ↗Pass
- Pre-approved tools are scopedNo pre-approved tools; the agent asks before using onegithub.com/devin-axis/ipollowork/blob/HEAD/.opencode/skills/ ↗Pass
SKILL.md
View on GitHubSkill: Create an OpenCode Plugin
Scaffold a working OpenCode plugin for use in iPolloWork.
When to use
- User asks "create a plugin that does X"
- User asks "write a plugin" or "make a plugin"
- User wants to extend iPolloWork/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.jsonpluginarray - URL:
file:orhttps:path in thepluginarray
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
- Export default an async function that returns the hooks object.
- Tool args use
zodSchema.shape(aZodRawShape), not theZodObject. executereturns astringor{ output: string; metadata?: Record<string, unknown> }.- Tools are declared, not registered imperatively — return them in the hooks object.
fetch()works — plugins run in-process inside the OpenCode runtime.process.envis 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:
| Aspect | OpenCode Plugin | Anthropic Plugin |
|---|---|---|
| Entry point | Async factory function | Manifest JSON |
| Tool args | Zod schema .shape |
JSON Schema |
| Runtime | In-process (Bun/Node) | Sandboxed container |
| Auth | process.env |
OAuth/API key in manifest |
| Distribution | npm / file path / URL | Anthropic marketplace |
To adapt an Anthropic plugin for OpenCode:
- Rewrite the tool definitions using Zod instead of JSON Schema.
- Move any auth from the manifest to env vars or
opencode.jsonprovider config. - Export the async factory function instead of the manifest.
- 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:
- Create
.opencode/plugins/<name>.tswith the plugin code. - Add it to
opencode.jsonpluginarray if not already present. - Tell the user to restart their session for the plugin to load.
Files in this skill
1create-plugin skill questions
How do I install the create-plugin skill in Claude Code?
Run npx degit Devin-AXIS/iPolloWork/.opencode/skills/create-plugin ~/.claude/skills/create-plugin. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the create-plugin skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
Are OpenCode plugins compatible with Anthropic plugins?
No, they are different. OpenCode plugins use an async factory function and Zod schemas, whereas Anthropic plugins use a Manifest JSON and JSON Schema.