Skip to main content
Skills are Markdown instructions that OpenCode can advertise to an agent and load when they are relevant. A skill can include supporting scripts, references, and other files in the same directory.

Create a skill

Create one directory per skill with a SKILL.md file:
.opencode/skills/
└── git-release/
    ├── SKILL.md
    ├── scripts/
    │   └── changelog.ts
    └── references/
        └── release-policy.md
.opencode/skills/git-release/SKILL.md
---
name: Git Release
description: Prepare release notes, version bumps, and GitHub releases
metadata:
  opencode/slash: "true"
---

## Workflow

1. Read `references/release-policy.md`.
2. Summarize merged changes since the previous tag.
3. Propose the version bump before changing files.
4. Run `scripts/changelog.ts` only after the user approves the version.
Paths in a skill are relative to the directory containing SKILL.md.

Discovery

OpenCode automatically adds the following source directories:
ScopeSources
Global~/.config/opencode/skills
Global compatibility~/.claude/skills, ~/.agents/skills
Project.opencode/skills
Project compatibility.claude/skills, .agents/skills
For project sources, OpenCode searches from the current directory upward to the project root and includes matching directories at every level. Within each source directory, OpenCode discovers:
  • Markdown files at the source root, such as skills/git-release.md
  • SKILL.md files at any depth, such as skills/git-release/SKILL.md
The directory form is recommended because it gives the skill a private base directory for supporting files.

Configure sources

Use the skills array in any opencode.json or opencode.jsonc to add local directories or HTTP catalogs:
opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "skills": [
    "./team-skills",
    "~/shared/opencode-skills",
    "/opt/company-skills",
    "https://example.com/opencode/skills/"
  ]
}
Relative paths are resolved from the active OpenCode working directory, not from the directory containing the config file. Paths beginning with ~/ use the current user’s home directory. Only http:// and https:// values are treated as URL sources. Every discovered config document contributes its skills entries; the arrays are additive rather than replacing one another.

HTTP catalogs

An HTTP source is a base URL containing an index.json:
index.json
{
  "skills": [
    {
      "name": "git-release",
      "version": "3",
      "files": [
        "git-release.md",
        "references/release-policy.md"
      ]
    }
  ]
}
OpenCode downloads those files from <base-url>/git-release/<file>. File paths must be safe, relative, same-origin paths. Each entry must include either SKILL.md or a Markdown file named after the index entry, such as git-release.md. Use the named Markdown form for HTTP catalogs. Each downloaded skill directory is itself a source root, so git-release.md produces the ID git-release; a root-level SKILL.md produces the literal ID SKILL in the current V2 implementation. Increment version when files change so OpenCode refreshes the cached copy.

Frontmatter

V2 reads these fields:
FieldPurpose
nameDisplay name; defaults to the path-derived ID
descriptionSummary shown to the model and command catalog
slashSet to false to hide the skill from the V2 slash-command catalog
metadata.opencode/slashBoolean or "true"/"false"; overrides slash
metadata.opencode/autoinvokeSet to false to omit the skill from model-facing discovery
Frontmatter, name, and description are optional at runtime. However, a clear description is strongly recommended: skills without one are not advertised to the model. license, compatibility, and other metadata may be included for portability, but V2 does not interpret them. opencode/autoinvoke: false only removes the skill from the model’s available skills list. The skill remains registered and can still be activated explicitly by its ID.

IDs and validation

The skill ID comes from its path, not its frontmatter:
FileID
<source>/git-release.mdgit-release
<source>/git-release/SKILL.mdgit-release
<source>/teams/release/SKILL.mdrelease
IDs are exact and case-sensitive. V2 currently does not enforce the Agent Skills name regex, length limits, a match between name and the directory, or a maximum description length. The frontmatter name is only a display label. For portable, predictable skills, use a unique lowercase kebab-case ID of 1-64 characters and keep it aligned with the directory name:
^[a-z0-9]+(-[a-z0-9]+)*$

Precedence

Skills are keyed by ID. If several sources define the same ID, the later source wins. Sources are registered in this order, from lower to higher precedence:
  1. Built-in skills
  2. .claude/skills sources, global first and then from the current directory upward
  3. .agents/skills sources, global first and then from the current directory upward
  4. ~/.config/opencode/skills
  5. Project .opencode/skills, from the project root toward the current directory
  6. Explicit skills config entries, in config priority and array order
Avoid duplicate IDs unless an override is intentional.

Runtime loading

At each model step, OpenCode advertises permitted skills that have a description and do not set opencode/autoinvoke to false. The advertisement contains only each skill’s ID, name, and description; it does not add every skill body to the prompt. When the model calls the skill tool with an exact ID, OpenCode:
  1. Resolves the current winning definition for that ID
  2. Checks the skill permission for the selected agent
  3. Adds the Markdown body, without frontmatter, to the conversation
  4. Provides the skill’s base directory and a sample of up to ten supporting file paths
Supporting file contents are not loaded automatically. The agent can read a referenced file when the skill instructs it to do so. The supporting-file sample is available for directory-based SKILL.md skills; flat Markdown skills receive no neighboring file list. In the V2 CLI, skills appear as /id commands unless slash resolves to false. Selecting one appends the skill body as a skill message and resumes the session.

Permissions

Permission rules use the skill action and the skill ID as the resource. Rules are evaluated in order, with the last matching rule winning:
opencode.jsonc
{
  "permissions": [
    { "action": "skill", "resource": "*", "effect": "allow" },
    { "action": "skill", "resource": "internal-*", "effect": "deny" },
    { "action": "skill", "resource": "experimental-*", "effect": "ask" }
  ]
}
deny removes matching skills from model-facing discovery and rejects skill tool loading. ask advertises the skill but requests approval when the model loads it. The same rules can be placed under an individual agents.<id>.permissions array.

Troubleshooting

If a skill is missing or loads the wrong content:
  1. Confirm the file is either a root-level *.md or a nested file named exactly SKILL.md.
  2. Check the path-derived ID rather than the frontmatter name.
  3. Add a description if the skill should be advertised to the model.
  4. Check opencode/autoinvoke and the selected agent’s skill permissions.
  5. Look for a later source defining the same ID.
  6. For HTTP catalogs, verify index.json, same-origin file paths, and a changed version.