On Reusing Agents And Commands Between Opencode And Claude Code
This month I have decided to give Opencode a more serious try alongside of Claude Code which I still consider to be the frontrunner when it comes to CLI agents. One topic I return to is: what can we reuse between both? Here I will be going into (sub)agents and commands.
Although their exact content, mostly the front matter, differs, the nice and tempting thing is: both support markdown, so can we enable reuse between them?
I did not want to resort to conversion scripts. Writing scripts may be fun, or not, but once you start relying on it you also have to keep on maintaining them by keeping up with the changes each tool may be making. They do not seem to evolve much but I would rather not maintain another script and I was looking for a low effort setup.
Since both agents and commands for both tools are stored as markdown files in directory structures, the most straightforward idea is to use symbolic links. In short, this works relatively well for commands, not so much for agents. The main reason is: unknown front matter keys are ignored in command definitions while for agents they generate errors. Claude Code is flexible but Opencode is much more strict here.
Agents
The main issue here is that unknown front matter fields make Opencode fail on start up. So we would have to resort to the least common denominator of fields — in other words, only use the fields Opencode supports, but this would feel like constraining Claude Code's capabilities too much.
Some of the issues I encountered, these are just examples, there are obviously more:
- the
descriptionfield generated by Claude Code, if created with the/agentcommand, which is how I often do it, generates errors in Opencode because of how the text is formatted and escaped. This could probably be fixed but I do not want to make Claude Code less effective or have to change the description text for every agent file. - the
colorfield that Claude Code supports makes Opencode fail
Instead, to port an agent from Claude Code to Opencode I now simply use a prompt to create an Opencode agent from a Claude Code agent. Once it is created they evolve separately unless I update manually.
Commands
Creating a symbolic link from the Opencode commands directory to the Claude Code one works almost seamlessly except for one caveat I have found (so far): the model field in the frontmatter.
Since Claude Code is my primary tool I use .claude/commands/ as the canonical source.
To symlink the global commands (similar for project commands):
ln -s ~/.claude/commands ~/.config/opencode/command
Now commands created in ~/.claude/commands appear in Opencode's commands list as well.
Works in both tools the same way:
- Argument passing (
$1,$2,$ARGUMENTS) - File references resolution (
@filename.txt) - Bash execution (
!`command`)
Importantly, unknown fields in the frontmatter are ignored by Opencode. So opposed to agents, Claude Code fields can still be used here which make this simple setup work quite well.
One point of attention: the model field is now shared between both tools, but Opencode does not accept unknown model values. So you need to specify a field value from models.dev, which are different from Claude Code's expected values, but (luckily?) Claude Code seems to accept these values as well to configure the model. You can also omit the model field altogether, in this case the commands will use the model used by the main chat. However, in general I think it is valuable to specify the model so I just put the model.dev strings.