| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- ---
- title: "Skills"
- description: ""
- ---
- 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:
- ```text
- .opencode/skills/
- └── git-release/
- ├── SKILL.md
- ├── scripts/
- │ └── changelog.ts
- └── references/
- └── release-policy.md
- ```
- ```markdown title=".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:
- | Scope | Sources |
- | --- | --- |
- | 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:
- ```jsonc title="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`:
- ```json title="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:
- | Field | Purpose |
- | --- | --- |
- | `name` | Display name; defaults to the path-derived ID |
- | `description` | Summary shown to the model and command catalog |
- | `slash` | Set to `false` to hide the skill from the V2 slash-command catalog |
- | `metadata.opencode/slash` | Boolean or `"true"`/`"false"`; overrides `slash` |
- | `metadata.opencode/autoinvoke` | Set 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:
- | File | ID |
- | --- | --- |
- | `<source>/git-release.md` | `git-release` |
- | `<source>/git-release/SKILL.md` | `git-release` |
- | `<source>/teams/release/SKILL.md` | `release` |
- 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:
- ```text
- ^[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:
- ```jsonc title="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`.
|