Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build LLM-powered apps with the Anthropic Claude API or SDK across Python, TypeScript, Java, Go, Ruby, C#, and PHP.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
typescript/managed-agents/README.md
1# Managed Agents — TypeScript23> **Bindings not shown here:** This README covers the most common managed-agents flows for TypeScript. If you need a class, method, namespace, field, or behavior that isn't shown, WebFetch the TypeScript SDK repo **or the relevant docs page** from `shared/live-sources.md` rather than guess. Do not extrapolate from cURL shapes or another language's SDK.45> **Agents are persistent — create once, reference by ID.** Store the agent ID returned by `agents.create` and pass it to every subsequent `sessions.create`; do not call `agents.create` in the request path. The Anthropic CLI is one convenient way to create agents and environments from version-controlled YAML — its URL is in `shared/live-sources.md`. The examples below show in-code creation for completeness; in production the create call belongs in setup, not in the request path.67## Installation89```bash10npm install @anthropic-ai/sdk11```1213## Client Initialization1415```typescript16import Anthropic from "@anthropic-ai/sdk";1718// Default — resolves credentials from the environment:19// ANTHROPIC_API_KEY, or ANTHROPIC_AUTH_TOKEN, or an `ant auth login` profile.20// Prefer this for local dev; don't hardcode a key.21const client = new Anthropic();2223// Explicit API key (only when you must inject a specific key)24const client = new Anthropic({ apiKey: "your-api-key" });25```2627---2829## Create an Environment3031```typescript32const environment = await client.beta.environments.create(33{34name: "my-dev-env",35config: {36type: "cloud",37networking: { type: "unrestricted" },38},39},40);41console.log(environment.id); // env_...42```4344---4546## Create an Agent (required first step)4748> ⚠️ **There is no inline agent config.** `model`/`system`/`tools` live on the agent object, not the session. Always start with `agents.create()` — the session only takes `agent: { type: "agent", id: agent.id }`.4950### Minimal5152```typescript53// 1. Create the agent (reusable, versioned)54const agent = await client.beta.agents.create(55{56name: "Coding Assistant",57model: "claude-opus-4-8",58tools: [{ type: "agent_toolset_20260401", default_config: { enabled: true } }],59},60);6162// 2. Start a session63const session = await client.beta.sessions.create(64{65agent: { type: "agent", id: agent.id, version: agent.version },66environment_id: environment.id,67},68);69console.log(session.id, session.status);70```7172### With system prompt and custom tools7374```typescript75const agent = await client.beta.agents.create(76{77name: "Code Reviewer",78model: "claude-opus-4-8",79system: "You are a senior code reviewer.",80tools: [81{ type: "agent_toolset_20260401", default_config: { enabled: true } },82{83type: "custom",84name: "run_tests",85description: "Run the test suite",86input_schema: {87type: "object",88properties: {89test_path: { type: "string", description: "Path to test file" },90},91required: ["test_path"],92},93},94],95},96);9798const session = await client.beta.sessions.create(99{100agent: { type: "agent", id: agent.id, version: agent.version },101environment_id: environment.id,102title: "Code review session",103resources: [104{105type: "github_repository",106url: "https://github.com/owner/repo",107mount_path: "/workspace/repo",108authorization_token: process.env.GITHUB_TOKEN,109branch: "main",110},111],112},113);114```115116---117118## Send a User Message119120```typescript121await client.beta.sessions.events.send(122session.id,123{124events: [125{126type: "user.message",127content: [{ type: "text", text: "Review the auth module" }],128},129],130},131);132```133134> 💡 **Stream-first:** Open the stream *before* (or concurrently with) sending the message. The stream only delivers events that occur after it opens — stream-after-send means early events arrive buffered in one batch. See [Steering Patterns](../../shared/managed-agents-events.md#steering-patterns).135136---137138## Stream Events (SSE)139140```typescript141// Stream-first: open stream and send concurrently142const [events] = await Promise.all([143collectStream(session.id),144client.beta.sessions.events.send(145session.id,146{ events: [{ type: "user.message", content: [{ type: "text", text: "..." }] }] },147),148]);149150// Standalone stream iteration:151const stream = await client.beta.sessions.events.stream(152session.id,153);154155for await (const event of stream) {156switch (event.type) {157case "agent.message":158for (const block of event.content) {159if (block.type === "text") {160process.stdout.write(block.text);161}162}163break;164case "agent.custom_tool_use":165// Custom tool invocation — session is now idle166console.log(`\nCustom tool call: ${event.name}`);167console.log(`Input: ${JSON.stringify(event.input)}`);168break;169case "session.status_idle":170console.log("\n--- Agent idle ---");171break;172case "session.status_terminated":173console.log("\n--- Session terminated ---");174break;175}176}177```178179---180181## Provide Custom Tool Result182183```typescript184await client.beta.sessions.events.send(185session.id,186{187events: [188{189type: "user.custom_tool_result",190custom_tool_use_id: "sevt_abc123",191content: [{ type: "text", text: "All 42 tests passed." }],192},193],194},195);196```197198---199200## Poll Events201202```typescript203const events = await client.beta.sessions.events.list(204session.id,205);206for (const event of events.data) {207console.log(`${event.type}: ${event.id}`);208}209```210211---212213## Full Streaming Loop with Custom Tools214215```typescript216function runCustomTool(toolName: string, toolInput: unknown): string {217if (toolName === "run_tests") {218// Your tool implementation here219return "All tests passed.";220}221return `Unknown tool: ${toolName}`;222}223224async function runSession(client: Anthropic, sessionId: string) {225while (true) {226const stream = await client.beta.sessions.events.stream(227sessionId,228);229230const toolCalls: Anthropic.Beta.Sessions.BetaManagedAgentsAgentCustomToolUseEvent[] = [];231232for await (const event of stream) {233if (event.type === "agent.message") {234for (const block of event.content) {235if (block.type === "text") {236process.stdout.write(block.text);237}238}239} else if (event.type === "agent.custom_tool_use") {240toolCalls.push(event);241} else if (event.type === "session.status_idle") {242break;243} else if (event.type === "session.status_terminated") {244return;245}246}247248if (toolCalls.length === 0) break;249250// Process custom tool calls251const results = toolCalls.map((call) => ({252type: "user.custom_tool_result" as const,253custom_tool_use_id: call.id,254content: [{ type: "text" as const, text: runCustomTool(call.name, call.input) }],255}));256257await client.beta.sessions.events.send(258sessionId,259{ events: results },260);261}262}263```264265---266267## Upload a File268269```typescript270import fs from "fs";271272const file = await client.beta.files.upload({273file: fs.createReadStream("data.csv"),274});275276// Use in a session277const session = await client.beta.sessions.create(278{279agent: { type: "agent", id: agent.id, version: agent.version },280environment_id: environment.id,281resources: [{ type: "file", file_id: file.id, mount_path: "/workspace/data.csv" }],282},283);284```285286---287288## List and Download Session Files289290List files the agent wrote to `/mnt/session/outputs/` during a session, then download them.291292```typescript293import fs from "fs";294295// List files associated with a session296const files = await client.beta.files.list({297scope_id: session.id,298betas: ["managed-agents-2026-04-01"],299});300for (const f of files.data) {301console.log(f.filename, f.size_bytes);302303// Download and save to disk304const resp = await client.beta.files.download(f.id);305const buffer = Buffer.from(await resp.arrayBuffer());306fs.writeFileSync(f.filename, buffer);307}308```309310> 💡 There's a brief indexing lag (~1–3s) between `session.status_idle` and output files appearing in `files.list`. Retry once or twice if the list is empty.311312---313314## Session Management315316```typescript317// Get session details318const session = await client.beta.sessions.retrieve("sesn_011CZxAbc123Def456");319console.log(session.status, session.usage);320321// List sessions322const sessions = await client.beta.sessions.list();323324// Delete a session325await client.beta.sessions.delete("sesn_011CZxAbc123Def456");326327// Archive a session328await client.beta.sessions.archive("sesn_011CZxAbc123Def456");329```330331---332333## MCP Server Integration334335```typescript336// Agent declares MCP server (no auth here — auth goes in a vault)337const agent = await client.beta.agents.create({338name: "MCP Agent",339model: "claude-opus-4-8",340mcp_servers: [341{ type: "url", name: "my-tools", url: "https://my-mcp-server.example.com/sse" },342],343tools: [344{ type: "agent_toolset_20260401", default_config: { enabled: true } },345{ type: "mcp_toolset", mcp_server_name: "my-tools" },346],347});348349// Session attaches vault(s) containing credentials for those MCP server URLs350const session = await client.beta.sessions.create({351agent: agent.id,352environment_id: environment.id,353vault_ids: [vault.id],354});355```356357See `shared/managed-agents-tools.md` §Vaults for creating vaults and adding credentials.358