Build This Now
Build This Now
Atalhos de TecladoGuia da Status Line
Guia de HooksHooks Multiplataforma para o Claude CodeHooks de Setup do Claude CodeStop HooksAgentes Claude Code Auto-ValidantesHooks de Ciclo de Vida de Sessão do Claude CodeHooks de Backup de Contexto para o Claude CodeHook de Ativação de SkillsHook de Permissões do Claude CodeMCP Tool Hooks no Claude Code
speedy_devvkoen_salo
Blog/Toolkit/Hooks/MCP Tool Hooks in Claude Code

MCP Tool Hooks no Claude Code

Como chamar ferramentas de servidores MCP diretamente dos hooks do Claude Code usando type: mcp_tool — schema, sintaxe de substituição, casos de uso e padrões para produção.

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.

Published Apr 24, 20269 min readToolkit hubHooks index

O problema: os teus hooks executam shell scripts. Cada vez que um hook precisa chamar um servidor MCP, ele cria um subprocesso, configura o transporte, trata autenticação, faz o parse da resposta e formata a saída JSON de volta ao stdout. Para um formatter ou uma verificação de segurança que dispara a cada escrita de ficheiro, esse overhead vai acumulando.

A solução rápida: a partir da v2.1.118, os hooks têm um novo tipo que chama ferramentas MCP diretamente. Adiciona isto ao .claude/settings.json para executar um scan de segurança depois de cada escrita de ficheiro, sem subprocesso nenhum:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "semgrep",
            "tool": "scan_file",
            "input": { "path": "${tool_input.file_path}" }
          }
        ]
      }
    ]
  }
}

O servidor MCP já está a correr. O hook ignora completamente o shell e chama diretamente a conexão RPC do servidor. O output de texto da ferramenta passa pelo mesmo parser de decisões JSON que qualquer hook de comando.

O que é type: "mcp_tool" na prática

Antes da v2.1.118, os hooks tinham quatro tipos de handler: command, http, prompt e agent. Agora são cinco:

TipoO que executa
commandSubprocesso shell (stdin/stdout)
httpPOST para um endpoint URL
mcp_toolChamada RPC direta a um servidor MCP conectado
promptAvaliação LLM de turno único (Haiku por omissão)
agentSubagente multi-turno com acesso Read/Grep/Glob

O tipo mcp_tool funciona com todos os eventos de hook, igual ao command e ao http. A única ressalva prática: SessionStart e Setup disparam enquanto os servidores ainda estão a conectar, por isso esses hooks podem receber um erro "servidor não conectado" na primeira execução. As seguintes correm bem.

O Schema Completo

Três campos são específicos dos hooks mcp_tool. Os restantes são partilhados entre todos os tipos de hook:

{
  "type": "mcp_tool",
  "server": "my-mcp-server",
  "tool": "tool_name",
  "input": {
    "arg1": "${tool_input.file_path}",
    "arg2": "${session_id}"
  },
  "timeout": 30,
  "statusMessage": "Checking...",
  "if": "Edit(*.ts|*.tsx)"
}
CampoObrigatórioDescrição
serverSIMNome exato do servidor MCP conforme configurado nas settings
toolSIMNome da ferramenta nesse servidor
inputnãoArgumentos passados à ferramenta. Suporta substituição ${path}
timeoutnãoSegundos antes de o hook ser cancelado
statusMessagenãoTexto do spinner mostrado enquanto o hook corre
ifnãoFiltro de sintaxe de regras de permissão. O hook só dispara quando a chamada completa corresponde

Atenção: server tem de corresponder exatamente ao nome do servidor na tua configuração MCP. Uma única diferença de caractere faz o hook falhar silenciosamente com um erro não bloqueante.

Substituição de Input

Os valores de string em input suportam notação de ponto ${field.path} para aceder ao JSON completo do evento do hook. Para um hook PostToolUse numa chamada Write, o JSON do evento é assim:

{
  "session_id": "abc123",
  "cwd": "/your/project",
  "hook_event_name": "PostToolUse",
  "tool_name": "Write",
  "tool_use_id": "toolu_01...",
  "tool_input": {
    "file_path": "/your/project/src/api.ts",
    "content": "..."
  },
  "tool_response": { "filePath": "/your/project/src/api.ts", "success": true },
  "duration_ms": 142
}

Então "${tool_input.file_path}" resolve para /your/project/src/api.ts. Qualquer campo desse objeto é acessível. O campo duration_ms foi adicionado na v2.1.119, uma release depois do mcp_tool ter chegado.

Como o Output é Processado

O conteúdo de texto da ferramenta MCP é tratado exatamente como o stdout de um hook de comando. Se fizer parse como JSON válido, o Claude Code age sobre os campos de decisão. Se não, o texto torna-se contexto para o Claude.

Os campos de decisão funcionam igual a qualquer hook:

{
  "decision": "block",
  "reason": "Security issue found in src/api.ts: SQL injection risk on line 42."
}

Retorna isto num hook PostToolUse de ferramenta MCP e o Claude recebe a mensagem e corrige o ficheiro. A ferramenta já executou, por isso isto é consultivo, não preventivo. Para bloquear antes de uma ferramenta correr, usa PreToolUse e retorna permissionDecision: "deny".

Um campo é exclusivo dos hooks mcp_tool em PostToolUse: updatedMCPToolOutput. Substitui o que o Claude vê como output da ferramenta antes de entrar na conversa. Um servidor MCP a correr pode pós-processar o resultado de outra ferramenta antes de o Claude o ler.

Porquê Isto Importa vs. Hooks de Comando Shell

Há duas diferenças concretas, não só velocidade.

Servidores com estado. Um subprocesso shell começa do zero cada vez. Um servidor MCP é um processo vivo com o seu próprio estado: configurações carregadas, conexões abertas, caches, contexto de sessão acumulado. Um MCP de linting que fez o parse do teu tsconfig.json no arranque não o volta a fazer em cada escrita de ficheiro. Um hook de comando faz.

Sem dependência do ambiente shell. Os hooks de comando falham silenciosamente quando o PATH está errado, quando o jq não está instalado, quando o ~/.zshrc imprime algo no stdout em shells não-interativas. Os hooks de ferramenta MCP contornam tudo isso. A chamada vai diretamente do Claude Code para o servidor pela conexão RPC existente.

O Campo if: Restringe os Teus Hooks

Sem if, um hook dispara em cada evento que corresponde ao matcher. Com if, o processo do hook só é criado quando a chamada completa à ferramenta (nome e argumentos) corresponde à sintaxe de regras de permissão:

{
  "type": "mcp_tool",
  "server": "semgrep",
  "tool": "scan_file",
  "if": "Edit(*.py|*.ts|*.js)",
  "input": { "path": "${tool_input.file_path}" }
}

Este hook nunca corre em ficheiros .md ou .json. Num projeto com muitas edições de documentação, essa diferença de performance é real.

Padrão 1: Scan de Segurança em Cada Escrita

Um servidor MCP de segurança que aceita um caminho de ficheiro e retorna findings. Bloqueia o Claude se encontrar algo:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "semgrep",
            "tool": "scan_file",
            "if": "Write(*.ts|*.py|*.js|*.go)",
            "input": { "path": "${tool_input.file_path}" },
            "statusMessage": "Scanning..."
          }
        ]
      }
    ]
  }
}

Se a ferramenta MCP retornar um finding, estrutura a resposta assim:

{
  "decision": "block",
  "reason": "Semgrep finding: [description of issue at line N]"
}

O Claude recebe a mensagem de bloqueio e rework o ficheiro. O scan corre no ruleset em cache do servidor, não num parse de subprocesso a arrancar do zero.

Padrão 2: Hook Stop com Verificação Externa

Um hook Stop que chama um MCP do Linear ou Jira para verificar se o ticket relacionado está mesmo fechado antes de deixar o Claude declarar que terminou:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "linear",
            "tool": "get_issue_status",
            "input": { "issue_id": "${tool_input.issue_id}" }
          }
        ]
      }
    ]
  }
}

A ferramenta MCP retorna o estado do ticket. Se vier como In Progress, o JSON de resposta deve ter decision: "block" e uma razão. O Claude continua a trabalhar.

Verifica sempre stop_hook_active na lógica do teu hook Stop. O JSON do evento inclui este campo como "true" quando o Claude já está a continuar de um disparo anterior do hook Stop. Um servidor que não verifica isto cria um loop infinito. Incorpora a proteção na ferramenta MCP: se stop_hook_active for "true" no input, retorna output vazio e sai limpo.

Padrão 3: Verificação de Erros de Produção Antes de Parar

Depois de o Claude terminar uma funcionalidade, verifica se algo novo quebrou em staging antes de marcar a sessão como completa. Um MCP do Sentry trata a consulta:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "sentry",
            "tool": "get_new_errors_since",
            "input": { "minutes": "5", "skip_if_active": "${stop_hook_active}" }
          }
        ]
      }
    ]
  }
}

Se apareceram novos erros nos últimos cinco minutos, a ferramenta MCP retorna-os junto com decision: "block". O Claude lê os detalhes do erro e corrige a regressão antes de parar.

Padrão 4: Injeção Automática de Docs Antes de Cada Prompt

Um hook UserPromptSubmit com um MCP Context7 que vai buscar documentação atualizada de qualquer biblioteca mencionada no prompt, antes de o Claude o processar:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "context7",
            "tool": "get_library_docs",
            "input": { "prompt": "${prompt}" },
            "timeout": 15
          }
        ]
      }
    ]
  }
}

Antes, isto exigia que o Claude chamasse explicitamente a ferramenta MCP. Agora acontece automaticamente em cada prompt. O Claude começa com docs atuais em vez de dados de treino.

Padrão 5: Aplicação de Políticas para Equipas de Agentes

Em workflows multi-agente, um servidor MCP de políticas partilhado pode controlar quais agentes escrevem em quais diretórios. A variável de ambiente CLAUDE_AGENT_NAME identifica o agente atual. Um hook PreToolUse chama o servidor de políticas:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "policy-server",
            "tool": "check_write_permission",
            "input": {
              "agent": "${agent_name}",
              "path": "${tool_input.file_path}"
            }
          }
        ]
      }
    ]
  }
}

O servidor de políticas tem o mapa de autorização completo. Atualiza o servidor uma vez e todos os agentes em todos os projetos herdam as novas regras, sem tocar num único settings.json.

Padrão 6: Hooks de Ferramenta MCP no Frontmatter de Agentes

Os hooks não têm de viver no settings.json. Podem ficar no frontmatter YAML de um agente, com scope para o ciclo de vida desse agente:

---
name: backend-developer
description: Builds API endpoints and database logic
hooks:
  PostToolUse:
    - matcher: "Write"
      hooks:
        - type: mcp_tool
          server: semgrep
          tool: scan_file
          input: { "path": "${tool_input.file_path}" }
  Stop:
    - hooks:
        - type: agent
          prompt: "Verify all API endpoints have corresponding tests. Block if any are missing."
---

Cada agente especialista numa equipa orquestrada traz a sua própria lógica de validação. O agente de backend faz scan de segurança. O agente de frontend verifica acessibilidade. Nenhum precisa de um hook global que se aplique a toda a gente.

Controlo de Elicitation

O evento Elicitation dispara quando um servidor MCP pede input ao utilizador a meio de uma tarefa. Um hook mcp_tool pode responder automaticamente a prompts conhecidos chamando um gestor de segredos:

{
  "hooks": {
    "Elicitation": [
      {
        "matcher": "my-db-server",
        "hooks": [
          {
            "type": "mcp_tool",
            "server": "secrets-manager",
            "tool": "get_credential",
            "input": { "key": "${elicitation.field_name}" }
          }
        ]
      }
    ]
  }
}

Os prompts de credenciais previsíveis resolvem-se automaticamente. A tarefa corre sem interrupção.

Servidores MCP que Combinam Bem com Hooks

Nem todos os servidores MCP fazem sentido como alvo de hooks. Os que melhor se encaixam são ferramentas que precisam de disparar em eventos específicos sem intervenção do utilizador:

ServidorEventoO que faz
SemgrepPostToolUse: WriteScan de segurança em cada escrita
SentryStopVerifica erros novos em staging antes de completar
Linear / JiraStop, TaskCompletedVerifica estado do ticket, atualiza na conclusão
Context7UserPromptSubmitVai buscar docs atuais das bibliotecas mencionadas
ElevenLabsStop, NotificationÁudio TTS na conclusão de tarefas
SlackNotification, StopAlertas de equipa sem boilerplate de curl
E2BStopExecuta scripts gerados numa sandbox antes de marcar como concluído
claude-memPostCompact, SessionStartRestaura contexto de sessão depois de compaction
n8nTaskCompletedDispara um workflow externo na conclusão

Bug Conhecido: PostToolUse + Eventos MCP + additionalContext

Existe um bug aberto (GitHub issue #24788) onde additionalContext de hooks é silenciosamente descartado quando o evento que o desencadeou foi uma chamada de ferramenta MCP. Isto afeta hooks type: "command" que respondem a eventos de ferramentas MCP, não os hooks mcp_tool em si.

A distinção é importante: hooks que SÃO invocações MCP funcionam bem. Hooks que RESPONDEM A chamadas de ferramentas MCP e retornam additionalContext não. A solução é usar exit 2 mais stderr para mensagens críticas de hooks PostToolUse que visam chamadas de ferramentas MCP. O padrão de bloqueio funciona; a injeção consultiva não.

Os Hooks de Ferramenta MCP São a Última Peça em Falta

Antes, os hooks eram uma rede de segurança. Comandos shell que podiam bloquear coisas perigosas ou correr formatters. Sem estado, locais ao processo, desconectados de tudo o que os teus servidores MCP já sabem.

Depois: os hooks são uma camada de orquestração determinística. Qualquer evento, qualquer ferramenta MCP, controlo total de decisões, com estado que persiste entre chamadas e sem overhead de subprocessos.

O pipeline está agora completo. PreToolUse valida. PostToolUse formata e faz scan. PostToolBatch corre testes. Stop verifica com dados externos reais. Cada passo pode ser uma invocação de ferramenta MCP, e nenhum deles precisa de um shell script.

Continue in Hooks

  • Hooks de Setup do Claude Code
    Combina scripts, agentes e documentação em hooks de setup do Claude Code. Um comando corre um script determinístico, passa o output para um agente de diagnóstico, e regista documentação viva.
  • Hooks de Backup de Contexto para o Claude Code
    Um hook de backup de contexto do Claude Code baseado em StatusLine. Escreve snapshots estruturados a cada 10K tokens para que a compactação automática nunca apague erros, assinaturas nem decisões.
  • Hooks Multiplataforma para o Claude Code
    Hooks do Claude Code multiplataforma: elimina wrappers .cmd, .sh e .ps1 e invoca node diretamente para que um único ficheiro .mjs corra em macOS, Linux e Windows por toda a equipa.
  • Guia de Hooks
    Hooks do Claude Code do princípio ao fim: exit codes, output JSON, comandos assíncronos, endpoints HTTP, matchers PreToolUse e PostToolUse, padrões para produção.
  • Hook de Permissões do Claude Code
    Instala um hook de permissões em três camadas para o Claude Code: aprovação instantânea para chamadas seguras, recusa instantânea para as perigosas, e verificação LLM para a zona cinzenta. Sem flag de skip.
  • Agentes Claude Code Auto-Validantes
    Agentes Claude Code auto-validantes: liga hooks PostToolUse de lint, hooks Stop e sub-agentes revisores em modo só-leitura às definições dos agentes para que output de má qualidade nunca seja entregue.

More from Toolkit

  • Atalhos de Teclado
    Configure o keybindings.json do Claude Code: 17 contextos, sintaxe de teclas, sequências de acordes, combinações de modificadores e como desvincular qualquer atalho padrão instantaneamente.
  • Guia da Status Line
    Configure uma status line no Claude Code para ver o nome do modelo, branch do git, custo da sessão e uso do contexto. Configuração via settings.json, input JSON, scripts em bash, Python e Node.js.
  • Otimização de SEO e GEO com IA
    Um resumo sobre Generative Engine Optimization: como fazer com que o teu conteúdo seja citado dentro das respostas do ChatGPT, Claude e Perplexity, em vez de apenas aparecer no Google.
  • Claude Code vs Cursor em 2026
    Uma comparação lado a lado entre Claude Code e Cursor em 2026: modelos de agente, janelas de contexto, planos de preço e como cada ferramenta se encaixa em diferentes fluxos de trabalho.

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.

On this page

O que é type: "mcp_tool" na prática
O Schema Completo
Substituição de Input
Como o Output é Processado
Porquê Isto Importa vs. Hooks de Comando Shell
O Campo if: Restringe os Teus Hooks
Padrão 1: Scan de Segurança em Cada Escrita
Padrão 2: Hook Stop com Verificação Externa
Padrão 3: Verificação de Erros de Produção Antes de Parar
Padrão 4: Injeção Automática de Docs Antes de Cada Prompt
Padrão 5: Aplicação de Políticas para Equipas de Agentes
Padrão 6: Hooks de Ferramenta MCP no Frontmatter de Agentes
Controlo de Elicitation
Servidores MCP que Combinam Bem com Hooks
Bug Conhecido: PostToolUse + Eventos MCP + additionalContext
Os Hooks de Ferramenta MCP São a Última Peça em Falta

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.