기본적으로 Managed Agents는 Anthropic이 관리하는 클라우드 샌드박스 내에서 도구와 코드를 실행합니다. 셀프 호스팅 샌드박스는 오케스트레이션은 Anthropic 측에 유지하되 도구 실행을 여러분이 제어하는 인프라로 옮기므로, 에이전트의 코드, 파일시스템, 네트워크 이그레스가 여러분의 환경을 벗어나지 않습니다.
도구 실행은 여러분의 호스트에 유지됩니다. 에이전트가 읽고 쓰는 파일시스템, 에이전트가 생성하는 프로세스, 에이전트가 접근할 수 있는 네트워크가 모두 여러분의 제어 하에 있습니다. 도구 입력과 출력은 여전히 Anthropic의 컨트롤 플레인(Claude가 실행되는 곳)으로 전달되어 모델이 결과를 확인하고 다음에 무엇을 할지 결정할 수 있습니다. 전체 데이터 흐름 경계는 보안 모델을 참조하세요.
셀프 호스팅 샌드박스는 Claude Opus 4.8과 Claude Opus 5를 포함하여 Managed Agents에서 사용 가능한 모든 Claude 모델을 지원합니다. 모델은 환경이 아니라 에이전트에서 구성됩니다.
| 클라우드 환경 | 셀프 호스팅 샌드박스 | |
|---|---|---|
| 도구 실행 위치 | Anthropic이 관리하는 샌드박스 | 여러분의 인프라 |
| 네트워크 접근 범위 | Anthropic의 이그레스 제어 | 여러분의 네트워크 정책 |
| 파일 및 GitHub 저장소 마운트 | Anthropic이 관리 | 여러분이 관리 |
| 라이프사이클 | Anthropic이 관리 | 여러분이 관리 |
셀프 호스팅은 에이전트가 네트워크 경계를 벗어날 수 없는 데이터를 다루거나, 공개적으로 라우팅되지 않는 내부 서비스에 접근하거나, 조직 자체의 컴플라이언스 및 감사 제어 하에서 실행되어야 할 때 적합합니다.
Zero Data Retention 및 HIPAA BAA 적격성에 대해서는 API 및 데이터 보존을 참조하세요.
셀프 호스팅은 에이전트의 코드가 실행되는 위치를 제어합니다. MCP 터널은 Anthropic이 여러분의 네트워크에 있는 MCP 서버에 도달하는 방법을 제어합니다. 이 둘은 독립적입니다. Anthropic의 클라우드 샌드박스에서 실행되는 세션도 터널을 통해 프라이빗 MCP 서버에 접근할 수 있고, 셀프 호스팅 세션도 터널링된 MCP 서버나 공개 MCP 서버를 모두 사용할 수 있습니다. 실행과 도구 접근을 모두 여러분의 경계 안에 유지하려면 둘 다 사용하세요. 터널을 실행하지 않고 네트워크 내부의 MCP 서버에서 에이전트에 도구를 제공하려면, 워커가 제공하는 커스텀 도구로 서버를 래핑할 수도 있습니다.
이 가이드는 일반적인 샌드박싱 플랫폼으로 워커를 구축하는 방법을 설명합니다. 플랫폼별 추가 가이드는 AWS Lambda MicroVMs, Blaxel, Cloudflare, Daytona, E2B, GKE Agent Sandbox, Modal, Namespace, Superserve, Vercel에서 확인할 수 있습니다.
환경 워커는 여러분의 자체 인프라에서 실행하는 프로세스입니다. Anthropic으로부터 도구 실행 요청을 받아 로컬에서 실행합니다. self_hosted 환경은 작업 큐 역할을 합니다. 세션이 해당 환경에 할당되면 Anthropic은 세션을 작업 항목으로 큐에 넣습니다. 워커는 해당 큐에서 작업 항목을 클레임하고, 각 항목에 대한 실행 컨텍스트를 생성하고, 에이전트의 스킬(에이전트에 도메인별 전문성을 제공하는 재사용 가능한 파일시스템 기반 리소스)을 다운로드하고, 도구 호출을 실행한 다음, 결과를 다시 게시합니다.
작업 항목은 환경의 큐를 폴링하여 클레임됩니다. 지속적으로 폴링하는 상시 실행 워커를 사용하거나, session.status_run_started에서 깨어나 폴링을 시작하는 웹훅 트리거 핸들러를 사용할 수 있습니다.
CLI와 SDK 모두 사전 구축된 워커를 제공합니다. ant CLI는 상시 실행 패턴만 지원하고, SDK는 상시 실행과 웹훅 트리거를 모두 지원합니다. 둘 다 구성 가능합니다. CLI 플래그는 레퍼런스의 셀프 호스팅 워커를, SDK 옵션은 이 페이지의 SDK 헬퍼를 참조하세요. 더 많은 제어가 필요하면 Environments Work 엔드포인트를 직접 호출하여 자체 워커를 구현하세요.
/workspace: 도구 실행 및 스킬 다운로드를 위한 시스템 기본 작업 디렉터리입니다. CLI의 --workdir 플래그는 현재 디렉터리가 기본값입니다. 시스템 기본값과 일치시키려면 --workdir /workspace를 전달하세요. 스킬은 <workdir>/skills/<name>/에 다운로드됩니다. 다른 작업 디렉터리를 사용하는 경우, Claude가 스킬 파일을 찾을 수 있도록 에이전트의 시스템 프롬프트를 업데이트하세요./mnt/session/outputs 지침이 생략되므로, 최종 결과물은 에이전트가 샌드박스 파일시스템에 쓰는 위치(일반적으로 작업 디렉터리 아래)에 저장됩니다.다음이 필요합니다:
/bin/bash가 있는 Linux 호스트. 워커의 bash 도구는 PATH를 참조하지 않고 이를 직접 호출합니다. TypeScript SDK는 추가로 PATH에 unzip과 tar가 있어야 하고 Node.js 22 이상이 필요합니다. Python 및 Go SDK는 아카이브 추출에 표준 라이브러리를 사용하므로 추가 바이너리 요구 사항이 없습니다.ant CLI 또는 Anthropic SDK(Python, TypeScript 또는 Go).Claude Platform on AWS에서는 워커가 환경 키가 아니라 AWS IAM(SigV4) 또는 AWS Console에서 생성한 API 키로 인증합니다. 워커가 실행되는 IAM 주체에 AnthropicSelfHostedEnvironmentAccess 관리형 정책을 연결하세요. Claude Console에서 생성한 환경 키는 Claude Platform on AWS 엔드포인트에서 작동하지 않습니다.
셀프 호스팅 환경 생성
Console에서: Workspace > Environments > New > Self-hosted
또는 API를 통해:
client = anthropic.Anthropic()
environment = client.beta.environments.create(
name="self-hosted", config={"type": "self_hosted"}
)
print(environment.id)환경 키 생성
Console에서 환경을 열고 Generate environment key를 클릭하세요. 환경을 Console에서 생성했든 API로 생성했든 관계없이 키 생성은 Console에서만 가능합니다. 그런 다음 워커 호스트에서 환경 ID와 키를 내보내세요:
export ANTHROPIC_ENVIRONMENT_KEY="sk-ant-oat01-..."
export ANTHROPIC_ENVIRONMENT_ID="env_..."스킬에는 에이전트가 직접 실행할 수 있는 실행 파일이 포함될 수 있습니다. CLI 및 SDK 워커는 스킬 번들을 추출할 때 번들에 기록된 실행 권한을 보존합니다. 스킬 다운로드를 수동으로 구현하는 경우, 실행 권한 설정은 여러분의 책임입니다.
가장 간단한 설정을 원한다면 상시 실행을 선택하세요. 장기 실행 프로세스가 큐를 지속적으로 폴링하며 아웃바운드 HTTPS만 필요합니다. 유휴 폴러를 실행하지 않으려면 웹훅 트리거를 선택하세요. 이 경우 Anthropic이 접근할 수 있는 웹훅 엔드포인트가 필요합니다(엔드포인트 설정 및 서명 검증은 웹훅 참조).
ant CLI 설치
워커 호스트에서 실행하세요.
Linux 환경에서는 릴리스 바이너리를 직접 다운로드하세요.
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 ant모든 릴리스는 GitHub 릴리스 페이지에서 확인할 수 있습니다.
워커 실행
인프로세스
ant beta:worker poll은 환경에 할당된 작업 항목을 클레임하고, 스킬을 다운로드하고, 작업 디렉터리에서 도구 호출을 실행하고, 결과를 다시 게시합니다. 환경 변수에서 ANTHROPIC_ENVIRONMENT_KEY와 ANTHROPIC_ENVIRONMENT_ID를 읽습니다.
ant beta:worker poll \
--workdir "/workspace"워커는 SIGTERM 또는 SIGINT에서 깔끔하게 종료됩니다. 진행 중인 도구 호출을 취소하고, 오류 결과를 게시하고, 중지하기 전에 작업 항목을 해제합니다.
세션별 샌드박스
더 강력한 격리(새로운 파일시스템, 리소스 제한 또는 세션별 네트워크 제어)가 필요하면 각 세션을 자체 샌드박스에서 실행하세요. ant가 설치되고 ant beta:worker run을 엔트리포인트로 하는 이미지를 빌드하세요. 베이스 이미지는 /bin/bash를 제공해야 하며, curl은 빌드 시에만 사용됩니다. 샌드박스가 시작되면 환경 변수에서 세션 세부 정보를 읽고, 해당 세션을 처리한 후 종료합니다:
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"]그런 다음 세션 세부 정보를 새 샌드박스로 전달하는 스폰 스크립트를 작성하세요. 폴러는 ANTHROPIC_SESSION_ID, ANTHROPIC_WORK_ID, ANTHROPIC_ENVIRONMENT_ID, ANTHROPIC_ENVIRONMENT_KEY를 스크립트의 환경에 주입합니다. ANTHROPIC_BASE_URL은 선택 사항이며 폴러 호스트에 설정된 경우에만 전달됩니다. 이는 기본 API 엔드포인트를 재정의합니다. 예제에서 /host/outputs는 여러분이 선택하는 호스트 디렉터리입니다. 샌드박스의 작업 디렉터리(/workspace)에 바인드 마운트되어 샌드박스 종료 후 세션 결과물을 가져올 수 있습니다. 셀프 호스팅 환경에서 에이전트는 /mnt/session/outputs가 아니라 작업 디렉터리 아래에 결과물을 작성하므로(샌드박스 파일시스템 참조), 작업 디렉터리를 마운트하는 것이 결과물을 캡처하는 방법입니다. 이 마운트는 다운로드된 skills/ 트리와 에이전트가 생성하는 중간 파일도 함께 가져옵니다.
#!/bin/bash
# spawn.sh: 클레임된 작업 항목마다 한 번씩 호출됩니다
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-image스크립트를 가리키도록 폴러를 시작하세요:
ant beta:worker poll \
--on-work ./spawn.shSDK는 서로 다른 제어 수준의 세 가지 헬퍼를 제공합니다. EnvironmentWorker가 대부분의 사용 사례를 다룹니다. 세션별로 자체 프로세스를 시작하거나 이미 클레임된 세션에 대해 도구를 실행해야 할 때는 하위 수준 헬퍼를 사용하세요.
EnvironmentWorker: 즉시 사용 가능한 워커입니다. 폴링, 설정, 실행을 처음부터 끝까지 처리합니다.
.run(): 세션이 도착하는 대로 처리하며 무기한 실행됩니다..handle_item(): 클레임된 단일 작업 항목을 처리하고 종료합니다. 작업, 세션, 환경 식별자를 명시적으로 전달하거나, ant beta:worker poll --on-work가 생성하는 프로세스에 설정하는 ANTHROPIC_* 변수를 읽도록 할 수 있습니다.work.poller(): 작업 큐를 대신 폴링하고 클레임된 각 세션을 제공합니다. 각 세션에 대해 무엇을 할지 직접 결정하고 싶을 때(예: 인프로세스로 도구를 실행하는 대신 샌드박스를 시작) 사용하세요.
drain: 새 작업을 기다리지 않고 큐가 비면 폴링을 중지할지 여부입니다.block_ms: 반환하기 전에 작업이 도착하기를 기다리는 시간(밀리초)입니다. 1에서 999 사이여야 합니다(폴링당 대기 시간이며, 헬퍼가 자동으로 다시 폴링합니다). 논블로킹 확인을 위해서는 null(Python에서는 None, Go에서는 param.Null[int64]())을 전달하세요. 매개변수를 생략하면 기본값인 999ms 롱 폴링이 사용됩니다.reclaim_older_than_ms: 클레임되었지만 이 밀리초 내에 확인(acknowledge)되지 않은 작업 항목을 다시 클레임합니다.auto_stop: 루프 본문이 각 작업 항목 처리를 마치면 중지 신호를 게시할지 여부입니다. Go 폴러는 옵트아웃이 없고 항상 중지 신호를 게시하므로, 분리하지 말고 세션이 완료될 때까지 루프 본문에서 블로킹하세요.client.beta.sessions.events.tool_runner(): 세션 ID와 도구 목록이 주어지면 단일 세션에 대한 도구 호출을 실행합니다. 이미 작업을 클레임했고 실행 계층만 필요할 때 사용하세요.세션별로 자체 프로세스를 시작하고 싶을 때(예: 클레임된 각 세션에 대해 샌드박스를 스핀업) 작업 폴러를 직접 사용하세요:
import asyncio
import os
from anthropic import AsyncAnthropic
from anthropic.types.beta.environments import BetaSelfHostedWork
async def launch_container(work: BetaSelfHostedWork) -> None:
# 자체 세션별 샌드박스 런처로 교체하세요. 실행된 샌드박스에는
# ANTHROPIC_ENVIRONMENT_KEY를 전달하고, 절대
# API 키를 전달하지 마세요.
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**는 도구 호출을 위한 실행 컨텍스트입니다. 작업 디렉터리와 경로 정책을 정의하고 세션의 스킬을 다운로드할 수 있습니다. **beta_agent_toolset_20260401(env)**는 AgentToolContext를 받아 표준 도구 구현(bash, read, write, edit, glob, grep)을 반환합니다.
EnvironmentWorker 사용 시: 둘 다 자동으로 관리됩니다. 도구 목록을 커스터마이즈하려면 tools 팩토리를 전달하세요:
EnvironmentWorker(client, ..., tools=lambda env: [beta_bash_tool(env), my_custom_tool])work.poller() 및 tool_runner() 사용 시: client.beta.sessions.events.tool_runner()에 도구 목록을 tools로 전달하세요. 해당 목록을 만들려면 AgentToolContext를 직접 설정하고 beta_agent_toolset_20260401(env)를 호출하세요:
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:
# /workspace/skills/<name>/에 다운로드된 스킬
tools = beta_agent_toolset_20260401(env)별도의 셸에서 ANTHROPIC_API_KEY를 Claude API 키(환경 키가 아님)로 설정한 상태에서 workers_polling이 1 이상인지 확인하세요:
ant beta:environments:work stats --environment-id "$ANTHROPIC_ENVIRONMENT_ID"workers_polling이 0에 머물러 있다면 워커가 큐에 도달하지 못하는 것입니다. 워커 호스트에 ANTHROPIC_ENVIRONMENT_KEY와 ANTHROPIC_ENVIRONMENT_ID가 설정되어 있는지 확인하세요. 전체 통계 응답과 다른 언어 예제는 큐 깊이 읽기를 참조하세요.
워커가 실행되면 해당 환경을 대상으로 하는 세션을 생성하세요. AGENT_ID를 시작하기 전에에서 기록한 에이전트 ID로 설정하세요. 세션은 환경의 작업 큐에 들어가 워커가 클레임할 때까지 대기합니다. 연결된 워커가 없으면 세션은 실패하지 않고 큐에 남아 있습니다.
Anthropic은 셀프 호스팅 샌드박스에 파일이나 GitHub 저장소를 마운트하지 않습니다. 세션별 파일을 사용할 수 있게 하려면 세션 metadata 필드에 파일 참조(예: S3 경로 또는 커밋 SHA)를 전달하세요. 클레임된 작업 항목에는 세션의 메타데이터가 포함되지 않지만 세션 ID는 포함됩니다. 스폰 스크립트나 --on-work 핸들러가 세션을 조회(GET /v1/sessions/{session_id})하여 metadata 필드를 읽은 다음, 도구 실행이 시작되기 전에 파일을 작업 디렉터리에 준비합니다.
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
metadata={"input_file": "s3://my-bucket/data.csv"},
)셀프 호스팅 샌드박스는 resources 항목을 지원하지 않습니다. 셀프 호스팅 환경에서 리소스를 포함하는 세션은 거부됩니다.
CLI 플래그의 전체 목록은 레퍼런스의 셀프 호스팅 워커를, SDK 헬퍼 옵션은 SDK 헬퍼를 참조하세요.
커스텀 도구는 여러분의 코드가 실행하는 도구입니다. 에이전트가 agent.custom_tool_use 이벤트를 발생시키고 일치하는 user.custom_tool_result를 기다립니다. 워커가 그 코드가 될 수 있으며, 워커는 샌드박스 내부에서 실행되므로 도구는 샌드박스에 구성한 내부 서비스, 자격 증명, 네트워크 이그레스에만 접근할 수 있습니다. 환경 키가 커스텀 도구 결과 게시를 승인하므로 Claude API 키는 워커 호스트에 두지 않아도 됩니다.
커스텀 도구를 제공하려면 SDK 워커가 필요합니다. ant CLI 워커에는 커스텀 도구 구현을 등록할 방법이 없습니다. 세션별 샌드박스 패턴에서는 ant beta:worker run 대신 샌드박스 내부에서 handle_item()(TypeScript에서는 handleItem, Go에서는 HandleItem)으로 EnvironmentWorker를 실행하세요.
에이전트에 도구 선언
워커가 등록하는 도구와 name이 일치하는 custom 항목을 에이전트의 tools에 추가하세요. 전체 선언 형식은 커스텀 도구를 참조하세요.
{
"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"]
}
}워커에 구현 등록
내장 도구 세트와 함께 워커의 tools 팩토리를 통해 도구를 전달하세요(SDK 헬퍼 참조):
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."""
# 워커 호스트에서 실행됩니다: 샌드박스가 접근할 수 있는 모든 것을 호출할 수 있습니다.
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())워커는 자신에게 등록된 도구에만 응답합니다. 에이전트에 선언되었지만 어떤 워커나 클라이언트에도 등록되지 않은 커스텀 도구는 무언가가 결과를 게시할 때까지 세션을 requires_action 중지 이유로 일시 중지 상태로 둡니다. 이벤트 흐름은 커스텀 도구 호출 처리를 참조하세요.
MCP 커넥터는 Anthropic 측에서 MCP 서버에 연결하므로, 서버는 직접 또는 MCP 터널을 통해 Anthropic이 접근할 수 있는 HTTP 엔드포인트를 노출해야 합니다. 여러분의 네트워크에서만 접근할 수 있는 서버를 사용하려면, 대신 워커를 MCP 클라이언트로 만들고 서버의 도구를 커스텀 도구로 선언하세요. MCP 서버는 네트워크 외부로부터의 인바운드 연결이 필요 없습니다. Anthropic은 에이전트에 선언한 도구 정의, 각 호출의 입력, 워커가 다시 게시하는 결과를 받습니다. 런타임에 모델은 래핑된 도구를 다른 커스텀 도구와 동일하게 호출합니다:
agent.custom_tool_use 이벤트를 발생시킵니다.user.custom_tool_result로 게시합니다.SDK의 클라이언트 측 MCP 헬퍼는 서버의 도구를 워커가 받아들이는 실행 가능한 도구로 변환합니다. Anthropic SDK와 함께 MCP SDK를 설치하세요(pip install "anthropic[mcp]" "mcp>=1.24", npm install @modelcontextprotocol/sdk, go get github.com/modelcontextprotocol/go-sdk). 예제는 인증 없이 연결합니다. 자격 증명을 보내려면 MCP 전송에 전달하는 HTTP 클라이언트 또는 요청 옵션(Python에서는 http_client, TypeScript에서는 requestInit, Go에서는 HTTPClient)을 구성하세요.
에이전트에 서버의 도구 선언
MCP 서버의 도구를 나열하고 각각을 custom 도구로 선언하세요. MCP의 name, description, inputSchema는 커스텀 도구의 필드에 일대일로 매핑됩니다. 서버가 도구 목록을 페이지네이션하는 경우 모든 페이지를 선언하세요. 워커도 동일한 페이지를 나열해야 합니다.
import asyncio
from typing import Any, cast
from anthropic import AsyncAnthropic
from anthropic.types.beta import BetaManagedAgentsCustomToolParams
from mcp import ClientSession, types
# mcp >= 1.24가 필요합니다. 이 버전에서 streamablehttp_client가 streamable_http_client로 이름이 변경되었습니다.
from mcp.client.streamable_http import streamable_http_client
MCP_SERVER_URL = "http://mcp.internal.example.com:8000/mcp"
def to_custom_tool(tool: types.Tool) -> BetaManagedAgentsCustomToolParams:
# MCP 필드는 커스텀 도구 선언에 일대일로 매핑됩니다. 캐스트는
# 스키마 딕셔너리를 SDK의 타입 지정 매개변수에 그대로 전달합니다.
return {
"type": "custom",
"name": tool.name,
"description": tool.description or tool.name,
"input_schema": cast(Any, tool.inputSchema),
}
async def main() -> None:
# 워커 호스트가 아니라 에이전트를 생성하는 곳에서 실행하세요.
# Claude API 키(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())워커에서 도구 제공
시작 시 동일한 MCP 서버에 연결하고, MCP 헬퍼로 도구를 변환하고, 내장 도구 세트와 함께 등록하세요. 워커의 수명 동안 하나의 MCP 세션을 열어 두세요.
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
# mcp >= 1.24가 필요합니다. 이 버전에서 streamablehttp_client가 streamable_http_client로 이름이 변경되었습니다.
from mcp.client.streamable_http import streamable_http_client
MCP_SERVER_URL = "http://mcp.internal.example.com:8000/mcp"
async def main() -> None:
environment_key = os.environ["ANTHROPIC_ENVIRONMENT_KEY"]
environment_id = os.environ["ANTHROPIC_ENVIRONMENT_ID"]
# 시작 시 MCP 서버에 한 번 연결하고 워커가 실행되는 동안
# 세션을 열어 둡니다. 타임아웃은 멈춘 도구 호출을 중단된 호출이 아닌
# 오류 결과로 바꿉니다.
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())MCP 서버를 래핑할 때 다음 사항에 유의하세요:
tools 배열은 최대 128개 항목을 받습니다(래핑된 각 도구가 하나의 항목이고 내장 도구 세트가 하나 더 추가됩니다). API는 도구 이름을 재사용하거나, bash나 read 같은 내장 에이전트 도구의 이름을 커스텀 도구에 사용하거나, 예약된 mcp__ 접두사를 사용하는 선언을 거부합니다. MCP 헬퍼는 서버의 이름과 설명을 그대로 유지하므로 필요한 경우 이름을 변경하거나 줄이세요. 두 서버가 동일한 도구 이름을 노출하는 경우, 접두사가 붙은 이름으로 래퍼를 직접 정의하고 서버의 원래 도구 이름을 호출하도록 하세요.additionalProperties와 title 같이 MCP 서버가 일반적으로 내보내는 JSON Schema 키워드를 허용합니다. 커스텀 도구의 input_schema 어디에서든 $ref 같은 참조 키워드는 거부하므로, pydantic 같은 생성기가 $defs로 분리하는 스키마는 인라인으로 만드세요. 또한 최상위 oneOf, anyOf, allOf와 문자, 숫자, 밑줄, 점, 하이픈(1–64자) 이외의 속성 이름도 거부합니다.read_timeout_seconds로 하는 것처럼 MCP 클라이언트에 타임아웃을 설정하면 더 빠르고 명확하게 실패합니다. 타임아웃이 없으면 멈춘 호출은 TypeScript MCP SDK의 기본 요청 타임아웃(약 1분)이 발동하거나 워커 자체의 백스톱이 발동할 때(Python에서는 약 2분 30초, Go에서는 2분 — 워커가 120초 기본값을 초과하는 도구 호출을 취소하고 오류 결과를 게시)에만 오류 결과가 됩니다.bash를 포함한 다른 도구로 무엇을 할지에 영향을 줄 수 있는 신뢰할 수 없는 입력입니다. 에이전트가 사용하도록 의도한 도구만 선언하세요.이러한 호출은 워커 플릿을 관찰하고 관리하기 위해 Claude API 키로 인증된 모니터링 또는 운영 도구에서 실행됩니다. 클레임 및 킵얼라이브 루프는 워커 헬퍼 내부에서 처리되므로 해당 엔드포인트를 직접 호출하지 않습니다.
이러한 엔드포인트는 조직 API 키 또는 환경 키를 모두 허용합니다. 워커 호스트 외부에서 조직 API 키로 호출하세요. 워커 호스트에 ANTHROPIC_API_KEY를 설정하면 조직 범위의 자격 증명이 에이전트 도구 호출에 노출됩니다.
work.stats는 환경의 큐 상태를 반환합니다:
depth는 클레임 대기 중인 항목 수입니다. 이 값을 기준으로 워커 플릿을 확장하거나 백로그에 대해 알림을 설정하세요.pending은 워커가 클레임했지만 아직 확인(acknowledge)하지 않은 항목 수입니다. 워커 헬퍼는 각 항목을 처리하기 전에 확인하므로 정상 운영에서는 이 값이 0에 가깝게 유지됩니다. 0이 아닌 값이 지속되면 워커가 클레임과 확인 사이에서 멈췄다는 의미입니다.oldest_queued_at은 아직 큐에 있는 가장 오래된 항목(클레임 대기 중이거나 클레임되었지만 아직 확인되지 않음)의 타임스탬프이며, 없으면 null입니다.workers_polling은 지난 30초 동안 폴링한 워커 수입니다. 라이브니스 알림에 사용하세요.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
}work.stop을 사용하여 특정 세션을 처리하는 워커에게 종료를 요청합니다. 기본적으로 작업 항목은 stopping 상태로 전환됩니다. 워커는 다음 리스 하트비트에서 이를 감지하고, 세션의 진행 중인 도구 호출을 취소한 후 종료를 확인하며, 이 시점에 작업 항목은 stopped 상태가 됩니다. 워커의 확인을 기다리지 않고 작업 항목을 즉시 stopped로 표시하려면 요청 본문에 force: true를 전달하세요(CLI의 경우 --force를 전달).
이러한 호출은 워커 호스트가 아닌 운영 도구에서 실행되므로 ANTHROPIC_WORK_ID가 자동으로 설정되지 않습니다. 다음 예제를 실행하기 전에 대상 작업 항목의 ID로 설정하세요. 작업 항목의 ID를 찾으려면 Environments Work 엔드포인트를 통해 환경의 작업 항목을 나열하세요.
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)자체 호스팅 샌드박스 환경을 위한 공동 책임 모델입니다.
에이전트를 실행하고 작업 수행을 시작할 세션을 생성합니다.
인바운드 포트를 열거나 서비스를 공용 인터넷에 노출하지 않고도 프라이빗 네트워크에서 실행 중인 MCP 서버에 Claude를 안전하게 연결합니다.
Was this page helpful?