Ferramentas personalizadas em sandboxes auto-hospedados
Sirva ferramentas personalizadas a partir de um worker de sandbox auto-hospedado e encapsule um servidor MCP dentro da sua rede como ferramentas personalizadas sem executar um túnel.
Ferramentas personalizadas são ferramentas que o seu próprio código executa: o agente emite um evento agent.custom_tool_use e aguarda um user.custom_tool_result correspondente. O seu worker pode ser esse código. Como ele é executado dentro do seu sandbox, a ferramenta alcança os serviços internos, as credenciais e o "network egress" (saída de rede) que você configurou para o sandbox, e nada mais.
A chave de ambiente autoriza o envio de resultados de ferramentas personalizadas, de modo que a sua chave de API do Claude fica fora do host do worker.
Servir uma ferramenta personalizada
Declare a ferramenta no agente
Adicione uma entrada
customàstoolsdo agente cujonamecorresponda à ferramenta que o seu worker registra. Consulte Ferramentas personalizadas para ver o formato completo da declaração.{ "type": "custom", "name": "get_order_status", "description": "Look up an order in the internal fulfillment system by order ID.", "input_schema": { "type": "object", "properties": { "order_id": { "type": "string", "description": "The order ID" } }, "required": ["order_id"] } }Registre a implementação no worker
Passe a ferramenta pela factory
toolsdo worker (consulteEnvironmentWorker), junto com o conjunto de ferramentas integrado:import asyncio import os from anthropic import AsyncAnthropic, beta_async_tool from anthropic.lib.environments import EnvironmentWorker from anthropic.lib.tools.agent_toolset import beta_agent_toolset_20260401 @beta_async_tool async def get_order_status(order_id: str) -> str: """Look up an order in the internal fulfillment system by order ID.""" # Executa no host do worker: chame qualquer coisa que o sandbox possa alcançar. return f"Order {order_id}: shipped" async def main() -> None: environment_key = os.environ["ANTHROPIC_ENVIRONMENT_KEY"] environment_id = os.environ["ANTHROPIC_ENVIRONMENT_ID"] async with AsyncAnthropic(auth_token=environment_key) as client: await EnvironmentWorker( client, environment_id=environment_id, environment_key=environment_key, workdir="/workspace", tools=lambda env: [*beta_agent_toolset_20260401(env), get_order_status], ).run() asyncio.run(main())
O worker responde apenas às ferramentas registradas nele. Se uma ferramenta for declarada no agente, mas nenhum worker ou cliente a servir, a sessão é pausada com um motivo de parada requires_action. Ela permanece pausada até que algo envie o resultado. Consulte Lidando com chamadas de ferramentas personalizadas para ver o fluxo de eventos.
Encapsular um servidor MCP como ferramentas personalizadas
O conector MCP se conecta a servidores MCP a partir do lado da Anthropic. Portanto, um servidor precisa expor um endpoint HTTP que a Anthropic consiga alcançar, diretamente ou por meio de um túnel MCP.
Para usar um servidor que apenas a sua rede consegue alcançar, faça do worker o cliente MCP e declare as ferramentas do servidor como ferramentas personalizadas. O servidor MCP não precisa de conectividade de entrada vinda de fora da sua rede. A Anthropic recebe as definições de ferramentas que você declara no agente, a entrada de cada chamada e o resultado que o seu worker envia de volta.
Em tempo de execução, o modelo chama uma ferramenta encapsulada como qualquer outra ferramenta personalizada:
- O agente emite um evento
agent.custom_tool_use. - O worker, dentro do seu sandbox, encaminha a chamada pela sua sessão MCP aberta para o servidor na sua rede.
- O worker envia a resposta do servidor como o
user.custom_tool_result.
Instalar um SDK MCP
Os helpers MCP do lado do cliente do SDK convertem as ferramentas do servidor nas ferramentas executáveis que o worker aceita. Instale um SDK MCP junto com o SDK da Anthropic: pip install "anthropic[mcp]" "mcp>=1.24".
Os exemplos se conectam sem autenticação. Para enviar credenciais, configure o http_client que você entrega ao transporte MCP.
Declarar e servir as ferramentas
Declare as ferramentas do servidor no agente
Liste as ferramentas do servidor MCP e declare cada uma como uma ferramenta
custom. Os campos MCPname,descriptioneinputSchemacorrespondem um a um aos campos da ferramenta personalizada. Se o servidor paginar sua lista de ferramentas, declare todas as páginas; o worker precisa listar as mesmas páginas.import asyncio from typing import Any, cast from anthropic import AsyncAnthropic from anthropic.types.beta import BetaManagedAgentsCustomToolParams from mcp import ClientSession, types # Requer mcp >= 1.24, que renomeou streamablehttp_client para streamable_http_client. from mcp.client.streamable_http import streamable_http_client MCP_SERVER_URL = "http://mcp.internal.example.com:8000/mcp" def to_custom_tool(tool: types.Tool) -> BetaManagedAgentsCustomToolParams: # Os campos MCP mapeiam um a um para uma declaração de ferramenta personalizada. O cast # entrega o dicionário do schema ao parâmetro tipado do SDK sem alterações. return { "type": "custom", "name": tool.name, "description": tool.description or tool.name, "input_schema": cast(Any, tool.inputSchema), } async def main() -> None: # Execute isto onde você cria agentes, não no host worker: ele # autentica com sua chave de API do Claude (ANTHROPIC_API_KEY). async with ( streamable_http_client(MCP_SERVER_URL) as (read, write, _), ClientSession(read, write) as mcp_session, AsyncAnthropic() as client, ): await mcp_session.initialize() listed = await mcp_session.list_tools() agent = await client.beta.agents.create( name="Internal tools agent", model="claude-opus-5-5", tools=[ {"type": "agent_toolset_20260401"}, *[to_custom_tool(tool) for tool in listed.tools], ], ) print(agent.id) asyncio.run(main())Sirva as ferramentas a partir do worker
Conecte-se ao mesmo servidor MCP na inicialização, converta suas ferramentas com
async_mcp_toole registre-as junto combeta_agent_toolset_20260401. Mantenha uma sessão MCP aberta durante toda a vida do worker.import asyncio import os from datetime import timedelta from anthropic import AsyncAnthropic from anthropic.lib.environments import EnvironmentWorker from anthropic.lib.tools.agent_toolset import beta_agent_toolset_20260401 from anthropic.lib.tools.mcp import async_mcp_tool from mcp import ClientSession # Requer mcp >= 1.24, que renomeou streamablehttp_client para streamable_http_client. from mcp.client.streamable_http import streamable_http_client MCP_SERVER_URL = "http://mcp.internal.example.com:8000/mcp" async def main() -> None: environment_key = os.environ["ANTHROPIC_ENVIRONMENT_KEY"] environment_id = os.environ["ANTHROPIC_ENVIRONMENT_ID"] # Conecta ao servidor MCP uma vez na inicialização e mantém a sessão aberta durante # toda a vida do worker. O timeout transforma uma chamada de ferramenta travada em um # resultado de erro em vez de uma chamada paralisada. async with ( streamable_http_client(MCP_SERVER_URL) as (read, write, _), ClientSession(read, write, read_timeout_seconds=timedelta(seconds=60)) as mcp_session, AsyncAnthropic(auth_token=environment_key) as client, ): await mcp_session.initialize() listed = await mcp_session.list_tools() mcp_tools = [async_mcp_tool(tool, mcp_session) for tool in listed.tools] await EnvironmentWorker( client, environment_id=environment_id, environment_key=environment_key, workdir="/workspace", tools=lambda env: [*beta_agent_toolset_20260401(env), *mcp_tools], ).run() asyncio.run(main())
Limites e comportamento
As ferramentas são declaradas, não descobertas em tempo de execução
O worker lista as ferramentas do servidor MCP uma única vez na inicialização e não pode adicionar ferramentas a uma sessão em execução. Quando as ferramentas do servidor mudarem:
- Declare-as novamente, no agente ou em uma sessão ociosa por meio de Atualizando a configuração do agente.
- Reinicie o worker.
As declarações precisam se adequar à API do Managed Agents
Os helpers MCP mantêm os nomes e as descrições do servidor, e a maioria dos schemas passa sem alterações. Renomeie, reduza ou incorpore inline quando uma declaração violar uma destas regras:
| Campo | Regra |
|---|---|
name | Único por agente. Letras, dígitos, sublinhados e hifens, de 1 a 128 caracteres. Não pode coincidir com uma ferramenta integrada do agente, como bash ou read, nem usar o prefixo reservado mcp__. |
description | Obrigatório e não vazio. |
input_schema | Aceita as palavras-chave de JSON Schema que servidores MCP costumam emitir, como additionalProperties e title. Rejeita palavras-chave de referência, como $ref, em qualquer lugar, e oneOf, anyOf e allOf no nível superior. Os nomes de propriedades usam letras, dígitos, sublinhados, pontos e hifens, de 1 a 64 caracteres. |
O array tools do agente | No máximo 128 entradas. Cada ferramenta encapsulada é uma entrada, e o conjunto de ferramentas integrado é mais uma. |
Dois casos exigem trabalho extra:
- Dois servidores expõem o mesmo nome de ferramenta: Defina você mesmo o wrapper com um nome prefixado e faça-o chamar o nome original da ferramenta no servidor.
- Um gerador como o pydantic fatora schemas em
$defs: Incorpore esses schemas inline antes de declarar a ferramenta.
Falhas de ferramentas aparecem como resultados de ferramenta com erro
Quando o servidor MCP relata um erro de ferramenta, o worker envia um resultado de ferramenta com erro ao qual o modelo pode reagir. Conteúdo MCP sem equivalente em resultado de ferramenta, como blocos de áudio e links de recursos, também aparece como erro.
Defina um timeout no cliente MCP para obter uma falha mais rápida e clara, como o exemplo de worker em Python faz com read_timeout_seconds. Consulte Uma chamada de ferramenta MCP encapsulada trava para saber o que acontece sem um.
Encapsule apenas servidores que você opera ou nos quais confia
O nome, a descrição e os resultados de uma ferramenta encapsulada entram no contexto do modelo como os de qualquer outra ferramenta. Eles são entradas não confiáveis que podem influenciar o que o agente faz com suas outras ferramentas, incluindo bash no host do worker. Declare apenas as ferramentas que você pretende que o agente use.
Políticas de permissão não se aplicam
Políticas de permissão regem os conjuntos de ferramentas integrado e MCP. O worker executa toda chamada de ferramenta encapsulada que o modelo faz, portanto coloque qualquer etapa de aprovação no código da sua própria ferramenta.
Was this page helpful?