Skip to content

Course · OpenCode · Skills

Reuse a skill your team already wrote

Suppose feedmill - the course’s illustrative Go feed aggregator - has a routine for adding a feed source, and you package it as a skill: a SKILL.md under .opencode/skills/ that OpenCode loads when a new source shows up. Someone on your team may have written the same procedure already. It could be sitting in another feedmill checkout - or a sibling service - as a Claude Code skill, or a Codex one, with its own wording of the steps: “register the parser, add the source row, wire it into the poller.” Writing a second version for OpenCode would be busywork, and worse, you’d now have two copies to keep in sync the moment the procedure changes.

You don’t have to. OpenCode reads the other tools’ skill folders directly. A skill authored for Claude Code or Codex generally works in OpenCode unchanged - the folder is the interface, and OpenCode already knows where the other tools put theirs (Codex, for its part, scans .agents/skills up to the repository root - Codex skills documentation, as of September 2026).

When OpenCode looks for skills it doesn’t only check its own directory. It reads from all three of the standard locations, at both project and global scope:

project:
.opencode/skills/<name>/SKILL.md
.claude/skills/<name>/SKILL.md ← Claude Code's path
.agents/skills/<name>/SKILL.md ← the .agents / Codex path
global:
~/.config/opencode/skills/<name>/SKILL.md
~/.claude/skills/<name>/SKILL.md
~/.agents/skills/<name>/SKILL.md

So the colleague who wrote the add-a-feed skill under .claude/skills/add-feed/SKILL.md already wrote it somewhere OpenCode reads. You don’t move it, rename it, or convert it. You just open OpenCode in a checkout that has that folder, and the skill is there, provided its frontmatter has a name that matches the folder and a description. Claude Code treats both as optional, so a skill written without them loads there and silently does not appear here (the frontmatter section below covers the fix).

Skills discovery works like the walk that finds AGENTS.md (the rules layer’s standing-facts file): OpenCode walks up from your current working directory until it reaches the git worktree, the top of your checkout, and loads every matching skills directory it passes along the way (as of October 2026; skills documentation). In the source (instruction.ts at v1.18.32, as of October 2026), the rules walk also loads every AGENTS.md on that climb, a stacking the rules documentation leaves unstated (discovery and the nesting walk has the detail). Open OpenCode three levels deep inside feedmill and a .claude/skills/ folder at the repo root is still found.

The global roots matter just as much for a team. If everyone keeps their personal, cross-project procedures in ~/.claude/skills/, those load in OpenCode too without anyone exporting or re-homing them. A skill you wrote once for Claude Code on this machine is available to OpenCode in every repo, without a rewrite. That reach has a price: every discovered skill’s name and description sits in the agent’s context in every session, where overlapping or irrelevant global skills add noise and compete on description, and a key that kept a personal skill manual in Claude Code has no effect here (see the frontmatter section below).

Say a teammate’s add-a-feed skill lives in .claude/skills/add-feed/. You’ve cloned the repo and you open OpenCode. There’s no separate “list” step to run - the skills documentation says discovered skills are listed in the built-in skill tool, including skills found under .claude/skills/ (as of October 2026). So the teammate’s add-feed skill is in front of the agent the moment you start, described exactly like a native OpenCode skill, because to OpenCode there’s no difference. You onboard a new source the same way you would have with your own skill, by describing the outcome and letting the agent reach for the procedure. To confirm discovery, ask the agent which skills it has available; add-feed should be in the list. If it is missing, check the frontmatter (see the section below) check that neither OPENCODE_DISABLE_CLAUDE_CODE_SKILLS nor OPENCODE_DISABLE_CLAUDE_CODE is set, because either variable hides .claude/skills/ (rules documentation, as of October 2026), and check that no deny rule in the skill permission hides it.

Keep one copy of the procedure. If you already packaged your own version under .opencode/skills/, delete your .opencode/skills/ copy and keep the teammate’s, because OpenCode also reads the root their tool reads. Two skills with the same name do not merge: OpenCode keeps one and logs a duplicate-name warning (skill loader source, as of October 2026), and the troubleshooting list in the skills documentation says names must be unique across all locations. Two skills with different names and overlapping descriptions both stay in the list, and the model picks between them on the description alone.

One note on the transcript’s marker: out of the box, build (OpenCode’s default coding agent) lands its edits without asking, but this repo’s opencode.json (OpenCode’s config file) sets permission.edit to ask, a gate that holds file edits behind an approval prompt - so the parser write below is marked approved (permissions documentation, as of October 2026). An illustrative exchange:

> onboard the Hacker News JSON feed as a new source
| Skill add-feed
Following the add-feed procedure: I'll add a parser under
internal/feed for the HN JSON shape, register the source row, and
route its fetch through internal/sync/limiter.go - respecting the
rate-limit delay per the repo conventions.
| Write internal/feed/hn.go → approved

The agent saw add-feed in its skill list, decided this task matched the description, and called the skill tool to load the body on demand - the same invocation path a native OpenCode skill uses. The procedure your team already proved out is now driving an OpenCode run, and you wrote none of it.

Why tool-specific frontmatter doesn’t break it

Section titled “Why tool-specific frontmatter doesn’t break it”

The reason this works unchanged is worth understanding, because it tells you what will and won’t carry over. A Claude Code SKILL.md often carries frontmatter keys that OpenCode does not recognize - Claude Code’s disable-model-invocation, for example, or allowed-tools, which the Agent Skills specification lists as experimental (as of September 2026). OpenCode has no concept of these knobs: it doesn’t choke on them and it doesn’t try to honor them. Unknown frontmatter fields are simply ignored.

What OpenCode actually reads from the frontmatter is a small, shared core: name (which must match the directory) and description are the required pair, with license, compatibility, and metadata recognized as optional. Everything else in the block is inert (as of October 2026; skills documentation). Claude Code requires neither of the pair: its documentation marks every frontmatter field optional and defaults name to the directory name (as of September 2026; Claude Code skills documentation). A teammate’s skill that omits name or description can be missing from OpenCode’s list without an error, so check that the file sets name to the folder name and has a non-empty description. That’s the whole compatibility story: the part of the format that matters - name, description, and the Markdown procedure in the body - is the open Agent Skills standard (originally developed by Anthropic and released as an open spec) that Claude Code, Codex, and OpenCode all share, and the tool-specific extras each tool layers on top are skipped by the tools that don’t recognize them.

The practical consequence: the behavior a Claude-specific key was buying you doesn’t transfer. If your teammate used disable-model-invocation to stop Claude Code from auto-running the skill, OpenCode ignores that key, so it won’t suppress invocation the same way. allowed-tools is lost in the other direction: in Claude Code it pre-approves the listed tools for the turn that invokes the skill and does not restrict which tools are available (Claude Code skills documentation, as of September 2026). In OpenCode those tool calls run under the agent’s own permission settings, so a call Claude Code ran without asking can prompt here. Access is a control question, and OpenCode answers it outside the skill file: the skill permission, which matches on the skill’s name, decides which agents may load it (permissions documentation, as of October 2026). The procedure travels; the tool-specific gating does not. That’s the seam to watch when you reuse a skill across tools: it’ll run, but any invocation or approval rules baked into another tool’s frontmatter are yours to re-establish on the OpenCode side: the skill permission for which agents may load it, and the agent’s tool permissions for what it may run without asking.

That re-establishing is exactly what comes next: now that a shared skill can run in OpenCode, you’ll want to decide which agents are allowed to reach for it. Next: control which agents can run a skill.