Start typing to search the documentation.

Docs navigation

Skills

Create a skill to give an agent reusable instructions for a specific task. Put a SKILL.md file in .opencode/skills/<skill-id> and describe when to use it in description.

.opencode/skills/git-release/SKILL.md
---
name: Git Release
description: Prepare release notes, version bumps, and GitHub releases
---

## 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.

OpenCode advertises this skill when it is relevant. The agent can then load its instructions with the skill tool instead of adding every skill to every prompt.

Create

Keep related scripts, references, and templates beside SKILL.md:

.opencode/skills/
└── git-release/
    ├── SKILL.md
    ├── scripts/
    │   └── changelog.ts
    └── references/
        └── release-policy.md

Paths written inside the skill are relative to the directory containing SKILL.md. The directory form is recommended because it gives supporting files a private base directory.

Discovery

OpenCode automatically searches these locations:

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 up to the project root and includes matching directories at every level.

Each source can contain either form:

skills/
├── review.md
└── git-release/
    └── SKILL.md
  • Markdown files must be at the source root, such as skills/review.md.
  • Files named exactly SKILL.md can be at any depth, such as skills/git-release/SKILL.md.

Sources

Add more local directories or HTTP catalogs with the skills array in any opencode.json or opencode.jsonc:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "skills": [
    "./team-skills",
    "~/shared/opencode-skills",
    "/opt/company-skills",
    "https://example.com/opencode/skills/",
  ],
}
ValueResolution
Relative pathFrom the active OpenCode working directory, not the config file
~/ pathFrom the current user’s home directory
Absolute pathUsed as written
http:// or https:// URLLoaded as an HTTP catalog

Every discovered config file contributes its entries. skills arrays are combined rather than replaced.

Catalogs

An HTTP catalog is a base URL with an index.json file:

index.json
{
  "skills": [
    {
      "name": "git-release",
      "version": "3",
      "files": ["git-release.md", "references/release-policy.md"]
    }
  ]
}

For that entry, OpenCode downloads each file from <base-url>/git-release/<file>.

RuleRequirement
PathsMust be safe, relative, and same-origin
Entry fileInclude SKILL.md or <name>.md, such as git-release.md
UpdatesIncrement version when files change so OpenCode refreshes its cache

Prefer the named Markdown form in an HTTP catalog. Each downloaded skill directory becomes a source root, so git-release.md has the ID git-release. A root-level SKILL.md currently has the literal ID SKILL in V2.

Frontmatter

Use frontmatter to name the skill and control where it appears:

SKILL.md
---
name: Git Release
description: Prepare a repository release
slash: true
metadata:
  opencode/autoinvoke: false
---

Prepare the changelog, version bump, tag, and release notes.
FieldBehavior
nameDisplay name; defaults to the path-derived ID
descriptionSummary used to show the skill to the model
slashSet to false to hide the skill from interactive command catalogs
metadata.opencode/slashBoolean or "true"/"false"; overrides slash
metadata.opencode/autoinvokeSet to false to omit the skill from the model’s available list

All frontmatter is optional at runtime. Add a clear description when the model should discover the skill; skills without one are not advertised.

opencode/autoinvoke: false only hides the skill from the model’s available list. The skill remains registered and can still be loaded explicitly by ID. V2 accepts portability fields such as license and compatibility but does not interpret them.

IDs

The file path determines the skill ID. The frontmatter name is only a display label.

FileID
<source>/git-release.mdgit-release
<source>/git-release/SKILL.mdgit-release
<source>/teams/release/SKILL.mdrelease

IDs are exact and case-sensitive. For portable 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]+)*$

V2 currently does not enforce this pattern, the 1–64 character recommendation, a match between name and the directory, or a maximum description length.

Precedence

Skills are selected by ID. If two sources define git-release, the source registered later supplies the skill that OpenCode loads:

~/.config/opencode/skills/git-release/SKILL.md  ← lower precedence
.opencode/skills/git-release/SKILL.md           ← loaded

Sources are registered from lower to higher precedence:

  1. Built-in skills
  2. .claude/skills, global first and then from the farthest ancestor toward the current directory
  3. .agents/skills, global first and then from the farthest ancestor toward the current directory
  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 you intend to override an earlier skill.

Loading

At each model step, OpenCode lists permitted skills that have a description and do not set opencode/autoinvoke to false. The list includes only the ID, name, and description, not the full Markdown body.

The model loads a skill by calling the skill tool with its exact ID:

skill tool input
{
  "id": "git-release"
}

OpenCode then:

  1. Selects the current definition for that ID.
  2. Checks the selected agent’s skill permission.
  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 reads them when the skill directs it to do so. The file sample is available for directory-based SKILL.md skills; flat Markdown skills do not receive a neighboring file list.

Permissions

Use the skill action and the skill ID as the resource. Rules run in order, and the last matching rule wins:

opencode.jsonc
{
  "permissions": [
    { "action": "skill", "resource": "*", "effect": "allow" },
    { "action": "skill", "resource": "internal-*", "effect": "deny" },
    { "action": "skill", "resource": "experimental-*", "effect": "ask" },
  ],
}
EffectBehavior
allowAdvertises and loads matching skills without approval
askAdvertises matching skills and asks before loading them
denyHides matching skills from the model and rejects loading

Place the same rules under agents.<id>.permissions to apply them only to one agent.

Troubleshooting

For example, this skill’s ID is release, not its frontmatter name Git Release:

.opencode/skills/release/SKILL.md
                      └─ ID: release

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, case-sensitive ID rather than the frontmatter name.
  3. Add a description if the model should discover the skill.
  4. Check opencode/autoinvoke and the selected agent’s skill permissions.
  5. Look for a later source that defines the same ID.
  6. For HTTP catalogs, verify index.json, same-origin file paths, and a changed version.