Alat kustom di sandbox self-hosted
Layani alat kustom dari worker sandbox self-hosted, dan bungkus server MCP di dalam jaringan Anda sebagai alat kustom tanpa menjalankan tunnel.
Alat kustom adalah alat yang dieksekusi oleh kode Anda sendiri: agen memancarkan event agent.custom_tool_use dan menunggu user.custom_tool_result yang sesuai. Worker Anda dapat menjadi kode tersebut. Karena berjalan di dalam sandbox Anda, alat tersebut menjangkau layanan internal, kredensial, dan "network egress" (lalu lintas jaringan keluar) yang Anda konfigurasikan untuk sandbox, dan tidak lebih dari itu.
Environment key mengotorisasi pengiriman hasil alat kustom, sehingga kunci API Claude Anda tetap berada di luar host worker.
Melayani alat kustom
Deklarasikan alat pada agen
Tambahkan entri
customketoolsmilik agen yangname-nya cocok dengan alat yang didaftarkan worker Anda. Lihat Alat kustom untuk bentuk deklarasi lengkapnya.{ "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"] } }Daftarkan implementasi dengan worker
Teruskan alat melalui factory
toolsmilik worker (lihatEnvironmentWorker), bersama dengan toolset bawaan: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.""" # Berjalan di host worker: dapat memanggil apa pun yang bisa dijangkau sandbox. 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())
Worker hanya menjawab alat yang didaftarkan padanya. Jika sebuah alat dideklarasikan pada agen tetapi tidak ada worker atau klien yang melayaninya, sesi akan dijeda dengan alasan berhenti requires_action. Sesi tetap dijeda sampai ada sesuatu yang mengirimkan hasilnya. Lihat Menangani pemanggilan alat kustom untuk alur event-nya.
Membungkus server MCP sebagai alat kustom
Konektor MCP terhubung ke server MCP dari sisi Anthropic. Oleh karena itu, server harus mengekspos endpoint HTTP yang dapat dijangkau Anthropic, baik secara langsung maupun melalui tunnel MCP.
Untuk menggunakan server yang hanya dapat dijangkau oleh jaringan Anda, jadikan worker sebagai klien MCP dan deklarasikan alat-alat server tersebut sebagai alat kustom. Server MCP tidak memerlukan konektivitas masuk dari luar jaringan Anda. Anthropic menerima definisi alat yang Anda deklarasikan pada agen, input setiap panggilan, dan hasil yang dikirimkan kembali oleh worker Anda.
Saat runtime, model memanggil alat yang dibungkus seperti alat kustom lainnya:
- Agen memancarkan event
agent.custom_tool_use. - Worker, di dalam sandbox Anda, meneruskan panggilan melalui sesi MCP yang terbuka ke server di jaringan Anda.
- Worker mengirimkan respons server sebagai
user.custom_tool_result.
Menginstal SDK MCP
Helper MCP sisi klien milik SDK mengonversi alat-alat server menjadi alat yang dapat dijalankan yang diterima worker. Instal SDK MCP bersama dengan SDK Anthropic: pip install "anthropic[mcp]" "mcp>=1.24".
Contoh-contoh ini terhubung tanpa autentikasi. Untuk mengirim kredensial, konfigurasikan http_client yang Anda berikan ke transport MCP.
Mendeklarasikan dan melayani alat
Deklarasikan alat-alat server pada agen
Ambil daftar alat server MCP dan deklarasikan masing-masing sebagai alat
custom.name,description, daninputSchemaMCP dipetakan satu per satu ke field alat kustom. Jika server melakukan paginasi pada daftar alatnya, deklarasikan setiap halaman; worker harus mengambil daftar dari halaman yang sama.import asyncio from typing import Any, cast from anthropic import AsyncAnthropic from anthropic.types.beta import BetaManagedAgentsCustomToolParams from mcp import ClientSession, types # Memerlukan mcp >= 1.24, yang mengganti nama streamablehttp_client menjadi 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: # Field MCP dipetakan satu-ke-satu ke deklarasi alat kustom. Cast ini # meneruskan dictionary skema ke parameter bertipe milik SDK tanpa perubahan. return { "type": "custom", "name": tool.name, "description": tool.description or tool.name, "input_schema": cast(Any, tool.inputSchema), } async def main() -> None: # Jalankan ini di tempat Anda membuat agen, bukan di host worker: skrip ini # melakukan autentikasi dengan kunci API Claude Anda (ANTHROPIC_API_KEY). async with ( streamable_http_client(MCP_SERVER_URL) as (read, write, _), ClientSession(read, write) as mcp_session, AsyncAnthropic() as client, ): await mcp_session.initialize() listed = await mcp_session.list_tools() agent = await client.beta.agents.create( name="Internal tools agent", model="claude-opus-5-5", tools=[ {"type": "agent_toolset_20260401"}, *[to_custom_tool(tool) for tool in listed.tools], ], ) print(agent.id) asyncio.run(main())Layani alat dari worker
Hubungkan ke server MCP yang sama saat startup, konversikan alat-alatnya dengan
async_mcp_tool, dan daftarkan bersama denganbeta_agent_toolset_20260401. Pertahankan satu sesi MCP tetap terbuka selama masa hidup worker.import asyncio import os from datetime import timedelta from anthropic import AsyncAnthropic from anthropic.lib.environments import EnvironmentWorker from anthropic.lib.tools.agent_toolset import beta_agent_toolset_20260401 from anthropic.lib.tools.mcp import async_mcp_tool from mcp import ClientSession # Memerlukan mcp >= 1.24, yang mengganti nama streamablehttp_client menjadi 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"] # Hubungkan ke server MCP sekali saat startup dan biarkan sesi tetap terbuka selama # masa hidup worker. Timeout mengubah panggilan alat yang macet menjadi hasil # error alih-alih panggilan yang terhenti. 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())
Batasan dan perilaku
Alat dideklarasikan, bukan ditemukan saat runtime
Worker mengambil daftar alat server MCP sekali saat startup dan tidak dapat menambahkan alat ke sesi yang sedang berjalan. Ketika alat-alat server berubah:
- Deklarasikan ulang alat-alat tersebut, pada agen atau pada sesi yang sedang idle melalui Memperbarui konfigurasi agen.
- Mulai ulang worker.
Deklarasi harus sesuai dengan Managed Agents API
Helper MCP mempertahankan nama dan deskripsi server, dan sebagian besar skema diteruskan tanpa perubahan. Ganti nama, pangkas, atau lakukan inline jika sebuah deklarasi melanggar salah satu aturan berikut:
| Field | Aturan |
|---|---|
name | Unik per agen. Huruf, angka, garis bawah, dan tanda hubung, 1–128 karakter. Tidak boleh sama dengan alat agen bawaan seperti bash atau read, atau menggunakan prefiks mcp__ yang dicadangkan. |
description | Wajib dan tidak boleh kosong. |
input_schema | Menerima kata kunci JSON Schema yang umum dipancarkan server MCP, seperti additionalProperties dan title. Menolak kata kunci referensi seperti $ref di mana pun, serta oneOf, anyOf, dan allOf di tingkat atas. Nama properti menggunakan huruf, angka, garis bawah, titik, dan tanda hubung, 1–64 karakter. |
Array tools milik agen | Paling banyak 128 entri. Setiap alat yang dibungkus adalah satu entri, dan toolset bawaan adalah satu entri lagi. |
Dua kasus memerlukan pekerjaan tambahan:
- Dua server mengekspos nama alat yang sama: Definisikan sendiri pembungkusnya dengan nama berprefiks dan buat pembungkus tersebut memanggil nama alat asli server.
- Generator seperti pydantic memfaktorkan skema ke dalam
$defs: Lakukan inline pada skema tersebut sebelum Anda mendeklarasikan alat.
Kegagalan alat muncul sebagai hasil alat error
Ketika server MCP melaporkan error alat, worker mengirimkan hasil alat error yang dapat ditanggapi oleh model. Konten MCP yang tidak memiliki padanan hasil alat, seperti blok audio dan tautan sumber daya, juga muncul sebagai error.
Tetapkan timeout pada klien MCP untuk kegagalan yang lebih cepat dan lebih jelas, seperti yang dilakukan contoh worker Python dengan read_timeout_seconds. Lihat Panggilan alat MCP yang dibungkus macet untuk mengetahui apa yang terjadi tanpa timeout.
Bungkus hanya server yang Anda operasikan atau percayai
Nama, deskripsi, dan hasil alat yang dibungkus masuk ke konteks model seperti alat lainnya. Semua itu adalah input tidak tepercaya yang dapat memengaruhi apa yang dilakukan agen dengan alat-alat lainnya, termasuk bash pada host worker. Deklarasikan hanya alat yang Anda maksudkan untuk digunakan oleh agen.
Kebijakan izin tidak berlaku
Kebijakan izin mengatur toolset bawaan dan toolset MCP. Worker mengeksekusi setiap panggilan alat yang dibungkus yang dibuat oleh model, jadi tempatkan langkah persetujuan apa pun di dalam kode alat Anda sendiri.
Was this page helpful?