OpenCode uses primary agents (Build and Plan) for direct interaction, cycling via Tab, and subagents (General, Explore, Scout) invoked by mention to delegate specialized tasks—each with distinct tool permissions and capabilities. Skills are reusable agent instructions stored in SKILL.md files, discovered across project and global locations, with access controlled by permission patterns and available on-demand to any agent via the skill tool.
OpenCode has two types of agents: primary agents, interacted with directly and cycled via the Tab key (or the configured switch_agent keybind), and subagents, invoked by primary agents or manually via @ mention.[1] OpenCode ships two built-in primary agents — Build and Plan — and three built-in subagents — General, Explore, and Scout.[1]
The Build agent is the default primary agent with all tools enabled, intended for standard development work requiring full file and system access.[1] The Plan agent is a restricted primary agent where file edits and bash permissions default to ask, preventing unintended code changes during analysis or planning.[1] Three hidden system primary agents run automatically and are not selectable in the UI: Compaction (compacts long context into a smaller summary), Title (generates short session titles, with temperature: 0.5), and Summary (generates session summaries).[1]
The General subagent has full tool access (except todowrite, which is denied to prevent it from managing the todo list) and is designed for multi-step tasks or parallel units of work; invoke it manually with @general in a message.[1][2] The Explore subagent is read-only and cannot modify files; it is optimized for fast codebase exploration using pattern and keyword searches.[1] The Scout subagent is read-only and designed for external dependency research — cloning repos into OpenCode's managed cache and cross-referencing against upstream implementations without touching the workspace.[1]
Subagents can be manually invoked by @ mentioning them in a message (e.g. @general help me search for this function); primary agents also invoke subagents automatically.[1] When subagents create child sessions, use session_child_first (default <Leader>+Down) to enter the first child session from the parent; session_child_cycle (default Right) and session_child_cycle_reverse (default Left) cycle between children; session_parent (default Up) returns to the parent.[1] Subagents run in isolated child sessions, keeping their working detail separate from the parent session's context; the parent agent receives only a summary of the subagent's result.
Agents can be configured in opencode.json under the agent key, or via markdown files placed in ~/.config/opencode/agents/ (global) or .opencode/agents/ (per-project); the markdown filename becomes the agent name.[1] Agent configuration supports the fields: mode, model, prompt, permission, description, temperature, steps, top_p, color, hidden, variant, options (deep-merged), and disable.[1][2] Setting disable: true on an agent key in opencode.json deletes the built-in agent; a new key with no pre-existing agent creates a custom agent with mode: "all" and the merged default-plus-user permission set.[2] The prompt config option accepts a file reference using the syntax {file:./path/to/file.txt}, resolved relative to the config file's location; the model ID uses the format provider/model-id (e.g. anthropic/claude-sonnet-4-20250514).[1] The temperature option controls LLM response randomness; if unspecified, OpenCode uses model-specific defaults — typically 0 for most models and 0.55 for Qwen models.[1] The steps option caps the maximum number of agentic iterations; when the cap is reached, the agent is instructed to summarize its work and list remaining tasks. Without steps, iteration continues until the model stops or the user interrupts.[1] The maxSteps agent config field is deprecated — use steps instead. The tools agent config field is also deprecated in favor of permission, which offers more fine-grained control; agent-specific tools config overrides the global tools config.[1] The --permissions flag for opencode agent create accepts a comma-separated list of permissions to allow (bash, read, edit, glob, grep, webfetch, task, todowrite, websearch, lsp, skill); anything omitted is denied. The flag is also aliased as --tools.[3]
Example: configuring a custom subagent code-reviewer in opencode.json with a restricted permission set.[1]
Skills are reusable agent instructions stored in SKILL.md files and exposed to agents through the native skill tool; agents see available skills listed in the tool description and load them on-demand by calling skill({ name: "<skill-name>" }).[4] OpenCode searches for SKILL.md files in six locations: .opencode/skills/<name>/SKILL.md, ~/.config/opencode/skills/<name>/SKILL.md, .claude/skills/<name>/SKILL.md, ~/.claude/skills/<name>/SKILL.md, .agents/skills/<name>/SKILL.md, and ~/.agents/skills/<name>/SKILL.md.[4] For project-local paths, OpenCode walks up from the current working directory to the git worktree root, loading any matching skills/*/SKILL.md files found along the way.[4]
Each SKILL.md must have YAML frontmatter with name (required) and description (required); license, compatibility, and metadata (string-to-string map) are optional. Unknown frontmatter fields are ignored.[4] Skill name must be 1–64 characters, lowercase alphanumeric with single-hyphen separators, must not start or end with -, must not contain --, and must match the directory name containing the SKILL.md. Equivalent regex: ^[a-z0-9]+(-[a-z0-9]+)*$.[4] Skill description must be 1–1024 characters.[4]
Skill access is controlled by pattern-based permissions in opencode.json under permission.skill; values are allow (loads immediately), deny (hidden from agent, access rejected), or ask (user prompted before loading). Wildcards are supported, e.g. internal-*.[4] Skill permissions can be overridden per-agent — for custom agents via frontmatter permission.skill, and for built-in agents via opencode.json under agent.<name>.permission.skill.[4] Setting tools.skill: false for an agent completely disables the skill tool; when disabled, the <available_skills> section is omitted entirely from the tool description.[4]
If a skill does not appear, common causes are: SKILL.md is not spelled in all caps, frontmatter is missing name or description, duplicate skill names across locations, or the skill has deny permission.[4]
The Agent.Info schema in packages/opencode/src/agent/agent.ts defines the full shape of an agent configuration, including name, description, mode (one of "subagent", "primary", or "all"), native, hidden, topP, temperature, color, permission, model (with modelID and providerID), variant, prompt, options, and steps.[2] The Agent.Service in packages/opencode/src/agent/agent.ts exposes interface methods get, list, defaultInfo, defaultAgent, and generate; the generate method accepts a description string and an optional model spec and returns { identifier, whenToUse, systemPrompt }, failing with Provider.DefaultModelError.[2] Agent.Service in packages/opencode/src/agent/agent.ts depends on Config.Service, Auth.Service, Plugin.Service, Skill.Service, Provider.Service, and LocationServiceMap.Service at construction time.[2] Whitelisted directories for the external_directory permission in packages/opencode/src/agent/agent.ts include Truncate.GLOB, the temp directory glob (Global.Path.tmp/*), all skill dirs, and all reference dirs, allowing agents to read/write these without prompting.[2] Agent prompts for explore, compaction, title, and summary are loaded from text files at build time (./prompt/explore.txt, ./prompt/compaction.txt, ./prompt/title.txt, ./prompt/summary.txt) and injected into the respective agent definitions in packages/opencode/src/agent/agent.ts.[2]
Sources