Bring Anthropic's Agent Skills Specification (v1.0) to OpenCode. This plugin automatically discovers and registers skills as dynamic tools, enabling the Agent to leverage specialized knowledge, workflows, and bundled resources.
- ✅ Auto-discovery - Scans project, home, and config directories for skills
- ✅ Spec compliance - Validates against Anthropic's Skills Specification v1.0
- ✅ Dynamic tools - Each skill becomes a
skills_{{name}}tool - ✅ Path resolution - Base directory context for relative file paths
- ✅ Nested skills - Supports hierarchical skill organization
- ✅ Graceful errors - Invalid skills skipped with helpful messages
- OpenCode SDK ≥ 1.0.126 - Required for agent context preservation and
noReplymessage insertion pattern
Add to your opencode.json or ~/.config/opencode/opencode.json:
{
"plugin": ["opencode-skills"]
}OpenCode auto-installs plugins on startup.
Pin to a specific version:
{
"plugin": ["opencode-skills@x.y.z"]
}Check installed version:
cat ~/.cache/opencode/node_modules/opencode-skills/package.json | grep versionForce update to latest:
rm -rf ~/.cache/opencodeThen restart OpenCode.
The plugin scans these locations (lowest to highest priority):
~/.config/opencode/skills/- XDG config location (or$XDG_CONFIG_HOME/opencode/skills/)~/.opencode/skills/- Global skills (all projects)$OPENCODE_CONFIG_DIR/skills/(if set) - Custom OpenCode config directory (higher priority than global, lower than project-local).opencode/skills/- Project-local skills (overrides all other locations)
All locations are merged. If duplicate skill names exist, the project-local version takes precedence and a warning is logged.
mkdir -p .opencode/skills/my-skill.opencode/skills/my-skill/SKILL.md:
---
name: my-skill
description: A custom skill that helps with specific tasks in my project
license: MIT
---
# My Custom Skill
This skill helps you accomplish specific tasks.
## Instructions
1. First, do this
2. Then, do that
3. Finally, verify the results
You can reference supporting files like `scripts/helper.py` or `references/docs.md`.The plugin will discover and register your skill.
skills_my_skill
The Agent receives the skill content and follows its instructions.
Every skill must have a SKILL.md file with YAML frontmatter:
---
name: skill-name # Must match directory name
description: What this skill does and when to use it (min 20 chars)
license: MIT # Optional
allowed-tools: # Optional (parsed but not enforced)
- read
- write
metadata: # Optional key-value pairs
version: "1.0"
---
# Skill Content
Your skill instructions in Markdown format.my-skill/
├── SKILL.md # Required
├── scripts/ # Executable code
│ └── helper.py
├── references/ # Documentation to load as needed
│ └── api-docs.md
└── assets/ # Files used in output
└── template.html
| Directory | Frontmatter Name | Tool Name |
|---|---|---|
brand-guidelines/ |
brand-guidelines |
skills_brand_guidelines |
tools/analyzer/ |
analyzer |
skills_tools_analyzer |
Rules:
- Directory name: lowercase with hyphens (
my-skill) - Frontmatter
name: must match directory name exactly - Tool name: auto-generated with underscores (
skills_my_skill)
By default, all discovered skills are available to all agents. Use OpenCode's tool configuration to control which agents can access which skills.
💡 Tip: Use
skills*: falseat project level to prevent context pollution, then enable only what each agent needs.
Disable all skills by default, then enable specific ones in your opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"tools": {
"skills*": false,
"skills_my_skill": true
}
}Override defaults for specific built-in agents (like build, plan, etc.):
{
"$schema": "https://opencode.ai/config.json",
"tools": {
"skills*": false
},
"agent": {
"build": {
"tools": {
"skills_document_skills_docx": true,
"skills_document_skills_xlsx": true
}
}
}
}Now only the build agent has access to document skills.
For custom subagents, control tools via YAML frontmatter in the agent definition:
mode: subagent
description: Content creator agent
tools:
skills_brand_guidelines: true
skills_writing_style: trueThis subagent gets specific skills even if they're disabled globally.
The plugin uses Anthropic's message insertion pattern to deliver skill content:
- Skill loading message - Announces skill activation
- Skill content message - Delivers instructions with base directory context
- Tool confirmation - Returns
"Launching skill: {name}"
Both messages use noReply: true, so they appear as user messages (not tool responses). This ensures skill content persists throughout long conversations, even when OpenCode purges tool responses to manage context.
Skills can reference files with relative paths:
Read `references/api.md` and run `scripts/deploy.sh`The Agent receives base directory context:
Base directory for this skill: /path/to/.opencode/skills/my-skill/
And automatically resolves paths like: /path/to/.opencode/skills/my-skill/references/api.md
Skills not discovered?
- Verify
SKILL.mdfiles exist in discovery paths - Check console for discovery messages
- Confirm frontmatter is valid YAML
Tool not appearing?
- Ensure
namefield matches directory name exactly - Check for duplicate tool names (logged as warnings)
- Restart OpenCode after adding/modifying skills
Paths not resolving?
- Check the base directory shown in skill output
- Verify supporting files exist at specified paths
- Ensure paths in SKILL.md are relative (not absolute)
Invalid skill errors?
- Name must be lowercase with hyphens only (
[a-z0-9-]+) - Description must be at least 20 characters
- Name in frontmatter must match directory name
Plugin not updating?
- Check version:
cat ~/.cache/opencode/node_modules/opencode-skills/package.json | grep version - Force update:
rm -rf ~/.cache/opencodethen restart - Pin version: Add
@versionto plugin name inopencode.json
The plugin exports a single function that registers skills as dynamic tools:
export const SkillsPlugin: PluginDiscovery: Scans .opencode/skills/, ~/.opencode/skills/, and ~/.config/opencode/skills/
Validation: Enforces Anthropic Skills Specification v1.0
Tool naming: skills_{name} with underscores for nested paths
See types for full interface definitions.
Design Decisions
The allowed-tools field in skill frontmatter is parsed for Anthropic spec compliance, but enforcement happens at the OpenCode agent level (see Controlling Skill Access). This provides:
- Clearer permission model aligned with OpenCode's existing system
- Centralized control in
opencode.jsonrather than scattered across skills - Flexibility to override permissions per-project or per-agent
Skills are discovered at startup and cached. Adding or modifying skills requires restarting OpenCode. This is acceptable because skills change infrequently and simplifies the implementation.
Contributions welcome! Fork, create a feature branch, and submit a PR.
MIT - see LICENSE
Not affiliated with OpenAI or Anthropic. This is an independent open-source project.