Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One capture · api

One read of Claude Developer Platformapi-20261015T200735Z

78 pages moved out of 781 read.

Pages moved 78 significant first
Pages read 781 in this capture
Captured 20:07 UTC
Corpus hash 28c59a41a592 corpus-hash

What this read moved

51-75 of 78, page 3 of 4

This capture is too large to show at once. Changes 51-75 of 78 are below, significant first; the rest are on the following screens.

managed-agents/secure-deployment Changed · +3 / -3 lines

from line 14
1414 
1515| Section | Setting or decision | Recommended |
1616| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
17| [Choose where the agent runs](https://platform.claude.com/docs/en/managed-agents/secure-deployment#choose-where-the-agent-runs) | Cloud or self-hosted sandbox | Cloud, unless files and processes must stay on your infrastructure |
17| [Choose where the agent runs](https://platform.claude.com/docs/en/managed-agents/secure-deployment#choose-where-the-agent-runs) | Cloud or self-hosted sandbox | Cloud, unless tools must run on infrastructure you control |
1818| [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) | Environment `networking.type` | `limited`, with only the hosts the agent needs |
1919| [Keep credentials in vaults](https://platform.claude.com/docs/en/managed-agents/secure-deployment#keep-credentials-in-vaults) | `injection_location` and `networking` on each environment variable credential | Request headers only, and `limited` networking with only the hosts the key is for |
2020| [Restrict web search and web fetch](https://platform.claude.com/docs/en/managed-agents/secure-deployment#restrict-web-search-and-web-fetch) | `allowed_domains` on each web tool | An allowlist on each tool. On `web_fetch`, list only the sites the agent needs. On `web_search`, list the sites you want results from |
from line 29
2929 
3030## Choose where the agent runs
3131 
32Choose a cloud environment unless you need files and processes to stay on infrastructure you control. Session history and tool inputs and outputs go to Anthropic either way.
32Where the agent's tools run decides who secures the sandbox: Anthropic, with a cloud environment, or you, with a self-hosted sandbox. To choose between them and learn what reaches Anthropic with each, see [Choosing an agent environment](https://platform.claude.com/docs/en/managed-agents/choosing-an-environment).
3333 
3434If you use a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes), keep these four points in mind:
3535 
from line 36
3636* **Network:** [Limit the network](https://platform.claude.com/docs/en/managed-agents/secure-deployment#limit-the-network) applies to cloud environments. For a self-hosted sandbox, set the equivalent limits on its traffic in your own firewall. Your firewall does not limit the MCP servers an agent declares, so review them, and any that your application sets for a session.
3737* **Web tools:** The web tools run on Anthropic's servers, so your firewall does not limit them. Limit them with their domain lists. See [Restrict web search and web fetch](https://platform.claude.com/docs/en/managed-agents/secure-deployment#restrict-web-search-and-web-fetch).
3838* **Credentials:** Environment variable credentials are not yet supported with self-hosted sandboxes.
39* **Isolation and hardening:** You are responsible for isolating sessions from each other, hardening the sandbox image, and storing the environment service key. See the [Security model](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-security).
39* **Isolation and hardening:** You are responsible for both. See the [Security model](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-security).
4040 
4141Neither option changes the compliance coverage of Managed Agents or how long it keeps session history. See [Monitor sessions and review retention](https://platform.claude.com/docs/en/managed-agents/secure-deployment-monitoring#monitor-sessions-and-review-retention).
4242 

managed-agents/self-hosted-sandboxes-custom-tools Changed · +209 / -45 lines

from line 43
4343 <Step title="Register the implementation with the worker">
4444 Pass the tool through the worker's `tools` (go: `ToolsFunc`) factory (see [`EnvironmentWorker`](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-reference#environment-worker)), alongside the built-in toolset:
4545 
46 <CodeGroup exclude="shell">
46 <CodeGroup exclude="shell, csharp, java, php, ruby">
4747 ```python Python
4848 import asyncio
4949 import os
from line 109
109109 }).run();
110110 ```
111111 
112 ```csharp C#
113 // EnvironmentWorker is not currently available in the C# SDK.
114 // To answer custom tool calls directly, see the session event stream.
115 ```
112 <CodeGroupItem language="C#">
113 The C# SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
114 </CodeGroupItem>
116115 
117116 ```go Go
118117 package main
from line 175
176175 
177176 ```
178177 
179 ```java Java
180 // EnvironmentWorker is not currently available in the Java SDK.
181 // To answer custom tool calls directly, see the session event stream.
182 ```
178 <CodeGroupItem language="Java">
179 The Java SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
180 </CodeGroupItem>
183181 
184 ```php PHP
185 // EnvironmentWorker is not currently available in the PHP SDK.
186 // To answer custom tool calls directly, see the session event stream.
187 ```
182 <CodeGroupItem language="PHP">
183 The PHP SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
184 </CodeGroupItem>
188185 
189 ```ruby Ruby
190 # EnvironmentWorker is not currently available in the Ruby SDK.
191 # To answer custom tool calls directly, see the session event stream.
192 ```
186 <CodeGroupItem language="Ruby">
187 The Ruby SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
188 </CodeGroupItem>
193189 </CodeGroup>
194190 </Step>
195191</Steps>
from line 206
210206 
211207### Install an MCP SDK
212208 
213The SDK's [Client-side MCP helpers](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector#client-side-mcp-helpers) convert the server's tools into the runnable tools the worker accepts. Install an MCP SDK alongside the Anthropic SDK: `pip install "anthropic[mcp]" "mcp>=1.24"` (typescript: `npm install @modelcontextprotocol/sdk`; go: `go get github.com/modelcontextprotocol/go-sdk`).
209The SDK's [Client-side MCP helpers](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector#client-side-mcp-helpers) convert the server's tools into the runnable tools the worker accepts. Install an MCP SDK alongside the Anthropic SDK: `pip install "anthropic[mcp]" "mcp>=1.24"` (typescript: `npm install @modelcontextprotocol/sdk`; go: `go get github.com/modelcontextprotocol/go-sdk`; csharp: `dotnet add package ModelContextProtocol`; java: `com.anthropic:anthropic-java-mcp`; php: `composer require mcp/sdk`; ruby: `bundle add mcp faraday event_stream_parser`).
214210 
215The examples connect without authentication. To send credentials, configure the `http_client` (typescript: `requestInit`; go: `HTTPClient`) you hand to the MCP transport.
211The examples connect without authentication. To send credentials, configure the `http_client` (typescript: `requestInit`; go: `HTTPClient`; csharp: `AdditionalHeaders`; java: `customizeRequest`; php, ruby: `headers`) you hand to the MCP transport.
216212 
217213### Declare and serve the tools
218214 
from line 299
303299 ```
304300 
305301 ```csharp C#
306 // See the Python, TypeScript, and Go tabs. Declaring custom tools from
307 // C# works the same way once you list the server's tools with an MCP client.
302 using System.Text.Json;
303 using Anthropic;
304 using Anthropic.Models.Beta.Agents;
305 using ModelContextProtocol.Client;
306 
307 const string McpServerUrl = "http://mcp.internal.example.com:8000/mcp";
308 
309 // Run this wherever you create agents, not on the worker host: it
310 // authenticates with your Claude API key (ANTHROPIC_API_KEY).
311 var client = new AnthropicClient();
312 
313 await using var mcpClient = await McpClient.CreateAsync(
314 new HttpClientTransport(new HttpClientTransportOptions { Endpoint = new Uri(McpServerUrl) })
315 );
316 var mcpTools = await mcpClient.ListToolsAsync();
317 
318 List<Tool> tools =
319 [
320 new BetaManagedAgentsAgentToolset20260401Params { Type = "agent_toolset_20260401" },
321 ];
322 foreach (var tool in mcpTools)
323 {
324 var description = tool.Description;
325 if (string.IsNullOrEmpty(description))
326 {
327 description = tool.Name;
328 }
329 
330 // The MCP fields map one to one onto a custom tool declaration. The
331 // schema's keywords pass to the SDK unchanged.
332 tools.Add(
333 new BetaManagedAgentsCustomToolParams
334 {
335 Type = "custom",
336 Name = tool.Name,
337 Description = description,
338 InputSchema = new(
339 tool.ProtocolTool.InputSchema.Deserialize<Dictionary<string, JsonElement>>()!
340 ),
341 }
342 );
343 }
344 
345 var agent = await client.Beta.Agents.Create(new()
346 {
347 Name = "Internal tools agent",
348 Model = BetaManagedAgentsModel.ClaudeOpus5_5,
349 Tools = tools,
350 });
351 Console.WriteLine(agent.ID);
308352 ```
309353 
310354 ```go Go
from line 460
416460 ```
417461 
418462 ```java Java
419 // See the Python, TypeScript, and Go tabs. Declaring custom tools from
420 // Java works the same way once you list the server's tools with an MCP client.
463 import com.anthropic.client.okhttp.AnthropicOkHttpClient;
464 import com.anthropic.core.JsonValue;
465 import com.anthropic.models.beta.agents.AgentCreateParams;
466 import com.anthropic.models.beta.agents.BetaManagedAgentsAgentToolset20260401Params;
467 import com.anthropic.models.beta.agents.BetaManagedAgentsCustomToolInputSchema;
468 import com.anthropic.models.beta.agents.BetaManagedAgentsCustomToolParams;
469 import com.anthropic.models.beta.agents.BetaManagedAgentsModel;
470 import io.modelcontextprotocol.client.McpClient;
471 import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
472 import io.modelcontextprotocol.spec.McpSchema;
473 
474 // The MCP fields map one to one onto a custom tool declaration. The MCP Java
475 // SDK keeps only these top-level keywords of a tool's input schema: type,
476 // properties, required, additionalProperties, $defs and definitions.
477 BetaManagedAgentsCustomToolParams toCustomTool(McpSchema.Tool tool) {
478 var description = tool.description();
479 if (description == null || description.isEmpty()) {
480 description = tool.name();
481 }
482 
483 return BetaManagedAgentsCustomToolParams.builder()
484 .type(BetaManagedAgentsCustomToolParams.Type.CUSTOM)
485 .name(tool.name())
486 .description(description)
487 .inputSchema(JsonValue.from(tool.inputSchema())
488 .convert(BetaManagedAgentsCustomToolInputSchema.class))
489 .build();
490 }
491 
492 void main() {
493 // Run this wherever you create agents, not on the worker host: it
494 // authenticates with your Claude API key (ANTHROPIC_API_KEY).
495 var client = AnthropicOkHttpClient.fromEnv();
496 
497 // The MCP server's address, then the path of its MCP endpoint.
498 var transport = HttpClientStreamableHttpTransport.builder("http://mcp.internal.example.com:8000")
499 .endpoint("/mcp")
500 .build();
501 try (var mcpClient = McpClient.sync(transport)
502 .clientInfo(new McpSchema.Implementation("declare-agent-tools", "1.0.0"))
503 .build()) {
504 mcpClient.initialize();
505 
506 var params = AgentCreateParams.builder()
507 .name("Internal tools agent")
508 .model(BetaManagedAgentsModel.CLAUDE_OPUS_5_5)
509 .addTool(BetaManagedAgentsAgentToolset20260401Params.builder()
510 .type(BetaManagedAgentsAgentToolset20260401Params.Type.AGENT_TOOLSET_20260401)
511 .build());
512 for (var tool : mcpClient.listTools().tools()) {
513 params.addTool(toCustomTool(tool));
514 }
515 
516 var agent = client.beta().agents().create(params.build());
517 IO.println(agent.id());
518 }
519 }
421520 ```
422521 
423522 ```php PHP
424 // See the Python, TypeScript, and Go tabs. Declaring custom tools from
425 // PHP works the same way once you list the server's tools with an MCP client.
523 use Anthropic\Beta\Agents\BetaManagedAgentsModel;
524 use Anthropic\Client as Anthropic;
525 use Mcp\Client as McpClient;
526 use Mcp\Client\Transport\HttpTransport;
527 
528 $mcpServerUrl = 'http://mcp.internal.example.com:8000/mcp';
529 
530 // Run this wherever you create agents, not on the worker host: it
531 // authenticates with your Claude API key (ANTHROPIC_API_KEY).
532 $client = new Anthropic();
533 
534 $mcpClient = McpClient::builder()->build();
535 $mcpClient->connect(new HttpTransport($mcpServerUrl));
536 
537 $tools = [['type' => 'agent_toolset_20260401']];
538 foreach ($mcpClient->listTools()->tools as $tool) {
539 // The MCP fields map one to one onto a custom tool declaration. The
540 // schema's keywords pass to the SDK unchanged.
541 $tools[] = [
542 'type' => 'custom',
543 'name' => $tool->name,
544 'description' => $tool->description ?: $tool->name,
545 'inputSchema' => $tool->inputSchema,
546 ];
547 }
548 
549 $agent = $client->beta->agents->create(
550 name: 'Internal tools agent',
551 model: BetaManagedAgentsModel::CLAUDE_OPUS_5_5,
552 tools: $tools,
553 );
554 echo $agent->id, "\n";
555 
556 $mcpClient->disconnect();
426557 ```
427558 
428559 ```ruby Ruby
429 # See the Python, TypeScript, and Go tabs. Declaring custom tools from
430 # Ruby works the same way once you list the server's tools with an MCP client.
560 require "anthropic"
561 require "mcp"
562 
563 MCP_SERVER_URL = "http://mcp.internal.example.com:8000/mcp"
564 
565 # Run this wherever you create agents, not on the worker host: it
566 # authenticates with your Claude API key (ANTHROPIC_API_KEY).
567 client = Anthropic::Client.new
568 
569 transport = MCP::Client::HTTP.new(url: MCP_SERVER_URL)
570 mcp_client = MCP::Client.new(transport: transport)
571 mcp_client.connect
572 
573 custom_tools = mcp_client.tools.map do |tool|
574 description = tool.description
575 description = tool.name if description.nil? || description.empty?
576 
577 # The MCP fields map one to one onto a custom tool declaration. The
578 # schema's keywords pass to the SDK unchanged.
579 {
580 type: :custom,
581 name: tool.name,
582 description: description,
583 input_schema: tool.input_schema
584 }
585 end
586 
587 agent = client.beta.agents.create(
588 name: "Internal tools agent",
589 model: Anthropic::Beta::BetaManagedAgentsModel::CLAUDE_OPUS_5_5,
590 tools: [{type: :agent_toolset_20260401}, *custom_tools]
591 )
592 puts agent.id
593 
594 transport.close
431595 ```
432596 </CodeGroup>
433597 </Step>
from line 599
435599 <Step title="Serve the tools from the worker">
436600 Connect to the same MCP server at startup, convert its tools with `async_mcp_tool` (typescript: `mcpTools`; go: `mcp.NewBetaTools`), and register them alongside `beta_agent_toolset_20260401` (typescript: `betaAgentToolset20260401`; go: `agenttoolset.BetaAgentToolset20260401`). Keep one MCP session open for the life of the worker.
437601 
438 <CodeGroup exclude="shell">
602 <CodeGroup exclude="shell, csharp, java, php, ruby">
439603 ```python Python
440604 import asyncio
441605 import os
from line 683
519683 }).run();
520684 ```
521685 
522 ```csharp C#
523 // EnvironmentWorker is not currently available in the C# SDK.
524 ```
686 <CodeGroupItem language="C#">
687 The C# SDK does not have `EnvironmentWorker`.
688 </CodeGroupItem>
525689 
526690 ```go Go
527691 package main
from line 749
585749 
586750 ```
587751 
588 ```java Java
589 // EnvironmentWorker is not currently available in the Java SDK.
590 ```
752 <CodeGroupItem language="Java">
753 The Java SDK does not have `EnvironmentWorker`.
754 </CodeGroupItem>
591755 
592 ```php PHP
593 // EnvironmentWorker is not currently available in the PHP SDK.
594 ```
756 <CodeGroupItem language="PHP">
757 The PHP SDK does not have `EnvironmentWorker`.
758 </CodeGroupItem>
595759 
596 ```ruby Ruby
597 # EnvironmentWorker is not currently available in the Ruby SDK.
598 ```
760 <CodeGroupItem language="Ruby">
761 The Ruby SDK does not have `EnvironmentWorker`.
762 </CodeGroupItem>
599763 </CodeGroup>
600764 </Step>
601765</Steps>

managed-agents/self-hosted-sandboxes-memory Changed · +13 / -13 lines

from line 93
9393 
9494For example, to sync every 10 seconds and only log the deletes the worker would have made:
9595 
96<CodeGroup exclude="shell">
96<CodeGroup exclude="shell, csharp, java, php, ruby">
9797 ```python Python
9898 worker = EnvironmentWorker(
9999 client,
from line 116
116116 });
117117 ```
118118 
119 ```csharp C#
120 // EnvironmentWorker is not currently available in the C# SDK.
121 ```
119 <CodeGroupItem language="C#">
120 The C# SDK does not have `EnvironmentWorker`.
121 </CodeGroupItem>
122122 
123123 ```go Go
124124 worker := environments.NewEnvironmentWorker(client, environments.EnvironmentWorkerOptions{
from line 130
130130 })
131131 ```
132132 
133 ```java Java
134 // EnvironmentWorker is not currently available in the Java SDK.
135 ```
133 <CodeGroupItem language="Java">
134 The Java SDK does not have `EnvironmentWorker`.
135 </CodeGroupItem>
136136 
137 ```php PHP
138 // EnvironmentWorker is not currently available in the PHP SDK.
139 ```
137 <CodeGroupItem language="PHP">
138 The PHP SDK does not have `EnvironmentWorker`.
139 </CodeGroupItem>
140140 
141 ```ruby Ruby
142 # EnvironmentWorker is not currently available in the Ruby SDK.
143 ```
141 <CodeGroupItem language="Ruby">
142 The Ruby SDK does not have `EnvironmentWorker`.
143 </CodeGroupItem>
144144</CodeGroup>
145145 
146146## Read-only stores and conflicts

managed-agents/self-hosted-sandboxes-reference Changed · +30 / -34 lines

from line 87
8787 
8888`EnvironmentWorker` manages the `AgentToolContext` and the toolset automatically. Pass a `tools` (go: `ToolsFunc`) factory to customize the tool list:
8989 
90<CodeGroup exclude="shell">
90<CodeGroup exclude="shell, csharp, java, php, ruby">
9191 ```python Python
9292 EnvironmentWorker(client, ..., tools=lambda env: [beta_bash_tool(env), my_custom_tool])
9393 ```
from line 101
101101 });
102102 ```
103103 
104 ```csharp C#
105 // EnvironmentWorker is not currently available in the C# SDK.
106 // To answer custom tool calls directly, see the session event stream.
107 ```
104 <CodeGroupItem language="C#">
105 The C# SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
106 </CodeGroupItem>
108107 
109108 ```go Go
110109 worker := environments.NewEnvironmentWorker(client, environments.EnvironmentWorkerOptions{
from line 115
116115 })
117116 ```
118117 
119 ```java Java
120 // EnvironmentWorker is not currently available in the Java SDK.
121 // To answer custom tool calls directly, see the session event stream.
122 ```
118 <CodeGroupItem language="Java">
119 The Java SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
120 </CodeGroupItem>
123121 
124 ```php PHP
125 // EnvironmentWorker is not currently available in the PHP SDK.
126 // To answer custom tool calls directly, see the session event stream.
127 ```
122 <CodeGroupItem language="PHP">
123 The PHP SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
124 </CodeGroupItem>
128125 
129 ```ruby Ruby
130 # EnvironmentWorker is not currently available in the Ruby SDK.
131 # To answer custom tool calls directly, see the session event stream.
132 ```
126 <CodeGroupItem language="Ruby">
127 The Ruby SDK does not have `EnvironmentWorker`. To answer custom tool calls from your own code, send each result on the session's event stream, as in [Return a custom tool result](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#return-a-custom-tool-result).
128 </CodeGroupItem>
133129</CodeGroup>
134130 
135131### Work poller
from line 143
147143 
148144`client.beta.sessions.events.tool_runner()` (typescript: `client.beta.sessions.events.toolRunner()`; go: `client.Beta.Sessions.Events.NewToolRunner()`) takes a tool list as `tools` (go: `Tools`). To build that list, set up `AgentToolContext` yourself and call `beta_agent_toolset_20260401(env)` (typescript: `betaAgentToolset20260401(ctx)`; go: `agenttoolset.BetaAgentToolset20260401(env)`):
149145 
150<CodeGroup exclude="shell">
146<CodeGroup exclude="shell, csharp, java, php, ruby">
151147 ```python Python
152148 from anthropic.lib.tools.agent_toolset import (
153149 AgentToolContext,
from line 168
172168 const tools = betaAgentToolset20260401(ctx);
173169 ```
174170 
175 ```csharp C#
176 // AgentToolContext is not currently available in the C# SDK.
177 ```
171 <CodeGroupItem language="C#">
172 The C# SDK does not have `AgentToolContext`.
173 </CodeGroupItem>
178174 
179175 ```go Go
180176 env := &agenttoolset.AgentToolContext{Workdir: "/workspace"}
from line 181
185181 tools := agenttoolset.BetaAgentToolset20260401(env)
186182 ```
187183 
188 ```java Java
189 // AgentToolContext is not currently available in the Java SDK.
190 ```
184 <CodeGroupItem language="Java">
185 The Java SDK does not have `AgentToolContext`.
186 </CodeGroupItem>
191187 
192 ```php PHP
193 // AgentToolContext is not currently available in the PHP SDK.
194 ```
188 <CodeGroupItem language="PHP">
189 The PHP SDK does not have `AgentToolContext`.
190 </CodeGroupItem>
195191 
196 ```ruby Ruby
197 # AgentToolContext is not currently available in the Ruby SDK.
198 ```
192 <CodeGroupItem language="Ruby">
193 The Ruby SDK does not have `AgentToolContext`.
194 </CodeGroupItem>
199195</CodeGroup>
200196 
201197### AgentToolContext and the agent toolset

managed-agents/self-hosted-sandboxes-workers Changed · +78 / -94 lines

from line 40
4040 
4141## Run an always-on worker
4242 
43Both workers authenticate with the [environment key](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#run-your-first-session) from the quickstart.
43Start a worker that polls the queue continuously. It authenticates with the [environment key](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes#run-your-first-session) from the quickstart:
4444 
45With the `ant` CLI:
45<CodeGroup exclude="shell:cURL, csharp, java, php, ruby">
46 ```bash CLI
47 ant beta:worker poll --workdir /workspace
48 ```
4649 
47```bash
48ant beta:worker poll --workdir /workspace
49```
50 
51With the SDK, `EnvironmentWorker` does the same work:
52 
53<CodeGroup exclude="shell">
5450 ```python Python
5551 import asyncio
5652 import contextlib
from line 101
105101 }).run();
106102 ```
107103 
108 ```csharp C#
109 // EnvironmentWorker is not currently available in the C# SDK. Use the ant CLI worker instead.
110 ```
104 <CodeGroupItem language="C#">
105 The C# SDK does not have `EnvironmentWorker`. Run the `ant` CLI worker instead: `ant beta:worker poll --workdir /workspace`.
106 </CodeGroupItem>
111107 
112108 ```go Go
113109 package main
from line 141
145141 
146142 ```
147143 
148 ```java Java
149 // EnvironmentWorker is not currently available in the Java SDK. Use the ant CLI worker instead.
150 ```
144 <CodeGroupItem language="Java">
145 The Java SDK does not have `EnvironmentWorker`. Run the `ant` CLI worker instead: `ant beta:worker poll --workdir /workspace`.
146 </CodeGroupItem>
151147 
152 ```php PHP
153 // EnvironmentWorker is not currently available in the PHP SDK. Use the ant CLI worker instead.
154 ```
148 <CodeGroupItem language="PHP">
149 The PHP SDK does not have `EnvironmentWorker`. Run the `ant` CLI worker instead: `ant beta:worker poll --workdir /workspace`.
150 </CodeGroupItem>
155151 
156 ```ruby Ruby
157 # EnvironmentWorker is not currently available in the Ruby SDK. Use the ant CLI worker instead.
158 ```
152 <CodeGroupItem language="Ruby">
153 The Ruby SDK does not have `EnvironmentWorker`. Run the `ant` CLI worker instead: `ant beta:worker poll --workdir /workspace`.
154 </CodeGroupItem>
159155</CodeGroup>
160156 
161157## Trigger workers from webhooks
from line 172
176172 <Step title="Implement the webhook handler">
177173 Invoke the worker when `session.status_run_started` fires. The handler drains the queue and hands each claimed work item to `handle_item()` (typescript: `handleItem()`; go: `HandleItem()`), which downloads skills, executes tool calls, posts results back, and returns.
178174 
179 <CodeGroup exclude="shell">
175 <CodeGroup exclude="shell, csharp, java, php, ruby">
180176 <CodeGroupItem>
181177 To verify webhook signatures, install the webhooks extra: `pip install "anthropic[webhooks]"`.
182178 
from line 295
299295 }
300296 ```
301297 
302 ```csharp C#
303 // EnvironmentWorker is not currently available in the C# SDK.
304 // To handle work items directly, see the Environments Work endpoints.
305 ```
298 <CodeGroupItem language="C#">
299 The C# SDK does not have `EnvironmentWorker`. To handle work items from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
300 </CodeGroupItem>
306301 
307302 ```go Go
308303 package main
from line 410
415410 
416411 ```
417412 
418 ```java Java
419 // EnvironmentWorker is not currently available in the Java SDK.
420 // To handle work items directly, see the Environments Work endpoints.
421 ```
413 <CodeGroupItem language="Java">
414 The Java SDK does not have `EnvironmentWorker`. To handle work items from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
415 </CodeGroupItem>
422416 
423 ```php PHP
424 // EnvironmentWorker is not currently available in the PHP SDK.
425 // To handle work items directly, see the Environments Work endpoints.
426 ```
417 <CodeGroupItem language="PHP">
418 The PHP SDK does not have `EnvironmentWorker`. To handle work items from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
419 </CodeGroupItem>
427420 
428 ```ruby Ruby
429 # EnvironmentWorker is not currently available in the Ruby SDK.
430 # To handle work items directly, see the Environments Work endpoints.
431 ```
421 <CodeGroupItem language="Ruby">
422 The Ruby SDK does not have `EnvironmentWorker`. To handle work items from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
423 </CodeGroupItem>
432424 </CodeGroup>
433425 
434426 Because the handler claims work itself, it must [forward the work item's secret](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-workers#forward-the-work-items-secret), as the `work_secret` (typescript: `workSecret`; go: `WorkSecret`) argument does here.
from line 497
505497 
506498To claim work from your own code instead of `ant beta:worker poll --on-work`, use `work.poller()` (go: `environments.NewWorkPoller()`). It polls the queue and gives you each claimed session, and you launch the sandbox:
507499 
508<CodeGroup>
509 ```bash cURL
510 # The work poller is an SDK helper (Python, TypeScript, Go), not a raw
511 # endpoint. From the shell, use `ant beta:worker poll --on-work` instead.
512 ```
500<CodeGroup exclude="shell, csharp, java, php, ruby">
501 <CodeGroupItem language="cURL">
502 Claiming work in a loop and launching a sandbox for each session needs more logic than a single shell command. From the shell, run `ant beta:worker poll --on-work` with a spawn script, as in [Run one sandbox per session](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-workers#run-one-sandbox-per-session).
503 </CodeGroupItem>
513504 
514 ```bash CLI
515 # The work poller is an SDK helper (Python, TypeScript, Go), not a raw
516 # endpoint. From the shell, use `ant beta:worker poll --on-work` instead.
517 ```
505 <CodeGroupItem language="CLI">
506 To claim work from the shell and launch a sandbox for each session, run `ant beta:worker poll --on-work` with a spawn script, as in [Run one sandbox per session](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-workers#run-one-sandbox-per-session).
507 </CodeGroupItem>
518508 
519509 ```python Python
520510 import asyncio
from line 606
616606 }
617607 ```
618608 
619 ```csharp C#
620 // A work-polling helper is not currently available in the C# SDK.
621 // To claim work directly, see the Environments Work endpoints.
622 ```
609 <CodeGroupItem language="C#">
610 The C# SDK does not have a helper that polls for work. To claim work from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
611 </CodeGroupItem>
623612 
624613 ```go Go
625614 package main
from line 680
691680 }
692681 ```
693682 
694 ```java Java
695 // A work-polling helper is not currently available in the Java SDK.
696 // To claim work directly, see the Environments Work endpoints.
697 ```
683 <CodeGroupItem language="Java">
684 The Java SDK does not have a helper that polls for work. To claim work from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
685 </CodeGroupItem>
698686 
699 ```php PHP
700 // A work-polling helper is not currently available in the PHP SDK.
701 // To claim work directly, see the Environments Work endpoints.
702 ```
687 <CodeGroupItem language="PHP">
688 The PHP SDK does not have a helper that polls for work. To claim work from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
689 </CodeGroupItem>
703690 
704 ```ruby Ruby
705 # A work-polling helper is not currently available in the Ruby SDK.
706 # To claim work directly, see the Environments Work endpoints.
707 ```
691 <CodeGroupItem language="Ruby">
692 The Ruby SDK does not have a helper that polls for work. To claim work from your own code, call the [Environments Work endpoints](https://platform.claude.com/docs/en/api/beta/environments/work).
693 </CodeGroupItem>
708694</CodeGroup>
709695 
710696### Run the SDK worker inside the sandbox
from line 697
711697 
712698Replace the `ant beta:worker run` entrypoint with an SDK entrypoint when the sandbox must [serve custom tools](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-custom-tools) or use [non-default memory sync settings](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes-memory#configure-sync). The entrypoint constructs `EnvironmentWorker` and calls `handle_item()` (typescript: `handleItem()`; go: `HandleItem()`), which reads the same `ANTHROPIC_*` variables that the spawn script forwards.
713699 
714<CodeGroup exclude="shell">
700<CodeGroup exclude="shell, csharp, java, php, ruby">
715701 ```python Python
716702 import asyncio
717703 import contextlib
from line 745
759745 }).handleItem();
760746 ```
761747 
762 ```csharp C#
763 // EnvironmentWorker is not currently available in the C# SDK.
764 ```
748 <CodeGroupItem language="C#">
749 The C# SDK does not have `EnvironmentWorker`.
750 </CodeGroupItem>
765751 
766752 ```go Go
767753 package main
from line 783
797783 
798784 ```
799785 
800 ```java Java
801 // EnvironmentWorker is not currently available in the Java SDK.
802 ```
786 <CodeGroupItem language="Java">
787 The Java SDK does not have `EnvironmentWorker`.
788 </CodeGroupItem>
803789 
804 ```php PHP
805 // EnvironmentWorker is not currently available in the PHP SDK.
806 ```
790 <CodeGroupItem language="PHP">
791 The PHP SDK does not have `EnvironmentWorker`.
792 </CodeGroupItem>
807793 
808 ```ruby Ruby
809 # EnvironmentWorker is not currently available in the Ruby SDK.
810 ```
794 <CodeGroupItem language="Ruby">
795 The Ruby SDK does not have `EnvironmentWorker`.
796 </CodeGroupItem>
811797</CodeGroup>
812798 
813799## Stage files for a session
from line 811
825811 -H "anthropic-version: 2023-06-01" \
826812 -H "anthropic-beta: managed-agents-2026-04-01" \
827813 -H "content-type: application/json" \
828 -d @- <<EOF
829 {
830 "agent": "$AGENT_ID",
831 "environment_id": "$ANTHROPIC_ENVIRONMENT_ID",
832 "metadata": {"input_file": "s3://my-bucket/data.csv"}
833 }
834 EOF
814 -d '{
815 "agent": "'"$AGENT_ID"'",
816 "environment_id": "'"$ANTHROPIC_ENVIRONMENT_ID"'",
817 "metadata": {"input_file": "s3://my-bucket/data.csv"}
818 }'
835819 ```
836820 
837821 ```bash CLI

managed-agents/session-operations Changed · +11 / -13 lines

from line 40
4040 -H "anthropic-version: 2023-06-01" \
4141 -H "anthropic-beta: managed-agents-2026-04-01" \
4242 -H "content-type: application/json" \
43 -d @- <<EOF
44 {
45 "agent": {
46 "tools": [
47 {"type": "agent_toolset_20260401"},
48 {"type": "mcp_toolset", "mcp_server_name": "linear"}
49 ],
50 "mcp_servers": [
51 {"type": "url", "name": "linear", "url": "https://mcp.linear.app/sse"}
52 ]
53 }
54 }
55 EOF
43 -d '{
44 "agent": {
45 "tools": [
46 {"type": "agent_toolset_20260401"},
47 {"type": "mcp_toolset", "mcp_server_name": "linear"}
48 ],
49 "mcp_servers": [
50 {"type": "url", "name": "linear", "url": "https://mcp.linear.app/sse"}
51 ]
52 }
53 }'
5654 ```
5755 
5856 ```bash CLI

managed-agents/session-threads Changed · +4 / -5 lines

from line 695
695695 
696696The following example goes inside the event loop of the [tool confirmation handler](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#tool-confirmation). For each ID in `stop_reason.event_ids`, it sends a `user.tool_confirmation` that allows the call. The same pattern applies to `user.custom_tool_result`, which you can also send as soon as its `agent.custom_tool_use` event arrives.
697697 
698<CodeGroup>
698<CodeGroup exclude="shell:CLI">
699699 ```bash cURL
700700 while IFS= read -r event_id; do
701701 jq -n --arg id "$event_id" \
from line 709
709709 done < <(jq -r '.stop_reason.event_ids[]' <<<"$data")
710710 ```
711711 
712 ```bash CLI
713 # This workflow does not translate well to a one-off shell command.
714 # Use one of the SDK examples in this code group instead.
715 ```
712 <CodeGroupItem language="CLI">
713 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
714 </CodeGroupItem>
716715 
717716 ```python Python
718717 for event_id in stop.event_ids:

managed-agents/sessions Changed · +56 / -72 lines

from line 23
2323 -H "anthropic-version: 2023-06-01" \
2424 -H "anthropic-beta: managed-agents-2026-04-01" \
2525 -H "content-type: application/json" \
26 -d @- <<EOF
27 {
28 "agent": "$AGENT_ID",
29 "environment_id": "$ENVIRONMENT_ID"
30 }
31 EOF
26 -d '{
27 "agent": "'"$AGENT_ID"'",
28 "environment_id": "'"$ENVIRONMENT_ID"'"
29 }'
3230 ```
3331 
3432 ```bash CLI
from line 100
102100 -H "anthropic-version: 2023-06-01" \
103101 -H "anthropic-beta: managed-agents-2026-04-01" \
104102 -H "content-type: application/json" \
105 -d @- <<EOF
106 {
107 "agent": {"type": "agent", "id": "$AGENT_ID", "version": 1},
108 "environment_id": "$ENVIRONMENT_ID"
109 }
110 EOF
103 -d '{
104 "agent": {"type": "agent", "id": "'"$AGENT_ID"'", "version": 1},
105 "environment_id": "'"$ENVIRONMENT_ID"'"
106 }'
111107 ```
112108 
113109 ```bash CLI
from line 198
202198 -H "anthropic-version: 2023-06-01" \
203199 -H "anthropic-beta: managed-agents-2026-04-01" \
204200 -H "content-type: application/json" \
205 -d @- <<EOF
206 {
207 "agent": "$AGENT_ID",
208 "environment_id": "$ENVIRONMENT_ID",
209 "initial_events": [
210 {
211 "type": "user.message",
212 "content": [{"type": "text", "text": "List the files in the working directory."}]
213 }
214 ]
215 }
216 EOF
201 -d '{
202 "agent": "'"$AGENT_ID"'",
203 "environment_id": "'"$ENVIRONMENT_ID"'",
204 "initial_events": [
205 {
206 "type": "user.message",
207 "content": [{"type": "text", "text": "List the files in the working directory."}]
208 }
209 ]
210 }'
217211 )
218212 SEEDED_SESSION_ID=$(jq -r '.id' <<< "$seeded_session")
219213 
from line 479
485479 -H "anthropic-version: 2023-06-01" \
486480 -H "anthropic-beta: managed-agents-2026-04-01" \
487481 -H "content-type: application/json" \
488 -d @- <<EOF
489 {
490 "agent": {
491 "type": "agent_with_overrides",
492 "id": "$AGENT_ID",
493 "model": {"id": "claude-sonnet-5-5"},
494 "system": null
495 },
496 "environment_id": "$ENVIRONMENT_ID"
497 }
498 EOF
482 -d '{
483 "agent": {
484 "type": "agent_with_overrides",
485 "id": "'"$AGENT_ID"'",
486 "model": {"id": "claude-sonnet-5-5"},
487 "system": null
488 },
489 "environment_id": "'"$ENVIRONMENT_ID"'"
490 }'
499491 ```
500492 
501493 ```bash CLI
from line 645
653645 -H "anthropic-version: 2023-06-01" \
654646 -H "anthropic-beta: managed-agents-2026-04-01" \
655647 -H "content-type: application/json" \
656 -d @- <<EOF
657 {
658 "agent": {
659 "type": "agent_with_overrides",
660 "id": "$AGENT_ID",
661 "model": {"id": "claude-opus-5-5", "inference_geo": "us"}
662 },
663 "environment_id": "$ENVIRONMENT_ID"
664 }
665 EOF
648 -d '{
649 "agent": {
650 "type": "agent_with_overrides",
651 "id": "'"$AGENT_ID"'",
652 "model": {"id": "claude-opus-5-5", "inference_geo": "us"}
653 },
654 "environment_id": "'"$ENVIRONMENT_ID"'"
655 }'
666656 )
667657 echo "Inference geo: $(jq -r '.agent.model.inference_geo' <<< "$session")"
668658 ```
from line 801
811801 -H "anthropic-version: 2023-06-01" \
812802 -H "anthropic-beta: managed-agents-2026-04-01" \
813803 -H "content-type: application/json" \
814 -d @- <<EOF
815 {
816 "agent": "$AGENT_ID",
817 "environment_id": "$ENVIRONMENT_ID",
818 "budget": {
819 "type": "limit",
820 "max_list_cost": {"amount": "125", "currency": "USD"}
821 }
822 }
823 EOF
804 -d '{
805 "agent": "'"$AGENT_ID"'",
806 "environment_id": "'"$ENVIRONMENT_ID"'",
807 "budget": {
808 "type": "limit",
809 "max_list_cost": {"amount": "125", "currency": "USD"}
810 }
811 }'
824812 ```
825813 
826814 ```bash CLI
from line 930
942930 -H "anthropic-version: 2023-06-01" \
943931 -H "anthropic-beta: managed-agents-2026-04-01" \
944932 -H "content-type: application/json" \
945 -d @- <<EOF
946 {
947 "agent": "$AGENT_ID",
948 "environment_id": "$ENVIRONMENT_ID",
949 "vault_ids": ["$VAULT_ID"]
950 }
951 EOF
933 -d '{
934 "agent": "'"$AGENT_ID"'",
935 "environment_id": "'"$ENVIRONMENT_ID"'",
936 "vault_ids": ["'"$VAULT_ID"'"]
937 }'
952938 ```
953939 
954940 ```bash CLI
from line 1020
10341020 -H "anthropic-version: 2023-06-01" \
10351021 -H "anthropic-beta: managed-agents-2026-04-01" \
10361022 -H "content-type: application/json" \
1037 -d @- <<'EOF'
1038 {
1039 "events": [
1040 {
1041 "type": "user.message",
1042 "content": [{"type": "text", "text": "List the files in the working directory."}]
1043 }
1044 ]
1045 }
1046 EOF
1023 -d '{
1024 "events": [
1025 {
1026 "type": "user.message",
1027 "content": [{"type": "text", "text": "List the files in the working directory."}]
1028 }
1029 ]
1030 }'
10471031 ```
10481032 
10491033 ```bash CLI

managed-agents/skills Changed · +9 / -11 lines

from line 222
222222 -H "x-api-key: $ANTHROPIC_API_KEY" \
223223 -H "anthropic-version: 2023-06-01" \
224224 -H "anthropic-beta: managed-agents-2026-04-01" \
225 --json @- <<'EOF'
226 {
227 "name": "Financial Analyst",
228 "model": "claude-opus-5-5",
229 "system": "You are a financial analysis agent.",
230 "skills": [
231 {"type": "anthropic", "skill_id": "xlsx"},
232 {"type": "custom", "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv", "version": "latest"}
233 ]
234 }
235 EOF
225 --json '{
226 "name": "Financial Analyst",
227 "model": "claude-opus-5-5",
228 "system": "You are a financial analysis agent.",
229 "skills": [
230 {"type": "anthropic", "skill_id": "xlsx"},
231 {"type": "custom", "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv", "version": "latest"}
232 ]
233 }'
236234 )
237235 ```
238236 

managed-agents/tools Changed · +32 / -36 lines

from line 46
4646 -H "anthropic-version: 2023-06-01" \
4747 -H "anthropic-beta: managed-agents-2026-04-01" \
4848 -H "content-type: application/json" \
49 -d @- <<'EOF'
50 {
51 "name": "Coding Assistant",
52 "model": "claude-opus-5-5",
53 "tools": [
54 {
55 "type": "agent_toolset_20260401",
56 "configs": [
57 {"name": "web_fetch", "enabled": false}
58 ]
59 }
60 ]
61 }
62 EOF
49 -d '{
50 "name": "Coding Assistant",
51 "model": "claude-opus-5-5",
52 "tools": [
53 {
54 "type": "agent_toolset_20260401",
55 "configs": [
56 {"name": "web_fetch", "enabled": false}
57 ]
58 }
59 ]
60 }'
6361 )
6462 ```
6563 
from line 259
261259 -H "anthropic-version: 2023-06-01" \
262260 -H "anthropic-beta: managed-agents-2026-04-01" \
263261 -H "content-type: application/json" \
264 -d @- <<'EOF'
265 {
266 "name": "Weather Agent",
267 "model": "claude-opus-5-5",
268 "tools": [
269 {
270 "type": "agent_toolset_20260401"
271 },
272 {
273 "type": "custom",
274 "name": "get_weather",
275 "description": "Get current weather for a location",
276 "input_schema": {
277 "type": "object",
278 "properties": {
279 "location": {"type": "string", "description": "City name"}
280 },
281 "required": ["location"]
262 -d '{
263 "name": "Weather Agent",
264 "model": "claude-opus-5-5",
265 "tools": [
266 {
267 "type": "agent_toolset_20260401"
268 },
269 {
270 "type": "custom",
271 "name": "get_weather",
272 "description": "Get current weather for a location",
273 "input_schema": {
274 "type": "object",
275 "properties": {
276 "location": {"type": "string", "description": "City name"}
277 },
278 "required": ["location"]
279 }
282280 }
283 }
284 ]
285 }
286 EOF
281 ]
282 }'
287283 )
288284 ```
289285 

managed-agents/tools-web-restrictions Changed · +26 / -28 lines

from line 32
3232 -H "anthropic-version: 2023-06-01" \
3333 -H "anthropic-beta: managed-agents-2026-04-01" \
3434 -H "content-type: application/json" \
35 -d @- <<'EOF'
36 {
37 "name": "Research Agent",
38 "model": "claude-opus-5-5",
39 "tools": [
40 {
41 "type": "agent_toolset_20260401",
42 "configs": [
43 {
44 "type": "web_search",
45 "name": "web_search",
46 "allowed_domains": ["docs.example.com", "arxiv.org"],
47 "user_location": {
48 "type": "approximate",
49 "country": "US",
50 "timezone": "America/Los_Angeles"
35 -d '{
36 "name": "Research Agent",
37 "model": "claude-opus-5-5",
38 "tools": [
39 {
40 "type": "agent_toolset_20260401",
41 "configs": [
42 {
43 "type": "web_search",
44 "name": "web_search",
45 "allowed_domains": ["docs.example.com", "arxiv.org"],
46 "user_location": {
47 "type": "approximate",
48 "country": "US",
49 "timezone": "America/Los_Angeles"
50 }
51 },
52 {
53 "type": "web_fetch",
54 "name": "web_fetch",
55 "blocked_domains": ["ads.example.com"],
56 "max_content_tokens": 50000
5157 }
52 },
53 {
54 "type": "web_fetch",
55 "name": "web_fetch",
56 "blocked_domains": ["ads.example.com"],
57 "max_content_tokens": 50000
58 }
59 ]
60 }
61 ]
62 }
63 EOF
58 ]
59 }
60 ]
61 }'
6462 )
6563 jq '.tools[0].configs' <<< "$agent"
6664 ```

managed-agents/vaults Changed · +12 / -14 lines

from line 29
2929 -H "anthropic-version: 2023-06-01" \
3030 -H "anthropic-beta: managed-agents-2026-04-01" \
3131 -H "content-type: application/json" \
32 --data @- <<'EOF'
33 {
34 "display_name": "Alice",
35 "metadata": {"external_user_id": "usr_abc123"}
36 }
37 EOF
32 --data '{
33 "display_name": "Alice",
34 "metadata": {"external_user_id": "usr_abc123"}
35 }'
3836 ```
3937 
4038 <CodeGroupItem>
from line 140
142140 Environment variable credentials (`environment_variable`) are not yet supported with [self-hosted sandboxes](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes).
143141</Note>
144142 
143To get the same behavior with a self-hosted sandbox, you can run your own proxy that replaces placeholder values with the real secrets at egress.
144 
145145<Tabs>
146146 <Tab title="MCP OAuth">
147147 Use `mcp_oauth` when the MCP server uses OAuth 2.0. If you supply a `refresh` (csharp, go: `Refresh`) block, Anthropic refreshes the access token on your behalf when it expires.
from line 745
745745 -H "anthropic-version: 2023-06-01" \
746746 -H "anthropic-beta: managed-agents-2026-04-01" \
747747 -H "content-type: application/json" \
748 --data @- <<EOF
749 {
750 "agent": "$AGENT_ID",
751 "environment_id": "$ENVIRONMENT_ID",
752 "vault_ids": ["$VAULT_ID"],
753 "title": "Alice's Slack digest"
754 }
755 EOF
748 --data '{
749 "agent": "'"$AGENT_ID"'",
750 "environment_id": "'"$ENVIRONMENT_ID"'",
751 "vault_ids": ["'"$VAULT_ID"'"],
752 "title": "Slack digest for Alice"
753 }'
756754 ```
757755 
758756 ```bash CLI

managed-agents/workflow-runs Changed · +11 / -11 lines

from line 34
3434* **Pass results from one agent to another:** Each agent returns its result to the program. The program can pass that result on to another agent. In the diagram, the agent in the second phase works with what the first three returned. A run's agents also work with the same files, in the session's sandbox.
3535* **Take the next step by itself:** An agent's result goes to the program, not to the agent that the session runs. The program determines which agents run next, and it writes their prompts.
3636* **Repeat and choose:** Inside a phase, the program can repeat work and choose its next step from what an agent returned. For example, it can have a draft revised until a review passes or a set number of rounds is used up. In the diagram, the program can repeat a step inside the second phase.
37* **Handle a failed agent:** When one of its agents fails, the program can handle the failure or let it end the run.
37* **Handle a failed agent:** When one of its agents fails, the server usually runs that agent once more, on a new thread, while the run's other agents keep working. If it fails again, the program can handle the failure or let it end the run. If the program handles a failure, the run can still end `completed`, so tell the agent that the session runs to report what failed.
3838 
3939When the run ends, the agent that the session runs gets a turn to read what the run did. It can then answer you or start another run. [Run events](https://platform.claude.com/docs/en/managed-agents/workflow-runs#run-events) lists the cases where that turn comes later or doesn't come.
4040 
4141You can guide how a run does the work, for example how it splits the work and what it does when an agent fails. See [Tell the agent when to use a run](https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration#tell-the-agent-when-to-use-a-run).
4242 
43There's no approval step before a run starts: the agent starts a run in the same turn that it writes the workflow. To review a plan first, tell the agent to describe the run and wait for your go-ahead. As a run starts, `workflow_run.created` shows its name, description, and phases. If a run starts that you didn't approve, ask the agent to stop it (see [Interrupt a session with runs open](https://platform.claude.com/docs/en/managed-agents/workflow-runs#interrupt-a-session-with-runs-open)).
44 
4345## How a run moves through its states
4446 
4547<Frame>
from line 168
166168* **Answers custom tool calls** when each `agent.custom_tool_use` arrives, because a run's thread can wait on your client while the session stays `running`. If your agent's tools [ask for confirmation](https://platform.claude.com/docs/en/managed-agents/events-and-streaming#tool-confirmation), add a branch that answers each `agent.tool_use` or `agent.mcp_tool_use` whose `evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`) is `ask`. The sample has none, because a branch that allows every call would turn `always_ask` into always allow.
167169* **Stops** when the [work is done](https://platform.claude.com/docs/en/managed-agents/workflow-runs#know-when-the-work-is-done): no run is open, and the session goes idle with `end_turn`. It also stops if the session terminates. On an idle with any other stop reason except `requires_action`, such as `budget_reached`, `retries_exhausted`, or `refusal`, it prints the reason and stops, so handle those in your own code. It stops on `retries_exhausted` even when the server is about to start a new turn by itself. It keeps waiting on `requires_action`, and on `end_turn` while a run is open.
168170 
169<CodeGroup>
170 ```bash cURL
171 # This workflow does not translate well to a one-off shell command.
172 # Use one of the SDK examples in this code group instead.
173 ```
171<CodeGroup exclude="shell">
172 <CodeGroupItem language="cURL">
173 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
174 </CodeGroupItem>
174175 
175 ```bash CLI
176 # This workflow does not translate well to a one-off shell command.
177 # Use one of the SDK examples in this code group instead.
178 ```
176 <CodeGroupItem language="CLI">
177 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
178 </CodeGroupItem>
179179 
180180 ```python Python
181181 open_runs: dict[str, str] = {} # workflow_run_id -> run name

models/fable-5-1/migration-guide Changed · +64 / -70 lines

from line 67
6767 -H "content-type: application/json" \
6868 -H "x-api-key: $ANTHROPIC_API_KEY" \
6969 -H "anthropic-version: 2023-06-01" \
70 -d @- <<'EOF'
71 {
72 "model": "claude-fable-5",
73 "max_tokens": 16000,
74 "tools": [
75 {
76 "name": "record_summary",
77 "description": "Record the structured summary of the document.",
78 "input_schema": {
79 "type": "object",
80 "properties": {"summary": {"type": "string"}},
81 "required": ["summary"]
70 -d '{
71 "model": "claude-fable-5",
72 "max_tokens": 16000,
73 "tools": [
74 {
75 "name": "record_summary",
76 "description": "Record the structured summary of the document.",
77 "input_schema": {
78 "type": "object",
79 "properties": {"summary": {"type": "string"}},
80 "required": ["summary"]
81 }
8282 }
83 }
84 ],
85 "tool_choice": {"type": "tool", "name": "record_summary"},
86 "messages": [
87 {"role": "user", "content": "Summarize: The meeting moved to Thursday."}
88 ]
89 }
90 EOF
83 ],
84 "tool_choice": {"type": "tool", "name": "record_summary"},
85 "messages": [
86 {"role": "user", "content": "Summarize: The meeting moved to Thursday."}
87 ]
88 }'
9189 ```
9290 
9391 ```bash CLI
from line 307
309307 -H "content-type: application/json" \
310308 -H "x-api-key: $ANTHROPIC_API_KEY" \
311309 -H "anthropic-version: 2023-06-01" \
312 -d @- <<'EOF'
313 {
314 "model": "claude-fable-5-1",
315 "max_tokens": 16000,
316 "tools": [
317 {
318 "name": "record_summary",
319 "description": "Record the structured summary of the document.",
320 "strict": true,
321 "input_schema": {
322 "type": "object",
323 "properties": {"summary": {"type": "string"}},
324 "required": ["summary"],
325 "additionalProperties": false
310 -d '{
311 "model": "claude-fable-5-1",
312 "max_tokens": 16000,
313 "tools": [
314 {
315 "name": "record_summary",
316 "description": "Record the structured summary of the document.",
317 "strict": true,
318 "input_schema": {
319 "type": "object",
320 "properties": {"summary": {"type": "string"}},
321 "required": ["summary"],
322 "additionalProperties": false
323 }
326324 }
327 }
328 ],
329 "tool_choice": {"type": "auto"},
330 "messages": [
331 {"role": "user", "content": "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."}
332 ]
333 }
334 EOF
325 ],
326 "tool_choice": {"type": "auto"},
327 "messages": [
328 {"role": "user", "content": "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."}
329 ]
330 }'
335331 ```
336332 
337333 ```bash CLI
from line 577
581577 -H "content-type: application/json" \
582578 -H "x-api-key: $ANTHROPIC_API_KEY" \
583579 -H "anthropic-version: 2023-06-01" \
584 -d @- <<'EOF'
585 {
586 "model": "claude-fable-5-1",
587 "max_tokens": 16000,
588 "system": "You are a customer support assistant for an online electronics store.",
589 "tools": [
590 {
591 "name": "search_help_center",
592 "description": "Search the help center for policy and troubleshooting articles.",
593 "strict": true,
594 "input_schema": {
595 "type": "object",
596 "properties": {"query": {"type": "string"}},
597 "required": ["query"],
598 "additionalProperties": false
580 -d '{
581 "model": "claude-fable-5-1",
582 "max_tokens": 16000,
583 "system": "You are a customer support assistant for an online electronics store.",
584 "tools": [
585 {
586 "name": "search_help_center",
587 "description": "Search the help center for policy and troubleshooting articles.",
588 "strict": true,
589 "input_schema": {
590 "type": "object",
591 "properties": {"query": {"type": "string"}},
592 "required": ["query"],
593 "additionalProperties": false
594 }
599595 }
600 }
601 ],
602 "messages": [
603 {"role": "user", "content": "My headphones from order A1234 arrived yesterday."},
604 {"role": "assistant", "content": "Thanks for confirming. How can I help with order A1234?"},
605 {"role": "user", "content": "I opened the box. Can I still return them?"},
606 {
607 "role": "system",
608 "content": "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."
609 }
610 ]
611 }
612 EOF
596 ],
597 "messages": [
598 {"role": "user", "content": "My headphones from order A1234 arrived yesterday."},
599 {"role": "assistant", "content": "Thanks for confirming. How can I help with order A1234?"},
600 {"role": "user", "content": "I opened the box. Can I still return them?"},
601 {
602 "role": "system",
603 "content": "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the latest message from the user. Begin your response with the search_help_center tool call. Do not reply with text only."
604 }
605 ]
606 }'
613607 ```
614608 
615609 ```bash CLI

release-notes/overview Changed · +8 / -0 lines

### October 15, 2026 ### October 15, 2026

from line 12
1212 For updates to Claude Code, see the [complete CHANGELOG.md](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) in the `claude-code` repository.
1313</Tip>
1414 
15### October 15, 2026
16 
17* The [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) now returns the text each organization member saved as **Instructions for Claude** in claude.ai and as **Global instructions** in Cowork, in beta for Claude Enterprise organizations. Call `GET /v1/compliance/organizations/{org_uuid}/user_preferences` with your existing Compliance Access Key and the `read:compliance_user_data` scope. See [List user preferences](https://platform.claude.com/docs/en/manage-claude/compliance-org-data#list-user-preferences).
18 
19### October 15, 2026
20 
21* [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) is out of research preview for Claude Opus 5.5, and you no longer need to request access. Requests to Claude Opus 5.5 no longer require the `fast-mode-2026-02-01` beta header, and requests that still send it keep working. Claude Opus 5.5 now has a default fast mode rate limit in every usage tier. Fast mode for Claude Opus 5 and Claude Opus 4.8 remains in research preview. Keep sending the beta header with fast mode requests to those models.
22 
1523### October 14, 2026
1624 
1725* We've launched [OpenTelemetry export](https://platform.claude.com/docs/en/manage-claude/opentelemetry) in beta, so you can trace Messages API requests and Claude Managed Agents sessions in your observability backend. The Claude SDK emits spans in Python, TypeScript, C#, Go, Java, PHP, and Ruby. To get spans from the API, [add an OpenTelemetry destination](https://platform.claude.com/docs/en/manage-claude/opentelemetry/api#add-a-destination) in the Claude Console.

test-and-evaluate/develop-tests Changed · +433 / -40 lines

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 152
152152 def get_completion(prompt: str):
153153 message = client.messages.create(
154154 model="claude-opus-5-5",
155 max_tokens=50,
155 max_tokens=1024,
156156 messages=[{"role": "user", "content": prompt}],
157157 )
158158 return next(block.text for block in message.content if block.type == "text")
from line 164
164164 
165165 outputs = [
166166 get_completion(
167 f"Classify this as 'positive', 'negative', 'neutral', or 'mixed': {tweet['text']}"
167 f"Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: {tweet['text']}"
168168 )
169169 for tweet in tweets
170170 ]
from line 195
195195 async function getCompletion(prompt: string): Promise<string> {
196196 const message = await client.messages.create({
197197 model: "claude-opus-5-5",
198 max_tokens: 50,
198 max_tokens: 1024,
199199 messages: [{ role: "user", content: prompt }]
200200 });
201201 const textBlock = message.content.find((block) => block.type === "text");
from line 209
209209 let correctCount = 0;
210210 for (const tweet of tweets) {
211211 const output = await getCompletion(
212 `Classify this as 'positive', 'negative', 'neutral', or 'mixed': ${tweet.text}`
212 `Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: ${tweet.text}`
213213 );
214214 if (evaluateExactMatch(output, tweet.sentiment)) {
215215 correctCount++;
from line 237
237237 var message = await client.Messages.Create(new MessageCreateParams
238238 {
239239 Model = Model.ClaudeOpus5_5,
240 MaxTokens = 50,
240 MaxTokens = 1024,
241241 Messages = [new() { Role = Role.User, Content = prompt }],
242242 });
243243 return ContentText(message);
from line 265
265265 foreach (var tweet in tweets)
266266 {
267267 var output = await GetCompletion(
268 $"Classify this as 'positive', 'negative', 'neutral', or 'mixed': {tweet.Text}");
268 $"Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: {tweet.Text}");
269269 if (EvaluateExactMatch(output, tweet.Sentiment))
270270 {
271271 correct++;
from line 307
307307 func getCompletion(prompt string) string {
308308 message, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
309309 Model: anthropic.ModelClaudeOpus5_5,
310 MaxTokens: 50,
310 MaxTokens: 1024,
311311 Messages: []anthropic.MessageParam{
312312 anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)),
313313 },
from line 325
325325 func main() {
326326 correct := 0
327327 for _, item := range tweets {
328 output := getCompletion("Classify this as 'positive', 'negative', 'neutral', or 'mixed': " + item.Text)
328 output := getCompletion("Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: " + item.Text)
329329 if evaluateExactMatch(output, item.Sentiment) {
330330 correct++
331331 }
from line 360
360360 String getCompletion(String prompt) {
361361 var params = MessageCreateParams.builder()
362362 .model(Model.CLAUDE_OPUS_5_5)
363 .maxTokens(50L)
363 .maxTokens(1024L)
364364 .addUserMessage(prompt)
365365 .build();
366366 return contentText(client.messages().create(params));
from line 374
374374 int correct = 0;
375375 for (var tweet : tweets) {
376376 var output = getCompletion(
377 "Classify this as 'positive', 'negative', 'neutral', or 'mixed': " + tweet.text());
377 "Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: " + tweet.text());
378378 if (evaluateExactMatch(output, tweet.sentiment())) {
379379 correct++;
380380 }
from line 400
400400 {
401401 $message = $client->messages->create(
402402 model: Model::CLAUDE_OPUS_5_5,
403 maxTokens: 50,
403 maxTokens: 1024,
404404 messages: [
405405 [
406406 'role' => 'user',
from line 431
431431 foreach ($tweets as $tweet) {
432432 $output = getCompletion(
433433 $client,
434 "Classify this as 'positive', 'negative', 'neutral', or 'mixed': {$tweet['text']}",
434 "Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: {$tweet['text']}",
435435 );
436436 if (evaluateExactMatch($output, $tweet['sentiment'])) {
437437 $correct++;
from line 460
460460 def get_completion(client, prompt)
461461 message = client.messages.create(
462462 model: Anthropic::Model::CLAUDE_OPUS_5_5,
463 max_tokens: 50,
463 max_tokens: 1024,
464464 messages: [
465465 {
466466 role: "user",
from line 478
478478 correct = tweets.count do |tweet|
479479 output = get_completion(
480480 client,
481 "Classify this as 'positive', 'negative', 'neutral', or 'mixed': #{tweet[:text]}"
481 "Classify this as 'positive', 'negative', 'neutral', or 'mixed'. Output only the label: #{tweet[:text]}"
482482 )
483483 evaluate_exact_match(output, tweet[:sentiment])
484484 end
from line 619
619619 ```
620620 
621621 ```csharp C#
622 // Sentence-embedding models are not available as a native C# library. See the Python or TypeScript tab for this eval recipe.
622 using System.Numerics.Tensors;
623 // ...
624 using Microsoft.Extensions.AI;
625 using Microsoft.SemanticKernel;
626 
627 Faq[] faqVariations =
628 [
629 new(
630 [
631 "What's your return policy?",
632 "How can I return an item?",
633 "Wut's yur retrn polcy?",
634 ],
635 "Our return policy allows..."), // Edge case: Typos
636 new(
637 [
638 "I bought something last week, and it's not really what I expected, so I was wondering if maybe I could possibly return it?",
639 "I read online that your policy is 30 days but that seems like it might be out of date because the website was updated six months ago, so I'm wondering what exactly is your current policy?",
640 ],
641 "Our return policy allows..."), // Edge case: Long, rambling question
642 new(
643 [
644 "I'm Jane's cousin, and she said you guys have great customer service. Can I return this?",
645 "Reddit told me that contacting customer service this way was the fastest way to get an answer. I hope they're right! What is the return window for a jacket?",
646 ],
647 "Our return policy allows..."), // Edge case: Irrelevant info
648 // ... 47 more FAQs
649 ];
650 
651 var client = new AnthropicClient();
652 
653 // Download onnx/model.onnx and vocab.txt from https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
654 #pragma warning disable SKEXP0070
655 var kernel = Kernel.CreateBuilder()
656 .AddBertOnnxEmbeddingGenerator("model.onnx", "vocab.txt")
657 .Build();
658 #pragma warning restore SKEXP0070
659 var embeddingGenerator = kernel.GetRequiredService<IEmbeddingGenerator<string, Embedding<float>>>();
660 
661 async Task<string> GetCompletion(string prompt)
662 {
663 var message = await client.Messages.Create(new MessageCreateParams
664 {
665 Model = Model.ClaudeOpus5_5,
666 MaxTokens = 2048,
667 Messages = [new() { Role = Role.User, Content = prompt }],
668 });
669 foreach (var block in message.Content)
670 {
671 if (block.TryPickText(out var textBlock))
672 {
673 return textBlock.Text;
674 }
675 }
676 return "";
677 }
678 
679 async Task<double> EvaluateCosineSimilarity(List<string> outputs)
680 {
681 var embeddings = await embeddingGenerator.GenerateAsync(outputs);
682 
683 double total = 0;
684 foreach (var embeddingA in embeddings)
685 {
686 foreach (var embeddingB in embeddings)
687 {
688 total += TensorPrimitives.CosineSimilarity(embeddingA.Vector.Span, embeddingB.Vector.Span);
689 }
690 }
691 return total / (embeddings.Count * embeddings.Count);
692 }
693 
694 foreach (var faq in faqVariations)
695 {
696 var outputs = new List<string>();
697 foreach (var question in faq.Questions)
698 {
699 outputs.Add(await GetCompletion(question));
700 }
701 var similarityScore = await EvaluateCosineSimilarity(outputs);
702 Console.WriteLine($"FAQ Consistency Score: {similarityScore * 100}%");
703 }
704 
705 record Faq(string[] Questions, string Answer);
623706 ```
624707 
625708 ```go Go
626 // Sentence-embedding models are not available as a native Go library. See the Python or TypeScript tab for this eval recipe.
709 import (
710 "context"
711 "fmt"
712 "log"
713 "math"
714 
715 // ...
716 "github.com/knights-analytics/hugot"
717 "github.com/knights-analytics/hugot/pipelines"
718 )
719 
720 var client = anthropic.NewClient()
721 
722 type faq struct {
723 Questions []string
724 Answer string
725 }
726 
727 var faqVariations = []faq{
728 {
729 []string{
730 "What's your return policy?",
731 "How can I return an item?",
732 "Wut's yur retrn polcy?",
733 },
734 "Our return policy allows...",
735 }, // Edge case: Typos
736 {
737 []string{
738 "I bought something last week, and it's not really what I expected, so I was wondering if maybe I could possibly return it?",
739 "I read online that your policy is 30 days but that seems like it might be out of date because the website was updated six months ago, so I'm wondering what exactly is your current policy?",
740 },
741 "Our return policy allows...",
742 }, // Edge case: Long, rambling question
743 {
744 []string{
745 "I'm Jane's cousin, and she said you guys have great customer service. Can I return this?",
746 "Reddit told me that contacting customer service this way was the fastest way to get an answer. I hope they're right! What is the return window for a jacket?",
747 },
748 "Our return policy allows...",
749 }, // Edge case: Irrelevant info
750 // ... 47 more FAQs
751 }
752 
753 func getCompletion(prompt string) string {
754 message, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
755 Model: anthropic.ModelClaudeOpus5_5,
756 MaxTokens: 2048,
757 Messages: []anthropic.MessageParam{
758 anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)),
759 },
760 })
761 if err != nil {
762 log.Fatal(err)
763 }
764 for _, block := range message.Content {
765 if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
766 return textBlock.Text
767 }
768 }
769 return ""
770 }
771 
772 func cosineSimilarity(embeddingA, embeddingB []float32) float64 {
773 var dot, normA, normB float64
774 for i := range embeddingA {
775 dot += float64(embeddingA[i] * embeddingB[i])
776 normA += float64(embeddingA[i] * embeddingA[i])
777 normB += float64(embeddingB[i] * embeddingB[i])
778 }
779 return dot / (math.Sqrt(normA) * math.Sqrt(normB))
780 }
781 
782 func evaluateCosineSimilarity(embeddingPipeline *pipelines.FeatureExtractionPipeline, outputs []string) float64 {
783 result, err := embeddingPipeline.RunPipeline(context.Background(), outputs)
784 if err != nil {
785 log.Fatal(err)
786 }
787 
788 total := 0.0
789 for _, embeddingA := range result.Embeddings {
790 for _, embeddingB := range result.Embeddings {
791 total += cosineSimilarity(embeddingA, embeddingB)
792 }
793 }
794 return total / float64(len(result.Embeddings)*len(result.Embeddings))
795 }
796 
797 func main() {
798 ctx := context.Background()
799 session, err := hugot.NewGoSession(ctx)
800 if err != nil {
801 log.Fatal(err)
802 }
803 defer session.Destroy()
804 
805 downloadOptions := hugot.NewDownloadOptions()
806 downloadOptions.OnnxFilePath = "onnx/model.onnx"
807 modelPath, err := hugot.DownloadModel(ctx, "sentence-transformers/all-MiniLM-L6-v2", "./models/", downloadOptions)
808 if err != nil {
809 log.Fatal(err)
810 }
811 embeddingPipeline, err := hugot.NewPipeline(session, hugot.FeatureExtractionConfig{
812 ModelPath: modelPath,
813 Name: "embeddingPipeline",
814 })
815 if err != nil {
816 log.Fatal(err)
817 }
818 
819 for _, item := range faqVariations {
820 var outputs []string
821 for _, question := range item.Questions {
822 outputs = append(outputs, getCompletion(question))
823 }
824 similarityScore := evaluateCosineSimilarity(embeddingPipeline, outputs)
825 fmt.Printf("FAQ Consistency Score: %v%%\n", similarityScore*100)
826 }
827 }
627828 ```
628829 
629830 ```java Java
630 // Sentence-embedding models are not available as a native Java library. See the Python or TypeScript tab for this eval recipe.
831 import dev.langchain4j.data.segment.TextSegment;
832 import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
833 import dev.langchain4j.store.embedding.CosineSimilarity;
834 // ...
835 
836 record Faq(List<String> questions, String answer) {}
837 
838 List<Faq> faqVariations = List.of(
839 new Faq(
840 List.of(
841 "What's your return policy?",
842 "How can I return an item?",
843 "Wut's yur retrn polcy?"),
844 "Our return policy allows..."), // Edge case: Typos
845 new Faq(
846 List.of(
847 "I bought something last week, and it's not really what I expected, so I was wondering if maybe I could possibly return it?",
848 "I read online that your policy is 30 days but that seems like it might be out of date because the website was updated six months ago, so I'm wondering what exactly is your current policy?"),
849 "Our return policy allows..."), // Edge case: Long, rambling question
850 new Faq(
851 List.of(
852 "I'm Jane's cousin, and she said you guys have great customer service. Can I return this?",
853 "Reddit told me that contacting customer service this way was the fastest way to get an answer. I hope they're right! What is the return window for a jacket?"),
854 "Our return policy allows...") // Edge case: Irrelevant info
855 // ... 47 more FAQs
856 );
857 
858 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
859 
860 String getCompletion(String prompt) {
861 var params = MessageCreateParams.builder()
862 .model(Model.CLAUDE_OPUS_5_5)
863 .maxTokens(2048L)
864 .addUserMessage(prompt)
865 .build();
866 Message message = client.messages().create(params);
867 return message.content().stream()
868 .flatMap(block -> block.text().stream())
869 .map(textBlock -> textBlock.text())
870 .findFirst()
871 .orElse("");
872 }
873 
874 double evaluateCosineSimilarity(List<String> outputs) {
875 var embeddingModel = new AllMiniLmL6V2EmbeddingModel();
876 var segments = outputs.stream().map(TextSegment::from).toList();
877 var embeddings = embeddingModel.embedAll(segments).content();
878 
879 double total = 0;
880 for (var embeddingA : embeddings) {
881 for (var embeddingB : embeddings) {
882 total += CosineSimilarity.between(embeddingA, embeddingB);
883 }
884 }
885 return total / (embeddings.size() * embeddings.size());
886 }
887 
888 void main() {
889 for (var faq : faqVariations) {
890 var outputs = faq.questions().stream().map(this::getCompletion).toList();
891 double similarityScore = evaluateCosineSimilarity(outputs);
892 IO.println("FAQ Consistency Score: " + similarityScore * 100 + "%");
893 }
894 }
631895 ```
632896 
633897 ```php PHP
634 // Sentence-embedding models are not available as a native PHP library. See the Python or TypeScript tab for this eval recipe.
898 use function Codewithkyrian\Transformers\Pipelines\pipeline;
899 
900 $client = new Client();
901 
902 $faqVariations = [
903 [
904 'questions' => [
905 "What's your return policy?",
906 'How can I return an item?',
907 "Wut's yur retrn polcy?",
908 ],
909 'answer' => 'Our return policy allows...',
910 ], // Edge case: Typos
911 [
912 'questions' => [
913 "I bought something last week, and it's not really what I expected, so I was wondering if maybe I could possibly return it?",
914 "I read online that your policy is 30 days but that seems like it might be out of date because the website was updated six months ago, so I'm wondering what exactly is your current policy?",
915 ],
916 'answer' => 'Our return policy allows...',
917 ], // Edge case: Long, rambling question
918 [
919 'questions' => [
920 "I'm Jane's cousin, and she said you guys have great customer service. Can I return this?",
921 "Reddit told me that contacting customer service this way was the fastest way to get an answer. I hope they're right! What is the return window for a jacket?",
922 ],
923 'answer' => 'Our return policy allows...',
924 ], // Edge case: Irrelevant info
925 // ... 47 more FAQs
926 ];
927 
928 function getCompletion(Client $client, string $prompt): string
929 {
930 $message = $client->messages->create(
931 model: Model::CLAUDE_OPUS_5_5,
932 maxTokens: 2048,
933 messages: [
934 [
935 'role' => 'user',
936 'content' => $prompt,
937 ],
938 ],
939 );
940 foreach ($message->content as $block) {
941 if ($block instanceof \Anthropic\Messages\TextBlock) {
942 return $block->text;
943 }
944 }
945 return '';
946 }
947 
948 function evaluateCosineSimilarity(array $outputs): float
949 {
950 $extractor = pipeline('embeddings', 'Xenova/all-MiniLM-L6-v2');
951 $embeddings = $extractor($outputs, normalize: true, pooling: 'mean');
952 
953 $total = 0.0;
954 foreach ($embeddings as $embeddingA) {
955 foreach ($embeddings as $embeddingB) {
956 // Vectors are normalized, so cosine similarity is the dot product
957 $total += array_sum(array_map(fn ($valueA, $valueB) => $valueA * $valueB, $embeddingA, $embeddingB));
958 }
959 }
960 return $total / count($embeddings) ** 2;
961 }
962 
963 foreach ($faqVariations as $faq) {
964 $outputs = array_map(fn ($question) => getCompletion($client, $question), $faq['questions']);
965 $similarityScore = evaluateCosineSimilarity($outputs);
966 echo 'FAQ Consistency Score: ' . ($similarityScore * 100) . '%' . PHP_EOL;
967 }
635968 ```
636969 
637970 ```ruby Ruby
638 # Sentence-embedding models are not available as a native Ruby library. See the Python or TypeScript tab for this eval recipe.
971 require "informers"
972 
973 client = Anthropic::Client.new
974 
975 faq_variations = [
976 {
977 questions: [
978 "What's your return policy?",
979 "How can I return an item?",
980 "Wut's yur retrn polcy?"
981 ],
982 answer: "Our return policy allows..."
983 }, # Edge case: Typos
984 {
985 questions: [
986 "I bought something last week, and it's not really what I expected, so I was wondering if maybe I could possibly return it?",
987 "I read online that your policy is 30 days but that seems like it might be out of date because the website was updated six months ago, so I'm wondering what exactly is your current policy?"
988 ],
989 answer: "Our return policy allows..."
990 }, # Edge case: Long, rambling question
991 {
992 questions: [
993 "I'm Jane's cousin, and she said you guys have great customer service. Can I return this?",
994 "Reddit told me that contacting customer service this way was the fastest way to get an answer. I hope they're right! What is the return window for a jacket?"
995 ],
996 answer: "Our return policy allows..."
997 } # Edge case: Irrelevant info
998 # ... 47 more FAQs
999 ]
1000 
1001 def get_completion(client, prompt)
1002 message = client.messages.create(
1003 model: Anthropic::Model::CLAUDE_OPUS_5_5,
1004 max_tokens: 2048,
1005 messages: [
1006 {
1007 role: "user",
1008 content: prompt
1009 }
1010 ]
1011 )
1012 text_block = message.content.find { |block| block.is_a?(Anthropic::Models::TextBlock) }
1013 text_block ? text_block.text : ""
1014 end
1015 
1016 def evaluate_cosine_similarity(outputs)
1017 model = Informers.pipeline("embedding", "sentence-transformers/all-MiniLM-L6-v2")
1018 embeddings = model.(outputs)
1019 
1020 # Vectors are normalized, so cosine similarity is the dot product
1021 total = embeddings.sum do |embedding_a|
1022 embeddings.sum { |embedding_b| embedding_a.zip(embedding_b).sum { |value_a, value_b| value_a * value_b } }
1023 end
1024 total / embeddings.length**2
1025 end
1026 
1027 faq_variations.each do |faq|
1028 outputs = faq[:questions].map { |question| get_completion(client, question) }
1029 similarity_score = evaluate_cosine_similarity(outputs)
1030 puts "FAQ Consistency Score: #{similarity_score * 100}%"
1031 end
6391032 ```
6401033 </CodeGroup>
6411034 </Accordion>
from line 1605
12121605 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
12131606 response = client.messages.create(
12141607 model="claude-opus-5-5",
1215 max_tokens=50,
1608 max_tokens=1024,
12161609 messages=[{"role": "user", "content": tone_prompt}],
12171610 )
12181611 return int(
from line 1663
12701663 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
12711664 const response = await client.messages.create({
12721665 model: "claude-opus-5-5",
1273 max_tokens: 50,
1666 max_tokens: 1024,
12741667 messages: [{ role: "user", content: tonePrompt }]
12751668 });
12761669 const textBlock = response.content.find((block) => block.type === "text");
from line 1725
13321725 var response = await client.Messages.Create(new MessageCreateParams
13331726 {
13341727 Model = Model.ClaudeOpus5_5,
1335 MaxTokens = 50,
1728 MaxTokens = 1024,
13361729 Messages = [new() { Role = Role.User, Content = tonePrompt }],
13371730 });
13381731 return int.Parse(ContentText(response).Trim());
from line 1807
14141807 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
14151808 response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
14161809 Model: anthropic.ModelClaudeOpus5_5,
1417 MaxTokens: 50,
1810 MaxTokens: 1024,
14181811 Messages: []anthropic.MessageParam{
14191812 anthropic.NewUserMessage(anthropic.NewTextBlock(tonePrompt)),
14201813 },
from line 1876
14831876 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
14841877 var params = MessageCreateParams.builder()
14851878 .model(Model.CLAUDE_OPUS_5_5)
1486 .maxTokens(50L)
1879 .maxTokens(1024L)
14871880 .addUserMessage(tonePrompt)
14881881 .build();
14891882 var judgment = contentText(client.messages().create(params));
from line 1934
15411934 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
15421935 $response = $client->messages->create(
15431936 model: Model::CLAUDE_OPUS_5_5,
1544 maxTokens: 50,
1937 maxTokens: 1024,
15451938 messages: [
15461939 [
15471940 'role' => 'user',
from line 2011
16182011 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
16192012 response = client.messages.create(
16202013 model: Anthropic::Model::CLAUDE_OPUS_5_5,
1621 max_tokens: 50,
2014 max_tokens: 1024,
16222015 messages: [
16232016 {
16242017 role: "user",
from line 2085
16922085 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
16932086 response = client.messages.create(
16942087 model="claude-opus-5-5",
1695 max_tokens=50,
2088 max_tokens=1024,
16962089 messages=[{"role": "user", "content": binary_prompt}],
16972090 )
16982091 return (
from line 2162
17692162 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
17702163 const response = await client.messages.create({
17712164 model: "claude-opus-5-5",
1772 max_tokens: 50,
2165 max_tokens: 1024,
17732166 messages: [{ role: "user", content: binaryPrompt }]
17742167 });
17752168 const textBlock = response.content.find((block) => block.type === "text");
from line 2231
18382231 var response = await client.Messages.Create(new MessageCreateParams
18392232 {
18402233 Model = Model.ClaudeOpus5_5,
1841 MaxTokens = 50,
2234 MaxTokens = 1024,
18422235 Messages = [new() { Role = Role.User, Content = binaryPrompt }],
18432236 });
18442237 return ContentText(response).Trim().ToLowerInvariant() == "no";
from line 2327
19342327 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
19352328 response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
19362329 Model: anthropic.ModelClaudeOpus5_5,
1937 MaxTokens: 50,
2330 MaxTokens: 1024,
19382331 Messages: []anthropic.MessageParam{
19392332 anthropic.NewUserMessage(anthropic.NewTextBlock(binaryPrompt)),
19402333 },
from line 2404
20112404 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
20122405 var params = MessageCreateParams.builder()
20132406 .model(Model.CLAUDE_OPUS_5_5)
2014 .maxTokens(50L)
2407 .maxTokens(1024L)
20152408 .addUserMessage(binaryPrompt)
20162409 .build();
20172410 var judgment = contentText(client.messages().create(params));
from line 2475
20822475 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
20832476 $response = $client->messages->create(
20842477 model: Model::CLAUDE_OPUS_5_5,
2085 maxTokens: 50,
2478 maxTokens: 1024,
20862479 messages: [
20872480 [
20882481 'role' => 'user',
from line 2561
21682561 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
21692562 response = client.messages.create(
21702563 model: Anthropic::Model::CLAUDE_OPUS_5_5,
2171 max_tokens: 50,
2564 max_tokens: 1024,
21722565 messages: [
21732566 {
21742567 role: "user",
from line 2659
22662659 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
22672660 response = client.messages.create(
22682661 model="claude-opus-5-5",
2269 max_tokens=50,
2662 max_tokens=1024,
22702663 messages=[{"role": "user", "content": ordinal_prompt}],
22712664 )
22722665 return int(
from line 2751
23582751 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
23592752 const response = await client.messages.create({
23602753 model: "claude-opus-5-5",
2361 max_tokens: 50,
2754 max_tokens: 1024,
23622755 messages: [{ role: "user", content: ordinalPrompt }]
23632756 });
23642757 const textBlock = response.content.find((block) => block.type === "text");
from line 2834
24412834 var response = await client.Messages.Create(new MessageCreateParams
24422835 {
24432836 Model = Model.ClaudeOpus5_5,
2444 MaxTokens = 50,
2837 MaxTokens = 1024,
24452838 Messages = [new() { Role = Role.User, Content = ordinalPrompt }],
24462839 });
24472840 return int.Parse(ContentText(response).Trim());
from line 2944
25512944 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
25522945 response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
25532946 Model: anthropic.ModelClaudeOpus5_5,
2554 MaxTokens: 50,
2947 MaxTokens: 1024,
25552948 Messages: []anthropic.MessageParam{
25562949 anthropic.NewUserMessage(anthropic.NewTextBlock(ordinalPrompt)),
25572950 },
from line 3033
26403033 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
26413034 var params = MessageCreateParams.builder()
26423035 .model(Model.CLAUDE_OPUS_5_5)
2643 .maxTokens(50L)
3036 .maxTokens(1024L)
26443037 .addUserMessage(ordinalPrompt)
26453038 .build();
26463039 var judgment = contentText(client.messages().create(params));
from line 3104
27113104 // Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
27123105 $response = $client->messages->create(
27133106 model: Model::CLAUDE_OPUS_5_5,
2714 maxTokens: 50,
3107 maxTokens: 1024,
27153108 messages: [
27163109 [
27173110 'role' => 'user',
from line 3191
27983191 # Generally best practice to use a different model to evaluate than the model used to generate the evaluated output
27993192 response = client.messages.create(
28003193 model: Anthropic::Model::CLAUDE_OPUS_5_5,
2801 max_tokens: 50,
3194 max_tokens: 1024,
28023195 messages: [
28033196 {
28043197 role: "user",
28053198 

about-claude/models/choosing-a-model Changed · +1 / -1 lines

from line 9
99When choosing a Claude model, consider first evaluating these factors:
1010 
1111* **Capabilities:** What specific features or capabilities will you need the model to have to meet your needs?
12* **Speed:** How quickly does the model need to respond in your application? Claude Opus 5.5, Claude Opus 5, and Claude Opus 4.8 support [fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) (research preview), which delivers up to 2.5x higher output speed at premium pricing.
12* **Speed:** How quickly does the model need to respond in your application? [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) delivers up to 2.5x higher output speed at premium pricing on [supported models](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).
1313* **Cost:** What's your budget for both development and production usage?
1414* **Effort:** Several Claude models support an [effort parameter](https://platform.claude.com/docs/en/build-with-claude/effort) that trades intelligence for latency and cost within a single model. Tuning effort is often a better lever than switching models. On Claude Fable 5.1, Claude Opus 5, and Claude Sonnet 5.5, start with the default (`high`) and adjust up or down based on your evals. On Claude Opus 5.5 and Claude Haiku 5.5 the default is `medium`; start there and adjust the same way. On Claude Opus 4.8 and Claude Opus 4.7, the `xhigh` effort level, between `high` and `max`, is the best setting for most coding and agentic use cases.
1515 

about-claude/pricing Changed · +2 / -2 lines

from line 165
165165 
166166### Fast mode pricing
167167 
168[Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode), in research preview, provides significantly faster output for Claude Opus 5.5, Claude Opus 5, and Claude Opus 4.8 at premium pricing. Fast mode pricing applies across the full context window, including requests over 200k input tokens. Fast mode is available on the Claude API (first-party) only; it is not available on Claude Platform on AWS or partner-operated cloud platforms.
168[Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) provides significantly faster output for Claude Opus 5.5, Claude Opus 5, and Claude Opus 4.8 at premium pricing. Fast mode for Claude Opus 5 and Claude Opus 4.8 is in research preview. Fast mode pricing applies across the full context window, including requests over 200k input tokens. Fast mode is available on the Claude API (first-party) only; it is not available on Claude Platform on AWS or partner-operated cloud platforms.
169169 
170170| Model | Input | Output |
171171| ------------------------------- | ---------- | ---------- |
from line 172
172172| Claude Opus 5.5 | $8 / MTok | $40 / MTok |
173173| Claude Opus 5 / Claude Opus 4.8 | $10 / MTok | $50 / MTok |
174174 
175Fast mode is not available on Claude Opus 4.7 (requests with `speed: "fast"` return an error) or Claude Opus 4.6 (requests run at standard speed and are billed at standard rates). See [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).
175Fast mode is not available on Claude Opus 4.7 (requests with `speed: "fast"` return an error) or Claude Opus 4.6. See [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).
176176 
177177Fast mode pricing stacks with other pricing modifiers:
178178 

api/rate-limits Changed · +1 / -1 lines

from line 236
236236 
237237### Fast mode rate limits
238238 
239When using [fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) (research preview) with `speed: "fast"` on Claude Opus 5.5, Claude Opus 5, or Opus 4.8, dedicated rate limits apply that are separate from standard Opus rate limits. When fast mode rate limits are exceeded, the API returns a `429` error with a `retry-after` header. Fast mode is not available on Claude Opus 4.7 (requests return an error) or Claude Opus 4.6 (requests to `claude-opus-4-6` with `speed: "fast"` run at standard speed). See [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).
239When using [fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode) with `speed: "fast"` on Claude Opus 5.5, Claude Opus 5, or Opus 4.8, dedicated rate limits apply that are separate from standard Opus rate limits. Claude Opus 5.5 has a default fast mode rate limit in every usage tier, so you don't need to request access to use fast mode with it. Fast mode for Claude Opus 5 and Claude Opus 4.8 is in research preview. To see your fast mode rate limits, go to the [Rate limits](https://platform.claude.com/usage/limits) page in the Claude Console. When fast mode rate limits are exceeded, the API returns a `429` error with a `retry-after` header. Fast mode is not available on Claude Opus 4.7 (requests return an error) or Claude Opus 4.6. See [Fast mode](https://platform.claude.com/docs/en/build-with-claude/fast-mode#supported-models).
240240 
241241The response includes `anthropic-fast-*` headers that indicate your fast mode rate limit status. See [Fast mode rate limits](https://platform.claude.com/docs/en/build-with-claude/fast-mode#rate-limits) for details on these headers.
242242 

build-with-claude/compaction-background Changed · +1 / -3 lines

from line 469
469469 ```
470470 
471471 <CodeGroupItem language="PHP">
472 <Note>
473 The PHP SDK sends requests synchronously, so it can't run the compaction request in the background while the conversation goes on.
474 </Note>
472 The PHP SDK sends requests synchronously, so it can't run the compaction request in the background while the conversation goes on.
475473 </CodeGroupItem>
476474 
477475 ```ruby Ruby

manage-claude/cmek Changed · +1 / -0 lines

from line 107
107107* Activity Feed, audit logs, and telemetry network traffic such as OTEL, so customers can maintain compliance even if a key is revoked.
108108* Claude Managed Agents [vault credential](https://platform.claude.com/docs/en/managed-agents/vaults) values, such as OAuth tokens and client secrets. These are stored under Anthropic-managed encryption, are write-only, and are never returned in API responses.
109109* [User profiles](https://platform.claude.com/docs/en/api/beta/user_profiles): the `name`, `external_id`, and `metadata` fields are stored under Anthropic-managed encryption, not your key. Do not store sensitive personal data in profile `metadata`.
110* Ratings and comments about the Claude Console that members send with its **Feedback** option. No setting turns these off; members send them only when they choose to.
110111 
111112- [OpenTelemetry destination](https://platform.claude.com/docs/en/manage-claude/opentelemetry#add-a-destination) request headers, such as the API key header of your observability backend. These are stored under Anthropic-managed encryption. Their values are write-only and are never returned in API responses.
112113 

manage-claude/compliance-api-access Changed · +1 / -1 lines

from line 75
7575 | Scope | Grants |
7676 | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7777 | `read:compliance_activities` | Read the Activity Feed. A key covering the parent organization reads events for the parent organization and all linked organizations. |
78 | `read:compliance_user_data` | Read user chats, messages, files, projects, session metadata and transcripts, organization users, and group members |
78 | `read:compliance_user_data` | Read user chats, messages, files, projects, session metadata and transcripts, organization users, user preferences, and group members |
7979 | `delete:compliance_user_data` | Delete user chats, files, and projects |
8080 | `read:compliance_org_data` | Read organization metadata (names, types, roles, and groups) and the effective settings in force for organizations under the parent organization. User listings and group membership require `read:compliance_user_data`. |
8181 

manage-claude/opentelemetry/api Changed · +2 / -2 lines

from line 211
211211 ```
212212</CodeGroup>
213213 
214A create request takes the Console's settings except **Provider**, so enter your observability platform's endpoint URL and headers yourself. Set `traces.max_content_bytes` (csharp, go: `Traces.MaxContentBytes`; java, php: `traces.maxContentBytes`), in bytes, to fit what your observability platform accepts (see [Content limits](https://platform.claude.com/docs/en/manage-claude/opentelemetry#content-limits)). To list, change, or delete destinations, or to add or remove one workspace, use the other methods of the telemetry destinations API.
214A create request takes the Console's settings except **Provider**, so enter your observability platform's endpoint URL and headers yourself. Set `traces.max_content_bytes` (csharp, go: `Traces.MaxContentBytes`; java, php: `traces.maxContentBytes`), in bytes, to fit what your observability platform accepts (see [Content limits](https://platform.claude.com/docs/en/manage-claude/opentelemetry#content-limits)). To list, change, or delete destinations, or to add or remove one workspace, use the other methods of the [telemetry destinations API](https://platform.claude.com/docs/en/api/beta/organization/telemetry_destinations).
215215 
216216## 2. Choose workspaces for a destination
217217 
from line 239
239239 
240240By default, the API spans for a Messages API request or a Managed Agents session are in their own traces. Connect them to your application's traces, so that they nest under your own spans.
241241 
242The API reads each request's trace context from the W3C [`traceparent` header](https://www.w3.org/TR/trace-context/). If the sampled flag in the header is off, the API doesn't emit the request's span or the spans under it. Claude Platform on AWS doesn't support this header yet. The spans for requests that you send to it always start their own traces, even when the sampled flag is off.
242The API reads each request's trace context from the W3C [`traceparent` header](https://www.w3.org/TR/trace-context/). If the sampled flag in the header is off, the API doesn't emit the request's span or the spans under it.
243243 
244244<Tabs>
245245 <Tab title="With the Claude SDK">

manage-claude/opentelemetry/sdk Changed · +1 / -1 lines

from line 560
5605601. In the process that runs the worker, [set up SDK tracing](https://platform.claude.com/docs/en/manage-claude/opentelemetry/sdk#install-the-sdk) as in steps 1 to 4.
5615612. Allow network traffic from the sandbox to your observability platform or OpenTelemetry Collector.
562562 
563When the worker sends a tool result, that request's API span is nested under its SDK span. For requests that the worker sends to Claude Platform on AWS, the API spans are in their own traces instead.
563When the worker sends a tool result, that request's API span is nested under its SDK span.
564564 
565565## Trace context and baggage
566566 

managed-agents/overview Changed · +1 / -1 lines

from line 56
5656 </Step>
5757 
5858 <Step title="Create an environment">
59 Configure where the agent runs: a cloud sandbox, or a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes) on your own infrastructure.
59 [Configure where the agent runs](https://platform.claude.com/docs/en/managed-agents/choosing-an-environment): a cloud sandbox, or a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes) on your own infrastructure.
6060 </Step>
6161 
6262 <Step title="Start a session">
Feedback