Skip to content

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.

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’s skill tool 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.skill setting, globally and per-agent, plus turning the skill tool off entirely for an agent. So a review agent can’t load a procedure that writes parser code, while its edit and bash permissions 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.