OpenCode Architecture: Agents, Skills and MCP
Understand the core architecture of OpenCode: its agent system, skills framework, MCP protocol, configuration, and tool registry.
OpenCode Architecture: Agents, Skills and MCP
What is OpenCode?
OpenCode is an open-source CLI framework for AI-assisted software engineering. It bridges large language models with development environments through a structured system of agents, skills, and the Model Context Protocol (MCP).
OpenCode is configured via a single file: opencode.json at the project root or .opencode/config.json inside the .opencode/ directory. Both locations are equivalent, though .opencode/config.json keeps your configuration isolated.
Think of OpenCode as an operating system for AI coding assistants. Agents are the users, skills are the installed programs, MCP servers are peripheral devices, and permissions are the security policies.
Request Lifecycle
Every user interaction flows through a well-defined pipeline. Understanding this lifecycle is crucial for debugging and optimization.
When an agent behaves unexpectedly, trace the request lifecycle. The issue is often in the permission system (a denied tool) or the agent routing (wrong agent matched).
Agent System Overview
Agents are AI-powered assistants configured with specific models, prompts, and capabilities. OpenCode supports multiple agent types:
- Primary agent: The main coding assistant that interacts with the user
- Subagents: Specialized agents (e.g.,
customize-opencode) that handle domain-specific tasks - Custom agents: User-defined agents with tailored configurations
Each agent operates within a permission scope and has access to a defined set of tools and skills.
Subagents inherit the parent's permission scope unless explicitly overridden. This means a subagent with a powerful parent could accidentally perform destructive operations. Always review subagent permissions when delegating sensitive tasks.
Skills System
Skills are reusable instruction packages that teach an agent how to perform specific tasks. A skill includes:
- Instructions: Natural language guidance for the agent
- Tools: Optional tool definitions or constraints
- Resources: Bundled files (scripts, templates, references)
Skills are loaded automatically when an agent detects a matching task pattern.
# skill.yaml
name: customize-opencode
description: Editing or creating opencode configuration
instructions: |
When the user asks to edit opencode.json or related config files,
follow these steps:
1. Read the existing configuration
2. Validate JSON/YAML syntax
3. Apply changes safely
tools:
- read
- write
- edit
resources:
- schema/opencode-schema.json# Skills are auto-loaded when query matches their description
# Example: typing "edit my opencode config" triggers customize-opencode
# You can also force-load with: opencode --skill customize-opencodeMCP (Model Context Protocol)
MCP is a standard protocol for connecting LLMs with external tools and data sources. It allows OpenCode to integrate with:
- File systems (local and remote)
- Databases (SQL, vector stores)
- Web APIs (REST, GraphQL)
- Custom services (internal tools)
MCP servers run as separate processes and communicate via JSON-RPC over stdin/stdout or HTTP.
How MCP Communication Works
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["mcp-server-fs.js"],
"env": {
"ALLOWED_PATHS": "/home/user/projects"
}
}
}
}MCP servers are long-running processes. They start when OpenCode launches and shut down when the session ends. Resource-intensive servers should be carefully managed to avoid memory bloat.
Configuration via opencode.json
All OpenCode behavior is controlled through opencode.json (or .opencode/config.json).
The .opencode/ directory approach is preferred for team projects because you can add it to .gitignore selectively or version-control just the config file without cluttering the project root.
{
"agents": {
"default": {
"model": "gpt-4o",
"description": "Main coding assistant"
},
"reviewer": {
"model": "claude-sonnet-4-20250514",
"description": "Code review specialist",
"prompt": "You are a senior code reviewer focusing on security and performance."
}
},
"skills": {
"customize-opencode": {
"manifest": "skills/customize-opencode/skill.yaml"
},
"react-component": {
"manifest": "skills/react-component/skill.yaml",
"autoLoad": true,
"matchPattern": "react component|jsx"
}
},
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["mcp-server-fs.js", "/home/user/projects"]
},
"github": {
"command": "node",
"args": ["mcp-github-server.js"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
},
"permissions": [
{
"tool": "bash",
"allow": ["npm *", "git *", "pip *"],
"deny": ["rm -rf /", "sudo *"]
},
{
"tool": "write",
"allow": ["src/**", "docs/**"],
"deny": [".env", "secrets/**"]
}
],
"agentRouting": {
"mode": "auto",
"defaultAgent": "default",
"rules": [
{
"pattern": "security|vulnerability|CVE",
"agent": "reviewer"
}
]
}
}Tool Registry
The tool registry manages all available tools and their capabilities:
| Tool | Purpose | Requires Permission | Category |
|---|---|---|---|
bash | Execute shell commands | Yes | Execution |
read | Read files | No | Read |
write | Write files | Yes | Write |
edit | Edit files | Yes | Write |
grep | Search file contents | No | Read |
glob | Find files by pattern | No | Read |
webfetch | Fetch URLs | Optional | Network |
websearch | Search the web | Optional | Network |
task | Delegate to subagent/skill | Yes | Orchestration |
question | Ask user for input | No | Interaction |
// Tools are registered programmatically in the OpenCode SDK
import { ToolRegistry } from "opencode";
const registry = new ToolRegistry();
registry.register({
name: "bash",
description: "Execute shell commands",
requiresPermission: true,
handler: async (args: { command: string }) => {
// Execution logic with permission checks
}
});
registry.register({
name: "grep",
description: "Search file contents with regex",
requiresPermission: false,
handler: async (args: { pattern: string; path?: string }) => {
// Search logic
}
});Permission System
Permissions control what actions agents can perform. Rules are defined in opencode.json:
{
"permissions": [
{
"tool": "bash",
"allow": ["npm *", "git *"],
"deny": ["rm -rf *", "sudo *"]
},
{
"tool": "write",
"allow": ["src/**", "docs/**"],
"deny": [".env", "secrets/**"]
}
]
}Permission rules are evaluated in order: deny rules are checked first, then allow rules. If a command matches both an allow and a deny pattern, the deny rule takes precedence. This prevents accidental bypasses through overlapping patterns.
Comparison: Agents vs Skills vs Plugins
| Aspect | Agent | Skill | Plugin (MCP) |
|---|---|---|---|
| Purpose | AI assistant instance | Task instruction package | External tool/service |
| Config | opencode.json | YAML/JSON manifest | opencode.json MCP entry |
| Lifecycle | Session-based | On-demand loading | Long-running process |
| Scope | Full conversation | Specific task | Tool/service access |
| Language | Model-dependent | Natural language | Any (Node, Python, Go) |
| State | Stateful (conversation) | Stateless (instructions) | Stateful (process) |
| Example | Default coding agent | customize-opencode | MCP filesystem server |
| Dependencies | None | None (self-contained) | Runtime (Node, Python, etc.) |
Practice Questions
A team wants to enable their LLM-powered coding assistant to query a company's internal REST API. Which OpenCode mechanism should they use?
A developer is creating a reusable package that teaches an agent how to scaffold React components. What three components must this package include?
According to the tool registry, which two operations can modify files and always require an explicit permission rule?
A user has a primary coding agent and wants to add a specialized agent for database migration tasks. How does this specialized agent relate to the primary one?
You type a request and OpenCode's primary agent tries to use `bash` to install a package, but the command is denied. According to the request lifecycle, what is the most likely reason?
- OpenCode is an open-source CLI framework for AI-assisted software engineering with a layered architecture
- Agents provide AI-powered assistance through configurable model and prompt settings
- Skills are reusable instruction packages that guide agents through specific tasks
- MCP (Model Context Protocol) connects LLMs with external tools and data sources via JSON-RPC
- The tool registry centralizes access to all capabilities (bash, read, write, edit, grep, etc.)
opencode.jsonis the single configuration file controlling agents, skills, MCP, and permissions- The permission system enforces security with allow/deny rules and path restrictions
- The request lifecycle traces user input through agent routing, tool registry, permission checks, and execution
- MCP communication follows a structured sequence of initialize, list, call, and shutdown over JSON-RPC 2.0