Arquitetura do OpenCode: Agentes, Skills e MCP
Entenda a arquitetura central do OpenCode: sistema de agentes, framework de skills, protocolo MCP, configuração e registro de ferramentas.
Arquitetura do OpenCode: Agentes, Skills e MCP
O que é o OpenCode?
OpenCode é um framework CLI de código aberto para engenharia de software assistida por IA. Ele conecta modelos de linguagem de grande porte (LLMs) com ambientes de desenvolvimento através de um sistema estruturado de agentes, skills e o Model Context Protocol (MCP).
O OpenCode é configurado via um único arquivo: opencode.json na raiz do projeto ou .opencode/config.json dentro do diretório .opencode/. Ambos os locais são equivalentes, embora .opencode/config.json mantenha sua configuração isolada.
Pense no OpenCode como um sistema operacional para assistentes de codificação de IA. Agentes são os usuários, skills são os programas instalados, servidores MCP são dispositivos periféricos e permissões são as políticas de segurança.
Ciclo de Vida da Requisição
Cada interação do usuário flui através de um pipeline bem definido. Entender este ciclo é crucial para depuração e otimização.
Quando um agente se comporta inesperadamente, trace o ciclo de vida da requisição. Frequentemente o problema está no sistema de permissões (uma ferramenta negada) ou no roteamento de agentes (agente errado selecionado).
Visão Geral do Sistema de Agentes
Agentes são assistentes baseados em IA configurados com modelos, prompts e capacidades específicas. O OpenCode suporta vários tipos de agentes:
- Agente primário: O principal assistente de codificação que interage com o usuário
- Subagentes: Agentes especializados (ex.:
customize-opencode) para tarefas específicas - Agentes personalizados: Agentes definidos pelo usuário com configurações sob medida
Cada agente opera dentro de um escopo de permissão e tem acesso a um conjunto definido de ferramentas e skills.
Subagentes herdam o escopo de permissão do pai a menos que explicitamente sobrescrito. Isto significa que um subagente com um pai poderoso pode acidentalmente realizar operações destrutivas. Sempre revise as permissões do subagente ao delegar tarefas sensíveis.
Sistema de Skills
Skills são pacotes reutilizáveis de instruções que ensinam um agente a executar tarefas específicas. Uma skill inclui:
- Instruções: Guia em linguagem natural para o agente
- Ferramentas: Definições opcionais de ferramentas ou restrições
- Recursos: Arquivos empacotados (scripts, templates, referências)
Skills são carregadas automaticamente quando um agente detecta um padrão de tarefa correspondente.
# skill.yaml
name: customize-opencode
description: Editar ou criar configuração do OpenCode
instructions: |
Quando o usuário pedir para editar opencode.json ou arquivos de
configuração relacionados, siga estes passos:
1. Leia a configuração existente
2. Valide a sintaxe JSON/YAML
3. Aplique as alterações com segurança
tools:
- read
- write
- edit
resources:
- schema/opencode-schema.json# Skills são carregadas automaticamente quando a consulta corresponde à descrição
# Exemplo: digitar "editar minha config opencode" ativa customize-opencode
# Você também pode forçar o carregamento com: opencode --skill customize-opencodeMCP (Model Context Protocol)
MCP é um protocolo padrão para conectar LLMs com ferramentas externas e fontes de dados. Ele permite que o OpenCode se integre com:
- Sistemas de arquivos (locais e remotos)
- Bancos de dados (SQL, vetoriais)
- APIs web (REST, GraphQL)
- Serviços personalizados (ferramentas internas)
Servidores MCP executam como processos separados e se comunicam via JSON-RPC sobre stdin/stdout ou HTTP.
Como a Comunicação MCP Funciona
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["mcp-server-fs.js"],
"env": {
"ALLOWED_PATHS": "/home/usuario/projetos"
}
}
}
}Servidores MCP são processos de longa duração. Eles iniciam quando o OpenCode é lançado e são encerrados quando a sessão termina. Servidores com uso intensivo de recursos devem ser gerenciados cuidadosamente para evitar inchaço de memória.
Configuração via opencode.json
Todo o comportamento do OpenCode é controlado através do opencode.json (ou .opencode/config.json).
A abordagem do diretório .opencode/ é preferida para projetos em equipe porque você pode adicioná-lo ao .gitignore seletivamente ou versionar apenas o arquivo de configuração sem poluir a raiz do projeto.
{
"agents": {
"default": {
"model": "gpt-4o",
"description": "Assistente principal de codificação"
},
"reviewer": {
"model": "claude-sonnet-4-20250514",
"description": "Especialista em revisão de código",
"prompt": "Você é um revisor de código sênior focado em segurança e desempenho."
}
},
"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/usuario/projetos"]
},
"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": "segurança|vulnerabilidade|CVE",
"agent": "reviewer"
}
]
}
}Registro de Ferramentas
O registro de ferramentas gerencia todas as ferramentas disponíveis e suas capacidades:
| Ferramenta | Propósito | Requer Permissão | Categoria |
|---|---|---|---|
bash | Executar comandos shell | Sim | Execução |
read | Ler arquivos | Não | Leitura |
write | Escrever arquivos | Sim | Escrita |
edit | Editar arquivos | Sim | Escrita |
grep | Pesquisar conteúdo | Não | Leitura |
glob | Buscar arquivos por padrão | Não | Leitura |
webfetch | Buscar URLs | Opcional | Rede |
websearch | Pesquisar na web | Opcional | Rede |
task | Delegar para subagente/skill | Sim | Orquestração |
question | Perguntar ao usuário | Não | Interação |
Ferramentas marcadas como "Opcional" para permissões podem ser usadas sem regras, mas seu comportamento pode ser restrito. Por exemplo, webfetch sem regras allow pode ser limitado a certos domínios.
// Ferramentas são registradas programaticamente no SDK do OpenCode
import { ToolRegistry } from "opencode";
const registry = new ToolRegistry();
registry.register({
name: "bash",
description: "Executar comandos shell",
requiresPermission: true,
handler: async (args: { command: string }) => {
// Lógica de execução com verificações de permissão
}
});
registry.register({
name: "grep",
description: "Pesquisar conteúdo com regex",
requiresPermission: false,
handler: async (args: { pattern: string; path?: string }) => {
// Lógica de pesquisa
}
});Sistema de Permissões
Permissões controlam quais ações os agentes podem realizar. As regras são definidas no opencode.json:
{
"permissions": [
{
"tool": "bash",
"allow": ["npm *", "git *"],
"deny": ["rm -rf *", "sudo *"]
},
{
"tool": "write",
"allow": ["src/**", "docs/**"],
"deny": [".env", "secrets/**"]
}
]
}As regras de permissão são avaliadas em ordem: regras deny são verificadas primeiro, depois regras allow. Se um comando corresponde tanto a um padrão allow quanto deny, a regra deny tem precedência. Isso evita desvios acidentais através de padrões sobrepostos.
Comparação: Agentes vs Skills vs Plugins
| Aspecto | Agente | Skill | Plugin (MCP) |
|---|---|---|---|
| Propósito | Instância de assistente | Pacote de instruções | Ferramenta/serviço externo |
| Config | opencode.json | Manifesto YAML/JSON | Entrada MCP no config |
| Ciclo | Baseado em sessão | Carregamento sob demanda | Processo de longa duração |
| Escopo | Conversação completa | Tarefa específica | Acesso a ferramentas |
| Linguagem | Dependente do modelo | Linguagem natural | Qualquer (Node, Python, Go) |
| Estado | Stateful (conversação) | Stateless (instruções) | Stateful (processo) |
| Exemplo | Agente de codificação | customize-opencode | Servidor MCP filesystem |
| Dependências | Nenhuma | Nenhuma (autocontido) | Runtime (Node, Python, etc.) |
Escolha um agente quando você precisa de um parceiro de conversação persistente com expertise específica. Escolha uma skill quando quiser ensinar a qualquer agente um procedimento repetível. Escolha um plugin quando precisar se conectar a um sistema ou API externa.
Perguntas de Prática
Uma equipe quer que seu assistente de codificação baseado em LLM possa consultar uma API REST interna da empresa. Qual mecanismo do OpenCode eles devem usar?
Um desenvolvedor está criando um pacote reutilizável que ensina um agente a gerar componentes React. Quais três componentes este pacote deve incluir?
De acordo com o registro de ferramentas, quais duas operações podem modificar arquivos e sempre exigem uma regra de permissão explícita?
Um usuário tem um agente de codificação principal e quer adicionar um agente especializado para tarefas de migração de banco de dados. Como este agente especializado se relaciona com o principal?
Você digita uma requisição e o agente principal do OpenCode tenta usar `bash` para instalar um pacote, mas o comando é negado. De acordo com o ciclo de vida da requisição, qual é o motivo mais provável?
- OpenCode é um framework CLI de código aberto para engenharia de software assistida por IA com arquitetura em camadas
- Agentes fornecem assistência baseada em IA através de configurações de modelo e prompt
- Skills são pacotes reutilizáveis de instruções que guiam agentes em tarefas específicas
- MCP (Model Context Protocol) conecta LLMs a ferramentas externas via JSON-RPC
- O registro de ferramentas centraliza o acesso a todas as capacidades (bash, read, write, etc.)
opencode.jsoné o arquivo de configuração único que controla agentes, skills, MCP e permissões- O sistema de permissões aplica segurança com regras de allow/deny e restrições de caminho
- O ciclo de vida da requisição traça a entrada do usuário através do roteamento de agentes, registro de ferramentas, verificações de permissão e execução
- A comunicação MCP segue uma sequência estruturada de inicialização, listagem, chamada e encerramento via JSON-RPC 2.0