---
title: Appeler l'API sur un serveur auto-hébergé
url: https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api
description: Dirigez le SDK officiel, cURL ou la CLI ant vers votre serveur Claude Managed Agents auto-hébergé, démarrez une session et lisez la réponse de l'agent. Connectez ensuite vos propres workers, si vous en avez besoin.
---

<Note>
  Pour demander l’accès à Claude Managed Agents auto-hébergé, contactez l’équipe de votre compte Anthropic.
</Note>

Un serveur Claude Managed Agents auto-hébergé possède la même API que le service hébergé [Managed Agents](https://platform.claude.com/docs/fr/managed-agents/overview) d’Anthropic. Votre code l’appelle avec le SDK officiel, cURL ou la CLI `ant`. Deux choses changent : la « base URL » (URL de base) est l’adresse de votre serveur, et la clé API est votre [clé API du serveur](https://platform.claude.com/docs/fr/managed-agents/self-hosted#the-three-credentials) au lieu d’une clé API Claude.

Pour créer des agents et exécuter des sessions dans un navigateur, consultez [Utiliser la console de votre serveur](https://platform.claude.com/docs/fr/managed-agents/self-hosted/console).

## Prérequis

* **Un serveur en cours d’exécution :** démarrez-en un avec [Démarrer avec Claude Managed Agents auto-hébergé](https://platform.claude.com/docs/fr/managed-agents/self-hosted/quickstart) ou [Déployer sur Kubernetes](https://platform.claude.com/docs/fr/managed-agents/self-hosted/kubernetes).
* **Accès au serveur :** si quelqu’un d’autre exécute le serveur, demandez-lui son adresse et la manière de s’authentifier. S’il utilise le « single sign-on » (authentification unique), consultez [Permettre aux développeurs de se connecter depuis un terminal](https://platform.claude.com/docs/fr/managed-agents/self-hosted/configure#let-developers-log-in-from-a-terminal).
* **La CLI `ant` :** installez la dernière version, comme l’indique le [démarrage rapide de la CLI](https://platform.claude.com/docs/fr/cli-sdks-libraries/cli/quickstart#installation).

## Diriger votre client vers votre serveur

Le SDK et la CLI `ant` lisent l’adresse du serveur depuis `ANTHROPIC_BASE_URL` et la clé API depuis `ANTHROPIC_API_KEY`. Définissez ces deux variables dans un terminal que vous réservez à ce serveur.

Pour la [pile du démarrage rapide](https://platform.claude.com/docs/fr/managed-agents/self-hosted/quickstart), exécutez ces commandes depuis le répertoire qui contient votre fichier `.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)
```

Sur Kubernetes, définissez les deux variables comme l’indique [Exécuter une session](https://platform.claude.com/docs/fr/managed-agents/self-hosted/kubernetes#run-a-session), et laissez sa redirection de port en cours d’exécution.

Dans ce terminal, chaque commande `ant`, telle que `ant beta:agents list`, atteint votre serveur. N’exécutez ni Claude Code ni `docker compose` dans ce terminal, car ils lisent les mêmes variables.

## Démarrer une session

Une session a besoin de l’ID d’un agent et de l’ID d’un environnement :

* **Agent :** créez-en un comme l’indique [Créer un agent](https://platform.claude.com/docs/fr/managed-agents/agent-setup#create-an-agent), avec votre client dirigé vers votre serveur. Si vous envoyez des requêtes HTTP brutes, remplacez `https://api.anthropic.com` dans l’URL par `$ANTHROPIC_BASE_URL`.
* **Environnement :** la pile du démarrage rapide en crée un nommé `compose-sandbox`, et les charts Helm en créent un nommé `default`. `ant beta:environments list` affiche le nom et l’ID de chaque environnement. Pour vos propres workers, il s’agit de l’ID que la CLI d’administration a affiché dans [Exécuter vos propres workers](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#point-a-worker-at-your-server).

Placez vos deux ID dans votre shell, à la place de ces ID d’exemple :

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

L’exemple suivant crée une session et envoie son premier message dans la même requête :

<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>

La réponse contient l’ID de la session, qui commence par `sesn_`. L’agent se met immédiatement au travail. Ses outils intégrés, tels que `bash`, s’exécutent sur un worker qui sert l’environnement.

Pour suivre la session, ouvrez la [console de votre serveur](https://platform.claude.com/docs/fr/managed-agents/self-hosted/console) dans un navigateur, sélectionnez **Sessions**, puis sélectionnez la session. Une session que vous avez démarrée avec la clé API du serveur, comme sur cette page, n’apparaît qu’aux administrateurs.

Pour suivre plutôt la session dans votre terminal, passez son ID à [`ant beta:sessions connect`](https://platform.claude.com/docs/fr/cli-sdks-libraries/cli/sessions-connect) :

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

Pour découvrir ce qu’une session peut faire d’autre, comme épingler une version d’agent, consultez [Démarrer une session](https://platform.claude.com/docs/fr/managed-agents/sessions).

## Envoyer un message et lire la réponse

Placez l’ID de votre session dans votre shell, à la place de cet ID d’exemple :

```bash
export SESSION_ID=sesn_011CZkZAtmR3yMPDzynEDxu7
```

Attendez que la session soit inactive avant d’exécuter l’exemple suivant. L’exemple arrête la lecture à la fin d’un tour. Si un tour précédent est toujours en cours, sa fin peut arrêter l’exemple avant que la réponse à votre message n’arrive. La console et `ant beta:sessions connect` affichent toutes deux le statut de la session.

L’exemple suivant envoie un message et affiche la réponse de l’agent. Il ouvre d’abord le flux d’événements de la session, car un flux ne transmet que les événements qui surviennent après son ouverture :

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Ce flux de travail nécessite plus de logique qu’une seule commande shell. Utilisez le [SDK Anthropic](https://platform.claude.com/docs/fr/cli-sdks-libraries/overview) pour l’exécuter.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Ce flux de travail nécessite plus de logique qu’une seule commande shell. Pour envoyer des messages et lire les réponses dans votre terminal, utilisez [`ant beta:sessions connect`](https://platform.claude.com/docs/fr/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
      # ignorer les autres types d'événements
    end
  end
  ```
</CodeGroup>

Outre l’affichage du texte `agent.message`, la boucle gère trois événements :

* **`session.status_idle` :** la boucle se termine, sauf si le `stop_reason.type` de l’événement est `requires_action`.
* **`session.status_terminated` :** la boucle se termine.
* **`session.error` :** la boucle affiche le message de l’erreur et continue la lecture, car le serveur peut réessayer un appel au modèle ayant échoué et terminer le tour.

`requires_action` signifie que la session s’est mise en pause pour un appel d’outil. Ce qui met fin à la pause dépend de l’appel :

* **Un appel d’outil personnalisé, ou une demande de confirmation d’un appel d’outil :** seul votre code peut y répondre. Si votre agent utilise l’un ou l’autre, consultez [Répondre aux appels d’outils qui mettent la session en pause](https://platform.claude.com/docs/fr/managed-agents/events-and-streaming#answer-tool-calls-that-pause-the-session).
* **Un appel à un outil qu’un worker exécute, tel que `bash` :** Cet appel ne met normalement pas la session en pause. Si aucun worker ne prend en charge l’appel pendant environ 3 minutes, la session se met en pause jusqu’à ce qu’un worker renvoie le résultat. Votre code n’a alors rien à répondre. Gardez le flux ouvert : le tour reprend lorsqu’un worker exécute l’appel.

Pour les autres événements qu’une session envoie, et pour savoir comment se reconnecter sans en manquer aucun, consultez [Flux d’événements de session](https://platform.claude.com/docs/fr/managed-agents/events-and-streaming).

## Faire entrer et sortir des données d’une session

Les données entrent dans une session et en sortent par le répertoire de travail du worker.

Sur la pile du démarrage rapide, le conteneur de chaque session démarre avec un répertoire `/workspace` vide, à l’exception des clones des dépôts de la session. Par défaut, environ une minute après la fin d’un tour, le conteneur s’arrête, et Docker le supprime avec ce répertoire. Tout ce qu’une session doit conserver doit donc sortir avant ce moment par un appel d’outil, tel qu’un téléversement ou un `git push`.

Un conteneur s’arrête également environ une heure après son démarrage, même au milieu d’un tour. Aucun paramètre ne modifie ce comportement. Le tour se poursuit dans un nouveau conteneur, généralement au bout d’une minute ou deux, et votre client ne reçoit aucun événement pour ce changement. Le changement a deux conséquences :

* **Commandes :** tout ce qui s’exécute dans l’ancien conteneur s’arrête. Le nouveau conteneur exécute à nouveau depuis le début l’appel d’outil interrompu, mais rien ne redémarre une commande que l’agent a laissée s’exécuter en arrière-plan.
* **Fichiers :** le `/workspace` du nouveau conteneur est de nouveau vide, à l’exception de nouveaux clones des dépôts de la session.

Dans un tour long, demandez à l’agent de téléverser ou de pousser son travail au fur et à mesure, et évitez les commandes qui causent des dommages si elles s’exécutent deux fois.

Sur Kubernetes, une session conserve un pod pendant environ une heure au maximum, et le tour se poursuit de la même manière. Deux choses diffèrent : le nouveau pod trouve les fichiers de la session dans `/workspace`, et il démarre environ 6 minutes après l’arrêt de l’ancien pod.

Pour les workers que vous démarrez vous-même, placez les fichiers d’entrée dans le répertoire de travail avant d’envoyer le message qui en a besoin. Lisez-y les fichiers de sortie ensuite.

Lorsque vous démarrez vous-même un conteneur pour chaque session, montez un répertoire contenant les fichiers d’entrée de la session comme répertoire de travail du conteneur. Récupérez-y les fichiers de sortie une fois le conteneur arrêté. Consultez [Préparer des fichiers pour une session](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-workers#stage-files-for-a-session).

## Trouver d’autres exemples dans les guides du service hébergé

Les guides du service hébergé expliquent les [concepts fondamentaux](https://platform.claude.com/docs/fr/managed-agents/overview#core-concepts) de l’API et proposent des exemples pour chaque fonctionnalité. Leurs exemples du SDK et de la CLI appellent votre serveur lorsque vous les exécutez dans le terminal où `ANTHROPIC_BASE_URL` et `ANTHROPIC_API_KEY` sont définies. Leurs exemples cURL indiquent `https://api.anthropic.com` ; remplacez donc cette adresse par `$ANTHROPIC_BASE_URL` avant d’en exécuter un.

Pour certaines fonctionnalités, votre serveur a d’abord besoin d’un paramètre, ou un exemple nécessite une modification :

| Tâche                                                                     | Guide du service hébergé                                                                                                                                                           | Sur votre serveur                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Définir le modèle, l’invite système et les versions d’un agent            | [Définir votre agent](https://platform.claude.com/docs/fr/managed-agents/agent-setup)                                                                                              | Certains champs [dépendent de votre fournisseur d’inférence](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#differences-that-depend-on-your-inference-provider).                                                                                                                                                                                                    |
| Choisir des outils intégrés ou ajouter des outils personnalisés           | [Outils](https://platform.claude.com/docs/fr/managed-agents/tools)                                                                                                                 | Pour utiliser les outils web, activez-les d’abord, comme le décrit [Les outils web nécessitent un paramètre du serveur](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#web-tools-need-a-server-setting). Ceux qui existent dépendent de votre fournisseur d’inférence.                                                                                              |
| Connecter un serveur MCP et stocker son jeton                             | [Connecteur MCP](https://platform.claude.com/docs/fr/managed-agents/mcp-connector) et [S’authentifier avec des coffres](https://platform.claude.com/docs/fr/managed-agents/vaults) | Ajoutez l’hôte du serveur MCP à la [liste d’autorisation des serveurs MCP](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#mcp-servers-need-an-allowlist-entry). Stockez le jeton en tant qu’identifiant `static_bearer`.                                                                                                                                            |
| Donner des skills à un agent                                              | [Skills](https://platform.claude.com/docs/fr/managed-agents/skills)                                                                                                                | Téléversez chaque skill sous forme de fichiers individuels, car votre serveur refuse les archives zip. Les [skills prédéfinies](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#features-that-arent-available) des exemples de ce guide ne sont pas disponibles.                                                                                                     |
| Conserver une mémoire d’une session à l’autre                             | [Utiliser la mémoire d’agent](https://platform.claude.com/docs/fr/managed-agents/memory)                                                                                           | Si vous exécutez vos propres workers, fournissez-leur un répertoire `/mnt/memory` accessible en écriture, comme dans [Magasins de mémoire dans les sandboxes auto-hébergées](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-memory).                                                                                                                                  |
| Confier du travail à d’autres agents                                      | [Orchestration multiagent](https://platform.claude.com/docs/fr/managed-agents/multiagent-orchestration)                                                                            | Remplacez le bloc `multiagent_20261001` des exemples de ce guide par un [bloc `coordinator`](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#features-that-behave-differently).                                                                                                                                                                                      |
| Travailler dans un dépôt Git                                              | [Accéder à GitHub](https://platform.claude.com/docs/fr/managed-agents/github)                                                                                                      | Indiquez l’hôte Git dans les paramètres de votre serveur, comme le décrit [Les dépôts Git nécessitent une entrée dans la liste d’autorisation](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences#git-repositories-need-an-allowlist-entry). L’agent d’exemple de ce guide a également besoin de `api.githubcopilot.com` dans la liste d’autorisation des serveurs MCP. |
| Faire vérifier le travail par un évaluateur selon une grille d’évaluation | [Définir des résultats](https://platform.claude.com/docs/fr/managed-agents/define-outcomes)                                                                                        | Envoyez la grille d’évaluation sous forme de texte. La Files API n’est pas disponible ; [récupérez donc les fichiers de sortie](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#move-data-in-and-out-of-a-session) depuis le répertoire de travail.                                                                                                                 |
| Suivre une session et répondre à ses appels d’outils                      | [Flux d’événements de session](https://platform.claude.com/docs/fr/managed-agents/events-and-streaming)                                                                            | Le premier exemple de ce guide ferme le flux à chaque pause ; partez donc plutôt de la boucle de [Envoyer un message et lire la réponse](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#send-a-message-and-read-the-reply).                                                                                                                                        |

[Différences avec le service hébergé](https://platform.claude.com/docs/fr/managed-agents/self-hosted/differences) en donne la liste complète. Consultez-la avant de migrer une application existante.

## Exécuter vos propres workers

La [pile du démarrage rapide](https://platform.claude.com/docs/fr/managed-agents/self-hosted/quickstart) crée un environnement et exécute ses workers. Les charts Helm de [Déployer sur Kubernetes](https://platform.claude.com/docs/fr/managed-agents/self-hosted/kubernetes) en font autant. Si ces workers suffisent à vos besoins, ignorez cette section.

Vous exécutez les workers comme pour les [sandboxes auto-hébergés](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes) : avec les mêmes commandes `ant beta:worker` et les mêmes workers SDK, selon les méthodes que présente [Déployer des workers auto-hébergés](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-workers). L’exception concerne les workers déclenchés par des webhooks, car votre serveur n’en envoie aucun.

### Créer un environnement et sa clé

Créez un environnement et une clé d’environnement avec la CLI d’administration, et non dans la Claude Console. La CLI, `cma-server-admin`, se trouve à la racine de l’archive de la version ; exécutez donc la commande depuis cet emplacement. Pour `-base-url`, transmettez l’adresse à laquelle vos workers joignent le serveur :

* **Workers sur la machine qui exécute la pile du démarrage rapide :** `http://127.0.0.1:8400`
* **Workers sur une autre machine :** l’adresse `https` du [proxy TLS que vous placez devant le serveur](https://platform.claude.com/docs/fr/managed-agents/self-hosted/kubernetes#put-tls-in-front-of-the-server)

La CLI d’administration appelle le serveur à cette même adresse ; exécutez-la donc sur une machine qui peut joindre cette adresse.

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

La commande affiche les paramètres du worker, la commande qui démarre un worker, ainsi que l’ID et la date d’expiration de la clé :

```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: '...'
```

La commande n’affiche la clé qu’une seule fois ; stockez donc la clé, son ID et sa date d’expiration dans votre gestionnaire de secrets. La clé cesse de fonctionner au bout de 365 jours. Avant cette échéance, suivez [Remplacer une clé d’environnement pour vos propres workers](https://platform.claude.com/docs/fr/managed-agents/self-hosted/kubernetes#replace-an-environment-key-for-your-own-workers).

Tenez la clé API du serveur à l’écart des machines qui exécutent les workers. Exécutez les workers dans un conteneur ou une VM qui ne contient rien que vous deviez protéger. Pour vos autres obligations de sécurité, consultez [Vos responsabilités en matière de sécurité](https://platform.claude.com/docs/fr/managed-agents/self-hosted#your-security-responsibilities).

### Exécuter une expérimentation locale

Exécutez les trois lignes `export` dans le shell où vous démarrez le worker. Démarrez ensuite le worker avec ces commandes, et non avec celle qui est affichée. La première commande crée le répertoire de travail du worker, car le worker ne le crée pas :

```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` et `HISTFILE` configurent le shell derrière l’outil `bash` du worker, afin qu’il exécute chaque commande telle que l’agent l’a écrite :

* **`histchars=` :** le shell n’interprète pas `!` comme une référence à son historique de commandes.
* **`INPUTRC` :** le fichier désactive la complétion, qui consommerait sinon chaque caractère de tabulation d’une commande. Tenez le fichier à l’écart du répertoire de travail, où les outils de fichiers de l’agent pourraient le réécrire.
* **`HISTFILE=/dev/null` :** le shell ne lit ni n’écrit aucun fichier d’historique.

N’utilisez ce worker pour rien d’autre. Il détient la clé d’environnement et exécute les outils de toutes les sessions dans un seul processus. Il ne clone pas non plus les dépôts d’une session. La session s’exécute sans eux, et votre client ne reçoit aucune erreur.

### Exécuter des workers en production

Pour tout autre usage qu’une expérimentation locale, démarrez un conteneur pour chaque session et exécutez-y `ant beta:worker run`, comme l’indique [Exécuter un sandbox par session](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-workers#run-one-sandbox-per-session). Fournissez à son image ce qu’énumère [Créer votre propre image de sandbox](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#build-your-own-sandbox-image), et modifiez trois choses dans cette configuration :

* **Clé d’environnement :** ne transmettez pas `ANTHROPIC_ENVIRONMENT_KEY` au conteneur d’une session. Le serveur accepte cette clé pour toutes les sessions de l’environnement, et le conteneur n’a besoin d’accéder qu’à une seule session.
* **Secret de l’élément de travail :** transmettez ce secret à la place de la clé, car le serveur ne l’accepte que pour cette seule session. [Transmettre le secret de l’élément de travail](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-workers#forward-the-work-items-secret) montre où votre code le reçoit. Là où cette section définit `ANTHROPIC_WORK_SECRET`, placez le secret dans un fichier que seul l’utilisateur du conteneur peut lire. Par exemple, redirigez le secret vers l’entrée standard du conteneur, et faites en sorte que le conteneur écrive le fichier avant de démarrer le worker. Définissez ensuite `ANTHROPIC_WORK_SECRET_FILE` sur le chemin du fichier.
* **Adresse du serveur :** définissez `ANTHROPIC_BASE_URL` sur une adresse que le conteneur peut joindre. `http://127.0.0.1:8400` n’en est pas une.

Pour un worker SDK, deux points supplémentaires s’appliquent :

* **Version :** créez le worker avec la dernière version du SDK, comme le décrit [SDK, CLI et bibliothèques](https://platform.claude.com/docs/fr/cli-sdks-libraries/overview). Le worker de cette version attend une approbation avant d’exécuter un appel d’outil qui en nécessite une, et n’exécute jamais un appel qu’une politique refuse. Un worker créé avec une version antérieure exécute chaque appel d’outil dès qu’il arrive.
* **Exemples :** les exemples de [Exécuter le worker SDK à l’intérieur de la sandbox](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes-workers#run-the-sdk-worker-inside-the-sandbox) lisent la clé d’environnement, si bien qu’ils ne fonctionnent pas ici tels quels.

### Créer votre propre image de sandbox

Une image de votre cru nécessite ces paquets et paramètres :

* **Paquets :** Git 2.38 ou une version ultérieure, `curl`, `jq` et ripgrep, avec lequel l’outil `grep` du worker effectue ses recherches.

* **Paramètres du shell :** `histchars`, `HISTFILE` et `INPUTRC`, comme dans l’expérimentation locale, ainsi que `TERMINFO`. Placez ces lignes dans le Dockerfile, avant toute ligne `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` doit désigner le répertoire qui contient `d/dumb`, la description de terminal que lit le `bash` du worker. Sur Alpine avec `bash` installé, il s’agit de `/etc/terminfo`, comme indiqué. Sur une autre base, telle que Debian ou Ubuntu, il s’agit de `/lib/terminfo` ou `/usr/share/terminfo`, celui des deux qui contient `d/dumb`. Indiquez ce répertoire dans le paramètre `TERMINFO` et dans la ligne `RUN test`, qui arrête la construction si le fichier est absent.

L’image a également besoin de deux scripts de l’archive, qui s’exécutent avant le démarrage du worker :

1. Copiez `image-build/with-repositories.sh` vers `/usr/local/bin/cma-with-repositories`. Il clone les dépôts d’une session.
2. Copiez `image-build/with-egress.sh` vers `/usr/local/bin/cma-with-egress`. Il dirige les outils de la session vers l’[« egress gateway » (passerelle de sortie)](https://platform.claude.com/docs/fr/managed-agents/self-hosted/agent-identity#environment-variable-credentials), si votre serveur en exécute une.
3. Rendez les deux fichiers exécutables.
4. Placez les deux devant la commande du worker, comme dans `cma-with-egress cma-with-repositories ant beta:worker run ...`. Ignorez cette étape si votre image exécute le `kubernetes/sandbox/worker.sh` de l’archive, car ce script démarre le worker de cette manière.

Un worker qui démarre sans `cma-with-repositories` exécute la session sans aucun dépôt. Votre client ne reçoit aucune erreur.

### Migrer des workers depuis le service hébergé

Si vous exécutez déjà des workers pour le service hébergé d’Anthropic, ces mêmes workers peuvent plutôt servir votre serveur. Faites trois choses :

* Transmettez au processus qui interroge le serveur pour obtenir du travail les trois valeurs `export` que la CLI d’administration a affichées.
* Démarrez ce processus avec `histchars`, `HISTFILE` et `INPUTRC` définis, comme dans l’expérimentation locale.
* Appliquez les modifications que décrit [Exécuter des workers en production](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#run-workers-in-production), et vérifiez l’image de chaque session par rapport à [Créer votre propre image de sandbox](https://platform.claude.com/docs/fr/managed-agents/self-hosted/call-the-api#build-your-own-sandbox-image).

## Étapes suivantes

* [Permettre aux développeurs de se connecter depuis un terminal](https://platform.claude.com/docs/fr/managed-agents/self-hosted/configure#let-developers-log-in-from-a-terminal) : configurez l’authentification unique, afin que les développeurs utilisent la CLI `ant` sous leur propre identité, dans un terminal sans `ANTHROPIC_API_KEY`.
* [Identité et identifiants des agents](https://platform.claude.com/docs/fr/managed-agents/self-hosted/agent-identity) : permettez aux systèmes externes de faire confiance à vos agents, et conservez les identifiants des coffres-forts dans votre gestionnaire de secrets.
* [Fournisseur d’inférence](https://platform.claude.com/docs/fr/managed-agents/self-hosted/inference-provider) : envoyez les appels au modèle à un fournisseur cloud ou à votre propre passerelle de modèles.
