Claude Platform Docs
Managed AgentsSandboxes auto-hospedadas

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

  1. Declare a ferramenta no agente

    Adicione uma entrada custom às tools do agente cujo name corresponda à 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"]
      }
    }
  2. Registre a implementação no worker

    Passe a ferramenta pela factory tools do worker (consulte EnvironmentWorker), 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:

  1. O agente emite um evento agent.custom_tool_use.
  2. O worker, dentro do seu sandbox, encaminha a chamada pela sua sessão MCP aberta para o servidor na sua rede.
  3. 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

  1. Declare as ferramentas do servidor no agente

    Liste as ferramentas do servidor MCP e declare cada uma como uma ferramenta custom. Os campos MCP name, description e inputSchema correspondem 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())
  2. Sirva as ferramentas a partir do worker

    Conecte-se ao mesmo servidor MCP na inicialização, converta suas ferramentas com async_mcp_tool e registre-as junto com beta_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:

  1. Declare-as novamente, no agente ou em uma sessão ociosa por meio de Atualizando a configuração do agente.
  2. 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:

CampoRegra
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__.
descriptionObrigatório e não vazio.
input_schemaAceita 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 agenteNo 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?