Type to search the docs and updates.

Browse documentation

OpenCode (opencode)

Output

AGENTS.md                                 # canonical entry-point pointer body + inlined rules (written by sync)
.opencode/agents/<name>.md                # one native subagent definition per agent
.opencode/skills/<name>/SKILL.md          # one folder per skill, bundled assets included
.opencode/commands/<name>.md              # one per command spec
.opencode/commands/skill-<name>.md        # additional command form, only when emit-skills-as-commands: true
opencode.json                             # when MCP entries exist (merged with existing user config)
  • Routing: the entry point is the repo-root AGENTS.md.
    • OpenCode's rules lookup walks up the directory tree for it ("Local files by traversing up from the current directory (AGENTS.md, CLAUDE.md)"), confirmed in the vendor's own packages/core/src/instruction-context.ts on branch dev: fs.up({ targets: ["AGENTS.md"] }).
    • Codex, amp, warp, and the rest of the AGENTS.md family share that same path. The pointer body and the inlined rules block are byte-identical across them, so sync writes the file once instead of colliding.
    • Before #623, the adapter wrote .opencode/AGENTS.md to stay clear of Codex, but no OpenCode doc or code path ever read it: in a project syncing only opencode, no rule reached the tool at all.
    • A managed leftover at the old path is swept on the next sync; a hand-authored one is left alone.
  • Agents: native OpenCode agents at .opencode/agents/<name>.md (plural dir; the singular is legacy). Frontmatter is filtered to description, mode, model, temperature, permission, with arbitrary x-opencode keys passing through. The body is the system prompt.
  • Skills: native OpenCode skills folders at .opencode/skills/<name>/SKILL.md (OpenCode also scans .claude/skills/ and .agents/skills/), with bundled sibling files propagated byte-for-byte. A source-layout scope moves the full native tree under that directory and survives import. Set outputs.opencode.emit-skills-as-commands: true to additionally emit the command form.
  • Commands: one markdown file per command spec under .opencode/commands/<name>.md, frontmatter filtered to the OpenCode command keys (description, agent, model, subtask).
  • MCP: written into opencode.json at the project root with a $schema link and the mcp map.
    • Each entry carries a type: local|remote key. Stdio maps to {type: "local", command: [...], cwd}; HTTP/SSE/remote maps to {type: "remote", url, headers}.
    • cwd is documented on the local-server table only ("Working directory for the MCP server process. Relative paths resolve from the workspace."). timeout is documented on both ("Timeout in ms for fetching tools from the MCP server. Defaults to 5000 (5 seconds)."). Both names match the spec field exactly, so both map top-level with no rename (target-audit 2026-09-03, #641).
    • A spec's disabled: true writes "enabled": false, the key OpenCode's own MCP docs document ("You can also disable a server by setting enabled to false"). An enabled server gets no key at all, and import opencode reads enabled: false back into disabled: true.
    • Any other documented field, including the oauth client-credentials object for a "Pre-registered" remote server (same doc), reaches the entry through x-opencode, the same passthrough commands and agents already have.
    • Pre-existing non-managed keys (theme, model) are preserved; only $schema and mcp are overwritten. Drift checks (sync --check, doctor) read the existing file, so user keys never report as drift and doctor --fix keeps them.
  • Settings: a settings spec's default model merges into the same opencode.json. Existing native keys survive. import opencode restores the field to settings/imported.yaml.

Config keys

KeyDefaultNotes
outputs.opencode.agents-dir.opencode/agents
outputs.opencode.skills-dir.opencode/skills
outputs.opencode.commands-dir.opencode/commands
outputs.opencode.mcp-fileopencode.json
outputs.opencode.emit-skills-as-commandsfalse
outputs.opencode.rules-fileunsetwrites legacy concatenated rules and skips the pointer-body write

Verify

  1. Install: npm install -g sst/opencode (install docs).
  2. Check the tree: ls AGENTS.md .opencode/agents/ .opencode/skills/ .opencode/commands/ opencode.json, grep "Generated by agnostic-ai" .opencode/agents/*.md for the provenance header (it sits after the frontmatter), python -m json.tool opencode.json > /dev/null.
  3. Launch opencode. Every rule body from AGENTS.md is in context, every .opencode/agents/<name>.md appears in the agent picker, every .opencode/skills/<name>/ in the skills list, and every .opencode/commands/<name>.md in the slash-command picker.
  4. The MCP panel shows each mcp.<name> from opencode.json ready, with a disabled spec showing as disabled.