Standardmäßig führt Managed Agents Tools und Code in von Anthropic verwalteten Cloud-Sandboxes aus. Selbst gehostete Sandboxes belassen die Orchestrierung auf Anthropics Seite, verlagern die Tool-Ausführung aber in eine Infrastruktur, die du kontrollierst, sodass der Code, das Dateisystem und der ausgehende Netzwerkverkehr des Agenten deine Umgebung nie verlassen.
Die Tool-Ausführung bleibt auf deinem Host: Das Dateisystem, das der Agent liest und schreibt, die Prozesse, die er startet, und das Netzwerk, das er erreichen kann, stehen alle unter deiner Kontrolle. Tool-Eingaben und -Ausgaben fließen weiterhin zu Anthropics Control Plane (wo Claude läuft), damit das Modell Ergebnisse sehen und entscheiden kann, was als Nächstes zu tun ist. Siehe das Sicherheitsmodell für die vollständige Datenfluss-Grenze.
Selbst gehostete Sandboxes unterstützen alle in Managed Agents verfügbaren Claude-Modelle, einschließlich Claude Opus 4.8 und Claude Opus 5. Das Modell wird auf dem Agenten konfiguriert, nicht auf der Umgebung.
| Cloud-Umgebung | Selbst gehostete Sandbox | |
|---|---|---|
| Wo Tools laufen | Von Anthropic verwaltete Sandboxes | Deine Infrastruktur |
| Netzwerkreichweite | Anthropics Egress-Kontrollen | Deine Netzwerkrichtlinie |
| Einbinden von Dateien und GitHub-Repos | Von Anthropic verwaltet | Von dir verwaltet |
| Lebenszyklus | Von Anthropic verwaltet | Von dir verwaltet |
Self-Hosting ist eine gute Wahl, wenn der Agent mit Daten arbeiten muss, die deine Netzwerkgrenze nicht verlassen dürfen, interne Dienste erreichen muss, die nicht öffentlich routbar sind, oder unter den eigenen Compliance- und Audit-Kontrollen deiner Organisation laufen soll.
Für Zero Data Retention und HIPAA-BAA-Berechtigung siehe API und Datenspeicherung.
Self-Hosting steuert, wo der Code des Agenten ausgeführt wird. MCP-Tunnel steuern, wie Anthropic MCP-Server in deinem Netzwerk erreicht. Sie sind unabhängig voneinander: Eine Session, die in Anthropics Cloud-Sandboxes läuft, kann weiterhin private MCP-Server über einen Tunnel erreichen, und eine selbst gehostete Session kann entweder getunnelte oder öffentliche MCP-Server verwenden. Verwende beides, wenn du möchtest, dass sowohl Ausführung als auch Tool-Zugriff innerhalb deiner Grenze bleiben. Um dem Agenten Tools von einem MCP-Server innerhalb deines Netzwerks zu geben, ohne einen Tunnel zu betreiben, kannst du den Server auch als Custom Tools kapseln, die von deinem Worker bereitgestellt werden.
Dieser Leitfaden beschreibt, wie du einen Worker mit einer beliebigen generischen Sandboxing-Plattform baust. Zusätzliche, plattformspezifische Leitfäden sind verfügbar für AWS Lambda MicroVMs, Blaxel, Cloudflare, Daytona, E2B, GKE Agent Sandbox, Modal, Namespace, Superserve und Vercel.
Ein „environment worker" (Umgebungs-Worker) ist ein Prozess, den du auf deiner eigenen Infrastruktur betreibst. Er empfängt Tool-Ausführungsanfragen von Anthropic und führt sie lokal aus. Die self_hosted-Umgebung fungiert als Arbeitswarteschlange: Wenn ihr eine Session zugewiesen wird, stellt Anthropic die Session als Work Item in die Warteschlange. Dein Worker beansprucht Work Items aus dieser Warteschlange, startet für jedes einen Ausführungskontext, lädt die Skills des Agenten herunter (wiederverwendbare, dateisystembasierte Ressourcen, die dem Agenten domänenspezifisches Fachwissen geben), führt die Tool-Aufrufe aus und sendet die Ergebnisse zurück.
Work Items werden durch Polling der Warteschlange der Umgebung beansprucht: entweder durch einen Always-on-Worker, der kontinuierlich pollt, oder einen Webhook-getriggerten Handler, der bei session.status_run_started aufwacht und mit dem Polling beginnt.
Die CLI und das SDK liefern beide vorgefertigte Worker mit. Die ant-CLI unterstützt nur das Always-on-Muster; das SDK unterstützt sowohl Always-on als auch Webhook-getriggert. Beide sind konfigurierbar: Siehe Self-hosted worker in der Referenz für CLI-Flags und SDK-Helfer auf dieser Seite für die SDK-Optionen. Für mehr Kontrolle rufe die Environments-Work-Endpunkte direkt auf und implementiere deinen eigenen Worker.
/workspace: das systemseitige Standard-Arbeitsverzeichnis für Tool-Ausführung und Skill-Download. Das --workdir-Flag der CLI verwendet standardmäßig das aktuelle Verzeichnis; übergib --workdir /workspace, um dem Systemstandard zu entsprechen. Skills werden nach <workdir>/skills/<name>/ heruntergeladen. Wenn du ein anderes Arbeitsverzeichnis verwendest, aktualisiere den System-Prompt deines Agenten, damit Claude die Skill-Dateien finden kann./mnt/session/outputs-Anweisung weg, die in von Anthropic verwalteten Sandboxes verwendet wird, sodass finale Ergebnisse dort landen, wo der Agent sie in deinem Sandbox-Dateisystem schreibt, typischerweise unterhalb des Arbeitsverzeichnisses.Du benötigst:
/bin/bash unter genau diesem Pfad. Das Bash-Tool des Workers ruft es direkt auf, ohne PATH zu konsultieren. Das TypeScript-SDK benötigt zusätzlich unzip und tar im PATH sowie Node.js 22 oder neuer; die Python- und Go-SDKs verwenden ihre Standardbibliotheken für die Archiv-Extraktion und haben keine zusätzlichen Binär-Anforderungen.ant-CLI oder ein Anthropic-SDK (Python, TypeScript oder Go) auf dem Worker-Host.Auf der Claude Platform auf AWS authentifiziert sich der Worker mit AWS IAM (SigV4) oder einem in der AWS Console generierten API-Key, nicht mit einem Environment-Key. Hänge die verwaltete Richtlinie AnthropicSelfHostedEnvironmentAccess an das IAM-Principal an, unter dem dein Worker läuft. In der Claude Console generierte Environment-Keys funktionieren nicht mit dem Claude-Platform-auf-AWS-Endpunkt.
Erstelle eine selbst gehostete Umgebung
In der Console: Workspace > Environments > New > Self-hosted
Oder über die API:
client = anthropic.Anthropic()
environment = client.beta.environments.create(
name="self-hosted", config={"type": "self_hosted"}
)
print(environment.id)Generiere einen Environment-Key
Öffne in der Console die Umgebung und klicke auf Generate environment key. Die Key-Generierung ist nur über die Console möglich, unabhängig davon, ob du die Umgebung über die Console oder die API erstellt hast. Exportiere dann die Environment-ID und den Key auf dem Worker-Host:
export ANTHROPIC_ENVIRONMENT_KEY="sk-ant-oat01-..."
export ANTHROPIC_ENVIRONMENT_ID="env_..."Skills können ausführbare Dateien enthalten, die der Agent direkt ausführen kann. Die CLI- und SDK-Worker bewahren die im Skill-Bundle aufgezeichneten Ausführungsberechtigungen beim Extrahieren. Wenn du den Skill-Download manuell implementierst, bist du für das Setzen der Ausführungsberechtigungen verantwortlich.
Wähle Always-on für das einfachste Setup: Ein langlaufender Prozess pollt die Warteschlange kontinuierlich und benötigt nur ausgehendes HTTPS. Wähle Webhook-getriggert, um keinen untätigen Poller laufen zu lassen; dies erfordert einen Webhook-Endpunkt, den Anthropic erreichen kann (siehe Webhooks für Endpunkt-Einrichtung und Signaturverifizierung).
Installiere die ant CLI
Führe dies auf dem Worker-Host aus.
Für Linux-Umgebungen lade das Release-Binary direkt herunter.
VERSION=1.21.0
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
case $(uname -m) in
x86_64) ARCH=amd64 ;;
aarch64) ARCH=arm64 ;;
esac
curl -fsSL "https://github.com/anthropics/anthropic-cli/releases/download/v${VERSION}/ant_${VERSION}_${OS}_${ARCH}.tar.gz" \
| sudo tar -xz -C /usr/local/bin antDu findest alle Releases auf der GitHub-Releases-Seite.
Führe den Worker aus
In-Process
ant beta:worker poll beansprucht Work Items, die der Umgebung zugewiesen sind, lädt Skills herunter, führt Tool-Aufrufe im Arbeitsverzeichnis aus und sendet Ergebnisse zurück. Es liest ANTHROPIC_ENVIRONMENT_KEY und ANTHROPIC_ENVIRONMENT_ID aus der Umgebung.
ant beta:worker poll \
--workdir "/workspace"Der Worker beendet sich sauber bei SIGTERM oder SIGINT: Er bricht jeden laufenden Tool-Aufruf ab, sendet dessen Fehlerergebnis und gibt das Work Item frei, bevor er stoppt.
Sandbox pro Session
Wenn du stärkere Isolation benötigst (ein frisches Dateisystem, Ressourcenlimits oder Netzwerkkontrollen pro Session), führe jede Session in ihrer eigenen Sandbox aus. Baue ein Image mit installiertem ant und ant beta:worker run als Entrypoint. Das Basis-Image muss /bin/bash bereitstellen; curl wird nur zur Build-Zeit verwendet. Wenn eine Sandbox startet, liest sie Session-Details aus Umgebungsvariablen, bearbeitet diese Session und beendet sich:
FROM your-base-image
ARG ANT_VERSION=1.21.0
ARG TARGETARCH
RUN ARCH=$([ "$TARGETARCH" = "arm64" ] && echo arm64 || echo amd64) && \
curl -fsSL "https://github.com/anthropics/anthropic-cli/releases/download/v${ANT_VERSION}/ant_${ANT_VERSION}_linux_${ARCH}.tar.gz" \
| tar -xz -C /usr/local/bin ant
WORKDIR /workspace
VOLUME /workspace
ENTRYPOINT ["ant", "beta:worker", "run"]Schreibe dann ein Spawn-Skript, das Session-Details in eine frische Sandbox weiterleitet. Der Poller injiziert ANTHROPIC_SESSION_ID, ANTHROPIC_WORK_ID, ANTHROPIC_ENVIRONMENT_ID und ANTHROPIC_ENVIRONMENT_KEY in die Umgebung des Skripts. ANTHROPIC_BASE_URL ist optional und wird nur durchgereicht, wenn es auf dem Poller-Host gesetzt war; es überschreibt den Standard-API-Endpunkt. Im Beispiel ist /host/outputs ein von dir gewähltes Host-Verzeichnis; es wird per Bind-Mount in das Arbeitsverzeichnis der Sandbox (/workspace) eingebunden, damit du Session-Ergebnisse abrufen kannst, nachdem die Sandbox beendet wurde. In selbst gehosteten Umgebungen schreibt der Agent Ergebnisse unterhalb des Arbeitsverzeichnisses statt nach /mnt/session/outputs (siehe Sandbox-Dateisystem), daher erfasst das Einbinden des Arbeitsverzeichnisses diese; der Mount erfasst auch den heruntergeladenen skills/-Baum und alle Zwischendateien, die der Agent erstellt.
#!/bin/bash
# spawn.sh: wird einmal pro beanspruchtem Arbeitselement aufgerufen
mkdir -p "/host/outputs/$ANTHROPIC_SESSION_ID"
exec docker run --rm \
-e ANTHROPIC_SESSION_ID -e ANTHROPIC_ENVIRONMENT_KEY \
-e ANTHROPIC_WORK_ID -e ANTHROPIC_ENVIRONMENT_ID -e ANTHROPIC_BASE_URL \
-v "/host/outputs/$ANTHROPIC_SESSION_ID":/workspace \
your-imageStarte den Poller mit Verweis auf das Skript:
ant beta:worker poll \
--on-work ./spawn.shDas SDK bietet drei Helfer auf unterschiedlichen Kontrollebenen. EnvironmentWorker deckt die meisten Anwendungsfälle ab; greife auf die Low-Level-Helfer zurück, wenn du deinen eigenen Prozess pro Session starten oder Tools gegen eine bereits beanspruchte Session ausführen musst.
EnvironmentWorker: der sofort einsatzbereite Worker. Übernimmt Polling, Setup und Ausführung von Anfang bis Ende.
.run(): läuft unbegrenzt und nimmt Sessions auf, sobald sie eintreffen..handle_item(): bearbeitet ein einzelnes beanspruchtes Work Item und beendet sich. Übergib die Work-, Session- und Environment-Bezeichner explizit oder lass ihn die ANTHROPIC_*-Variablen lesen, die ant beta:worker poll --on-work für den von ihm gestarteten Prozess setzt.work.poller(): pollt die Arbeitswarteschlange für dich und gibt dir jede beanspruchte Session. Verwende dies, wenn du entscheiden möchtest, was für jede Session passiert, zum Beispiel das Starten einer Sandbox statt der In-Process-Ausführung von Tools.
drain: ob das Polling gestoppt werden soll, sobald die Warteschlange leer ist, statt auf neue Arbeit zu warten.block_ms: wie lange auf das Eintreffen von Arbeit gewartet werden soll, bevor zurückgekehrt wird, in Millisekunden. Muss zwischen 1 und 999 liegen (Wartezeit pro Poll; der Helfer pollt automatisch erneut). Übergib null (None in Python, param.Null[int64]() in Go) für eine nicht-blockierende Prüfung; das Weglassen des Parameters verwendet den Standard-Long-Poll von 999 ms.reclaim_older_than_ms: beansprucht Work Items erneut, die beansprucht, aber nicht innerhalb dieser Anzahl von Millisekunden bestätigt wurden.auto_stop: ob für jedes Work Item ein Stopp-Signal gesendet werden soll, sobald dein Schleifenkörper damit fertig ist. Der Go-Poller hat keine Opt-out-Möglichkeit und sendet das Stopp-Signal immer, blockiere also im Schleifenkörper, bis die Session abgeschlossen ist, statt dich abzukoppeln.client.beta.sessions.events.tool_runner(): führt Tool-Aufrufe für eine einzelne Session aus, gegeben die Session-ID und eine Tool-Liste. Verwende dies, wenn du die Arbeit bereits beansprucht hast und nur die Ausführungsschicht benötigst.Verwende den Work-Poller direkt, wenn du deinen eigenen Prozess pro Session starten möchtest, zum Beispiel das Hochfahren einer Sandbox für jede beanspruchte Session:
import asyncio
import os
from anthropic import AsyncAnthropic
from anthropic.types.beta.environments import BetaSelfHostedWork
async def launch_container(work: BetaSelfHostedWork) -> None:
# Ersetze dies durch deinen eigenen Sandbox-Launcher pro Session. Übergib
# ANTHROPIC_ENVIRONMENT_KEY an die gestartete Sandbox, niemals
# deinen API-Key.
print(f"claimed session {work.data.id}")
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:
async for work in client.beta.environments.work.poller(
environment_id=environment_id,
environment_key=environment_key,
auto_stop=False, # the launched sandbox owns the stop call
):
await launch_container(work)
asyncio.run(main())AgentToolContext ist der Ausführungskontext für Tool-Aufrufe. Er definiert das Arbeitsverzeichnis und die Pfad-Richtlinie und kann die Skills der Session herunterladen. beta_agent_toolset_20260401(env) nimmt einen AgentToolContext entgegen und gibt die Standard-Tool-Implementierungen zurück (bash, read, write, edit, glob, grep).
Mit EnvironmentWorker: Beide werden automatisch verwaltet. Übergib eine tools-Factory, um die Tool-Liste anzupassen:
EnvironmentWorker(client, ..., tools=lambda env: [beta_bash_tool(env), my_custom_tool])Mit work.poller() und tool_runner(): Übergib eine Tool-Liste als tools an client.beta.sessions.events.tool_runner(). Um diese Liste zu erstellen, richte AgentToolContext selbst ein und rufe beta_agent_toolset_20260401(env) auf:
from anthropic.lib.tools.agent_toolset import (
AgentToolContext,
beta_agent_toolset_20260401,
)
async with AgentToolContext(
workdir="/workspace", client=client, session_id=work.data.id
) as env:
# Skills heruntergeladen nach /workspace/skills/<name>/
tools = beta_agent_toolset_20260401(env)Bestätige von einer separaten Shell aus, mit ANTHROPIC_API_KEY auf deinen Claude-API-Key gesetzt (nicht den Environment-Key), dass workers_polling mindestens 1 ist:
ant beta:environments:work stats --environment-id "$ANTHROPIC_ENVIRONMENT_ID"Wenn workers_polling bei 0 bleibt, erreicht der Worker die Warteschlange nicht: Bestätige, dass ANTHROPIC_ENVIRONMENT_KEY und ANTHROPIC_ENVIRONMENT_ID auf dem Worker-Host gesetzt sind. Siehe Warteschlangentiefe lesen für die vollständige Stats-Antwort und Beispiele in anderen Sprachen.
Sobald dein Worker läuft, erstelle eine Session, die auf die Umgebung abzielt. Setze AGENT_ID auf die Agent-ID, die du dir in Bevor du beginnst notiert hast. Die Session tritt in die Arbeitswarteschlange der Umgebung ein und wartet dort, bis ein Worker sie beansprucht; wenn kein Worker verbunden ist, bleibt die Session in der Warteschlange, statt fehlzuschlagen.
Anthropic bindet keine Dateien oder GitHub-Repositories in selbst gehostete Sandboxes ein. Um sessionspezifische Dateien verfügbar zu machen, übergib Dateireferenzen (wie einen S3-Pfad oder Commit-SHA) im metadata-Feld der Session. Das beanspruchte Work Item enthält nicht die Metadaten der Session, aber es enthält die Session-ID: Dein Spawn-Skript oder --on-work-Handler ruft die Session ab (GET /v1/sessions/{session_id}), um das metadata-Feld zu lesen, und stellt dann die Dateien im Arbeitsverzeichnis bereit, bevor die Tool-Ausführung beginnt.
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
metadata={"input_file": "s3://my-bucket/data.csv"},
)Selbst gehostete Sandboxes unterstützen keine resources-Einträge; eine Session, die eine Ressource in einer selbst gehosteten Umgebung enthält, wird abgelehnt.
Siehe Self-hosted worker in der Referenz für die vollständige Liste der CLI-Flags und SDK-Helfer für die SDK-Helfer-Optionen.
Custom Tools sind Tools, die dein eigener Code ausführt: Der Agent gibt ein agent.custom_tool_use-Event aus und wartet auf ein passendes user.custom_tool_result. Der Worker kann dieser Code sein, und weil er innerhalb deiner Sandbox läuft, erreicht das Tool die internen Dienste, Zugangsdaten und den ausgehenden Netzwerkverkehr, die du für die Sandbox konfiguriert hast, und nichts darüber hinaus. Der Environment-Key autorisiert das Senden von Custom-Tool-Ergebnissen, sodass dein Claude-API-Key nicht auf dem Worker-Host liegt.
Das Bereitstellen von Custom Tools erfordert den SDK-Worker: Der ant-CLI-Worker hat keine Möglichkeit, eine Custom-Tool-Implementierung zu registrieren. Führe im Sandbox-pro-Session-Muster EnvironmentWorker innerhalb der Sandbox mit handle_item() (handleItem in TypeScript, HandleItem in Go) anstelle von ant beta:worker run aus.
Deklariere das Tool auf dem Agenten
Füge einen custom-Eintrag zu den tools des Agenten hinzu, dessen name mit dem Tool übereinstimmt, das dein Worker registriert. Siehe Custom Tools für die vollständige Deklarationsform.
{
"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"]
}
}Registriere die Implementierung beim Worker
Übergib das Tool über die tools-Factory des Workers (siehe SDK-Helfer), zusammen mit dem eingebauten Toolset:
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."""
# Läuft auf dem Worker-Host: Rufe alles auf, was die Sandbox erreichen kann.
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())Der Worker beantwortet nur die bei ihm registrierten Tools. Ein Custom Tool, das auf dem Agenten deklariert, aber bei keinem Worker oder Client registriert ist, lässt die Session mit einem requires_action-Stoppgrund pausiert, bis etwas sein Ergebnis sendet; siehe Umgang mit Custom-Tool-Aufrufen für den Event-Ablauf.
Der MCP-Connector verbindet sich von Anthropics Seite aus mit MCP-Servern, daher muss ein Server einen HTTP-Endpunkt bereitstellen, den Anthropic erreichen kann, direkt oder über einen MCP-Tunnel. Um einen Server zu verwenden, den nur dein Netzwerk erreichen kann, mache stattdessen den Worker zum MCP-Client und deklariere die Tools des Servers als Custom Tools. Der MCP-Server benötigt keine eingehende Konnektivität von außerhalb deines Netzwerks; Anthropic erhält die Tool-Definitionen, die du auf dem Agenten deklarierst, die Eingabe jedes Aufrufs und das Ergebnis, das dein Worker zurücksendet. Zur Laufzeit ruft das Modell ein gekapseltes Tool wie jedes andere Custom Tool auf:
agent.custom_tool_use-Event aus.user.custom_tool_result.Die clientseitigen MCP-Helfer der SDKs konvertieren die Tools des Servers in die ausführbaren Tools, die der Worker akzeptiert; installiere ein MCP-SDK neben dem Anthropic-SDK (pip install "anthropic[mcp]" "mcp>=1.24", npm install @modelcontextprotocol/sdk, go get github.com/modelcontextprotocol/go-sdk). Die Beispiele verbinden sich ohne Authentifizierung; um Zugangsdaten zu senden, konfiguriere den HTTP-Client oder die Request-Optionen, die du dem MCP-Transport übergibst (http_client in Python, requestInit in TypeScript, HTTPClient in Go).
Deklariere die Tools des Servers auf dem Agenten
Liste die Tools des MCP-Servers auf und deklariere jedes als custom-Tool; die MCP-Felder name, description und inputSchema werden eins zu eins auf die Felder des Custom Tools abgebildet. Wenn der Server seine Tool-Liste paginiert, deklariere jede Seite; der Worker muss dieselben Seiten auflisten.
import asyncio
from typing import Any, cast
from anthropic import AsyncAnthropic
from anthropic.types.beta import BetaManagedAgentsCustomToolParams
from mcp import ClientSession, types
# Erfordert mcp >= 1.24, das streamablehttp_client in streamable_http_client umbenannt hat.
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:
# Die MCP-Felder lassen sich eins zu eins auf eine Custom-Tool-Deklaration abbilden. Der Cast
# übergibt das Schema-Dictionary unverändert an den typisierten Parameter des SDK.
return {
"type": "custom",
"name": tool.name,
"description": tool.description or tool.name,
"input_schema": cast(Any, tool.inputSchema),
}
async def main() -> None:
# Führe dies dort aus, wo du Agenten erstellst, nicht auf dem Worker-Host:
# es authentifiziert sich mit deinem Claude-API-Key (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",
tools=[
{"type": "agent_toolset_20260401"},
*[to_custom_tool(tool) for tool in listed.tools],
],
)
print(agent.id)
asyncio.run(main())Stelle die Tools vom Worker bereit
Verbinde dich beim Start mit demselben MCP-Server, konvertiere seine Tools mit den MCP-Helfern und registriere sie zusammen mit dem eingebauten Toolset. Halte eine MCP-Session für die Lebensdauer des Workers offen.
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
# Erfordert mcp >= 1.24, das streamablehttp_client in streamable_http_client umbenannt hat.
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"]
# Verbinde dich beim Start einmal mit dem MCP-Server und halte die Session offen für
# die Lebensdauer des Workers. Das Timeout wandelt einen hängenden Tool-Aufruf
# in ein Fehlerergebnis statt eines blockierten Aufrufs um.
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())Beachte Folgendes, wenn du einen MCP-Server kapselst:
tools-Array eines Agenten nimmt höchstens 128 Einträge auf (jedes gekapselte Tool ist ein Eintrag, und das eingebaute Toolset ist ein weiterer). Die API lehnt eine Deklaration ab, die einen Tool-Namen wiederverwendet, ein Custom Tool nach einem eingebauten Agent-Tool wie bash oder read benennt oder das reservierte mcp__-Präfix verwendet. Die MCP-Helfer behalten die Namen und Beschreibungen des Servers bei, benenne also um oder kürze, wo nötig. Wenn zwei Server denselben Tool-Namen bereitstellen, definiere den Wrapper selbst unter einem Namen mit Präfix und lass ihn den ursprünglichen Tool-Namen des Servers aufrufen.additionalProperties und title. Sie lehnt Referenz-Schlüsselwörter wie $ref überall im input_schema eines Custom Tools ab, also inline die Schemas, die Generatoren wie pydantic in $defs auslagern. Sie lehnt außerdem oneOf, anyOf und allOf auf oberster Ebene ab sowie Eigenschaftsnamen außerhalb von Buchstaben, Ziffern, Unterstrichen, Punkten und Bindestrichen (1–64 Zeichen).read_timeout_seconds tut. Ohne einen solchen wird ein hängender Aufruf erst dann zu einem Fehlerergebnis, wenn der Standard-Request-Timeout des TypeScript-MCP-SDK auslöst (etwa eine Minute) oder wenn der eigene Backstop des Workers greift: etwa zweieinhalb Minuten in Python und zwei Minuten in Go, wo der Worker einen Tool-Aufruf abbricht, der seinen 120-Sekunden-Standard überschreitet, und ein Fehlerergebnis sendet.bash auf dem Worker-Host. Deklariere nur die Tools, die der Agent verwenden soll.Diese Aufrufe laufen von deinem Monitoring- oder Betriebs-Tooling aus, authentifiziert mit deinem Claude-API-Key, um die Worker-Flotte zu beobachten und zu verwalten. Die Claim- und Keep-Alive-Schleife wird innerhalb der Worker-Helfer abgewickelt, sodass du diese Endpunkte nicht direkt aufrufst.
Diese Endpunkte akzeptieren entweder deinen Organisations-API-Key oder den Environment-Key. Rufe sie von außerhalb des Worker-Hosts mit deinem Organisations-API-Key auf. Das Setzen von ANTHROPIC_API_KEY auf dem Worker-Host setzt ein organisationsweites Zugangsdatum den Agent-Tool-Aufrufen aus.
work.stats gibt den Warteschlangenzustand für eine Umgebung zurück:
depth ist die Anzahl der Items, die darauf warten, beansprucht zu werden. Skaliere deine Worker-Flotte oder alarmiere bei Rückstau basierend auf diesem Wert.pending ist die Anzahl der Items, die von einem Worker beansprucht, aber noch nicht bestätigt wurden. Die Worker-Helfer bestätigen jedes Item, bevor sie es verarbeiten, daher bleibt dieser Wert im Normalbetrieb nahe null; ein anhaltend von null verschiedener Wert bedeutet, dass ein Worker zwischen Beanspruchen und Bestätigen hängen geblieben ist.oldest_queued_at ist der Zeitstempel des ältesten Items, das sich noch in der Warteschlange befindet und darauf wartet, beansprucht zu werden, oder beansprucht, aber noch nicht bestätigt wurde, oder null, wenn es keines gibt.workers_polling ist die Anzahl der Worker, die in den letzten 30 Sekunden gepollt haben. Verwende dies für Liveness-Alarmierung.import os
import anthropic
client = anthropic.Anthropic()
stats = client.beta.environments.work.stats(os.environ["ANTHROPIC_ENVIRONMENT_ID"])
print(f"depth={stats.depth} pending={stats.pending}"){
"type": "work_queue_stats",
"depth": 0,
"pending": 0,
"oldest_queued_at": null,
"workers_polling": 0
}Verwende work.stop, um den Worker, der eine bestimmte Session bearbeitet, aufzufordern, sie herunterzufahren. Standardmäßig wechselt das Work-Item in den Zustand stopping: Der Worker bemerkt dies bei seinem nächsten Lease-Heartbeat, bricht den laufenden Tool-Aufruf der Session ab und bestätigt das Herunterfahren, woraufhin das Work-Item in den Zustand stopped übergeht. Übergib force: true im Request-Body (mit der CLI übergibst du --force), um das Work-Item sofort als stopped zu markieren, anstatt auf die Bestätigung des Workers zu warten.
Da diese Aufrufe von deinem Operations-Tooling und nicht vom Worker-Host ausgeführt werden, wird ANTHROPIC_WORK_ID nicht automatisch gesetzt. Setze sie auf die ID des Ziel-Work-Items, bevor du die folgenden Beispiele ausführst. Um die ID eines Work-Items zu finden, liste die Work-Items der Umgebung über die Environments-Work-Endpunkte auf.
import os
import anthropic
client = anthropic.Anthropic()
work = client.beta.environments.work.stop(
os.environ["ANTHROPIC_WORK_ID"],
environment_id=os.environ["ANTHROPIC_ENVIRONMENT_ID"],
)
print(work.state)Modell der geteilten Verantwortung für selbst gehostete Sandbox-Umgebungen.
Erstelle eine Session, um deinen Agenten auszuführen und mit der Ausführung von Aufgaben zu beginnen.
Verbinde Claude sicher mit MCP-Servern, die in deinem privaten Netzwerk laufen, ohne eingehende Ports zu öffnen oder Dienste dem öffentlichen Internet auszusetzen.
Was this page helpful?