beginner30 minLesson 1 of 5

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).

ℹ️Note

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.

100%
💡Tip

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.

100%
💡Tip

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.

⚠️Warning

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.

yaml
# 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
bash
# 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-opencode

MCP (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

100%
json
{ "mcpServers": { "filesystem": { "command": "node", "args": ["mcp-server-fs.js"], "env": { "ALLOWED_PATHS": "/home/user/projects" } } } }
📌Important

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).

ℹ️Note

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.

json
{ "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:

ToolPurposeRequires PermissionCategory
bashExecute shell commandsYesExecution
readRead filesNoRead
writeWrite filesYesWrite
editEdit filesYesWrite
grepSearch file contentsNoRead
globFind files by patternNoRead
webfetchFetch URLsOptionalNetwork
websearchSearch the webOptionalNetwork
taskDelegate to subagent/skillYesOrchestration
questionAsk user for inputNoInteraction
⚠️Warning
| Tools marked as "Optional" for permissions can be used without rules but their behavior may be restricted. For example, `webfetch` without allow rules may be limited to certain domains.
typescript
// 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:

json
{ "permissions": [ { "tool": "bash", "allow": ["npm *", "git *"], "deny": ["rm -rf *", "sudo *"] }, { "tool": "write", "allow": ["src/**", "docs/**"], "deny": [".env", "secrets/**"] } ] }
⚠️Warning

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

AspectAgentSkillPlugin (MCP)
PurposeAI assistant instanceTask instruction packageExternal tool/service
Configopencode.jsonYAML/JSON manifestopencode.json MCP entry
LifecycleSession-basedOn-demand loadingLong-running process
ScopeFull conversationSpecific taskTool/service access
LanguageModel-dependentNatural languageAny (Node, Python, Go)
StateStateful (conversation)Stateless (instructions)Stateful (process)
ExampleDefault coding agentcustomize-opencodeMCP filesystem server
DependenciesNoneNone (self-contained)Runtime (Node, Python, etc.)
💡Tip
| Choose an agent when you need a persistent conversational partner with a specific expertise. Choose a skill when you want to teach any agent a repeatable procedure. Choose a plugin when you need to connect to an external system or API.

Practice Questions

Practice Question

A team wants to enable their LLM-powered coding assistant to query a company's internal REST API. Which OpenCode mechanism should they use?

Practice Question

A developer is creating a reusable package that teaches an agent how to scaffold React components. What three components must this package include?

Practice Question

According to the tool registry, which two operations can modify files and always require an explicit permission rule?

Practice Question

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?

Practice Question

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?


**Key Takeaways**
  • 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.json is 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
Progress20%