SpyBara
Go Premium

plugins/components.md 2026-09-27 23:59 UTC to 2026-09-28 22:01 UTC

This page contains 1 addition and 1 deletion.

2026
Fri 25 23:58 Mon 28 22:59

Adicionar componentes a um plugin

Adicione skills, hooks, servidores MCP e todos os outros tipos de componentes a um plugin Claude Code, com um exemplo que valida cada um.

export const Piece = ({id, children}) =>

{children}
;

export const PluginExplorer = ({children}) => { const PIECES = [{ id: 'manifest', name: 'Manifest', path: '.claude-plugin/plugin.json', required: "Required by Anthropic's directory", lines: [{ depth: 0, kind: 'folder', text: '.claude-plugin/' }, { depth: 1, kind: 'file', text: 'plugin.json' }], href: '/en/plugins/manifest-reference#manifest-file', linkText: 'Go to the manifest reference' }, { id: 'skills', name: 'Skills', path: 'skills/review/SKILL.md', lines: [{ depth: 0, kind: 'folder', text: 'skills/' }, { depth: 1, kind: 'folder', text: 'review/' }, { depth: 2, kind: 'file', text: 'SKILL.md' }], href: '/en/plugins/components#skills', linkText: 'Go to the Skills section' }, { id: 'commands', name: 'Commands', path: 'commands/about.md', lines: [{ depth: 0, kind: 'folder', text: 'commands/' }, { depth: 1, kind: 'file', text: 'about.md' }], href: '/en/plugins/components#commands', linkText: 'Go to the Commands section' }, { id: 'agents', name: 'Agents', path: 'agents/security-reviewer.md', lines: [{ depth: 0, kind: 'folder', text: 'agents/' }, { depth: 1, kind: 'file', text: 'security-reviewer.md' }], href: '/en/plugins/components#agents', linkText: 'Go to the Agents section' }, { id: 'hooks', name: 'Hooks', path: 'hooks/hooks.json', lines: [{ depth: 0, kind: 'folder', text: 'hooks/' }, { depth: 1, kind: 'file', text: 'hooks.json' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'monitors', name: 'Monitors', path: 'monitors/monitors.json', lines: [{ depth: 0, kind: 'folder', text: 'monitors/' }, { depth: 1, kind: 'file', text: 'monitors.json' }], href: '/en/plugins/components#monitors', linkText: 'Go to the Monitors section' }, { id: 'output-styles', name: 'Output styles', path: 'output-styles/terse.md', lines: [{ depth: 0, kind: 'folder', text: 'output-styles/' }, { depth: 1, kind: 'file', text: 'terse.md' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'themes', name: 'Themes', path: 'themes/dracula.json', lines: [{ depth: 0, kind: 'folder', text: 'themes/' }, { depth: 1, kind: 'file', text: 'dracula.json' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'workflows', name: 'Workflows', path: 'workflows/audit-routes.js', lines: [{ depth: 0, kind: 'folder', text: 'workflows/' }, { depth: 1, kind: 'file', text: 'audit-routes.js' }], href: '/en/workflows#distribute-a-workflow-in-a-plugin', linkText: 'Go to Distribute a workflow in a plugin' }, { id: 'bin', name: 'Executables', path: 'bin/hello-plugin', lines: [{ depth: 0, kind: 'folder', text: 'bin/' }, { depth: 1, kind: 'file', text: 'hello-plugin' }], href: '/en/plugins/components#executables', linkText: 'Go to the Executables section' }, { id: 'scripts', name: 'Scripts', path: 'scripts/format.sh', lines: [{ depth: 0, kind: 'folder', text: 'scripts/' }, { depth: 1, kind: 'file', text: 'format.sh' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'settings', name: 'Default settings', path: 'settings.json', lines: [{ depth: 0, kind: 'file', text: 'settings.json' }], href: '/en/plugins/components#default-settings', linkText: 'Go to the Default settings section' }, { id: 'mcp', name: 'MCP servers', path: '.mcp.json', lines: [{ depth: 0, kind: 'file', text: '.mcp.json' }], href: '/en/plugins/components#mcp-servers', linkText: 'Go to the MCP servers section' }, { id: 'lsp', name: 'LSP servers', path: '.lsp.json', lines: [{ depth: 0, kind: 'file', text: '.lsp.json' }], href: '/en/plugins/components#lsp-servers', linkText: 'Go to the LSP servers section' }]; const [selectedId, setSelectedId] = useState('manifest'); const [isFullscreen, setIsFullscreen] = useState(false); const rootRef = useRef(null); useEffect(() => { const onFsChange = () => setIsFullscreen(!!document.fullscreenElement); document.addEventListener('fullscreenchange', onFsChange); return () => document.removeEventListener('fullscreenchange', onFsChange); }, []); const toggleFullscreen = () => { if (!rootRef.current) return; if (document.fullscreenElement) document.exitFullscreen(); else rootRef.current.requestFullscreen().catch(() => {}); }; const selected = PIECES.find(p => p.id === selectedId) || PIECES[0]; const onTreeKeyDown = e => { const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End']; if (keys.indexOf(e.key) === -1) return; const i = PIECES.findIndex(p => p.id === selectedId); let next = i; if (e.key === 'ArrowDown') next = Math.min(PIECES.length - 1, i + 1); if (e.key === 'ArrowUp') next = Math.max(0, i - 1); if (e.key === 'Home') next = 0; if (e.key === 'End') next = PIECES.length - 1; e.preventDefault(); if (next === i) return; const id = PIECES[next].id; setSelectedId(id); const el = document.getElementById('pe-node-' + id); if (el) el.focus(); }; const FolderIcon = () => ; const FileIcon = () => ; return <div ref={rootRef} className={isFullscreen ? 'pe-root pe-fullscreen not-prose' : 'pe-root not-prose'} data-selected={selected.id}>

  <div className="pe-head">
    <div className="pe-head-text">
      <div className="pe-title">What goes in a plugin</div>
      <div className="pe-sub">This example plugin, <code>my-plugin</code>, has one of every kind of component, each in its default location. Select a file or folder to read what it’s for and see what goes in it.</div>
    </div>
    <button type="button" className="pe-fs-btn" onClick={toggleFullscreen} aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
      {isFullscreen ? '⤡' : '⛶'}
    </button>
  </div>

  <div className="pe-body">
    <div className="pe-tree-pane">
      <div className="pe-caption" id="pe-tree-caption">Plugin directory</div>
      <div role="group" aria-labelledby="pe-tree-caption" onKeyDown={onTreeKeyDown}>
        <div className="pe-rootline"><FolderIcon /><span>my-plugin/</span></div>
        {PIECES.map(p => <button key={p.id} id={'pe-node-' + p.id} type="button" className="pe-node" aria-pressed={p.id === selected.id} aria-label={p.name + ', ' + p.path} onClick={() => setSelectedId(p.id)}>
            {p.lines.map((line, i) => <span key={i} className="pe-line pe-line-tree" style={{
paddingLeft: line.depth * 18 + 'px'

}}> {line.kind === 'folder' ? : } {line.text} {p.required && i === p.lines.length - 1 ? {p.required} : null} )} {p.path} {p.required ? {p.required} : null} )}

    <div className="pe-panel" role="region" aria-labelledby="pe-panel-caption" aria-live="polite" aria-atomic="true">
      <div className="pe-caption" id="pe-panel-caption">Selected piece</div>
      <div className="pe-name">{selected.name}{selected.required ? <span className="pe-req">{selected.required}</span> : null}</div>
      <div className="pe-path">{selected.path}</div>

      <div className="pe-block">{children}</div>

      <a className="pe-link" href={selected.href}>{selected.linkText}</a>
    </div>
  </div>
</div>;

};

Um plugin Claude Code é construído a partir de componentes, como skills, agentes, hooks e servidores MCP. Cada componente tem uma pasta padrão no plugin, uma chave de manifesto opcional em .claude-plugin/plugin.json que substitui ou adiciona àquela pasta, e um nome que o usuário vê. Para cada tabela de campos completa da chave, consulte a referência de manifesto.

Use esta página para adicionar um componente a um plugin que já carrega.

Depois de adicionar um componente, execute /reload-plugins em uma sessão em execução ou inicie uma nova para que Claude Code o carregue. Para verificar o arquivo do componente antes de carregá-lo, execute claude plugin validate . no seu shell a partir do diretório do plugin.

Explorar o diretório do plugin

O explorador mostra um plugin de exemplo, my-plugin, que tem um de cada tipo de componente em sua localização padrão:

Cada arquivo é o menor exemplo válido de seu formato, lá para mostrar a forma em vez de ser útil: uma skill ou agente real carrega instruções completas e frequentemente arquivos de suporte, e um hook ou monitor real faz trabalho real. As seções após o explorador usam os mesmos arquivos que seus exemplos e vinculam a versões mais completas. Selecione um arquivo ou pasta para ler para que serve, veja o que entra nele e encontre a seção que o cobre.

O [manifesto](/docs/pt/plugins/manifest-reference) é o arquivo `plugin.json` no diretório `.claude-plugin/` de um plugin. Ele contém os metadados do plugin e os valores `userConfig` que Claude Code solicita ao usuário. Apenas `name` é obrigatório. Neste, `description` é o texto que os usuários veem para o plugin em `/plugin`, e `version` mantém os usuários nessa versão até você alterá-la:
```json theme={null}
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Review, formatting, and database tools for this team"
}
```
Uma [skill](/docs/pt/skills) é um arquivo `SKILL.md`. Salve cada skill em seu próprio diretório em `skills/`. Claude lê a `description` de cada skill, e quando o que o usuário pede corresponde a ela, como pedir a Claude para revisar um pull request aqui, Claude carrega as instruções da skill e as segue. O usuário também pode executá-la diretamente como `/my-plugin:review`:
```markdown theme={null}
---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.
```
Um comando é um único arquivo Markdown que o usuário executa por nome. Comandos são o formato mais antigo: uma skill é executada por nome da mesma forma e também pode carregar arquivos de suporte em seu próprio diretório, então escreva novos como skills e mantenha `commands/` para arquivos que você já tem. Este arquivo se torna `/my-plugin:about` e usa o mesmo frontmatter que uma skill:
```markdown theme={null}
---
description: Summarize the repository
---

Summarize what this repository does in three sentences.
```
Um [subagente](/docs/pt/sub-agents) é um assistente separado, com suas próprias instruções e sua própria janela de contexto, que Claude pode delegar uma tarefa e obter um resultado. Cada arquivo Markdown em `agents/` define um: o frontmatter o nomeia e diz quando usá-lo, e o corpo é seu prompt do sistema. Este é nomeado `my-plugin:security-reviewer`, e o usuário pode invocá-lo com `@agent-my-plugin:security-reviewer`:
```markdown theme={null}
---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
```
Um [hook](/docs/pt/hooks-guide) executa algo automaticamente em um ponto do ciclo de vida do Claude Code, como após cada edição de arquivo: um comando shell, uma solicitação HTTP, uma chamada de ferramenta MCP, um prompt para um modelo ou um subagente. Salve os hooks do plugin em `hooks/hooks.json` na raiz do plugin. Este executa o `scripts/format.sh` do plugin após Claude escrever ou editar um arquivo:
```json theme={null}
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}
```
Um monitor é um comando shell que Claude Code inicia em segundo plano quando a sessão inicia e mantém em execução até que termine, usando a [ferramenta Monitor](/docs/pt/tools-reference#monitor-tool). O que ele imprime chega a Claude como notificações. Um campo `when` pode, em vez disso, iniciá-lo na primeira vez que uma skill nomeada é executada. Este monitora um log de erros:
```json theme={null}
[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]
```
Um plugin pode incluir [estilos de saída](/docs/pt/output-styles), que alteram como Claude formata e expressa suas respostas. Salve cada estilo de saída como `output-styles/.md`. Este aparece em `/output-style` como `my-plugin:terse`:
```markdown theme={null}
---
name: terse
description: Answer in as few words as possible
keep-coding-instructions: true
---

Keep every reply short. Skip preambles and summaries.
```
Um plugin pode incluir [temas de cor](/docs/pt/terminal-config#create-a-custom-theme) para a interface Claude Code. Salve cada tema como `themes/.json`. Este aparece em `/theme` como `Dracula`, marcado como de `my-plugin`:
```json theme={null}
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}
```
A pasta `workflows/` contém arquivos `.js` de [workflow](/docs/pt/workflows): um bloco `meta`, depois um corpo de script que orquestra vários subagentes. Este é executado como `/my-plugin:audit-routes`:
```javascript theme={null}
export const meta = {
  name: 'audit-routes',
  description: 'Audit every route handler for missing auth checks',
}

const found = await agent('List every .ts file under src/routes/.', {
  schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
})

const audits = await pipeline(found.files, file =>
  agent(`Audit ${file} for missing authentication checks.`, { label: file }),
)

return audits.filter(Boolean)
```
`bin/` é como um plugin envia uma ferramenta de linha de comando. Enquanto o plugin está habilitado, Claude Code coloca esta pasta no `PATH` do shell em que executa comandos, para que Claude, ou as instruções de uma skill, possam executar a ferramenta por nome sem o usuário instalar nada. Com este [executável](#executables) em vigor, `hello-plugin` é um comando que Claude pode executar:
```bash theme={null}
#!/bin/bash
echo "hello from my-plugin"
```
O hook em `hooks/hooks.json` executa um script, e esta pasta é onde o exemplo o mantém. O nome `scripts/` é uma convenção, não algo que Claude Code procure: o hook aponta para o arquivo por seu caminho, `${CLAUDE_PLUGIN_ROOT}/scripts/format.sh`. Um script de formatação pode parecer assim:
```bash theme={null}
#!/bin/bash
npx prettier --write .
```
Um `settings.json` na raiz do plugin contém [configurações](/docs/pt/settings-reference) que se aplicam enquanto o plugin está habilitado, para que um plugin possa alterar como a sessão se comporta e não apenas adicionar componentes. Apenas duas chaves têm efeito de um plugin, [`agent`](/docs/pt/settings-reference#agent) e [`subagentStatusLine`](/docs/pt/settings-reference#subagentstatusline); todas as outras chaves são descartadas. Consulte [Configurações padrão](#default-settings).
Este define `agent`, que executa o thread principal da sessão como o agente `security-reviewer` do plugin, para que o prompt do sistema, restrições de ferramentas e modelo desse agente se apliquem a toda a sessão:

```json theme={null}
{
  "agent": "security-reviewer"
}
```
Um [servidor MCP](/docs/pt/mcp) fornece a Claude ferramentas de um sistema externo. Declare-o em `.mcp.json` na raiz do plugin. Este inicia um servidor local a partir de um script dentro do plugin e aparece em `/mcp` como `plugin:my-plugin:db`:
```json theme={null}
{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}
```
Um servidor LSP fornece a Claude [diagnósticos e navegação de código](/docs/pt/plugins/code-intelligence) para uma linguagem. Declare o servidor em `.lsp.json` na raiz do plugin. Este conecta o servidor de linguagem Go para arquivos `.go`:
```json theme={null}
{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}
```

Adicionar cada tipo de componente

Cada seção abaixo cobre um tipo de componente: onde seus arquivos vão no plugin, um exemplo que valida, o que o usuário vê uma vez que o plugin carrega, e a chave de manifesto que altera a localização padrão. Adicione os que seu plugin precisa; nenhum é obrigatório.

Skills

Uma skill é um arquivo SKILL.md que Claude pode carregar quando sua descrição corresponde à tarefa. O usuário também pode executá-la como um comando. Salve cada skill em seu próprio diretório em skills/:

my-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    └── review/
        └── SKILL.md

Dê ao SKILL.md uma description para que Claude saiba quando usá-la:

---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.

Depois de carregar o plugin, /my-plugin:review executa a skill. O nome do comando e quem pode invocá-lo seguem estas regras:

Você também pode colocar skills fora do diretório padrão skills/:

Para incluir instruções em um plugin, escreva-as como uma skill. Claude Code não carrega um CLAUDE.md na raiz do plugin, e claude plugin validate avisa CLAUDE.md at the plugin root is not loaded as project context.

Para campos de frontmatter e arquivos de suporte, consulte Skills.

Comandos

Um comando é um único arquivo Markdown que o usuário executa por nome, como /my-plugin:about.

Salve um comando em commands/<file>.md e ele se torna /<plugin>:<file>. Um subdiretório adiciona um segmento, então commands/db/migrate.md é /my-plugin:db:migrate.

Arquivos de comando usam o mesmo frontmatter que skills.

Definir comandos no manifesto

Você só precisa disso se quiser manter arquivos de comando em algum lugar diferente de commands/, ou para definir um comando curto dentro de plugin.json sem um arquivo Markdown separado. Defina a chave de manifesto commands, e Claude Code a lê em vez de varrer commands/. A chave usa um caminho, uma matriz de caminhos ou um objeto que mapeia cada nome de comando para um arquivo source ou content inline.

Este manifesto define /my-plugin:about inline, sem arquivo Markdown:

{
  "name": "my-plugin",
  "commands": {
    "about": {
      "content": "Summarize what this repository does in three sentences.",
      "description": "Summarize the repository"
    }
  }
}

Carregue o plugin e execute /my-plugin:about na sessão para confirmar que carregou.

Para a sintaxe completa da chave, consulte commands.

Agentes

Um subagente é um assistente separado, com suas próprias instruções e janela de contexto, que Claude pode delegar uma tarefa. Cada arquivo Markdown em agents/ define um:

---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.

Este agente é nomeado my-plugin:security-reviewer, e o usuário pode invocá-lo explicitamente com @agent-my-plugin:security-reviewer. A forma do nome é <plugin>:<name>, onde <name> vem do frontmatter, ou do nome do arquivo quando não há.

A chave agents substitui a varredura agents/.

Organizar agentes em subpastas

Você pode colocar arquivos de agente do plugin em subpastas de agents/. Claude Code os carrega recursivamente e une o nome do plugin, cada nome de subpasta e o nome do arquivo com dois-pontos para formar o nome com escopo do agente. Por exemplo, agents/review/security.md em um plugin nomeado my-plugin carrega como my-plugin:review:security. Duas configurações alteram esse nome:

Campos de frontmatter em agentes de plugin

O frontmatter de um agente de plugin segue estas regras:

Para saber o que cada campo faz e as regras de precedência, consulte Subagentes.

Hooks

Um hook executa algo automaticamente em um ponto do ciclo de vida do Claude Code, como após cada edição de arquivo: um comando shell, uma solicitação HTTP, uma chamada de ferramenta MCP, um prompt para um modelo ou um subagente. Salve os hooks do plugin em hooks/hooks.json na raiz do plugin, sob uma chave "hooks" de nível superior, na mesma forma que o objeto hooks em settings.json. Isso permite copiar um hook de configurações existente sem alterações.

Este hook executa um script agrupado após cada Write ou Edit:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}

Salve o script em scripts/format.sh e torne-o executável.

Carregue o plugin e peça a Claude para editar um arquivo. Um hook PostToolUse que sai com 0 não mostra nada na transcrição, então confirme que foi executado com log de depuração ou pelo que o script em si altera.

Hooks em hooks/hooks.json e na chave de manifesto hooks ambos carregam. Para cada evento e sua carga útil, consulte Eventos de hook.

Quando os hooks do plugin disparam

Os hooks de um plugin não esperam que uma das skills ou comandos do plugin seja usada. Claude Code os registra quando uma sessão carrega o plugin, e eles disparam em seus eventos a partir de então. Para limitar quando um hook é executado, restrinja seu matcher.

Se um hook nunca dispara, consulte hooks que não disparam.

Ambiente, citação e correspondência de ferramentas MCP

O ambiente do hook, a citação de ${CLAUDE_PLUGIN_ROOT} e os matchers para as próprias ferramentas MCP do plugin funcionam da seguinte forma:

Servidores MCP

Um servidor MCP fornece a Claude ferramentas de um sistema externo. Declare-o em .mcp.json na raiz do plugin, na mesma forma que um .mcp.json de projeto. Este .mcp.json declara um servidor nomeado db:

{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}

Você também pode omitir o wrapper mcpServers e colocar db no nível superior do arquivo.

Carregue o plugin e execute /mcp para confirmar que o servidor aparece como plugin:my-plugin:db.

claude plugin validate verifica .mcp.json e relata uma entrada de servidor que Claude Code descartaria no tempo de carregamento como um erro. Requer Claude Code v2.1.281 ou posterior.

Para onde uma entrada ruim aparece no tempo de carregamento, consulte Servidores MCP que não iniciam.

A chave de manifesto mcpServers usa um mapa de servidor inline, um caminho para um arquivo JSON ou uma matriz daqueles. Quando um servidor de manifesto tem o mesmo nome que um em .mcp.json, o servidor de manifesto o substitui.

Alcançar usuários em claude.ai e Cowork

Um servidor stdio local, como o servidor db em Servidores MCP, é executado em Claude Code e em uma sessão Cowork que é executada em sua máquina no aplicativo Claude Desktop, mas não em claude.ai. Para alcançar usuários lá também, referencie um servidor remoto por sua URL https://, que claude.ai e Cowork oferecem ao usuário como um conector.

Nomes de servidor, nomes de ferramentas e recarregamentos

Os nomes do servidor, substituição de variáveis e comportamento de recarga seguem estas regras:

Incluir um servidor MCPB empacotado

A chave mcpServers também aceita um servidor empacotado como um arquivo MCPB, cuja extensão é .mcpb ou a mais antiga .dxt. Aponte a chave para o arquivo, como um caminho dentro do plugin ou uma URL https://:

{
  "name": "my-plugin",
  "mcpServers": "./servers/db.mcpb"
}

O servidor usa seu nome do name no manifesto do pacote.

Para transportes e autenticação, consulte MCP.

Servidores LSP

Um servidor LSP fornece a Claude diagnósticos e navegação de código para uma linguagem. Se um plugin oficial de inteligência de código já cobre sua linguagem, instale esse em vez de escrever um. Caso contrário, declare o servidor em .lsp.json na raiz do plugin:

{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}

O arquivo mapeia cada nome de servidor diretamente para sua configuração, sem objeto wrapper ao redor do mapa. command é o nome do binário, com seus argumentos em args. extensionToLanguage precisa de pelo menos uma extensão, cada uma começando com ..

claude plugin validate não lê este arquivo. Quando qualquer entrada é inválida, o arquivo inteiro é ignorado no carregamento e Invalid LSP server config for ".lsp.json" aparece na aba Errors de /plugin.

Seu plugin configura a conexão mas não instala o binário do servidor, e cada extensão de arquivo obtém um servidor:

A chave de manifesto lspServers usa o mesmo mapa inline, um caminho para um arquivo JSON ou uma matriz daqueles, e seus servidores adicionam aos em .lsp.json. Quando um servidor de manifesto tem o mesmo nome que um em .lsp.json, o servidor de manifesto o substitui.

Para transport, timeouts, reinicializações e os outros campos, consulte lspServers.

Envie a saída de log para stderr, não stdout. Claude Code lê stdout de um servidor apenas como mensagens de protocolo e aceita cabeçalhos de mensagem até 64 KiB e um corpo de mensagem até 32 MiB.

Claude Code desconecta um servidor que excede qualquer limite ou escreve saída não-protocolo para stdout, e conta a desconexão como uma falha para restartOnCrash e maxRestarts. Quando você executa com --debug, Claude Code escreve um erro nomeando a causa para o log de depuração.

Executáveis

Arquivos em bin/ na raiz do plugin estão no PATH do shell da ferramenta Bash enquanto o plugin está habilitado, para que Claude possa executá-los como comandos simples. Adicione um script executável:

#!/bin/bash
echo "hello from my-plugin"

Torne-o executável com chmod +x bin/hello-plugin e carregue o plugin. Quando você pede a Claude para executar hello-plugin, o resultado da ferramenta Bash mostra a saída do script.

Diretórios bin/ de plugin vêm após as entradas PATH do próprio usuário, então um plugin não pode sombrear git, ls ou outro comando do sistema.

claude.ai e Cowork não instalam um plugin que tem um diretório bin/ de nível superior, incluindo um que você distribui através das configurações da organização claude.ai.

Configurações padrão

Para definir padrões que se aplicam enquanto o plugin está habilitado, adicione um settings.json na raiz do plugin, ou coloque o mesmo objeto inline na chave de manifesto settings. Duas chaves têm efeito, agent e subagentStatusLine, e todas as outras chaves são descartadas.

Defina agent para executar um dos próprios agentes do plugin como o thread principal:

{
  "agent": "security-reviewer"
}

Carregue o plugin e inicie uma sessão. Claude então responde na conversa principal com o prompt do sistema e modelo do agente security-reviewer.

Para tudo que a chave controla, consulte a configuração agent.

Quando a mesma chave é definida em mais de um lugar, estas regras decidem qual valor se aplica:

Para a forma subagentStatusLine, consulte linhas de status de subagente.

Temas e estilos de saída

Um plugin pode incluir temas de cor e estilos de saída. Ambos aparecem nos mesmos seletores que os do usuário. Para qualquer um, definir a chave de manifesto substitui a varredura de pasta.

Componente Salvar como Formato Aparece em Chave de manifesto
Tema themes/<slug>.json O formato de arquivo de tema personalizado que os usuários escrevem em ~/.claude/themes/ /theme, sob o name do arquivo experimental.themes
Estilo de saída output-styles/<name>.md O formato de estilo de saída personalizado, com frontmatter name e description /output-style, como <plugin>:<name> outputStyles

Temas de plugin são somente leitura, então quando um usuário edita um em /theme, a edição é salva como uma cópia no diretório de temas próprio.

Este tema recolore o prompt de acento e texto de erro na predefinição escura:

{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}

Canais

Um canal permite que um sistema externo, como um aplicativo de chat, envie mensagens para uma sessão. Em um plugin, um canal é um dos servidores MCP mais uma entrada channels que se vincula a ele e pode solicitar sua própria configuração. Este manifesto vincula um canal a um servidor telegram e solicita um token de bot:

{
  "name": "my-plugin",
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}

server deve corresponder a uma chave em mcpServers. O userConfig por canal usa a mesma forma que a chave userConfig de nível superior.

Para o que o servidor deve implementar e como os usuários habilitam um plugin de canal, consulte Empacotar como um plugin na referência de canais. Para a tabela de campos, consulte channels.

Monitores

Um monitor é um comando shell que é executado em segundo plano para toda a sessão. O que ele imprime chega a Claude como notificações, para que Claude possa reagir a um log ou mudança de status sem ser solicitado a observá-lo. Salve as entradas em monitors/monitors.json:

[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]

O comando é executado em um shell, no diretório de trabalho em que a sessão foi iniciada.

O comando de um monitor é limitado em onde inicia e o que pode referenciar:

A chave de manifesto experimental.monitors usa a mesma matriz inline ou um caminho para um arquivo JSON, e é lida em vez de monitors/monitors.json.

Para o gatilho when e os outros campos, consulte monitors.

Solicitar ao usuário valores de configuração

Declare os valores que seu plugin precisa do usuário na chave de manifesto userConfig, para que os usuários não editem settings.json eles mesmos. Cada opção aparece em um diálogo com seu title como o rótulo e sua description abaixo.

Defina "sensitive": true para um token ou senha. O diálogo então mascara a entrada, e o valor é armazenado em armazenamento seguro em vez de settings.json.

Este manifesto solicita um endpoint e um token:

{
  "name": "my-plugin",
  "userConfig": {
    "api_url": {
      "type": "string",
      "title": "API URL",
      "description": "Base URL of your team's API"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for your team's API",
      "sensitive": true
    }
  }
}

Quando o diálogo de configuração aparece

O diálogo aparece apenas na interface interativa /plugin. Ele abre para qualquer opção que ainda não está definida quando o usuário faz qualquer um dos seguintes:

Para abrir o mesmo diálogo a qualquer momento, o usuário executa /plugin configure <plugin>@<marketplace>.

O comando shell claude plugin install nunca solicita valores userConfig. Para definir valores do shell, passe cada um como --config KEY=VALUE. Quando opções permanecem indefinidas, o comando imprime uma linha userConfig options not yet set que nomeia ambas as formas de defini-las. O diálogo userConfig nunca aparece cita a linha.

Para os campos de opção, onde cada valor é armazenado, como um componente referencia um valor salvo e quais campos rejeitam ${user_config.*}, consulte Configuração do usuário.

Referenciar caminhos de plugin e armazenar dados

Você não sabe onde seu plugin será instalado, então refira-se a seus arquivos e dados através destas variáveis em vez de caminhos fixos. Elas são substituídas em conteúdo de skill, comando e agente, em comandos de hook e monitor, e em configurações de servidor MCP e LSP. Elas também são exportadas para processos de hook, MCP e LSP:

No caminho do diretório de dados, <id> é o identificador do plugin com cada caractere diferente de letras, dígitos, _ e - substituído por -, então my-plugin@my-marketplace se torna my-plugin-my-marketplace.

No Windows, os caminhos substituídos usam barras para frente para que um shell não leia barras invertidas como escapes.

Instalar dependências no diretório de dados

Para um plugin instalado no marketplace, Claude Code instala dependências de pacote Node.js elegíveis automaticamente quando armazena em cache o plugin, então você pode não precisar instalá-las você mesmo. Quando você faz, este hook SessionStart instala node_modules em ${CLAUDE_PLUGIN_DATA} na primeira execução e novamente após uma atualização alterar package.json:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
          }
        ]
      }
    ]
  }
}

Após a primeira sessão, ~/.claude/plugins/data/<id>/node_modules existe. Um servidor MCP pode então definir NODE_PATH para ${CLAUDE_PLUGIN_DATA}/node_modules em seu env. Para quais campos substituem qual variável, consulte Variáveis de ambiente.

Próximos passos