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.
php/managed-agents/README.md
1# Managed Agents — PHP23> **Bindings not shown here:** This README covers the most common managed-agents flows for PHP. If you need a class, method, namespace, field, or behavior that isn't shown, WebFetch the PHP 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 `$client->beta->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```bash10composer require "anthropic-ai/sdk"11```1213## Client Initialization1415```php16use Anthropic\Client;1718// Default (uses ANTHROPIC_API_KEY env var)19$client = new Client();2021// Explicit API key22$client = new Client(apiKey: 'your-api-key');23```2425---2627## Create an Environment2829```php30$environment = $client->beta->environments->create(31name: 'my-dev-env',32config: ['type' => 'cloud', 'networking' => ['type' => 'unrestricted']],33);34echo "Environment ID: {$environment->id}\n"; // env_...35```3637---3839## Create an Agent (required first step)4041> ⚠️ **There is no inline agent config.** `model`/`system`/`tools` live on the agent object, not the session. Always start with `$client->beta->agents->create()` — the session takes either `agent: $agent->id` or the typed `BetaManagedAgentsAgentParams::with(type: 'agent', id: $agent->id, version: $agent->version)`.4243### Minimal4445```php46use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401Params;4748// 1. Create the agent (reusable, versioned)49$agent = $client->beta->agents->create(50name: 'Coding Assistant',51model: 'claude-opus-4-7',52system: 'You are a helpful coding assistant.',53tools: [54BetaManagedAgentsAgentToolset20260401Params::with(55type: 'agent_toolset_20260401',56),57],58);5960// 2. Start a session61$session = $client->beta->sessions->create(62agent: ['type' => 'agent', 'id' => $agent->id, 'version' => $agent->version],63environmentID: $environment->id,64title: 'Quickstart session',65);66echo "Session ID: {$session->id}\n";67```6869### Updating an Agent7071Updates create new versions; the agent object is immutable per version.7273```php74$updatedAgent = $client->beta->agents->update(75$agent->id,76version: $agent->version,77system: 'You are a helpful coding agent. Always write tests.',78);79echo "New version: {$updatedAgent->version}\n";8081// List all versions82foreach ($client->beta->agents->versions->list($agent->id)->pagingEachItem() as $version) {83echo "Version {$version->version}: {$version->updatedAt->format(DateTimeInterface::ATOM)}\n";84}8586// Archive the agent87$archived = $client->beta->agents->archive($agent->id);88echo "Archived at: {$archived->archivedAt->format(DateTimeInterface::ATOM)}\n";89```9091---9293## Send a User Message9495```php96$client->beta->sessions->events->send(97$session->id,98events: [99[100'type' => 'user.message',101'content' => [['type' => 'text', 'text' => 'Review the auth module']],102],103],104);105```106107> 💡 **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).108109---110111## Stream Events (SSE)112113> ℹ️ **Streaming transporter:** PHP's default buffered PSR-18 client never returns for the open-ended session event stream. Use a streaming Guzzle transporter for `streamStream()` calls — other calls keep the default client.114115```php116$streamingClient = new GuzzleHttp\Client(['stream' => true]);117118// Open the stream first, then send the user message119$stream = $client->beta->sessions->events->streamStream(120$session->id,121requestOptions: ['transporter' => $streamingClient],122);123$client->beta->sessions->events->send(124$session->id,125events: [126[127'type' => 'user.message',128'content' => [['type' => 'text', 'text' => 'Summarize the repo README']],129],130],131);132133foreach ($stream as $event) {134match ($event->type) {135'agent.message' => array_walk(136$event->content,137static fn($block) => $block->type === 'text' ? print($block->text) : null,138),139'agent.tool_use' => print("\n[Using tool: {$event->name}]\n"),140'session.error' => printf("\n[Error: %s]", $event->error?->message ?? 'unknown'),141default => null,142};143if ($event->type === 'session.status_idle' || $event->type === 'session.error') {144break;145}146}147$stream->close();148```149150### Reconnecting and Tailing151152When reconnecting mid-session, list past events first to dedupe, then tail live events:153154```php155$stream = $client->beta->sessions->events->streamStream(156$session->id,157requestOptions: ['transporter' => $streamingClient],158);159160// Stream is open and buffering. List history before tailing live.161$seenEventIds = [];162foreach ($client->beta->sessions->events->list($session->id)->pagingEachItem() as $event) {163$seenEventIds[$event->id] = true;164}165166// Tail live events, skipping anything already seen167foreach ($stream as $event) {168if (isset($seenEventIds[$event->id])) {169continue;170}171$seenEventIds[$event->id] = true;172match ($event->type) {173'agent.message' => array_walk(174$event->content,175static fn($block) => $block->type === 'text' ? print($block->text) : null,176),177default => null,178};179if ($event->type === 'session.status_idle') {180break;181}182}183$stream->close();184```185186---187188## Provide Custom Tool Result189190> ℹ️ The PHP managed-agents bindings for `user.custom_tool_result` are not yet documented in this skill or in the apps source examples. Refer to `shared/managed-agents-events.md` for the wire format and the `anthropic-ai/sdk` PHP repository for the corresponding params.191192---193194## Poll Events195196```php197foreach ($client->beta->sessions->events->list($session->id)->pagingEachItem() as $event) {198echo "{$event->type}: {$event->id}\n";199}200```201202---203204## Upload a File205206> ℹ️ **PHP file upload:** The PHP SDK's beta managed-agents file upload binding is not shown in the apps source examples; the canonical PHP example uses raw cURL against `POST /v1/files`. If your codebase prefers the SDK, WebFetch the `anthropic-ai/sdk` PHP repository for the latest binding before writing code.207208```php209use Anthropic\Beta\Sessions\BetaManagedAgentsFileResourceParams;210211// Raw cURL upload (canonical example from the apps source)212$csvPath = 'data.csv';213$ch = curl_init('https://api.anthropic.com/v1/files');214curl_setopt_array($ch, [215CURLOPT_RETURNTRANSFER => true,216CURLOPT_POST => true,217CURLOPT_HTTPHEADER => [218'x-api-key: ' . getenv('ANTHROPIC_API_KEY'),219'anthropic-version: 2023-06-01',220'anthropic-beta: files-api-2025-04-14',221],222CURLOPT_POSTFIELDS => ['file' => new CURLFile($csvPath, 'text/csv', 'data.csv')],223]);224$file = json_decode(curl_exec($ch));225echo "File ID: {$file->id}\n";226227// Mount in a session228$session = $client->beta->sessions->create(229agent: $agent->id,230environmentID: $environment->id,231resources: [232BetaManagedAgentsFileResourceParams::with(233type: 'file',234fileID: $file->id,235mountPath: '/workspace/data.csv',236),237],238);239```240241### Add and Manage Resources on an Existing Session242243```php244// Attach an additional file to an open session245$resource = $client->beta->sessions->resources->add(246$session->id,247type: 'file',248fileID: $file->id,249);250echo "{$resource->id}\n"; // "sesrsc_01ABC..."251252// List resources on the session253$listed = $client->beta->sessions->resources->list($session->id);254foreach ($listed->data as $entry) {255echo "{$entry->id} {$entry->type}\n";256}257258// Detach a resource259$client->beta->sessions->resources->delete($resource->id, sessionID: $session->id);260```261262---263264## List and Download Session Files265266> ℹ️ Listing and downloading files an agent wrote during a session is not yet documented for PHP in this skill or in the apps source examples. See `shared/managed-agents-events.md` and the `anthropic-ai/sdk` PHP repository for the file list/download bindings.267268---269270## Session Management271272```php273// List environments274$environments = $client->beta->environments->list();275276// Retrieve a specific environment277$env = $client->beta->environments->retrieve($environment->id);278279// Archive an environment (read-only, existing sessions continue)280$client->beta->environments->archive($environment->id);281282// Delete an environment (only if no sessions reference it)283$client->beta->environments->delete($environment->id);284285// Delete a session286$client->beta->sessions->delete($session->id);287```288289---290291## MCP Server Integration292293```php294use Anthropic\Beta\Agents\BetaManagedAgentsAgentToolset20260401Params;295use Anthropic\Beta\Agents\BetaManagedAgentsMCPToolsetParams;296use Anthropic\Beta\Agents\BetaManagedAgentsUrlmcpServerParams;297use Anthropic\Beta\Sessions\BetaManagedAgentsAgentParams;298299// Agent declares MCP server (no auth here — auth goes in a vault)300$agent = $client->beta->agents->create(301name: 'GitHub Assistant',302model: 'claude-opus-4-7',303mcpServers: [304BetaManagedAgentsUrlmcpServerParams::with(305type: 'url',306name: 'github',307url: 'https://api.githubcopilot.com/mcp/',308),309],310tools: [311BetaManagedAgentsAgentToolset20260401Params::with(type: 'agent_toolset_20260401'),312BetaManagedAgentsMCPToolsetParams::with(313type: 'mcp_toolset',314mcpServerName: 'github',315),316],317);318319// Session attaches vault(s) containing credentials for those MCP server URLs320$session = $client->beta->sessions->create(321agent: BetaManagedAgentsAgentParams::with(322type: 'agent',323id: $agent->id,324version: $agent->version,325),326environmentID: $environment->id,327vaultIDs: [$vault->id],328);329```330331See `shared/managed-agents-tools.md` §Vaults for creating vaults and adding credentials.332333---334335## Vaults336337```php338// Create a vault339$vault = $client->beta->vaults->create(340displayName: 'Alice',341metadata: ['external_user_id' => 'usr_abc123'],342);343echo $vault->id . "\n"; // "vlt_01ABC..."344345// Add an OAuth credential346$credential = $client->beta->vaults->credentials->create(347vaultID: $vault->id,348displayName: "Alice's Slack",349auth: [350'type' => 'mcp_oauth',351'mcp_server_url' => 'https://mcp.slack.com/mcp',352'access_token' => 'xoxp-...',353'expires_at' => '2026-04-15T00:00:00Z',354'refresh' => [355'token_endpoint' => 'https://slack.com/api/oauth.v2.access',356'client_id' => '1234567890.0987654321',357'scope' => 'channels:read chat:write',358'refresh_token' => 'xoxe-1-...',359'token_endpoint_auth' => [360'type' => 'client_secret_post',361'client_secret' => 'abc123...',362],363],364],365);366367// Rotate the credential (e.g., after a token refresh)368$client->beta->vaults->credentials->update(369$credential->id,370vaultID: $vault->id,371auth: [372'type' => 'mcp_oauth',373'access_token' => 'xoxp-new-...',374'expires_at' => '2026-05-15T00:00:00Z',375'refresh' => ['refresh_token' => 'xoxe-1-new-...'],376],377);378379// Archive a vault380$client->beta->vaults->archive($vault->id);381```382383---384385## GitHub Repository Integration386387Mount a GitHub repository as a session resource (a vault holds the GitHub MCP credential):388389```php390$session = $client->beta->sessions->create(391agent: $agent->id,392environmentID: $environment->id,393vaultIDs: [$vault->id],394resources: [395[396'type' => 'github_repository',397'url' => 'https://github.com/org/repo',398'mountPath' => '/workspace/repo',399'authorizationToken' => 'ghp_your_github_token',400],401],402);403```404405Multiple repositories on the same session:406407```php408$resources = [409[410'type' => 'github_repository',411'url' => 'https://github.com/org/frontend',412'mountPath' => '/workspace/frontend',413'authorizationToken' => 'ghp_your_github_token',414],415[416'type' => 'github_repository',417'url' => 'https://github.com/org/backend',418'mountPath' => '/workspace/backend',419'authorizationToken' => 'ghp_your_github_token',420],421];422```423424Rotating a repository's authorization token:425426```php427$listed = $client->beta->sessions->resources->list($session->id);428$repoResourceId = $listed->data[0]->id;429430$client->beta->sessions->resources->update(431$repoResourceId,432sessionID: $session->id,433authorizationToken: 'ghp_your_new_github_token',434);435```436