π This Plugin Has Graduated to Native OpenCode Support!
Great news! The skills functionality first brought to OpenCode by this plugin is now built into OpenCode as of v1.0.190.
This plugin served as the proof-of-concept that led to native skills support in OpenCode:
// opencode.json
{
- "plugin": ["opencode-skills"]
}
# Native uses skill/ (singular) at project root instead of .opencode/skills/
mv .opencode/skills skill
# For global skills
mv ~/.opencode/skills ~/.config/opencode/skill
Native skills use pattern-based permissions instead of tool-level config:
// opencode.json
{
- "tools": {
- "skills*": false,
- "skills_my_skill": true
- }
+ "permission": {
+ "skill": {
+ "my-skill": "allow",
+ "*": "deny"
+ }
+ }
}
| Aspect | This Plugin | Native (v1.0.190+) |
|---|---|---|
| Tool name | skills_my_skill | skill (single tool) |
| Directory | .opencode/skills/ | skill/ |
| Loading | Eager (all at startup) | Lazy (on-demand) |
| Permissions | tools config | permission.skill patterns |
Your existing SKILL.md files work unchanged - just move them to the new location!
To everyone who starred, used, and provided feedback on this plugin - your support made native implementation possible.
This plugin was the first stepping stone, proving that the OpenCode community wanted skills support. Your adoption and feedback directly influenced the native implementation.
Special thanks to the OpenCode maintainers (@thdxr) for the collaboration on PRs #5930 and #6000.
I'm working on something new. Stay tuned. β¨
In the meantime, check out my other OpenCode plugin:
Multi-agent collaboration and workflow orchestration for OpenCode
| Mode | What It Does |
|---|---|
| Fork | Explore multiple approaches in parallel (compare architectures!) |
| Message | Turn-based agent collaboration in the same conversation |
| New | Clean handoffs between phases (Research β Plan β Build) |
| Compact | Manual compression to maintain long conversations |
# Add to opencode.json: { "plugin": ["opencode-sessions"] }
skills_{{name}} toolnoReply message insertion patternAdd 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 version
Force update to latest:
rm -rf ~/.cache/opencode
Then 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:
my-skill)name: must match directory name exactlyskills_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: true
This subagent gets specific skills even if they're disabled globally.
The plugin uses Anthropic's message insertion pattern to deliver skill content:
"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?
SKILL.md files exist in discovery pathsTool not appearing?
name field matches directory name exactlyPaths not resolving?
Invalid skill errors?
[a-z0-9-]+)Plugin not updating?
cat ~/.cache/opencode/node_modules/opencode-skills/package.json | grep versionrm -rf ~/.cache/opencode then restart@version to plugin name in opencode.jsonThe plugin exports a single function that registers skills as dynamic tools:
export const SkillsPlugin: Plugin
Discovery: 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.
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:
opencode.json rather than scattered across skillsSkills 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
This repository is archived for historical reference. Not affiliated with OpenCode or Anthropic.
TypeScript
100.0%
π This Plugin Has Graduated to Native OpenCode Support!
Great news! The skills functionality first brought to OpenCode by this plugin is now built into OpenCode as of v1.0.190.
This plugin served as the proof-of-concept that led to native skills support in OpenCode:
// opencode.json
{
- "plugin": ["opencode-skills"]
}
# Native uses skill/ (singular) at project root instead of .opencode/skills/
mv .opencode/skills skill
# For global skills
mv ~/.opencode/skills ~/.config/opencode/skill
Native skills use pattern-based permissions instead of tool-level config:
// opencode.json
{
- "tools": {
- "skills*": false,
- "skills_my_skill": true
- }
+ "permission": {
+ "skill": {
+ "my-skill": "allow",
+ "*": "deny"
+ }
+ }
}
| Aspect | This Plugin | Native (v1.0.190+) |
|---|---|---|
| Tool name | skills_my_skill | skill (single tool) |
| Directory | .opencode/skills/ | skill/ |
| Loading | Eager (all at startup) | Lazy (on-demand) |
| Permissions | tools config | permission.skill patterns |
Your existing SKILL.md files work unchanged - just move them to the new location!
To everyone who starred, used, and provided feedback on this plugin - your support made native implementation possible.
This plugin was the first stepping stone, proving that the OpenCode community wanted skills support. Your adoption and feedback directly influenced the native implementation.
Special thanks to the OpenCode maintainers (@thdxr) for the collaboration on PRs #5930 and #6000.
I'm working on something new. Stay tuned. β¨
In the meantime, check out my other OpenCode plugin:
Multi-agent collaboration and workflow orchestration for OpenCode
| Mode | What It Does |
|---|---|
| Fork | Explore multiple approaches in parallel (compare architectures!) |
| Message | Turn-based agent collaboration in the same conversation |
| New | Clean handoffs between phases (Research β Plan β Build) |
| Compact | Manual compression to maintain long conversations |
# Add to opencode.json: { "plugin": ["opencode-sessions"] }
skills_{{name}} toolnoReply message insertion patternAdd 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 version
Force update to latest:
rm -rf ~/.cache/opencode
Then 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:
my-skill)name: must match directory name exactlyskills_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: true
This subagent gets specific skills even if they're disabled globally.
The plugin uses Anthropic's message insertion pattern to deliver skill content:
"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?
SKILL.md files exist in discovery pathsTool not appearing?
name field matches directory name exactlyPaths not resolving?
Invalid skill errors?
[a-z0-9-]+)Plugin not updating?
cat ~/.cache/opencode/node_modules/opencode-skills/package.json | grep versionrm -rf ~/.cache/opencode then restart@version to plugin name in opencode.jsonThe plugin exports a single function that registers skills as dynamic tools:
export const SkillsPlugin: Plugin
Discovery: 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.
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:
opencode.json rather than scattered across skillsSkills 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
This repository is archived for historical reference. Not affiliated with OpenCode or Anthropic.
TypeScript
100.0%