Agent Skills
Define reusable behavior via SKILL.md definitions
Agent skills let OpenCode discover reusable instructions from your repo or home directory.
Skills are loaded on-demand via the native skill tool—agents see available skills and can load the full content when needed.
Place files
Create one folder per skill name and put a SKILL.md inside it.
OpenCode searches these locations:
- Project config:
.opencode/skill/<name>/SKILL.md - Global config:
~/.config/opencode/skill/<name>/SKILL.md - Claude-compatible:
.claude/skills/<name>/SKILL.md
Understand discovery
For project-local paths, OpenCode walks up from your current working directory until it reaches the git worktree.
It loads any matching skill/*/SKILL.md in .opencode/ and any matching .claude/skills/*/SKILL.md along the way.
Global definitions are also loaded from ~/.config/opencode/skill/*/SKILL.md.
Write frontmatter
Each SKILL.md must start with YAML frontmatter.
Only these fields are recognized:
name(required)description(required)license(optional)compatibility(optional)metadata(optional, string-to-string map)
Unknown frontmatter fields are ignored.
Validate names
name must:
- Be 1–64 characters
- Be lowercase alphanumeric with single hyphen separators
- Not start or end with
- - Not contain consecutive
-- - Match the directory name that contains
SKILL.md
Equivalent regex:
^[a-z0-9]+(-[a-z0-9]+)*$Follow length rules
description must be 1-1024 characters.
Keep it specific enough for the agent to choose correctly.
Use an example
Create .opencode/skill/git-release/SKILL.md like this:
---name: git-releasedescription: Create consistent releases and changelogslicense: MITcompatibility: opencodemetadata: audience: maintainers workflow: github---
## What I do
- Draft release notes from merged PRs- Propose a version bump- Provide a copy-pasteable `gh release create` command
## When to use me
Use this when you are preparing a tagged release.Ask clarifying questions if the target versioning scheme is unclear.Recognize tool description
OpenCode lists available skills in the skill tool description.
Each entry includes the skill name and description:
<available_skills> <skill> <name>git-release</name> <description>Create consistent releases and changelogs</description> </skill></available_skills>The agent loads a skill by calling the tool:
skill({ name: "git-release" })Configure permissions
Control which skills agents can access using pattern-based permissions in opencode.json:
{ "permission": { "skill": { "pr-review": "allow", "internal-*": "deny", "experimental-*": "ask", "*": "allow" } }}| Permission | Behavior |
|---|---|
allow | Skill loads immediately |
deny | Skill hidden from agent, access rejected |
ask | User prompted for approval before loading |
Patterns support wildcards: internal-* matches internal-docs, internal-tools, etc.
Override per agent
Give specific agents different permissions than the global defaults.
For custom agents (in agent frontmatter):
---permission: skill: "documents-*": "allow"---For built-in agents (in opencode.json):
{ "agent": { "plan": { "permission": { "skill": { "internal-*": "allow" } } } }}Disable the skill tool
Completely disable skills for agents that shouldn’t use them:
For custom agents:
---tools: skill: false---For built-in agents:
{ "agent": { "plan": { "tools": { "skill": false } } }}When disabled, the <available_skills> section is omitted entirely.
Troubleshoot loading
If a skill does not show up:
- Verify
SKILL.mdis spelled in all caps - Check that frontmatter includes
nameanddescription - Ensure skill names are unique across all locations
- Check permissions—skills with
denyare hidden from agents