Back to Mind & Machine
Jiuhe Wang Feb 21, 2025

OpenCode Architecture Overview

Understanding Agents & Skills

Executive Summary

OpenCode is an open-source AI coding agent with a modular architecture that separates concerns into agents, tools, skills, and permissions. It uses a client/server design where the TUI is just one possible frontend.

Key Insight: Unlike Claude Code which is coupled to Anthropic, OpenCode is provider-agnostic and can work with Claude, OpenAI, Google, or even local models.

System Architecture

Client/Server Design
Client Layer — TUI, Desktop App, VS Code Extension
↓ WebSocket/IPC
Server Layer — Agent Engine, Tool Registry, Skill Registry
Agents — Primary, Subagents, System
Tools — bash, read, edit, grep, glob, skill...

Key Design Principles

  • Provider Agnostic: Not tied to any specific LLM provider
  • Modular Tools: Plugin-based tool system with built-in and custom tools
  • Skill System: Reusable instruction sets loaded on-demand
  • Permission-First: Fine-grained access control for all operations
  • Client/Server: Can run headless and be driven remotely

How Agents Work

Agent Types

Primary Agents
Switched with Tab key. User-facing main assistants.
Examples: build, plan
Subagents
Invoked via @mention. Specialized task agents.
Examples: general, explore, custom
System Agents
Hidden, automatic. Run in background.
Examples: compaction, title, summary

Agent Schema

opencode.json
{ "name": "security-audit", "description": "Security-focused code reviewer", "mode": "subagent", // primary | subagent | all "model": { "providerID": "anthropic", "modelID": "claude-sonnet" }, "temperature": 0.1, // 0.0-1.0 creativity "color": "#FF6B6B", "tools": { "read": true, "write": false }, "permission": [] // Access control rules }

Agent Loading Order

  1. Built-in agents loaded first (build, plan, general, explore)
  2. Config file agents (opencode.json) override or extend
  3. Markdown agents (.opencode/agents/*.md) loaded last
  4. Permissions merged with defaults

Creating Custom Agents

Method 1: Markdown (Recommended)

Create a file in .opencode/agents/:

.opencode/agents/security-audit.md
# Agent Configuration --- description: Security-focused code reviewer mode: subagent model: anthropic/claude-sonnet-4-20250514 temperature: 0.1 tools: read: true write: false bash: ask color: "#FF6B6B" --- # System Prompt You are a security auditor. Focus on: 1. Injection vulnerabilities (SQL, command, XSS) 2. Authentication issues 3. Data exposure risks 4. Dependency vulnerabilities Provide severity ratings and remediation steps.
Why Markdown? Version controlled with project, easier to read and maintain, supports long-form prompts, team can collaborate via PRs.

Method 2: JSON Configuration

opencode.json
{ "agent": { "security-audit": { "description": "Security-focused code reviewer", "mode": "subagent", "prompt": "You are a security auditor...", "temperature": 0.1 } } }

Best Practices

  • Specific descriptions — Helps LLM choose correct agent
  • Restricted permissions — Principle of least privilege
  • Lower temperature (0.1-0.3) for analysis tasks
  • Color coding — Visual distinction in UI
  • Use primary for user-facing, subagent for specialized tasks

The Skills System

Skills are reusable instruction documents that agents can load on-demand. Unlike agents (full configurations), skills provide specific domain knowledge or workflows.

Skill Discovery Locations

Search Order (Project → Global)
Project: .opencode/skills/<name>/SKILL.md
Global: ~/.config/opencode/skills/<name>/SKILL.md
Claude: .claude/skills/<name>/SKILL.md
Remote: https://example.com/skills-index.json

Skill File Format

.opencode/skills/git-release/SKILL.md
# Skill Configuration --- name: git-release description: Create consistent releases and changelogs license: MIT compatibility: opencode metadata: audience: maintainers workflow: github --- ## What I do - Draft release notes from merged PRs - Propose a version bump - Provide copy-pasteable `gh release create` command ## When to use me Use this when preparing a tagged release. Ask clarifying questions if versioning is unclear.

How Skills Are Loaded

At runtime, OpenCode exposes available skills to agents via the skill tool. The agent can then load a skill on-demand:

Runtime Skill Loading
// Agent sees available skills in tool description <available_skills> <skill> <name>git-release</name> <description>Create consistent releases...</description> </skill> </available_skills> // Agent loads skill when needed skill({ name: "git-release" }) // Returns full SKILL.md content

Skill Permissions

opencode.json
{ "permission": { "skill": { "*": "allow", // Allow all "internal-*": "deny", // Block internal skills "experimental-*": "ask" // Prompt user } } }
Permission Behavior
allow Skill loads immediately
deny Skill hidden from agent, access rejected
ask User prompted for approval before loading

Best Practices for Skills

  1. Keep focused — One domain per skill
  2. Write good descriptions — Helps agent choose correctly
  3. Include examples — Step-by-step instructions work best
  4. Version control — Project-specific skills with code
  5. Share via URLs — Team-wide standards via remote index

Key Takeaways

Agents
Specialized AI assistants with custom prompts, models, and permissions
Skills
Reusable instruction documents loaded on-demand via the skill tool
Tools
Capabilities (bash, edit, read, etc.) controlled by permissions
Permissions
Hierarchical pattern system for fine-grained access control
Remember: Markdown files are the best way to define project-specific agents and skills. Everything is configurable via JSON, Markdown, or environment variables. OpenCode is provider-agnostic!

Project File Structure

Project Structure
project/ ├── .opencode/ │ ├── opencode.json # Project config │ ├── agents/ # Custom agents │ │ ├── reviewer.md │ │ └── security-audit.md │ ├── skills/ # Custom skills │ │ ├── react-patterns/ │ │ │ └── SKILL.md │ │ └── deployment/ │ │ └── SKILL.md │ └── tools/ # Custom tools │ └── my-tool.ts └── src/ └── ... # Global config in home directory: ~/.config/opencode/ ├── opencode.json # Global config ├── agents/ # Global agents └── skills/ # Global skills ├── python/SKILL.md └── security/SKILL.md