Course · OpenCode · Skills
Skills
OpenCode has two homes for written-down knowledge, and they load differently. The rules layer is an AGENTS.md file of standing facts about the project - for feedmill, the course’s illustrative Go feed aggregator, facts like timestamps are stored UTC and the dedupe key is canonical-URL-plus-title. That file is read on every session, so it is the right home for what the agent must always know. A Skill is the other shape: a routine - a named, multi-step procedure you run over and over - written down once so the model can load it only when the task calls for it. Rules are standing knowledge; a Skill is a procedure the agent knows how to run on demand. The split is about context and cost: all of AGENTS.md sits in the agent’s context and is paid for in every session, while a Skill keeps only its name and description there and brings in the body when the model loads it. A procedure you need for one kind of task stays out of every other session.
A Skill is a directory with a SKILL.md file in it. The frontmatter says when it may be useful; the body says what to do. OpenCode keeps every Skill’s name and description in view and exposes them through a built-in skill tool - when the model decides the task matches one, it may call that tool to pull in the full body and follow it. And this is where OpenCode’s openness shows up: it doesn’t read skills only from its own .opencode/skills/ - it also reads the Claude Code (.claude/skills/) and Codex (.agents/skills/) paths, walking up from your current working directory until it reaches the git worktree, the top of your checkout (as of October 2026; skills documentation). Codex reads that path too - its own documentation has it scanning .agents/skills in every directory from your working directory up to the repository root (Codex skills documentation, as of September 2026). A skill you wrote for another tool loads here without a rewrite, though keys that only the other tool understands are ignored. This chapter walks the whole arc on one concrete procedure.
Those three are the project-scoped sources; OpenCode also picks up global skills from the home-directory equivalents - ~/.config/opencode/skills/, ~/.claude/skills/, and ~/.agents/skills/ - so a skill you keep machine-wide is available in every repo too (same skills documentation, as of October 2026). This chapter stays project-local, but it’s worth knowing the project dirs aren’t the only source.
The procedure we’ll package
Section titled “The procedure we’ll package”feedmill pulls dozens of feeds - RSS, Atom, a couple of awkward JSON-feed variants - and the set keeps growing, because the whole point of a self-hosted aggregator is that you decide what goes in it. Every time you add one, you do the same dance:
- sniff the format - fetch a sample of the feed and work out whether it’s RSS, Atom, or one of the JSON shapes, and where it tucks the fields that matter
- write a parser adapter that maps that feed’s quirks onto
feedmill’s internal item struct - the id, the title, the published timestamp, the link - register the adapter so the sync server actually reaches for it when it sees that source
- add a fixture test - drop the sample in
testdata/, assert the adapter produces the items you expect, so the next refactor can’t silently break this source
The steps never change; only the feed does. Done by hand, onboarding means narrating all four to OpenCode each time - “okay, this one’s an Atom feed, the timestamp is in <updated> not <published>, register it in the adapter map, and yes write the fixture test too.” That re-narrating is the waste. Write the procedure down once, as a Skill, and OpenCode can recognize “this is a new feed source to onboard” and run the whole thing itself.
The chapter’s pages, in reading order:
- Package the add-a-feed procedure - the directory, the
SKILL.md, the frontmatter and body - and build the onboard-a-feed routine end to end so OpenCode’sskilltool can fire it on recognition. - Reuse skills across tools - because OpenCode reads
.claude/skills/and.agents/skills/directly, a skill folder authored for Claude Code or Codex already loads here. You’ll drop one in and watch it work without a rewrite, and see which frontmatter keys travel and which get ignored. - Control which agents can run a skill - the
permission.skillsetting, globally and per-agent, plus turning theskilltool off entirely for an agent. So a review agent can’t load a procedure that writes parser code, while itseditandbashpermissions decide what it can actually do.
By the end, OpenCode picks up feed onboarding on recognition. You stop narrating the field-mapping, the fixture test is part of the written procedure instead of something you must remember to ask for (a skill is guidance the model usually follows, not a guarantee), and one skill folder serves two tools: a folder in .claude/skills/ serves OpenCode and Claude Code, and one in .agents/skills/ serves OpenCode and Codex (Claude Code reads only .claude/skills/ folders, as of September 2026; Claude Code skills documentation). Start by packaging the add-a-feed procedure.