Skip to main content
Ferramentas personalizadas estendem o Agent SDK permitindo que você defina suas próprias funções que Claude pode chamar durante uma conversa. Usando o servidor MCP em processo do SDK, você pode dar a Claude acesso a bancos de dados, APIs externas, lógica específica do domínio ou qualquer outra capacidade que sua aplicação necessite.

Referência rápida

Criar uma ferramenta personalizada

Uma ferramenta é definida por quatro partes, passadas como argumentos para o auxiliar tool() em TypeScript ou o decorador @tool em Python:
  • Nome: um identificador único que Claude usa para chamar a ferramenta.
  • Descrição: o que a ferramenta faz. Claude lê isso para decidir quando chamá-la.
  • Esquema de entrada: os argumentos que a ferramenta aceita, declarados conforme a linguagem:
    • TypeScript: um esquema Zod. Os args do manipulador obtêm seus tipos a partir dele. Chame .describe() em um campo para dar a ele uma descrição que Claude vê.
    • Python: um dicionário mapeando nomes para tipos, como {"latitude": float}, que o SDK converte para JSON Schema para você. Envolva um tipo em Annotated, como {"latitude": Annotated[float, "Latitude coordinate"]}, para dar ao campo uma descrição que Claude vê. O decorador também aceita um dicionário completo de JSON Schema diretamente quando você precisa de enums, intervalos, campos opcionais ou objetos aninhados.
  • Manipulador: a função assíncrona que é executada quando Claude chama a ferramenta. Ela recebe os argumentos validados e deve retornar um objeto com:
    • content (obrigatório): um array de blocos de resultado, cada um com um type de "text", "image", "audio", "resource" ou "resource_link". Veja Retornar imagens e recursos para blocos não-texto.
    • structuredContent (opcional): um objeto JSON contendo o resultado como dados legíveis por máquina, retornado junto com content. Veja Retornar dados estruturados.
    • isError (opcional): defina como true para sinalizar uma falha da ferramenta para que Claude possa reagir a ela. Veja Tratar erros.
Após definir uma ferramenta, envolva-a em um servidor com createSdkMcpServer (TypeScript) ou create_sdk_mcp_server (Python). O servidor é executado no processo dentro de sua aplicação, não como um processo separado. Os exemplos em Python nesta página que fazem requisições HTTP usam httpx. Adicione-o com o gerenciador de pacotes que seu projeto usa:

Exemplo de ferramenta de clima

Este exemplo define uma ferramenta get_temperature e a envolve em um servidor MCP, sem passar o servidor para query. Para executar a ferramenta, veja Chamar uma ferramenta personalizada abaixo.
Veja a referência TypeScript tool() ou a referência Python @tool para detalhes completos dos parâmetros, incluindo formatos de entrada JSON Schema e estrutura de valor de retorno.

Tornar um parâmetro opcional

Para tornar um parâmetro opcional, declare-o como opcional no esquema e aplique o padrão no manipulador:
  • TypeScript: adicione .optional() ao campo Zod.
  • Python: o esquema de dicionário exige todas as chaves. Use a forma JSON Schema, deixe o parâmetro fora de required e leia-o com args.get(). Para um esquema tipado com chaves opcionais, veja classe TypedDict.
A ferramenta get_precipitation_chance abaixo mostra ambos os padrões.

Chamar uma ferramenta personalizada

Passe o servidor MCP que você criou para query via a opção mcpServers. O nome totalmente qualificado de cada ferramenta é mcp__{server_name}__{tool_name}, onde {server_name} é a chave que você atribui ao servidor em mcpServers. Se a chave contiver caracteres como . ou espaços, substitua-os por _ ao escrever {server_name}. Liste o nome totalmente qualificado em allowedTools para que a ferramenta seja executada sem um prompt de permissão. Estes trechos reutilizam o weatherServer do exemplo de ferramenta de clima para perguntar a Claude qual é o clima em um local específico.
Combine este trecho com as definições de ferramenta e servidor do exemplo de ferramenta de clima em um arquivo, weather.py ou weather.ts, depois execute-o a partir do seu terminal:
Claude chama get_temperature e o script imprime uma resposta de uma linha com a temperatura atual em San Francisco.

Adicionar mais ferramentas

Um servidor contém quantas ferramentas você listar em seu array tools. Com mais de uma ferramenta em um servidor, você pode listar cada uma em allowedTools individualmente ou usar o curinga mcp__weather__* para cobrir todas as ferramentas que o servidor expõe. O exemplo abaixo define uma segunda ferramenta, get_precipitation_chance, e substitui a definição de weatherServer do exemplo de ferramenta de clima por uma que lista ambas as ferramentas no array.
Tool search está ativado por padrão e adia ferramentas SDK MCP: Claude vê o nome de cada ferramenta em uma lista compacta e carrega seu esquema completo sob demanda. Com a busca de ferramentas desativada, cada ferramenta neste array consome espaço da janela de contexto a cada turno. Em TypeScript, passe alwaysLoad: true no argumento extras de tool() ou nas opções de createSdkMcpServer() para manter o esquema completo de uma ferramenta no prompt inicial.

Adicionar anotações de ferramenta

Anotações de ferramenta são metadados opcionais descrevendo como uma ferramenta se comporta. Passe-as como o quinto argumento para o auxiliar tool() em TypeScript ou via o argumento de palavra-chave annotations para o decorador @tool em Python. Todos os campos de dica são Booleanos. Anotações são metadados, não imposição. Uma ferramenta marcada com readOnlyHint: true ainda pode escrever em disco se isso for o que o manipulador faz. Mantenha a anotação precisa em relação ao manipulador. Este exemplo adiciona readOnlyHint à ferramenta get_temperature do exemplo de ferramenta de clima.
Veja ToolAnnotations na referência TypeScript ou Python.

Controlar o acesso à ferramenta

O exemplo de ferramenta de clima registrou um servidor e listou ferramentas em allowedTools. Esta seção aborda como definir o escopo de acesso quando você tem múltiplas ferramentas ou deseja restringir as ferramentas integradas. Para saber como os nomes das ferramentas são construídos, consulte Chamar uma ferramenta personalizada.

Configurar ferramentas permitidas

A opção tools e as listas de permitidas/não permitidas afetam duas camadas: disponibilidade, que controla se uma ferramenta aparece no contexto do Claude, e permissão, que controla se uma chamada é aprovada uma vez que Claude tenta usá-la. tools e entradas disallowedTools com nome simples alteram a disponibilidade. allowedTools e regras disallowedTools com escopo alteram a permissão. Se você nomear uma das ferramentas de rastreamento de tarefas em allowedTools, Claude Code também ativa a sessão. Para remover uma ferramenta integrada completamente, omita-a de tools ou liste seu nome simples em disallowedTools (Python: disallowed_tools); ambas mantêm a ferramenta fora do contexto para que Claude nunca tente usá-la. Uma regra disallowedTools com escopo bloqueia as chamadas correspondentes, mas deixa a ferramenta visível, então Claude pode desperdiçar um turno tentando usá-la. Consulte Configurar permissões para a ordem de avaliação completa.

Tratar erros

Um erro de handler não interrompe o loop do agente. O servidor MCP em processo do SDK captura exceções não capturadas e as retorna como resultados de erro, portanto, a forma como você relata um erro determina o que Claude lê, não se a consulta falha: Em ambos os casos, Claude pode tentar novamente, tentar uma ferramenta diferente ou explicar a falha. Capture erros você mesmo quando a mensagem de exceção bruta não for suficiente para Claude agir. O exemplo abaixo captura dois tipos de falhas dentro do handler e compõe a mensagem de erro que Claude lê. Um status HTTP diferente de 200 é capturado da resposta e retornado como um resultado de erro. Um erro de rede ou JSON inválido é capturado pelo try/except (Python) ou try/catch (TypeScript) circundante e também retornado como um resultado de erro. Em ambos os casos, Claude recebe uma mensagem que descreve a falha em vez de uma string de exceção bruta.

Retornar imagens e recursos

O array content em um resultado de ferramenta aceita blocos text, image, audio, resource e resource_link. Você pode misturá-los na mesma resposta. Em TypeScript, o SDK salva blocos de áudio em disco e Claude recebe um bloco de texto com o caminho do arquivo salvo; em Python, o SDK remove blocos de áudio do resultado da ferramenta e registra um aviso. Claude recebe cada bloco de link de recurso como um bloco de texto contendo o nome, URI e descrição do link. Em TypeScript, sua aplicação também recebe os links como resourceLinks no tool_use_result da mensagem do usuário; em Python, o SDK os achata para texto antes que a CLI veja o resultado, portanto a chave resourceLinks do Python nunca é produzida para ferramentas em processo.

Imagens

Um bloco de imagem carrega os bytes da imagem inline, codificados em base64. Não há campo de URL. Para retornar uma imagem que existe em uma URL, busque-a no manipulador, leia os bytes da resposta e codifique-os em base64 antes de retornar. Uma imagem PNG, JPEG, GIF ou WebP chega a Claude como entrada visual; uma imagem de qualquer outro tipo é salva em disco e Claude recebe seu caminho de arquivo como texto.

Recursos

Um bloco de recurso incorpora um pedaço de conteúdo identificado por uma URI. O conteúdo real fica no campo text ou blob do bloco. Use isso quando sua ferramenta produz um arquivo gerado ou um registro de um sistema externo. Este exemplo mostra um bloco de recurso retornado de dentro de um manipulador de ferramenta. O SDK não lê do URI do exemplo, file:///tmp/report.md.
Essas formas de bloco vêm do tipo MCP CallToolResult. Consulte a especificação MCP para a definição completa.

Retornar dados estruturados

structuredContent é um objeto JSON opcional no resultado, separado do array content. Use-o para retornar valores brutos que Claude possa ler como campos exatos em vez de analisá-los de uma string de texto ou imagem. Quando structuredContent é definido, Claude recebe o JSON mais qualquer bloco de imagem ou recurso de content. Blocos de texto em content não são encaminhados, pois presume-se que duplicam os dados estruturados. O exemplo abaixo renderiza um gráfico como um bloco de imagem e retorna os pontos de dados por trás dele em structuredContent do mesmo manipulador. No trecho, chartPngBuffer é um Buffer contendo os bytes PNG renderizados.
TypeScript
O decorador Python @tool encaminha apenas content e is_error do dict de retorno do manipulador. Para retornar structuredContent do Python, execute um servidor MCP autônomo em vez de um servidor SDK em processo.

Exemplo: conversor de unidades

Esta ferramenta converte valores entre unidades de comprimento, temperatura e peso. Um usuário pode perguntar “converter 100 quilômetros para milhas” ou “quanto é 72°F em Celsius”, e Claude escolhe o tipo de unidade correto e as unidades da solicitação. Demonstra dois padrões:
  • Esquemas Enum: unit_type é restrito a um conjunto fixo de valores. Em TypeScript, use z.enum(). Em Python, o esquema dict não suporta enums, portanto o dict de JSON Schema completo é necessário.
  • Tratamento de entrada não suportada: quando um par de conversão não é encontrado, o manipulador retorna isError: true para que Claude possa informar ao usuário o que deu errado em vez de tratar uma falha como um resultado normal.
Depois que o servidor é definido, passe-o para query da mesma forma que o exemplo de clima. Este exemplo envia três prompts diferentes em um loop para mostrar a mesma ferramenta tratando diferentes tipos de unidades. Para cada resposta, ele inspeciona objetos AssistantMessage (que contêm as chamadas de ferramenta que Claude fez durante esse turno) e imprime cada ToolUseBlock antes de imprimir o texto final ResultMessage. Isso permite que você veja quando Claude está usando a ferramenta versus respondendo a partir de seu próprio conhecimento. Como tool search está ativado por padrão, a saída também pode incluir uma chamada ToolSearch conforme Claude carrega o esquema de ferramenta adiado.

Próximos passos

Você pode misturar os padrões nesta página no mesmo servidor: um único servidor pode conter uma ferramenta de banco de dados, uma ferramenta de gateway de API e um renderizador de imagem lado a lado. A partir daqui:
  • Se seu servidor crescer para dezenas de ferramentas, consulte pesquisa de ferramentas para adiar o carregamento delas até que Claude precise delas.
  • Para conectar a servidores MCP externos (sistema de arquivos, GitHub, Slack) em vez de construir os seus próprios, consulte Conectar servidores MCP.
  • Para controlar quais ferramentas são executadas automaticamente versus exigindo aprovação, consulte Configurar permissões.