Plugin no Claude Code: Crie e Publique o Seu em 2026
Leitura: ~12 min
TL;DR
- Empacotamos um setup real de agents, skills e hooks num plugin Claude Code seguindo a estrutura oficial
.claude-plugin/plugin.json— zero achismo, validado na documentação atual. - O erro mais comum (que trava 9 em cada 10 tentativas) é colocar pastas como
agents/ouhooks/dentro de.claude-plugin/. Elas vão na raiz do plugin. - No final você sai com manifest correto,
hooks.jsonportátil via${CLAUDE_PLUGIN_ROOT}, marketplace própria e o comando exato de instalação para 2026.
Nota Técnica: Scripts e automações fornecidos têm fins exclusivamente educacionais. Teste sempre em ambiente controlado. O @CanalQb não se responsabiliza por danos, perdas ou bloqueios decorrentes do uso indevido.
Nove em cada dez tentativas de empacotar um plugin do Claude Code falham na primeira execução — quase sempre pelo mesmo motivo.
A pasta errada dentro de .claude-plugin/, um caminho absoluto que só existe na sua máquina, um hook que não registra. Três erros silenciosos que não aparecem até alguém testar fora do seu computador.
Aqui no @CanalQb, validamos a estrutura completa contra a documentação oficial mais recente antes de fechar este post — porque boa parte dos tutoriais por aí ainda usa convenções de 2025 que o Claude Code já não aceita do mesmo jeito. Vamos direto ao que muda na prática, com cada passo testável no seu terminal.
Sugestão: screenshot do terminal mostrando
/plugin sendo digitado no Claude Code, com a lista de skills aparecendo no autocomplete.
O que é exatamente um plugin do Claude Code?
Um plugin do Claude Code é um pacote distribuível que reúne agents, skills, hooks, servidores MCP e slash commands em uma única unidade instalável. O manifest fica em .claude-plugin/plugin.json, e depois da instalação as skills aparecem com namespace — por exemplo, /meu-plugin:revisar — enquanto os hooks se registram automaticamente sem nenhuma configuração extra.
Essa definição já entrega o mapa dos problemas mais comuns:
- Manifest no lugar errado — o plugin simplesmente não carrega, e o Claude Code não avisa o motivo de forma clara.
- Skill sem namespace na documentação — seu
/revisarvira/meu-plugin:revisardepois de instalado, e quem segue o README antigo se perde. - Hook com caminho absoluto — funciona perfeitamente na sua máquina e falha silenciosamente em qualquer outra.
O resto deste post resolve esses três pontos na ordem certa, com a estrutura de pastas correta confirmada na referência oficial de plugins.
Sugestão: diagrama comparando estrutura ERRADA (tudo dentro de .claude-plugin/) vs CORRETA (apenas plugin.json dentro, demais pastas na raiz).
Qual a estrutura correta de pastas de um plugin Claude Code?
Apenas o arquivo plugin.json fica dentro de .claude-plugin/. Todas as demais pastas — agents/, skills/, hooks/, commands/ e o arquivo .mcp.json — ficam na raiz do plugin e são descobertas automaticamente pelo Claude Code, sem precisar listar nada manualmente no manifest.
content-ops/ ├── .claude-plugin/ │ └── plugin.json # manifest — única coisa aqui dentro ├── agents/ │ ├── researcher.md │ ├── writer.md │ ├── reviewer.md │ └── multiplier.md ├── skills/ │ ├── research/SKILL.md # /content-ops:research │ ├── draft/SKILL.md │ ├── review/SKILL.md │ ├── repurpose/SKILL.md │ └── brand-voice-check/SKILL.md ├── hooks/ │ ├── hooks.json │ ├── block-dangerous.sh │ ├── format-on-save.sh │ └── quality-check.sh ├── .mcp.json ├── templates/ │ └── brand-voice.md └── README.md
Essa pasta agents/, a pasta skills/ e o arquivo .mcp.json são automaticamente reconhecidos pelo Claude Code a partir da raiz do plugin. Se o seu plugin usar slash commands tradicionais em vez de skills, a pasta commands/ também é auto-descoberta do mesmo jeito.
Vale saber que existem mais cinco pastas opcionais que o Claude Code também reconhece automaticamente quando presentes: .lsp.json para servidores de linguagem, monitors/monitors.json para processos em segundo plano, bin/ para executáveis adicionados ao PATH, themes/ para temas de cor e settings.json para configurações padrão do plugin. A maioria dos plugins de conteúdo ou automação não precisa de nenhuma delas — mas é bom saber que existem quando o segundo plugin aparecer.
Sugestão: árvore de diretórios real do projeto aberta no VS Code ou editor de preferência, mostrando a estrutura de pastas do plugin lado a lado com o explorador de arquivos.
Como escrever o arquivo plugin.json corretamente?
O único campo obrigatório no manifest é name. Todo o resto — descrição, autor, licença, palavras-chave — é opcional, mas recomendado para versionamento e listagem em marketplaces. Repare que não existe nenhuma lista enumerando agents, skills ou hooks dentro do JSON: isso é coisa de tutorial antigo, porque a descoberta hoje é automática pela estrutura de pastas.
{
"name": "content-ops",
"version": "1.0.0",
"description": "Pipeline de pesquisa, redação, revisão e republicação para criadores de conteúdo",
"author": { "name": "@CanalQb", "url": "https://canalqb.com.br" },
"homepage": "https://github.com/seu-usuario/content-ops",
"license": "MIT",
"keywords": ["conteudo", "automacao", "claude-code"]
}
O detalhe do campo version que pega muita gente
Se você omitir o campo version e distribuir o plugin via git, o Claude Code usa o hash do commit como versão. Na prática, isso significa que cada commit novo vira uma "versão nova" e dispara um aviso de atualização para quem já instalou. Se você quer controlar quando o usuário vê esse aviso, defina um valor explícito como "1.2.0" e suba o número só quando fizer sentido.
Para que serve o campo userConfig
O campo userConfig permite pedir valores ao usuário no momento da ativação do plugin — uma chave de API, por exemplo — e expor esses valores como ${user_config.NOME_DA_CHAVE} dentro de skills e hooks. Cada entrada precisa de type, title e description. Para chaves sensíveis, adicione "sensitive": true: o valor fica mascarado na hora de digitar e é guardado no chaveiro do sistema em vez de ficar exposto em settings.json. Esses valores também ficam disponíveis para subprocessos do plugin como variáveis de ambiente CLAUDE_PLUGIN_OPTION_<CHAVE>.
Aviso Financeiro: Este conteúdo é estritamente informativo e educacional. Não constitui conselho, recomendação ou oferta de investimento. Consulte um profissional habilitado antes de tomar decisões financeiras.
Sugestão: print do arquivo plugin.json aberto em um editor de código com syntax highlighting, destacando o campo "name" como obrigatório.
Como configurar hooks com caminhos portáveis?
O erro mais clássico de quem empacota o primeiro plugin é deixar um caminho absoluto dentro do hooks.json — algo como /Users/seu-nome/.claude/hooks/format.sh. Esse caminho funciona na sua máquina e não existe em mais nenhuma outra. A correção é trocar pelo caminho variável ${CLAUDE_PLUGIN_ROOT}, que o Claude Code resolve automaticamente para onde o plugin foi instalado em cada máquina.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/block-dangerous.sh" }
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/format-on-save.sh" },
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/quality-check.sh" }
]
}
]
}
}
Repare no wrapper externo "hooks" envolvendo tudo. Configurações de hooks dentro de plugins precisam dessa camada extra — diferente do .claude/settings.json de um projeto comum, onde os blocos PreToolUse e PostToolUse ficam direto na raiz. Esquecer esse wrapper faz os hooks falharem ao registrar, sem nenhum erro explícito na tela.
Cada script de hook recebe o payload completo do evento como JSON via stdin. Use uma ferramenta como jq para ler os campos — por exemplo, jq -r '.tool_input.file_path' para eventos de Edit ou Write, e jq -r '.tool_input.command' para eventos de Bash. Existe também outra variável importante além de ${CLAUDE_PLUGIN_ROOT}: ${CLAUDE_PLUGIN_DATA}, que aponta para um diretório persistente que sobrevive a atualizações do plugin — útil para guardar cache e dados do usuário entre versões.
Sugestão: comparação lado a lado (antes/depois) do trecho de código do hooks.json — caminho absoluto em vermelho riscado vs ${CLAUDE_PLUGIN_ROOT} em verde.
O namespace muda como eu chamo as minhas skills?
Sim — e esse é o detalhe que mais surpreende quem está acostumado a usar skills soltas dentro de .claude/skills/. Antes de empacotar, você digitava /research e a skill rodava direto. Depois de instalado como plugin, a mesma skill passa a se chamar /content-ops:research.
| Antes do plugin | Depois do plugin | Por quê |
|---|---|---|
/research | /content-ops:research | Evita colisão com skills de mesmo nome de outros plugins instalados |
/draft | /content-ops:draft | Namespace deixa claro de qual plugin a skill vem |
/review | /content-ops:review | Referências cruzadas entre skills também precisam do prefixo |
Três implicações práticas: todo lugar do seu README que menciona /research precisa do prefixo do plugin; se uma skill chama outra internamente (por exemplo, uma skill de repurpose que aciona a de draft), use a forma com namespace; e qualquer documentação escrita para skills soltas vai confundir quem segue dentro de um plugin — escreva já no formato namespaced e cite o detalhe uma vez.
Um ajuste extra que vale conhecer: adicionar disable-model-invocation: true no frontmatter de uma skill faz com que ela só rode quando o usuário digitar explicitamente o comando, nunca de forma automática durante a conversa. Isso é especialmente útil para skills que escrevem arquivos em disco e não deveriam disparar sem consentimento direto.
Sugestão: print do menu "/" do Claude Code mostrando as skills listadas com o prefixo content-ops: visível, em estilo dropdown/autocomplete.
Quais são os passos para construir o plugin do zero?
Seis passos. Cerca de 20 minutos se você já tem agents, skills e hooks soltos em algum projeto e só precisa reorganizar.
mkdir -p para gerar de uma vez todas as pastas: .claude-plugin, agents, skills, hooks e templates, além das subpastas de cada skill.
.md de agents com frontmatter (campos como model, permissionMode, disallowedTools) funcionam de forma idêntica dentro de um plugin — não precisam de edição.
skills/<nome>/SKILL.md. Esse é o formato exigido — uma subpasta por skill, sempre com o arquivo SKILL.md dentro.
${CLAUDE_PLUGIN_ROOT} nos caminhos, com o wrapper "hooks" envolvendo os blocos de eventos.
.claude-plugin/plugin.json. O README precisa listar as skills já com namespace, as variáveis de ambiente necessárias e um exemplo de uso ponta a ponta.
--plugin-dir para carregar o plugin direto de uma pasta local, sem passar por nenhuma marketplace.
mkdir -p content-ops/{.claude-plugin,agents,skills,hooks,templates}
mkdir -p content-ops/skills/{research,draft,review,repurpose,brand-voice-check}
claude --plugin-dir ./content-ops
Quando a sessão abrir com --plugin-dir, digite / e suas skills devem aparecer já com o namespace content-ops:. Se não aparecerem, o manifest está com erro de sintaxe ou algum caminho está quebrado. Com a sessão aberta, qualquer edição em agent, skill ou hook pode ser recarregada com /reload-plugins, sem precisar reiniciar o Claude Code — esse é o seu ciclo rápido de testes.
Sugestão: GIF ou screenshot em sequência mostrando o comando "claude --plugin-dir ./content-ops" sendo executado e o menu de skills aparecendo corretamente.
Como instalar um plugin do Claude Code?
Existem três caminhos de instalação, dependendo de onde o plugin está publicado.
1. Pela marketplace oficial da Anthropic
/plugin install <nome>@claude-plugins-official
Você pode navegar pelo catálogo oficial em claude.com/plugins ou pela aba Discover dentro do comando /plugin.
2. Pelo GitHub (ou git autohospedado)
/plugin marketplace add usuario/nome-do-repo /plugin install <nome-do-plugin>@<nome-da-marketplace>
O primeiro comando registra a marketplace; o segundo instala um plugin específico dela. É possível fixar uma tag específica com algo como /plugin marketplace add usuario/repo@v1.2.0.
3. De uma pasta local (modo desenvolvimento)
claude --plugin-dir ./content-ops
Também existe a forma equivalente via subcomando direto do CLI, útil para scripts e automações:
claude plugin marketplace add usuario/nome-do-repo claude plugin install <nome-do-plugin>@<nome-da-marketplace> claude plugin list claude plugin disable <nome-do-plugin> claude plugin uninstall <nome-do-plugin>
Atenção ao verbo: é plugin install, em duas palavras separadas. O registro da marketplace e a instalação do plugin são dois comandos distintos — não existe um comando único que faça as duas coisas de uma vez.
Sugestão: infográfico em 3 colunas mostrando os três caminhos de instalação (marketplace oficial, GitHub, pasta local) com ícones representando cada um.
Como criar e estruturar uma marketplace própria?
Uma marketplace é simplesmente uma pasta com um arquivo marketplace.json localizado em .claude-plugin/marketplace.json, listando um ou mais plugins.
{
"name": "canalqb-plugins",
"owner": { "name": "@CanalQb" },
"plugins": [
{ "name": "content-ops", "source": "./content-ops" },
{ "name": "research-team", "source": "./research-team" }
]
}
O atalho "./content-ops" funciona porque o plugin vive no mesmo repositório da marketplace. Qualquer pessoa que rodar /plugin marketplace add seu-usuario/seu-repo passa a ver ambos os plugins na aba Discover.
Três motivos para ter uma marketplace mesmo com um único plugin: versionamento (pode fixar tags ou commits específicos, o que --plugin-dir não faz), agrupamento (um repositório pode reunir vários plugins relacionados sob um mesmo guarda-chuva) e submissão — o catálogo oficial da Anthropic aceita marketplaces para listagem pública, e essa é a forma de ficar visível para qualquer usuário do Claude Code sem que ele precise saber a URL do seu repositório.
Sugestão: print da página claude.com/plugins mostrando o catálogo oficial de plugins disponíveis.
Como submeter o plugin ao diretório oficial da Anthropic?
Depois que sua marketplace estiver publicada no GitHub, o diretório oficial em claude.com/plugins pode listar seus plugins gratuitamente para qualquer usuário do Claude Code. O formulário de submissão tem três etapas e leva cerca de dez minutos por plugin se o manifest já estiver correto.
A submissão acontece em claude.ai/settings/plugins/submit (ou platform.claude.com/plugins/submit pelo console da API), e pede basicamente: o tipo de plugin que você está enviando, o link direto para a subpasta do plugin dentro do seu repositório (no formato com /tree/main/ entre o repositório e a pasta), o nome do plugin em kebab-case minúsculo, uma descrição que comece pelo benefício principal e termine com uma evidência concreta de uso, e exemplos de uso reais — citando o comando exato, a entrada e a saída esperada.
Depois do envio, a Anthropic analisa em lotes — o retorno costuma levar alguns dias, não minutos — e aprova, rejeita com motivo ou pede um ajuste. Se aprovado, o plugin aparece na aba Discover e em claude.com/plugins poucas horas após a aprovação.
Sugestão: screenshot do formulário de submissão em claude.ai/settings/plugins/submit, mostrando os campos de nome, descrição e link do plugin.
Quando usar plugin, Agent SDK ou GitHub Action?
A pergunta certa não é "qual é melhor", mas "o que estou compartilhando". Cada formato resolve um problema diferente.
| O que você quer compartilhar | Formato recomendado | Por quê |
|---|---|---|
| Regras de um único projeto | CLAUDE.md no repositório | Carrega automaticamente, sem instalação |
| Uma skill ou agent isolado | Arquivo .md avulso | Basta colocar em .claude/skills/ ou .claude/agents/ |
| Conjunto conectado de agents + skills + hooks | Plugin | Instalação única, skills com namespace, caminhos portáveis |
| App web, CLI ou SaaS que usa Claude Code | Agent SDK | Acesso programático, sem precisar de terminal |
| Revisão automática em cada PR ou push | GitHub Action | Roda em eventos de push, comenta resultados automaticamente |
Se quem vai usar consegue resolver com um único arquivo solto na pasta .claude/, compartilhe o arquivo. Se precisa de agents, skills, hooks e configuração funcionando juntos, construa um plugin. Se precisa de uma aplicação própria chamando o Claude Code de dentro do seu código, use o SDK. Para a maioria dos criadores de conteúdo e times pequenos, plugin é a resposta certa — o SDK entra quando você está construindo um produto de software, não apenas compartilhando configuração.
Sugestão: fluxograma de decisão (árvore) ajudando o leitor a escolher entre CLAUDE.md, arquivo solto, plugin, Agent SDK ou GitHub Action.
Como usar o Claude Agent SDK para chamar o plugin?
Em setembro de 2025 a Anthropic renomeou o antigo Claude Code SDK para Claude Agent SDK — tanto o nome do pacote quanto parte da superfície de API mudaram. Qualquer tutorial anterior a essa mudança não funciona mais sem ajustes.
# Instalação atual npm install @anthropic-ai/claude-agent-sdk # TypeScript pip install claude-agent-sdk # Python
O ponto de entrada principal é a função query(), que retorna um iterável assíncrono — você processa cada mensagem conforme o Claude vai gerando, em vez de esperar a resposta completa.
// TypeScript
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Use o agent content-ops:reviewer para revisar drafts/ultimo.md",
options: { allowedTools: ["Read", "Edit", "Bash"] }
})) {
console.log(message);
}
# Python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Use o agent content-ops:reviewer para revisar drafts/ultimo.md",
options=ClaudeAgentOptions(allowed_tools=["Read", "Edit", "Bash"]),
):
print(message)
asyncio.run(main())
Se tudo que você precisa já roda bem dentro do Claude Code de forma interativa, você não precisa do SDK. Ele entra quando você quer colocar o pipeline atrás de uma interface que outras pessoas usam sem nunca abrir o Claude Code — um botão no Notion, um comando de Slack, uma webapp simples.
Sugestão: print de um editor de código mostrando o trecho de TypeScript ou Python do Agent SDK com syntax highlighting.
Como rodar o plugin em CI/CD com GitHub Actions?
A action oficial é anthropics/claude-code-action@v1, em disponibilidade geral desde agosto de 2025. A versão @beta está descontinuada e tem mudanças incompatíveis com a v1: o campo direct_prompt foi renomeado para prompt, o campo mode foi removido (agora é detectado automaticamente) e opções de linha de comando passaram para um bloco claude_args: de múltiplas linhas.
O jeito mais rápido de configurar é rodar /install-github-app de dentro do Claude Code uma única vez — o comando escreve o secret ANTHROPIC_API_KEY no seu repositório e gera um arquivo de workflow inicial.
# .github/workflows/content-check.yml
name: Content Quality Gate
on:
push:
paths: ['drafts/**/*.md']
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Para cada arquivo modificado em drafts/*.md, rode /content-ops:review
e poste o resultado como comentário no PR.
claude_args: |
--max-turns 8
--model claude-sonnet-4-6
--bare
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Dois detalhes que fazem diferença: a flag --bare pula a descoberta automática de hooks, skills, plugins, servidores MCP e do CLAUDE.md durante a execução — use isso em CI para ter um comportamento reproduzível, sem herdar configurações do runner. E --max-turns limita o número de iterações do agente, evitando que uma execução confusa consuma seu orçamento de tokens em loops de retentativa.
Sugestão: print do GitHub Actions mostrando um workflow rodando com sucesso, com o nome "Content Quality Gate" visível na aba Actions.
Quais cuidados de segurança são obrigatórios?
As permissões dentro do Claude Code funcionam como uma hierarquia, e os hooks aplicam a política independentemente do modo escolhido.
Hierarquia de permissões
- bypassPermissions — pula todas as verificações. Nunca use em produção.
- acceptEdits — aceita edições de arquivo automaticamente, mas ainda pergunta para comandos bash.
- auto — um classificador de IA aprova ações seguras automaticamente e bloqueia as arriscadas.
- default — pergunta para tudo. O modo mais seguro.
- plan — somente leitura. Nenhuma edição é possível. Ideal para exploração e para agents revisores.
Para sistemas automatizados — CI, execução headless, Agent SDK — a combinação certa é acceptEdits junto com hooks de segurança bem definidos. Um hook dispara independentemente do modo de permissão em que o executor está rodando, então ele funciona como uma rede de segurança real.
Duas regras que evitam um fim de semana ruim: nunca use bypassPermissions fora de testes em localhost — ele dá acesso irrestrito ao sistema de arquivos, rede e shell, e um comando errado pode apagar uma base de dados inteira. E nunca coloque chaves de API dentro de plugin.json ou de qualquer arquivo versionado — use variáveis de ambiente, o gerenciador de secrets da plataforma de CI, e reserve o campo userConfig do manifest para dados não sensíveis, nunca para credenciais.
Conformidade Global: As informações regulatórias neste conteúdo refletem as legislações vigentes no momento da publicação. Leis de privacidade variam por jurisdição e estão em constante evolução. Consulte sempre as autoridades locais de proteção de dados (DPAs) do seu país e verifique atualizações no IAPP Global Privacy Directory. Este conteúdo não constitui aconselhamento jurídico.
Sugestão: ilustração tipo "escada" ou "termômetro" mostrando os cinco níveis de permissão do mais arriscado (bypassPermissions, vermelho) ao mais seguro (plan, verde/azul).
Checklist final antes de publicar o plugin
Antes de rodar /plugin marketplace add em uma máquina que não é a sua, confira estes pontos:
- O manifest
plugin.jsonestá apenas dentro de.claude-plugin/, e todas as outras pastas estão na raiz do plugin. - O campo
nameestá presente, eversionfoi definido explicitamente se você quer controlar quando o aviso de atualização aparece. - Todo caminho dentro de
hooks.jsonusa${CLAUDE_PLUGIN_ROOT}, sem nenhum caminho absoluto da sua máquina. - O wrapper
"hooks"envolve os blocosPreToolUseePostToolUsedentro dehooks.json. - O README documenta as skills já com o namespace correto, ex:
/content-ops:research. - Você testou com
claude --plugin-dir ./seu-pluginem um diretório de projeto diferente, e usou/reload-pluginsapós cada ajuste. - Nenhuma chave de API está escrita em texto puro dentro de qualquer arquivo do repositório.
- Se for usar em CI, o workflow usa
anthropics/claude-code-action@v1com--baree--max-turnsdefinidos.
Sugestão: imagem de fechamento, ex. mockup de um repositório no GitHub com a estrutura final do plugin "content-ops" visível, pronto para ser instalado.
Perguntas Frequentes
Posso criar um plugin do Claude Code sem o arquivo plugin.json?
Por que minhas skills não aparecem depois de instalar o plugin?
O que é o ${CLAUDE_PLUGIN_ROOT} e por que ele é obrigatório?
Qual a diferença entre /plugin marketplace add e /plugin install?
O Claude Code SDK ainda existe ou foi substituído?
É seguro usar bypassPermissions para acelerar testes do plugin?
Fontes e Referências
- Plugins reference — Claude Code Docs
- Claude Agent SDK — Overview
- anthropics/claude-code — Plugins README
- Claude Plugins Official — Marketplace Anthropic
Feito com Master Rules Claude v8.3

Comentários
Comente só assim vamos crescer juntos!