---
title: Chamar a API em um servidor auto-hospedado
url: https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api
description: Aponte o SDK oficial, o cURL ou o ant CLI para o seu servidor auto-hospedado do Claude Managed Agents, inicie uma sessão e leia a resposta do agente. Em seguida, conecte os seus próprios workers, se precisar deles.
---

<Note>
  Para solicitar acesso ao Claude Managed Agents auto-hospedado, entre em contato com a equipe da sua conta na Anthropic.
</Note>

Um servidor auto-hospedado do Claude Managed Agents tem a mesma API que o serviço hospedado do [Managed Agents](https://platform.claude.com/docs/pt-BR/managed-agents/overview) da Anthropic. Seu código o chama com o SDK oficial, o cURL ou o `ant` CLI. Duas coisas mudam: a “base URL” (URL base) é o endereço do seu servidor, e a chave de API é a sua [chave de API do servidor](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted#the-three-credentials) em vez de uma chave de API do Claude.

Para criar agentes e executar sessões em um navegador, consulte [Usar o console no seu servidor](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/console).

## Pré-requisitos

* **Um servidor em execução:** Inicie um com [Comece a usar o Claude Managed Agents auto-hospedado](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/quickstart) ou [Implantar no Kubernetes](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/kubernetes).
* **Acesso ao servidor:** Se outra pessoa executa o servidor, peça a ela o endereço dele e como se autenticar. Se ela usa single sign-on, consulte [Permita que desenvolvedores façam login a partir de um terminal](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/configure#let-developers-log-in-from-a-terminal).
* **O CLI `ant`:** Instale a versão mais recente, como mostra o [início rápido da CLI](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/cli/quickstart#installation).

## Apontar o seu cliente para o seu servidor

O SDK e a CLI `ant` leem o endereço do servidor de `ANTHROPIC_BASE_URL` e a chave de API de `ANTHROPIC_API_KEY`. Defina as duas variáveis em um terminal que você reservar para este servidor.

Para a [stack do início rápido](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/quickstart), execute estes comandos a partir do diretório que contém o seu arquivo `.env`:

```bash
export ANTHROPIC_BASE_URL=http://127.0.0.1:8400
export ANTHROPIC_API_KEY=$(grep '^CMA_SERVER__API_KEY=' .env | cut -d= -f2)
```

No Kubernetes, defina as duas variáveis como mostra [Executar uma sessão](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/kubernetes#run-a-session) e mantenha o port-forward dele em execução.

Nesse terminal, todo comando `ant`, como `ant beta:agents list`, chega ao seu servidor. Não execute o Claude Code nem o `docker compose` nesse terminal, porque eles leem as mesmas variáveis.

## Iniciar uma sessão

Uma sessão precisa do ID de um agente e do ID de um ambiente:

* **Agente:** Crie um como mostra [Criar um agente](https://platform.claude.com/docs/pt-BR/managed-agents/agent-setup#create-an-agent), com o seu cliente apontado para o seu servidor. Se você envia requisições HTTP diretas, substitua `https://api.anthropic.com` na URL por `$ANTHROPIC_BASE_URL`.
* **Ambiente:** A stack do início rápido cria um chamado `compose-sandbox`, e os Helm charts criam um chamado `default`. `ant beta:environments list` imprime o nome e o ID de cada ambiente. Para os seus próprios workers, é o ID que a CLI de administração imprimiu em [Executar os seus próprios workers](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#point-a-worker-at-your-server).

Coloque os seus dois IDs no seu shell, no lugar destes IDs de exemplo:

```bash
export AGENT_ID=agent_011CYm1BLqPXpQRk5khsSXrs
export ENVIRONMENT_ID=env_01595EKxaaTTGwwY3kyXdtbs
```

O exemplo a seguir cria uma sessão e envia sua primeira mensagem na mesma requisição:

<CodeGroup>
  ```bash cURL
  curl -sS --fail-with-body "$ANTHROPIC_BASE_URL/v1/sessions" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "agent": "'"$AGENT_ID"'",
      "environment_id": "'"$ENVIRONMENT_ID"'",
      "initial_events": [
        {
          "type": "user.message",
          "content": [{"type": "text", "text": "List the files in the working directory."}]
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:sessions create --agent "$AGENT_ID" --environment-id "$ENVIRONMENT_ID" \
    --initial-event '{type: user.message, content: [{type: text, text: "List the files in the working directory."}]}'
  ```

  ```python Python
  import os

  from anthropic import Anthropic

  client = Anthropic()

  session = client.beta.sessions.create(
      agent=os.environ["AGENT_ID"],
      environment_id=os.environ["ENVIRONMENT_ID"],
      initial_events=[
          {
              "type": "user.message",
              "content": [
                  {"type": "text", "text": "List the files in the working directory."}
              ],
          },
      ],
  )
  print(session.id)
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";

  const client = new Anthropic();

  const session = await client.beta.sessions.create({
    agent: process.env["AGENT_ID"]!,
    environment_id: process.env["ENVIRONMENT_ID"]!,
    initial_events: [
      {
        type: "user.message",
        content: [{ type: "text", text: "List the files in the working directory." }]
      }
    ]
  });
  console.log(session.id);
  ```

  ```csharp C#
  using System;
  using Anthropic;
  using Anthropic.Models.Beta.Agents;
  using Anthropic.Models.Beta.Sessions;
  using Anthropic.Models.Beta.Sessions.Events;

  AnthropicClient client = new();

  var session = await client.Beta.Sessions.Create(new()
  {
      Agent = Environment.GetEnvironmentVariable("AGENT_ID")!,
      EnvironmentID = Environment.GetEnvironmentVariable("ENVIRONMENT_ID")!,
      InitialEvents =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Text = "List the files in the working directory.",
                  },
              ],
          },
      ],
  });
  Console.WriteLine(session.ID);
  ```

  ```go Go
  package main

  import (
  	"context"
  	"fmt"
  	"os"

  	"github.com/anthropics/anthropic-sdk-go/v2"
  )

  func main() {
  	client := anthropic.NewClient()

  	session, err := client.Beta.Sessions.New(context.Background(), anthropic.BetaSessionNewParams{
  		Agent: anthropic.BetaSessionNewParamsAgentUnion{
  			OfString: anthropic.String(os.Getenv("AGENT_ID")),
  		},
  		EnvironmentID: os.Getenv("ENVIRONMENT_ID"),
  		InitialEvents: []anthropic.BetaSessionNewParamsInitialEventUnion{{
  			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  						Text: "List the files in the working directory.",
  					},
  				}},
  			},
  		}},
  	})
  	if err != nil {
  		panic(err)
  	}
  	fmt.Println(session.ID)
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.models.beta.sessions.SessionCreateParams;
  import com.anthropic.models.beta.sessions.events.BetaManagedAgentsUserMessageEventParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var session = client.beta().sessions().create(SessionCreateParams.builder()
          .agent(System.getenv("AGENT_ID"))
          .environmentId(System.getenv("ENVIRONMENT_ID"))
          .addInitialEvent(BetaManagedAgentsUserMessageEventParams.builder()
              .addTextContent("List the files in the working directory.")
              .build())
          .build());
      IO.println(session.id());
  }
  ```

  ```php PHP
  <?php

  use Anthropic\Client;

  $client = new Client();

  $session = $client->beta->sessions->create(
      agent: (string) getenv('AGENT_ID'),
      environmentID: (string) getenv('ENVIRONMENT_ID'),
      initialEvents: [
          [
              'type' => 'user.message',
              'content' => [['type' => 'text', 'text' => 'List the files in the working directory.']],
          ],
      ],
  );
  echo $session->id, "\n";
  ```

  ```ruby Ruby
  require "anthropic"

  client = Anthropic::Client.new

  session = client.beta.sessions.create(
    agent: ENV.fetch("AGENT_ID"),
    environment_id: ENV.fetch("ENVIRONMENT_ID"),
    initial_events: [
      {
        type: :"user.message",
        content: [{type: :text, text: "List the files in the working directory."}]
      }
    ]
  )
  puts session.id
  ```
</CodeGroup>

A resposta contém o ID da sessão, que começa com `sesn_`. O agente começa a trabalhar imediatamente. Suas ferramentas integradas, como `bash`, são executadas em um worker que serve o ambiente.

Para acompanhar a sessão, abra o [console do seu servidor](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/console) em um navegador, selecione **Sessions** e, em seguida, selecione a sessão. Uma sessão que você iniciou com a chave de API do servidor, como nesta página, aparece apenas para administradores.

Para acompanhar a sessão no seu terminal em vez disso, passe o ID dela para [`ant beta:sessions connect`](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/cli/sessions-connect):

```bash
ant beta:sessions connect sesn_011CZkZAtmR3yMPDzynEDxu7
```

Para saber o que mais uma sessão pode fazer, como fixar uma versão do agente, consulte [Iniciar uma sessão](https://platform.claude.com/docs/pt-BR/managed-agents/sessions).

## Enviar uma mensagem e ler a resposta

Coloque o ID da sua sessão no seu shell, no lugar deste ID de exemplo:

```bash
export SESSION_ID=sesn_011CZkZAtmR3yMPDzynEDxu7
```

Aguarde até que a sessão esteja ociosa antes de executar o próximo exemplo. O exemplo para de ler quando um turno termina. Se um turno anterior ainda estiver em execução, o fim dele pode parar o exemplo antes que a resposta à sua mensagem chegue. O console e o `ant beta:sessions connect` mostram o status da sessão.

O exemplo a seguir envia uma mensagem e imprime a resposta do agente. Ele abre o stream de eventos da sessão primeiro, porque um stream entrega apenas os eventos que ocorrem depois que ele é aberto:

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Este fluxo de trabalho precisa de mais lógica do que um único comando de shell. Use o [SDK da Anthropic](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/overview) para executá-lo.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Este fluxo de trabalho precisa de mais lógica do que um único comando de shell. Para enviar mensagens e ler as respostas no seu terminal, use [`ant beta:sessions connect`](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/cli/sessions-connect).
  </CodeGroupItem>

  ```python Python
  import os

  from anthropic import Anthropic

  client = Anthropic()
  session_id = os.environ["SESSION_ID"]

  with client.beta.sessions.events.stream(session_id) as stream:
      client.beta.sessions.events.send(
          session_id,
          events=[
              {
                  "type": "user.message",
                  "content": [
                      {"type": "text", "text": "Summarize what you did in one sentence."}
                  ],
              },
          ],
      )

      for event in stream:
          match event.type:
              case "agent.message":
                  for block in event.content:
                      if block.type == "text":
                          print(block.text, end="")
              case "session.error":
                  error_message = event.error.message if event.error else "unknown"
                  print(f"\n[Error: {error_message}]")
              case "session.status_idle":
                  if event.stop_reason.type != "requires_action":
                      break
              case "session.status_terminated":
                  break
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";

  const client = new Anthropic();
  const sessionId = process.env["SESSION_ID"]!;

  const stream = await client.beta.sessions.events.stream(sessionId);
  await client.beta.sessions.events.send(sessionId, {
    events: [
      {
        type: "user.message",
        content: [{ type: "text", text: "Summarize what you did in one sentence." }]
      }
    ]
  });

  events: for await (const event of stream) {
    switch (event.type) {
      case "agent.message":
        for (const block of event.content) {
          if (block.type === "text") {
            process.stdout.write(block.text);
          }
        }
        break;
      case "session.error":
        console.log(`\n[Error: ${event.error?.message ?? "unknown"}]`);
        break;
      case "session.status_idle":
        if (event.stop_reason.type !== "requires_action") {
          break events;
        }
        break;
      case "session.status_terminated":
        break events;
    }
  }
  ```

  ```csharp C#
  using System;
  using Anthropic;
  using Anthropic.Models.Beta.Sessions.Events;

  AnthropicClient client = new();
  var sessionId = Environment.GetEnvironmentVariable("SESSION_ID")!;

  using var stream = await client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(sessionId);
  await client.Beta.Sessions.Events.Send(sessionId, new()
  {
      Events =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Content = [new BetaManagedAgentsTextBlock { Text = "Summarize what you did in one sentence." }],
          },
      ],
  });

  await foreach (var streamEvent in stream.Enumerate())
  {
      if (streamEvent.Value is BetaManagedAgentsAgentMessageEvent message)
      {
          foreach (var block in message.Content)
          {
              if (block.Value is BetaManagedAgentsTextBlock textBlock)
              {
                  Console.Write(textBlock.Text);
              }
          }
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionErrorEvent error)
      {
          Console.WriteLine($"\n[Error: {error.Error?.Message ?? "unknown"}]");
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionStatusIdleEvent idle
          && idle.StopReason?.Value is not BetaManagedAgentsSessionRequiresAction)
      {
          break;
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionStatusTerminatedEvent)
      {
          break;
      }
  }
  ```

  ```go Go
  package main

  import (
  	"cmp"
  	"context"
  	"fmt"
  	"os"

  	"github.com/anthropics/anthropic-sdk-go/v2"
  )

  func main() {
  	client := anthropic.NewClient()
  	ctx := context.Background()
  	sessionID := os.Getenv("SESSION_ID")

  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, sessionID, anthropic.BetaSessionEventStreamParams{})
  	defer stream.Close()

  	if _, err := client.Beta.Sessions.Events.Send(ctx, sessionID, anthropic.BetaSessionEventSendParams{
  		Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  						Text: "Summarize what you did in one sentence.",
  					},
  				}},
  			},
  		}},
  	}); err != nil {
  		panic(err)
  	}

  events:
  	for stream.Next() {
  		switch event := stream.Current().AsAny().(type) {
  		case anthropic.BetaManagedAgentsAgentMessageEvent:
  			for _, block := range event.Content {
  				if block.Type == "text" {
  					fmt.Print(block.Text)
  				}
  			}
  		case anthropic.BetaManagedAgentsSessionErrorEvent:
  			fmt.Printf("\n[Error: %s]\n", cmp.Or(event.Error.Message, "unknown"))
  		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
  			if _, paused := event.StopReason.AsAny().(anthropic.BetaManagedAgentsSessionRequiresAction); !paused {
  				break events
  			}
  		case anthropic.BetaManagedAgentsSessionStatusTerminatedEvent:
  			break events
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.core.JsonObject;
  import com.anthropic.models.beta.sessions.events.BetaManagedAgentsUserMessageEventParams;
  import com.anthropic.models.beta.sessions.events.EventSendParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();
      var sessionId = System.getenv("SESSION_ID");

      try (var stream = client.beta().sessions().events().streamStreaming(sessionId)) {
          client.beta().sessions().events().send(
              sessionId,
              EventSendParams.builder()
                  .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
                      .addTextContent("Summarize what you did in one sentence.")
                      .build())
                  .build()
          );

          events:
          for (var event : stream) {
              switch (event.type().value()) {
                  case AGENT_MESSAGE -> {
                      for (var block : event.asAgentMessage().content()) {
                          block.text().ifPresent(textBlock -> IO.print(textBlock.text()));
                      }
                  }
                  case SESSION_ERROR -> {
                      var errorMessage =
                          event.asSessionError().error()._json().orElse(null) instanceof JsonObject json
                              ? json.values().get("message").asStringOrThrow()
                              : "unknown";
                      IO.println("\n[Error: " + errorMessage + "]");
                  }
                  case SESSION_STATUS_IDLE -> {
                      if (!event.asSessionStatusIdle().stopReason().isRequiresAction()) {
                          break events;
                      }
                  }
                  case SESSION_STATUS_TERMINATED -> {
                      break events;
                  }
                  default -> {}
              }
          }
      }
  }
  ```

  ```php PHP
  <?php

  use Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionErrorEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionRequiresAction;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusIdleEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusTerminatedEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock;
  use Anthropic\Client;

  $client = new Client();
  $sessionId = (string) getenv('SESSION_ID');

  $stream = $client->beta->sessions->events->streamStream($sessionId);
  $client->beta->sessions->events->send(
      $sessionId,
      events: [
          [
              'type' => 'user.message',
              'content' => [['type' => 'text', 'text' => 'Summarize what you did in one sentence.']],
          ],
      ],
  );

  foreach ($stream as $event) {
      switch (true) {
          case $event instanceof ManagedAgentsAgentMessageEvent:
              foreach ($event->content as $block) {
                  if ($block instanceof ManagedAgentsTextBlock) {
                      echo $block->text;
                  }
              }
              break;
          case $event instanceof ManagedAgentsSessionErrorEvent:
              printf("\n[Error: %s]\n", $event->error->message);
              break;
          case $event instanceof ManagedAgentsSessionStatusIdleEvent:
              if (!($event->stopReason instanceof ManagedAgentsSessionRequiresAction)) {
                  break 2; // Break foreach loop
              }
              break;
          case $event instanceof ManagedAgentsSessionStatusTerminatedEvent:
              break 2; // Break foreach loop
      }
  }
  $stream->close();
  ```

  ```ruby Ruby
  require "anthropic"

  client = Anthropic::Client.new
  session_id = ENV.fetch("SESSION_ID")

  stream = client.beta.sessions.events.stream_events(session_id)

  client.beta.sessions.events.send_(
    session_id,
    events: [{
      type: "user.message",
      content: [{type: "text", text: "Summarize what you did in one sentence."}]
    }]
  )

  stream.each do |event|
    case event
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
      event.content.each do |block|
        print block.text if block.is_a?(Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock)
      end
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionErrorEvent
      puts "\n[Error: #{event.error&.message || "unknown"}]"
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      break unless event.stop_reason.is_a?(Anthropic::Beta::Sessions::BetaManagedAgentsSessionRequiresAction)
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusTerminatedEvent
      break
    else
      # ignora outros tipos de evento
    end
  end
  ```
</CodeGroup>

Além de imprimir o texto de `agent.message`, o loop trata três eventos:

* **`session.status_idle`:** O loop termina, a menos que o `stop_reason.type` do evento seja `requires_action`.
* **`session.status_terminated`:** O loop termina.
* **`session.error`:** O loop imprime a mensagem do erro e continua lendo, porque o servidor pode repetir uma chamada ao modelo que falhou e concluir o turno.

`requires_action` significa que a sessão pausou para uma chamada de ferramenta. O que encerra a pausa depende da chamada:

* **Uma chamada de ferramenta personalizada ou uma requisição para confirmar uma chamada de ferramenta:** Somente o seu código pode respondê-la. Se o seu agente usa alguma delas, consulte [Responder a chamadas de ferramenta que pausam a sessão](https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming#answer-tool-calls-that-pause-the-session).
* **Uma chamada a uma ferramenta que um worker executa, como `bash`:** Essa chamada normalmente não pausa a sessão. Se nenhum worker assumir a chamada por cerca de 3 minutos, a sessão pausa até que um worker retorne o resultado. O seu código não tem nada a responder nesse caso. Mantenha o stream aberto, e o turno é retomado quando um worker executar a chamada.

Para os outros eventos que uma sessão envia e para saber como se reconectar sem perder nenhum, consulte [Stream de eventos da sessão](https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming).

## Mover dados para dentro e para fora de uma sessão

Os dados chegam a uma sessão e saem dela pelo diretório de trabalho do worker.

Na stack do início rápido, o contêiner de cada sessão começa com um diretório `/workspace` vazio, exceto pelos clones dos repositórios da sessão. Por padrão, cerca de um minuto depois que um turno termina, o contêiner encerra, e o Docker o exclui junto com esse diretório. Qualquer coisa que uma sessão precise manter tem que sair por meio de uma chamada de ferramenta, como um upload ou um `git push`, antes disso.

Um contêiner também encerra cerca de uma hora depois de iniciar, mesmo no meio de um turno. Nenhuma configuração muda isso. O turno continua em um novo contêiner, geralmente depois de um ou dois minutos, e o seu cliente não recebe nenhum evento pela troca. A troca tem dois custos:

* **Comandos:** Tudo o que é executado no contêiner antigo para. O novo contêiner executa a chamada de ferramenta interrompida novamente desde o início, mas nada reinicia um comando que o agente deixou em execução em segundo plano.
* **Arquivos:** O `/workspace` do novo contêiner fica vazio de novo, exceto por clones novos dos repositórios da sessão.

Em um turno longo, faça o agente enviar ou fazer push do trabalho dele à medida que avança, e evite comandos que causem danos se forem executados duas vezes.

No Kubernetes, uma sessão mantém um pod por cerca de uma hora no máximo, e o turno continua da mesma forma. Duas coisas são diferentes: o novo pod encontra os arquivos da sessão em `/workspace`, e ele inicia cerca de 6 minutos depois que o pod antigo para.

Para workers que você mesmo inicia, coloque os arquivos de entrada no diretório de trabalho antes de enviar a mensagem que precisa deles. Leia os arquivos de saída dele depois.

Quando você mesmo inicia um contêiner para cada sessão, monte um diretório que contenha os arquivos de entrada da sessão como o diretório de trabalho do contêiner. Colete os arquivos de saída dele depois que o contêiner terminar. Consulte [Preparar arquivos para uma sessão](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-workers#stage-files-for-a-session).

## Encontrar mais exemplos nos guias do serviço hospedado

Os guias do serviço hospedado explicam os [conceitos principais](https://platform.claude.com/docs/pt-BR/managed-agents/overview#core-concepts) da API e têm exemplos para cada recurso. Os exemplos de SDK e CLI desses guias chamam o seu servidor quando você os executa no terminal em que `ANTHROPIC_BASE_URL` e `ANTHROPIC_API_KEY` estão definidas. Os exemplos de cURL desses guias usam o endereço `https://api.anthropic.com`, então substitua esse endereço por `$ANTHROPIC_BASE_URL` antes de executar um deles.

Para alguns recursos, o seu servidor precisa primeiro de uma configuração, ou um exemplo precisa de uma alteração:

| Tarefa                                                                   | Guia do serviço hospedado                                                                                                                                                   | No seu servidor                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Definir o modelo, o prompt do sistema e as versões de um agente          | [Defina seu agente](https://platform.claude.com/docs/pt-BR/managed-agents/agent-setup)                                                                                      | Alguns campos [dependem do seu provedor de inferência](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#differences-that-depend-on-your-inference-provider).                                                                                                                                                                                          |
| Escolher ferramentas integradas ou adicionar ferramentas personalizadas  | [Ferramentas](https://platform.claude.com/docs/pt-BR/managed-agents/tools)                                                                                                  | Para usar as ferramentas web, ative-as primeiro, como descreve [As ferramentas web precisam de uma configuração do servidor](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#web-tools-need-a-server-setting). Quais delas existem depende do seu provedor de inferência.                                                                            |
| Conectar um servidor MCP e armazenar o token dele                        | [Conector MCP](https://platform.claude.com/docs/pt-BR/managed-agents/mcp-connector) e [Autenticar com vaults](https://platform.claude.com/docs/pt-BR/managed-agents/vaults) | Adicione o host do servidor MCP à [lista de permissões de servidores MCP](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#mcp-servers-need-an-allowlist-entry). Armazene o token como uma credencial `static_bearer`.                                                                                                                                |
| Dar skills a um agente                                                   | [Skills](https://platform.claude.com/docs/pt-BR/managed-agents/skills)                                                                                                      | Faça o upload de cada skill como arquivos individuais, porque o seu servidor recusa um arquivo zip. As [skills pré-construídas](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#features-that-arent-available) dos exemplos desse guia não estão disponíveis.                                                                                        |
| Manter memória entre sessões                                             | [Usar a memória do agente](https://platform.claude.com/docs/pt-BR/managed-agents/memory)                                                                                    | Se você executa os seus próprios workers, forneça a eles um diretório `/mnt/memory` gravável, como em [Repositórios de memória em sandboxes auto-hospedados](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-memory).                                                                                                                                  |
| Passar trabalho para outros agentes                                      | [Orquestração multiagente](https://platform.claude.com/docs/pt-BR/managed-agents/multiagent-orchestration)                                                                  | Substitua o bloco `multiagent_20261001` nos exemplos desse guia por um [bloco `coordinator`](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#features-that-behave-differently).                                                                                                                                                                      |
| Trabalhar em um repositório Git                                          | [Acessar o GitHub](https://platform.claude.com/docs/pt-BR/managed-agents/github)                                                                                            | Liste o host Git nas configurações do seu servidor, como descreve [Os repositórios Git precisam de uma entrada na lista de permissões](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences#git-repositories-need-an-allowlist-entry). O agente de exemplo desse guia também precisa de `api.githubcopilot.com` na lista de permissões de servidores MCP. |
| Fazer com que um avaliador verifique o trabalho em relação a uma rubrica | [Definir resultados](https://platform.claude.com/docs/pt-BR/managed-agents/define-outcomes)                                                                                 | Envie a rubrica como texto. A Files API não está disponível, então [colete os arquivos de saída](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#move-data-in-and-out-of-a-session) do diretório de trabalho.                                                                                                                                       |
| Acompanhar uma sessão e responder às chamadas de ferramenta dela         | [Stream de eventos da sessão](https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming)                                                                   | O primeiro exemplo desse guia fecha o stream em qualquer pausa, então comece pelo loop de [Enviar uma mensagem e ler a resposta](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#send-a-message-and-read-the-reply) em vez disso.                                                                                                                   |

[Diferenças em relação ao serviço hospedado](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/differences) tem a lista completa. Consulte-a antes de migrar uma aplicação existente.

## Executar os seus próprios workers

A [stack do início rápido](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/quickstart) cria um ambiente e executa os workers dele. Os Helm charts de [Implantar no Kubernetes](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/kubernetes) também fazem isso. Se esses workers forem tudo de que você precisa, pule esta seção.

Você executa workers da mesma forma que faz com os [sandboxes auto-hospedados](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes): os mesmos comandos `ant beta:worker` e workers do SDK, das formas que [Implantar workers auto-hospedados](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-workers) mostra. A exceção são os workers acionados por webhooks, porque o seu servidor não envia nenhum.

### Criar um ambiente e a chave dele

Crie um ambiente e uma chave de ambiente com o CLI de administração, não no Claude Console. O CLI, `cma-server-admin`, fica no topo do arquivo compactado da versão, então execute o comando a partir dali. Em `-base-url`, passe o endereço pelo qual os seus workers alcançam o servidor:

* **Workers na máquina que executa a stack do início rápido:** `http://127.0.0.1:8400`
* **Workers em outra máquina:** o endereço `https` do [proxy TLS que você coloca na frente do servidor](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/kubernetes#put-tls-in-front-of-the-server)

O CLI de administração chama o servidor no mesmo endereço, então execute-o em uma máquina que consiga alcançar esse endereço.

```bash
echo "$ANTHROPIC_API_KEY" | ./cma-server-admin bootstrap \
  -base-url http://127.0.0.1:8400 -name my-env -key-file -
```

O comando imprime as configurações do worker, o comando que inicia um worker, e o ID e a expiração da chave:

```text wrap
export ANTHROPIC_BASE_URL='http://127.0.0.1:8400'
export ANTHROPIC_ENVIRONMENT_ID='env_...'
export ANTHROPIC_ENVIRONMENT_KEY='sk-ant-oat01-...'
# then: histchars= HISTFILE=/dev/null ant beta:worker poll --workdir /workspace
# key id: 'etok_...'  expires: '...'
```

O comando exibe a chave apenas uma vez, então armazene a chave, o ID dela e a expiração no seu gerenciador de segredos. A chave para de funcionar após 365 dias. Antes disso, siga [Substituir uma chave de ambiente para os seus próprios workers](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/kubernetes#replace-an-environment-key-for-your-own-workers).

Mantenha a chave de API do servidor fora das máquinas que executam workers. Execute workers em um contêiner ou VM que não contenha nada que você precise proteger. Para as suas outras obrigações de segurança, consulte [Suas responsabilidades de segurança](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted#your-security-responsibilities).

### Executar um experimento local

Execute as três linhas `export` no shell em que você inicia o worker. Em seguida, inicie o worker com estes comandos, não com o que foi impresso. O primeiro comando cria o diretório de trabalho do worker, porque o worker não o cria:

```bash
mkdir -p "$HOME/cma-workspace" "$HOME/.config/cma"
cat > "$HOME/.config/cma/worker.inputrc" <<'EOF'
$include /etc/inputrc
set disable-completion on
EOF
histchars= HISTFILE=/dev/null INPUTRC="$HOME/.config/cma/worker.inputrc" \
  ant beta:worker poll --workdir "$HOME/cma-workspace"
```

`histchars`, `INPUTRC` e `HISTFILE` configuram o shell por trás da ferramenta `bash` do worker, para que ele execute cada comando exatamente como o agente o escreveu:

* **`histchars=`:** O shell não trata `!` como uma referência ao seu histórico de comandos.
* **`INPUTRC`:** O arquivo desativa o completamento, que de outra forma consumiria cada caractere de tabulação em um comando. Mantenha o arquivo fora do diretório de trabalho, onde as ferramentas de arquivo do agente poderiam reescrevê-lo.
* **`HISTFILE=/dev/null`:** O shell não lê nem grava um arquivo de histórico.

Não use este worker para mais nada. Ele guarda a chave de ambiente e executa as ferramentas de todas as sessões em um único processo. Ele também não clona os repositórios de uma sessão. A sessão é executada sem eles, e o seu cliente não recebe nenhum erro.

### Executar workers em produção

Para qualquer uso além de um experimento local, inicie um contêiner para cada sessão e execute `ant beta:worker run` nele, como mostra [Executar um sandbox por sessão](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-workers#run-one-sandbox-per-session). Forneça à imagem dele o que [Criar a sua própria imagem de sandbox](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#build-your-own-sandbox-image) lista e altere três coisas nessa configuração:

* **Chave de ambiente:** Não passe `ANTHROPIC_ENVIRONMENT_KEY` para o contêiner de uma sessão. O servidor aceita essa chave para todas as sessões do ambiente, e o contêiner precisa de acesso a apenas uma sessão.
* **Segredo do item de trabalho:** Passe este segredo no lugar da chave, porque o servidor o aceita apenas para essa única sessão. [Encaminhar o segredo do item de trabalho](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-workers#forward-the-work-items-secret) mostra onde o seu código o recebe. Onde essa seção define `ANTHROPIC_WORK_SECRET`, coloque o segredo em um arquivo que apenas o usuário do contêiner pode ler. Por exemplo, envie o segredo por pipe para a entrada padrão do contêiner e faça o contêiner gravar o arquivo antes de iniciar o worker. Em seguida, defina `ANTHROPIC_WORK_SECRET_FILE` como o caminho do arquivo.
* **Endereço do servidor:** Defina `ANTHROPIC_BASE_URL` como um endereço que o contêiner consiga alcançar. `http://127.0.0.1:8400` não é um deles.

Para um worker do SDK, valem mais dois pontos:

* **Versão:** Crie o worker com a versão mais recente do SDK, conforme descrito em [SDKs, CLI e bibliotecas](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/overview). O worker dessa versão aguarda aprovação antes de executar uma chamada de ferramenta que precisa dela e nunca executa uma chamada que uma política nega. Um worker criado com uma versão anterior executa toda chamada de ferramenta assim que ela chega.
* **Exemplos:** Os exemplos em [Executar o worker do SDK dentro do sandbox](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted-sandboxes-workers#run-the-sdk-worker-inside-the-sandbox) leem a chave de ambiente, então não funcionam aqui como estão.

### Criar a sua própria imagem de sandbox

Uma imagem própria precisa destes pacotes e configurações:

* **Pacotes:** Git 2.38 ou posterior, `curl`, `jq` e ripgrep, que a ferramenta `grep` do worker usa para fazer buscas.

* **Configurações do shell:** `histchars`, `HISTFILE` e `INPUTRC`, como no experimento local, e `TERMINFO`. Coloque estas linhas no Dockerfile, antes de qualquer linha `USER`:

  ```dockerfile
  ENV histchars=
  RUN printf '\nset disable-completion on\n' >> /etc/inputrc
  ENV INPUTRC=/etc/inputrc TERMINFO=/etc/terminfo HISTFILE=/dev/null
  RUN test -r /etc/terminfo/d/dumb
  ```

  `TERMINFO` precisa indicar o diretório que contém `d/dumb`, a descrição de terminal que o `bash` do worker lê. No Alpine com `bash` instalado, esse diretório é `/etc/terminfo`, como mostrado. Em outra base, como Debian ou Ubuntu, é `/lib/terminfo` ou `/usr/share/terminfo`, o que contiver `d/dumb`. Escreva esse diretório na configuração `TERMINFO` e na linha `RUN test`, que interrompe o build se o arquivo estiver faltando.

A imagem também precisa de dois scripts do arquivo compactado, que são executados antes de o worker iniciar:

1. Copie `image-build/with-repositories.sh` para `/usr/local/bin/cma-with-repositories`. Ele clona os repositórios de uma sessão.
2. Copie `image-build/with-egress.sh` para `/usr/local/bin/cma-with-egress`. Ele aponta as ferramentas da sessão para o [“egress gateway” (gateway de saída)](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/agent-identity#environment-variable-credentials), se o seu servidor executar um.
3. Torne os dois arquivos executáveis.
4. Coloque os dois na frente do comando do worker, como em `cma-with-egress cma-with-repositories ant beta:worker run ...`. Pule esta etapa se a sua imagem executa o `kubernetes/sandbox/worker.sh` do arquivo compactado, porque esse script inicia o worker dessa forma.

Um worker que é iniciado sem `cma-with-repositories` executa a sessão sem nenhum repositório. O seu cliente não recebe nenhum erro.

### Migrar workers do serviço hospedado

Se você já executa workers para o serviço hospedado da Anthropic, os mesmos workers podem servir o seu servidor em vez disso. Faça três coisas:

* Passe para o processo que faz o polling de trabalho os três valores `export` que o CLI de administração imprimiu.
* Inicie esse processo com `histchars`, `HISTFILE` e `INPUTRC` definidos, como no experimento local.
* Faça as alterações que [Executar workers em produção](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#run-workers-in-production) descreve e verifique a imagem de cada sessão em relação a [Criar a sua própria imagem de sandbox](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/call-the-api#build-your-own-sandbox-image).

## Próximos passos

* [Permita que desenvolvedores façam login a partir de um terminal](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/configure#let-developers-log-in-from-a-terminal): Configure o single sign-on, para que os desenvolvedores usem o CLI `ant` com a própria identidade, em um terminal sem `ANTHROPIC_API_KEY`.
* [Identidade e credenciais do agente](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/agent-identity): Permita que sistemas externos confiem nos seus agentes e mantenha as credenciais de vault no seu gerenciador de segredos.
* [Provedor de inferência](https://platform.claude.com/docs/pt-BR/managed-agents/self-hosted/inference-provider): Envie chamadas ao modelo para um provedor de nuvem ou para o seu próprio gateway de modelos.
