One read of Claude Code CLIclaude-code-20260928T233702Z
154 pages moved out of 210 read.
Pages moved
154
significant first
Pages read
210
in this capture
Captured
23:37 UTC
Corpus hash
82a8d4497843
corpus-hash
What this read moved
1-25 of 154, page 1 of 7This capture is too large to show at once. Changes 1-25 of 154 are below, significant first; the rest are on the following screens.
accessibility Changed · +22 / -22 lines
from line 28
2828
2929The table lists each accessibility option, whether you set it as a flag, an environment variable, or a setting, and what it changes.
3030
31| Option | Type | What it changes |
32| :---------------------------------------------------------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33| [`--ax-screen-reader`](/docs/en/cli-reference#cli-flags) | Flag | Screen reader mode for one session. |
34| [`CLAUDE_AX_SCREEN_READER`](/docs/en/env-vars#variables) | Environment variable | Screen reader mode for sessions started from the shell where you set it. |
35| [`axScreenReader`](/docs/en/settings-reference#axscreenreader) | Setting | Screen reader mode for every session when `true`. |
36| [`CLAUDE_AX_STARTUP_QUIET_MS`](/docs/en/env-vars#variables) | Environment variable | How long Claude Code waits after the confirmation line before it draws the first prompt in screen reader mode. Requires Claude Code v2.1.217 or later. |
37| [`CLAUDE_AX_PREPARK_MS`](/docs/en/env-vars#variables) | Environment variable | How long Claude Code waits, with the cursor at the start of the line, before it writes a new or changed line in screen reader mode. Requires Claude Code v2.1.233 or later. |
38| [`CLAUDE_CODE_ACCESSIBILITY`](/docs/en/env-vars#variables) | Environment variable | A terminal cursor that stays visible for screen magnifiers such as macOS Zoom when you set it to `1`. The cursor follows the input caret and, on Claude Code v2.1.218 or later, the highlighted row in menus and panels such as `/config` and `/plugin`. |
39| [`prefersReducedMotion`](/docs/en/settings-reference#prefersreducedmotion) | Setting | Reduced or no spinners, shimmer, and other animations when `true`. |
40| [`theme`](/docs/en/settings-reference#theme) | Setting | The interface colors, including the colorblind-friendly `dark-daltonized` and `light-daltonized` themes. You can also pick one with [`/theme`](/docs/en/commands#all-commands). |
41| [`preferredNotifChannel`](/docs/en/settings-reference#preferrednotifchannel) | Setting | With the value `"terminal_bell"`, a terminal bell outside screen reader mode when Claude is waiting on you. |
31| Option | Type | What it changes |
32| :- | :- | :- |
33| [`--ax-screen-reader`](/docs/en/cli-reference#cli-flags) | Flag | Screen reader mode for one session. |
34| [`CLAUDE_AX_SCREEN_READER`](/docs/en/env-vars#variables) | Environment variable | Screen reader mode for sessions started from the shell where you set it. |
35| [`axScreenReader`](/docs/en/settings-reference#axscreenreader) | Setting | Screen reader mode for every session when `true`. |
36| [`CLAUDE_AX_STARTUP_QUIET_MS`](/docs/en/env-vars#variables) | Environment variable | How long Claude Code waits after the confirmation line before it draws the first prompt in screen reader mode. Requires Claude Code v2.1.217 or later. |
37| [`CLAUDE_AX_PREPARK_MS`](/docs/en/env-vars#variables) | Environment variable | How long Claude Code waits, with the cursor at the start of the line, before it writes a new or changed line in screen reader mode. Requires Claude Code v2.1.233 or later. |
38| [`CLAUDE_CODE_ACCESSIBILITY`](/docs/en/env-vars#variables) | Environment variable | A terminal cursor that stays visible for screen magnifiers such as macOS Zoom when you set it to `1`. The cursor follows the input caret and, on Claude Code v2.1.218 or later, the highlighted row in menus and panels such as `/config` and `/plugin`. |
39| [`prefersReducedMotion`](/docs/en/settings-reference#prefersreducedmotion) | Setting | Reduced or no spinners, shimmer, and other animations when `true`. |
40| [`theme`](/docs/en/settings-reference#theme) | Setting | The interface colors, including the colorblind-friendly `dark-daltonized` and `light-daltonized` themes. You can also pick one with [`/theme`](/docs/en/commands#all-commands). |
41| [`preferredNotifChannel`](/docs/en/settings-reference#preferrednotifchannel) | Setting | With the value `"terminal_bell"`, a terminal bell outside screen reader mode when Claude is waiting on you. |
4242
4343## What your screen reader hears
4444
from line 58
5858
5959Each message in the transcript starts with a label your screen reader announces, naming what it is: your messages, Claude's replies and thinking, tool activity, errors and warnings, and prompts. The labels are also searchable, so you can jump between sections of the transcript by searching your terminal's scrollback:
6060
61| Label | Meaning |
62| :--------------------- | :---------------------------------------------------------------------------------------- |
63| `you:` | Your messages |
64| `claude:` | Claude's replies |
65| `thinking:` | Claude's thinking |
66| `tool:` | Tool activity, such as a file edit or a command run |
67| `tool error:` | A tool that failed |
68| `error:` | An error in the conversation, such as a failed API request |
69| `warning:` | A warning from Claude Code, such as a switch to a fallback model |
70| `Permission Required:` | A permission prompt waiting for your answer |
71| `Cost:` | The session cost summary when Claude Code exits, if your account [shows costs](/docs/en/costs) |
61| Label | Meaning |
62| :- | :- |
63| `you:` | Your messages |
64| `claude:` | Claude's replies |
65| `thinking:` | Claude's thinking |
66| `tool:` | Tool activity, such as a file edit or a command run |
67| `tool error:` | A tool that failed |
68| `error:` | An error in the conversation, such as a failed API request |
69| `warning:` | A warning from Claude Code, such as a switch to a fallback model |
70| `Permission Required:` | A permission prompt waiting for your answer |
71| `Cost:` | The session cost summary when Claude Code exits, if your account [shows costs](/docs/en/costs) |
7272
7373Claude Code keeps the terminal cursor on the input caret, so your screen reader's read-current-line command reads the prompt you're editing.
7474
admin-setup Changed · +49 / -49 lines
from line 10
1010 SSO, SCIM provisioning, and seat assignment are configured at the Claude account level. See the [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide) and [seat assignment](https://support.claude.com/en/articles/11845131-use-claude-code-with-your-team-or-enterprise-plan) for those steps.
1111</Note>
1212
13| Decision | What you're choosing | Reference |
14| :---------------------------------------------------------------------- | :-------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15| [Choose your API provider](#choose-your-api-provider) | Where Claude Code authenticates and how it's billed | [Authentication](/docs/en/authentication), [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry) |
16| [Decide how settings reach devices](#decide-how-settings-reach-devices) | How managed policy reaches developer machines | [Server-managed settings](/docs/en/server-managed-settings), [Delivery mechanisms](/docs/en/managed-settings#delivery-mechanisms) |
17| [Decide what to enforce](#decide-what-to-enforce) | Which tools, commands, and integrations are allowed | [Permissions](/docs/en/permissions), [Sandboxing](/docs/en/sandboxing) |
18| [Set up usage visibility](#set-up-usage-visibility) | How you track spend and adoption | [Analytics](/docs/en/analytics), [Monitoring](/docs/en/monitoring-usage), [Costs](/docs/en/costs) |
19| [Review data handling](#review-data-handling) | Data retention and compliance posture | [Data usage](/docs/en/data-usage), [Security](/docs/en/security) |
13| Decision | What you're choosing | Reference |
14| :- | :- | :- |
15| [Choose your API provider](#choose-your-api-provider) | Where Claude Code authenticates and how it's billed | [Authentication](/docs/en/authentication), [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud's Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry) |
16| [Decide how settings reach devices](#decide-how-settings-reach-devices) | How managed policy reaches developer machines | [Server-managed settings](/docs/en/server-managed-settings), [Delivery mechanisms](/docs/en/managed-settings#delivery-mechanisms) |
17| [Decide what to enforce](#decide-what-to-enforce) | Which tools, commands, and integrations are allowed | [Permissions](/docs/en/permissions), [Sandboxing](/docs/en/sandboxing) |
18| [Set up usage visibility](#set-up-usage-visibility) | How you track spend and adoption | [Analytics](/docs/en/analytics), [Monitoring](/docs/en/monitoring-usage), [Costs](/docs/en/costs) |
19| [Review data handling](#review-data-handling) | Data retention and compliance posture | [Data usage](/docs/en/data-usage), [Security](/docs/en/security) |
2020
2121## Choose your API provider
2222
2323Claude Code connects to Claude through one of several API providers. Your choice affects billing, authentication, which compliance posture you inherit, and which Claude Code features your developers can use.
2424
25| Provider | Choose this when |
26| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
25| Provider | Choose this when |
26| :- | :- |
2727| Claude for Teams / Enterprise | You want Claude Code and claude.ai under one per-seat subscription with no infrastructure to run. This is the default recommendation. |
28| Claude Console | You're API-first or want pay-as-you-go billing |
29| Amazon Bedrock | You want to inherit existing AWS compliance controls and billing |
30| Google Cloud's Agent Platform | You want to inherit existing GCP compliance controls and billing |
31| Microsoft Foundry | You want to inherit existing Azure compliance controls and billing |
28| Claude Console | You're API-first or want pay-as-you-go billing |
29| Amazon Bedrock | You want to inherit existing AWS compliance controls and billing |
30| Google Cloud's Agent Platform | You want to inherit existing GCP compliance controls and billing |
31| Microsoft Foundry | You want to inherit existing Azure compliance controls and billing |
3232
3333Some Claude Code features require a claude.ai account. [Cloud sessions](/docs/en/claude-code-on-the-web), [Routines](/docs/en/routines), [Code Review](/docs/en/code-review), [Remote Control](/docs/en/remote-control), and the [Chrome extension](/docs/en/chrome) aren't available through Console API keys or cloud-provider credentials alone. If you deploy through Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry, plan whether developers also need Claude for Teams or Enterprise seats. Each feature page lists its plan requirements.
3434
from line 40
4040
4141Managed settings define organization policy. Claude Code checks the four sources in the table below in priority order. [How Claude Code combines managed sources](/docs/en/managed-settings#precedence-within-the-managed-tier) says which of them apply, what a policy helper changes, and how to compose every source. The table is the decision map.
4242
43| Mechanism | Delivery | Priority | Platforms |
44| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------- |
45| Server-managed | claude.ai admin console, or a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) for gateway sign-ins | Highest | All |
46| plist / registry policy | macOS: `com.anthropic.claudecode` plist<br />Windows: `HKLM\SOFTWARE\Policies\ClaudeCode` | High | macOS, Windows |
47| File-based managed | macOS: `/Library/Application Support/ClaudeCode/managed-settings.json`<br />Linux and WSL: `/etc/claude-code/managed-settings.json`<br />Windows: `C:\Program Files\ClaudeCode\managed-settings.json` | Medium | All |
48| Windows user registry | `HKCU\SOFTWARE\Policies\ClaudeCode` | Lowest | Windows only |
43| Mechanism | Delivery | Priority | Platforms |
44| :- | :- | :- | :- |
45| Server-managed | claude.ai admin console, or a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) for gateway sign-ins | Highest | All |
46| plist / registry policy | macOS: `com.anthropic.claudecode` plist<br />Windows: `HKLM\SOFTWARE\Policies\ClaudeCode` | High | macOS, Windows |
47| File-based managed | macOS: `/Library/Application Support/ClaudeCode/managed-settings.json`<br />Linux and WSL: `/etc/claude-code/managed-settings.json`<br />Windows: `C:\Program Files\ClaudeCode\managed-settings.json` | Medium | All |
48| Windows user registry | `HKCU\SOFTWARE\Policies\ClaudeCode` | Lowest | Windows only |
4949
5050Claude Code fetches server-managed settings at startup and refreshes them hourly during the session, with no endpoint infrastructure to deploy. Delivery through the claude.ai admin console requires a Claude for Teams or Enterprise plan. Deployments on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry can get the same remote delivery by running a [Claude apps gateway](/docs/en/claude-apps-gateway), or use one of the file-based or OS-level mechanisms instead.
5151
from line 81
8181
8282Managed settings can lock down tools, sandbox execution, restrict MCP servers and plugin sources, and control which hooks run. Each row is a control surface with the setting keys that drive it.
8383
84| Control | What it does | Key settings |
85| :------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
86| [Permission rules](/docs/en/permissions) | Allow, ask, or deny specific tools and commands | `permissions.allow`, `permissions.deny` |
87| [Permission lockdown](/docs/en/permissions#managed-only-settings) | Make managed settings the [only settings source of permission rules](/docs/en/settings-reference#allowmanagedpermissionrulesonly). Disable `--dangerously-skip-permissions` | `allowManagedPermissionRulesOnly`, `permissions.disableBypassPermissionsMode` |
88| [Starting permission mode](/docs/en/permission-modes#which-mode-a-session-starts-in) | Choose the permission mode your developers' terminal sessions start in instead of the built-in starting permission mode, or remove auto mode. [Switch permission modes](/docs/en/permission-modes#switch-permission-modes) lists when the VS Code extension reads a `defaultMode` you set | `permissions.defaultMode`, `permissions.disableAutoMode` |
89| [Sandboxing](/docs/en/sandboxing) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |
90| [Managed policy CLAUDE.md](/docs/en/memory#deploy-organization-wide-claude-md) | Org-wide instructions loaded in every session, can't be excluded | File at the managed policy path |
91| [MCP server control](/docs/en/managed-mcp) | Restrict which MCP servers users can add or connect to, deploy a fixed set, or provide remote servers to every user alongside their own | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`, `managedMcpServers`, or a deployed `managed-mcp.json` file |
92| [Plugin marketplace control](/docs/en/plugins/org#restrict-what-users-can-install) | Restrict which marketplace sources users can add and install from, reject the CLI flags that sideload plugins, agents, and MCP servers for a single run, block [`command` plugin sources](/docs/en/plugins/marketplace-reference#command-plugin-source), and allowlist which marketplaces' plugins can be suggested | `strictKnownMarketplaces`, `blockedMarketplaces`, `disableSideloadFlags`, `disableCommandPluginSources`, `pluginSuggestionMarketplaces` |
93| [Customization lockdown](/docs/en/settings-reference#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. Locking skills also stops the [skills your developers enable on claude.ai](/docs/en/skills#where-synced-skills-load) from syncing | `strictPluginOnlyCustomization` |
94| [Disable claude.ai sync](/docs/en/settings-reference#syncclaudeaiskills) | Stop Claude Code from loading the [skills](/docs/en/skills#how-synced-skills-behave) and [plugins](/docs/en/plugins/loading#synced-plugins) your developers enable on claude.ai. If you turn off Skills for your organization on claude.ai, Claude Code stops syncing both, and on v2.1.273 or later it also removes the ones it already synced. To stop either one without turning Skills off, set its key to `false` in managed settings | `syncClaudeAiSkills`, `syncClaudeAiPlugins` |
95| [Hook restrictions](/docs/en/settings-reference#allowmanagedhooksonly) | Restrict which hooks run and restrict HTTP hook URLs; see [what runs under `allowManagedHooksOnly`](/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) for the full effect list | `allowManagedHooksOnly`, `allowedHttpHookUrls` |
96| [Login enforcement](/docs/en/settings-reference#forceloginmethod) | Restrict login to a specific method or Anthropic organization. The method restriction applies across the VS Code extension, Agent SDK, `claude setup-token`, and `/install-github-app`, and the terminal's interactive login screen, reached by `/login` or first-run onboarding, pre-selects the method without enforcing it; Claude Code verifies the organization for claude.ai account logins in the terminal, VS Code extension, and Agent SDK, and doesn't check it for Claude Console logins or for [gateway](/docs/en/claude-apps-gateway) sign-in. Before v2.1.212, only terminal logins applied either key. When set, sessions authenticated by `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` are blocked at startup; cloud provider sessions aren't affected unless one of those credentials, or an API key saved by an earlier Claude Console login, is also present | `forceLoginMethod`, `forceLoginOrgUUID` |
97| [Disable agent view](/docs/en/agent-view#how-background-sessions-are-hosted) | Turn off `claude agents`, `--bg`, `/background`, and the on-demand supervisor | `disableAgentView` |
98| [Configure the corporate launcher](/docs/en/corporate-launcher) | Prefix the [background-agent supervisor](/docs/en/agent-view#how-background-sessions-are-hosted), its workers, and the [other covered background processes](/docs/en/corporate-launcher#what-the-launcher-covers) with a required corporate launcher instead of turning agent view off | `processWrapper` |
99| [Model restrictions](/docs/en/model-config#restrict-model-selection) | `availableModels` filters which models appear in the picker. Adding `enforceAvailableModels` also constrains the auto-selected default model. See [surface coverage](/docs/en/model-config#surface-coverage) for how this setting reaches the CLI, web, and IDE | `availableModels`, `enforceAvailableModels` |
100| [Effort cap](/docs/en/settings-reference#maxeffortlevel) | Cap the [effort level](/docs/en/model-config#adjust-effort-level) for every model or per model, on every provider | `maxEffortLevel` |
101| [Version floor](/docs/en/settings-reference#minimumversion) | Prevent auto-update from installing below an org-wide minimum | `minimumVersion` |
102| [Required version range](/docs/en/settings-reference#requiredminimumversion) | Refuse to start at all when the running version is outside an org-approved range. Stronger than `minimumVersion`, which only blocks downgrades | `requiredMinimumVersion`, `requiredMaximumVersion` |
103| [Telemetry opt-out](/docs/en/data-usage#telemetry-services) | Turn off Anthropic-bound usage metrics, error reports, and surveys on every device | `env` with `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set to `1`; the linked section lists the per-category variables |
84| Control | What it does | Key settings |
85| :- | :- | :- |
86| [Permission rules](/docs/en/permissions) | Allow, ask, or deny specific tools and commands | `permissions.allow`, `permissions.deny` |
87| [Permission lockdown](/docs/en/permissions#managed-only-settings) | Make managed settings the [only settings source of permission rules](/docs/en/settings-reference#allowmanagedpermissionrulesonly). Disable `--dangerously-skip-permissions` | `allowManagedPermissionRulesOnly`, `permissions.disableBypassPermissionsMode` |
88| [Starting permission mode](/docs/en/permission-modes#which-mode-a-session-starts-in) | Choose the permission mode your developers' terminal sessions start in instead of the built-in starting permission mode, or remove auto mode. [Switch permission modes](/docs/en/permission-modes#switch-permission-modes) lists when the VS Code extension reads a `defaultMode` you set | `permissions.defaultMode`, `permissions.disableAutoMode` |
89| [Sandboxing](/docs/en/sandboxing) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |
90| [Managed policy CLAUDE.md](/docs/en/memory#deploy-organization-wide-claude-md) | Org-wide instructions loaded in every session, can't be excluded | File at the managed policy path |
91| [MCP server control](/docs/en/managed-mcp) | Restrict which MCP servers users can add or connect to, deploy a fixed set, or provide remote servers to every user alongside their own | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`, `managedMcpServers`, or a deployed `managed-mcp.json` file |
92| [Plugin marketplace control](/docs/en/plugins/org#restrict-what-users-can-install) | Restrict which marketplace sources users can add and install from, reject the CLI flags that sideload plugins, agents, and MCP servers for a single run, block [`command` plugin sources](/docs/en/plugins/marketplace-reference#command-plugin-source), and allowlist which marketplaces' plugins can be suggested | `strictKnownMarketplaces`, `blockedMarketplaces`, `disableSideloadFlags`, `disableCommandPluginSources`, `pluginSuggestionMarketplaces` |
93| [Customization lockdown](/docs/en/settings-reference#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. Locking skills also stops the [skills your developers enable on claude.ai](/docs/en/skills#where-synced-skills-load) from syncing | `strictPluginOnlyCustomization` |
94| [Disable claude.ai sync](/docs/en/settings-reference#syncclaudeaiskills) | Stop Claude Code from loading the [skills](/docs/en/skills#how-synced-skills-behave) and [plugins](/docs/en/plugins/loading#synced-plugins) your developers enable on claude.ai. If you turn off Skills for your organization on claude.ai, Claude Code stops syncing both, and on v2.1.273 or later it also removes the ones it already synced. To stop either one without turning Skills off, set its key to `false` in managed settings | `syncClaudeAiSkills`, `syncClaudeAiPlugins` |
95| [Hook restrictions](/docs/en/settings-reference#allowmanagedhooksonly) | Restrict which hooks run and restrict HTTP hook URLs; see [what runs under `allowManagedHooksOnly`](/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) for the full effect list | `allowManagedHooksOnly`, `allowedHttpHookUrls` |
96| [Login enforcement](/docs/en/settings-reference#forceloginmethod) | Restrict login to a specific method or Anthropic organization. The method restriction applies across the VS Code extension, Agent SDK, `claude setup-token`, and `/install-github-app`, and the terminal's interactive login screen, reached by `/login` or first-run onboarding, pre-selects the method without enforcing it; Claude Code verifies the organization for claude.ai account logins in the terminal, VS Code extension, and Agent SDK, and doesn't check it for Claude Console logins or for [gateway](/docs/en/claude-apps-gateway) sign-in. Before v2.1.212, only terminal logins applied either key. When set, sessions authenticated by `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` are blocked at startup; cloud provider sessions aren't affected unless one of those credentials, or an API key saved by an earlier Claude Console login, is also present | `forceLoginMethod`, `forceLoginOrgUUID` |
97| [Disable agent view](/docs/en/agent-view#how-background-sessions-are-hosted) | Turn off `claude agents`, `--bg`, `/background`, and the on-demand supervisor | `disableAgentView` |
98| [Configure the corporate launcher](/docs/en/corporate-launcher) | Prefix the [background-agent supervisor](/docs/en/agent-view#how-background-sessions-are-hosted), its workers, and the [other covered background processes](/docs/en/corporate-launcher#what-the-launcher-covers) with a required corporate launcher instead of turning agent view off | `processWrapper` |
99| [Model restrictions](/docs/en/model-config#restrict-model-selection) | `availableModels` filters which models appear in the picker. Adding `enforceAvailableModels` also constrains the auto-selected default model. See [surface coverage](/docs/en/model-config#surface-coverage) for how this setting reaches the CLI, web, and IDE | `availableModels`, `enforceAvailableModels` |
100| [Effort cap](/docs/en/settings-reference#maxeffortlevel) | Cap the [effort level](/docs/en/model-config#adjust-effort-level) for every model or per model, on every provider | `maxEffortLevel` |
101| [Version floor](/docs/en/settings-reference#minimumversion) | Prevent auto-update from installing below an org-wide minimum | `minimumVersion` |
102| [Required version range](/docs/en/settings-reference#requiredminimumversion) | Refuse to start at all when the running version is outside an org-approved range. Stronger than `minimumVersion`, which only blocks downgrades | `requiredMinimumVersion`, `requiredMaximumVersion` |
103| [Telemetry opt-out](/docs/en/data-usage#telemetry-services) | Turn off Anthropic-bound usage metrics, error reports, and surveys on every device | `env` with `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set to `1`; the linked section lists the per-category variables |
104104
105105If your members sign in through claude.ai or the Anthropic API and you're on a Claude Enterprise plan, you can also govern models from your organization's admin settings without deploying anything:
106106
from line 120
120120
121121Choose monitoring based on what you need to report on. The dashboards, APIs, and spend controls differ between Claude for Teams or Enterprise plans and Claude Console organizations, so check the Availability column before you plan your reporting around a capability.
122122
123| Capability | What you get | Availability | Where to start |
124| :--------------------- | :---------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------- |
125| Usage monitoring | OpenTelemetry export of sessions, tools, and tokens | All providers | [Monitoring usage](/docs/en/monitoring-usage) |
126| Analytics dashboard | Adoption and contribution metrics with a leaderboard on Teams / Enterprise; per-user usage and spend metrics on Console | Teams / Enterprise at [claude.ai/analytics](https://claude.ai/analytics/claude-code), Console at [platform.claude.com/claude-code](https://platform.claude.com/claude-code) | [Analytics](/docs/en/analytics) |
127| Programmatic reporting | Per-user usage and cost data over an API | [Enterprise Analytics API](https://platform.claude.com/docs/en/api/admin/analytics) for Enterprise, [Claude Code Analytics API](https://platform.claude.com/docs/en/build-with-claude/claude-code-analytics-api) for Console | [Costs](/docs/en/costs#manage-costs-for-your-organization) |
128| Spend controls | Spend limits and rate limits | Admin settings for Teams / Enterprise, workspace limits for Console; on third-party clouds, cloud budget controls or a [Claude apps gateway](/docs/en/claude-apps-gateway) with per-user [spend limits](/docs/en/claude-apps-gateway-spend-limits) | [Costs](/docs/en/costs#manage-costs-for-your-organization) |
123| Capability | What you get | Availability | Where to start |
124| :- | :- | :- | :- |
125| Usage monitoring | OpenTelemetry export of sessions, tools, and tokens | All providers | [Monitoring usage](/docs/en/monitoring-usage) |
126| Analytics dashboard | Adoption and contribution metrics with a leaderboard on Teams / Enterprise; per-user usage and spend metrics on Console | Teams / Enterprise at [claude.ai/analytics](https://claude.ai/analytics/claude-code), Console at [platform.claude.com/claude-code](https://platform.claude.com/claude-code) | [Analytics](/docs/en/analytics) |
127| Programmatic reporting | Per-user usage and cost data over an API | [Enterprise Analytics API](https://platform.claude.com/docs/en/api/admin/analytics) for Enterprise, [Claude Code Analytics API](https://platform.claude.com/docs/en/build-with-claude/claude-code-analytics-api) for Console | [Costs](/docs/en/costs#manage-costs-for-your-organization) |
128| Spend controls | Spend limits and rate limits | Admin settings for Teams / Enterprise, workspace limits for Console; on third-party clouds, cloud budget controls or a [Claude apps gateway](/docs/en/claude-apps-gateway) with per-user [spend limits](/docs/en/claude-apps-gateway-spend-limits) | [Costs](/docs/en/costs#manage-costs-for-your-organization) |
129129
130130On Teams and Enterprise, per-user usage and spend numbers come from the [spend report](https://support.claude.com/en/articles/12883420-view-usage-analytics-for-team-and-enterprise-plans) in your organization's analytics settings, not the analytics dashboard. Cloud providers expose spend through AWS Cost Explorer, GCP Billing, or Azure Cost Management. For planning enterprise budgets across Claude chat, Claude Code, and Cowork, see the [Claude Enterprise consumption guide](https://support.claude.com/en/articles/14782391-claude-enterprise-consumption-guide).
131131
from line 133
133133
134134On Team, Enterprise, Claude API, and cloud provider plans, Anthropic doesn't train models on your code or prompts. Your API provider determines retention and compliance posture.
135135
136| Topic | What to know | Where to start |
137| :------------------------ | :--------------------------------------------------------------------------------------------------- | :--------------------------------------------- |
138| Data usage policy | What Anthropic collects, how long it's retained, what's never used for training | [Data usage](/docs/en/data-usage) |
136| Topic | What to know | Where to start |
137| :- | :- | :- |
138| Data usage policy | What Anthropic collects, how long it's retained, what's never used for training | [Data usage](/docs/en/data-usage) |
139139| Zero Data Retention (ZDR) | Nothing stored after the request completes. Available to qualified accounts on Claude for Enterprise | [Zero data retention](/docs/en/zero-data-retention) |
140| Security architecture | Network model, encryption, authentication, audit trail | [Security](/docs/en/security) |
140| Security architecture | Network model, encryption, authentication, audit trail | [Security](/docs/en/security) |
141141
142142If you need request-level audit logging or to route traffic by data sensitivity, place a gateway between developers and your provider: a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) records a per-request audit log with IdP identity, or use another [LLM gateway](/docs/en/llm-gateway). For regulatory requirements and certifications, see [Legal and compliance](/docs/en/legal-and-compliance).
143143
advisor Changed · +24 / -24 lines
from line 83
8383
8484The advisor must be at least as capable as the main model. The accepted advisors for each main model are:
8585
86| Main model | Accepted advisors | Notes |
87| ---------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------- |
88| Haiku 4.5 | Fable, Opus, Sonnet | Haiku can call the advisor but cannot act as one |
89| Sonnet 4.6 | Fable, Opus, Sonnet | |
90| Sonnet 5.5 or Sonnet 5 | Fable, Opus 4.7 or later, Sonnet 5 or later | A Sonnet 4.6 advisor is rejected, and the API refuses an Opus 4.6 advisor |
91| Opus 4.6 | Fable, Opus, Sonnet 5 or later | A Sonnet 4.6 advisor is rejected |
92| Opus 4.7 or Opus 4.8 | Fable, and Opus 4.7 or later | An Opus 4.6 or Sonnet advisor is rejected |
93| Opus 5.5 or Opus 5 | Fable, and Opus 5 or later | An Opus 4.6 or Sonnet advisor is rejected, and the API refuses an Opus 4.7 or Opus 4.8 advisor |
94| Fable 5 | Fable 5.1 or Fable 5 | An Opus or Sonnet advisor is rejected |
95| Fable 5.1 | Fable 5.1 | An Opus or Sonnet advisor is rejected, and the API refuses a Fable 5 advisor |
86| Main model | Accepted advisors | Notes |
87| - | - | - |
88| Haiku 4.5 | Fable, Opus, Sonnet | Haiku can call the advisor but cannot act as one |
89| Sonnet 4.6 | Fable, Opus, Sonnet | |
90| Sonnet 5.5 or Sonnet 5 | Fable, Opus 4.7 or later, Sonnet 5 or later | A Sonnet 4.6 advisor is rejected, and the API refuses an Opus 4.6 advisor |
91| Opus 4.6 | Fable, Opus, Sonnet 5 or later | A Sonnet 4.6 advisor is rejected |
92| Opus 4.7 or Opus 4.8 | Fable, and Opus 4.7 or later | An Opus 4.6 or Sonnet advisor is rejected |
93| Opus 5.5 or Opus 5 | Fable, and Opus 5 or later | An Opus 4.6 or Sonnet advisor is rejected, and the API refuses an Opus 4.7 or Opus 4.8 advisor |
94| Fable 5 | Fable 5.1 or Fable 5 | An Opus or Sonnet advisor is rejected |
95| Fable 5.1 | Fable 5.1 | An Opus or Sonnet advisor is rejected, and the API refuses a Fable 5 advisor |
9696
9797Fable 5.1 requires Claude Code v2.1.257 or later. Both Fable models require [Fable access](/docs/en/model-config#work-with-fable).
9898
from line 118
118118
119119Any accepted pairing works. These combinations balance cost against capability in different ways:
120120
121| Pairing | When to use |
122| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
123| Sonnet main + Opus advisor | Sonnet handles routine work and escalates planning, ambiguous failures, and completion checks to Opus |
124| Sonnet main + Fable advisor | Fable guidance at decision points without running Fable throughout. Requires Fable access |
125| Haiku main + Opus advisor | Lowest-cost main model with strong planning. Expect higher cost than Haiku alone but lower than switching the main model to Sonnet or Opus |
126| Opus main + Opus advisor | A second Opus reviews the first. Useful for high-stakes tasks where an independent check matters more than cost |
127| Fable main + Fable advisor | Highest-capability pairing when Fable is available. Claude Code doesn't apply an Opus or Sonnet advisor to a Fable main model |
128| Sonnet main + Sonnet advisor | A lower-cost second opinion for catching routine oversights |
121| Pairing | When to use |
122| - | - |
123| Sonnet main + Opus advisor | Sonnet handles routine work and escalates planning, ambiguous failures, and completion checks to Opus |
124| Sonnet main + Fable advisor | Fable guidance at decision points without running Fable throughout. Requires Fable access |
125| Haiku main + Opus advisor | Lowest-cost main model with strong planning. Expect higher cost than Haiku alone but lower than switching the main model to Sonnet or Opus |
126| Opus main + Opus advisor | A second Opus reviews the first. Useful for high-stakes tasks where an independent check matters more than cost |
127| Fable main + Fable advisor | Highest-capability pairing when Fable is available. Claude Code doesn't apply an Opus or Sonnet advisor to a Fable main model |
128| Sonnet main + Sonnet advisor | A lower-cost second opinion for catching routine oversights |
129129
130130## When Claude consults the advisor
131131
from line 186
186186
187187The advisor is one of several ways to combine model strengths. Pick based on when you want a second model involved.
188188
189| Approach | When the stronger model runs | How it starts |
190| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
191| Advisor tool | At decision points mid-task | Claude calls it when it needs guidance |
192| [`opusplan`](/docs/en/model-config#opusplan-model-setting) | During plan mode when [allowed by `availableModels`](/docs/en/model-config#restrict-model-selection), then switches to Sonnet for execution | You enter plan mode |
193| [Subagents](/docs/en/sub-agents#choose-a-model) with `model` set | For the entire delegated subtask | Claude delegates, or you invoke the subagent |
194| [`/model`](/docs/en/model-config#setting-your-model) | From the next request onward | You switch models |
189| Approach | When the stronger model runs | How it starts |
190| - | - | - |
191| Advisor tool | At decision points mid-task | Claude calls it when it needs guidance |
192| [`opusplan`](/docs/en/model-config#opusplan-model-setting) | During plan mode when [allowed by `availableModels`](/docs/en/model-config#restrict-model-selection), then switches to Sonnet for execution | You enter plan mode |
193| [Subagents](/docs/en/sub-agents#choose-a-model) with `model` set | For the entire delegated subtask | Claude delegates, or you invoke the subagent |
194| [`/model`](/docs/en/model-config#setting-your-model) | From the next request onward | You switch models |
195195
196196## See also
197197
agent-sdk/agent-loop Changed · +48 / -48 lines
from line 148
148148
149149The SDK includes the same tools that power Claude Code:
150150
151| Category | Tools | What they do |
152| :------------------ | :-------------------------------------------------------------- | :-------------------------------------------------------------------------- |
153| **File operations** | `Read`, `Edit`, `Write` | Read, modify, and create files |
154| **Search** | `Glob`, `Grep` | Find files by pattern, search content with regex |
155| **Execution** | `Bash` | Run shell commands, scripts, git operations |
156| **Web** | `WebSearch`, `WebFetch` | Search the web, fetch and parse pages |
157| **Discovery** | `ToolSearch` | Dynamically find and load tools on-demand instead of preloading all of them |
158| **Orchestration** | `Agent`, `Skill`, `AskUserQuestion`, `TaskCreate`, `TaskUpdate` | Spawn subagents, invoke skills, ask the user, track tasks |
151| Category | Tools | What they do |
152| :- | :- | :- |
153| **File operations** | `Read`, `Edit`, `Write` | Read, modify, and create files |
154| **Search** | `Glob`, `Grep` | Find files by pattern, search content with regex |
155| **Execution** | `Bash` | Run shell commands, scripts, git operations |
156| **Web** | `WebSearch`, `WebFetch` | Search the web, fetch and parse pages |
157| **Discovery** | `ToolSearch` | Dynamically find and load tools on-demand instead of preloading all of them |
158| **Orchestration** | `Agent`, `Skill`, `AskUserQuestion`, `TaskCreate`, `TaskUpdate` | Spawn subagents, invoke skills, ask the user, track tasks |
159159
160160On the [models that don't get the task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability), Claude Code provides `TaskCreate` and `TaskUpdate` only when you opt in.
161161
from line 189
189189
190190### Turns and budget
191191
192| Option | What it controls | Default |
193| :--------------------------------------------- | :--------------------------- | :------- |
194| Max turns (`max_turns` / `maxTurns`) | Maximum tool-use round trips | No limit |
192| Option | What it controls | Default |
193| :- | :- | :- |
194| Max turns (`max_turns` / `maxTurns`) | Maximum tool-use round trips | No limit |
195195| Max budget (`max_budget_usd` / `maxBudgetUsd`) | Maximum cost before stopping | No limit |
196196
197197When either limit is hit, the SDK returns a `ResultMessage` with a corresponding error subtype (`error_max_turns` or `error_max_budget_usd`). See [Handle the result](#handle-the-result) for how to check these subtypes and [`ClaudeAgentOptions`](/docs/en/agent-sdk/python#claudeagentoptions) / [`Options`](/docs/en/agent-sdk/typescript#options) for syntax.
from line 204
204204
205205The `effort` option controls how much reasoning Claude applies. Lower effort levels use fewer tokens per turn and reduce cost. Not all models support the effort parameter. See [Effort](https://platform.claude.com/docs/en/build-with-claude/effort) for which models support it.
206206
207| Level | Behavior | Good for |
208| :--------- | :-------------------------------- | :--------------------------------------------------------------------------------------------- |
209| `"low"` | Minimal reasoning, fast responses | File lookups, listing directories |
210| `"medium"` | Balanced reasoning | Routine edits, standard tasks |
211| `"high"` | Thorough analysis | Refactors, debugging |
212| `"xhigh"` | Extended reasoning depth | Coding and agentic tasks on the [models that support it](/docs/en/model-config#adjust-effort-level) |
213| `"max"` | Maximum reasoning depth | Multi-step problems requiring deep analysis |
207| Level | Behavior | Good for |
208| :- | :- | :- |
209| `"low"` | Minimal reasoning, fast responses | File lookups, listing directories |
210| `"medium"` | Balanced reasoning | Routine edits, standard tasks |
211| `"high"` | Thorough analysis | Refactors, debugging |
212| `"xhigh"` | Extended reasoning depth | Coding and agentic tasks on the [models that support it](/docs/en/model-config#adjust-effort-level) |
213| `"max"` | Maximum reasoning depth | Multi-step problems requiring deep analysis |
214214
215215If you don't set `effort`, Claude Code resolves the effort level itself, in the order [Adjust effort level](/docs/en/model-config#adjust-effort-level) describes.
216216
from line 224
224224
225225The permission mode option (`permission_mode` in Python, `permissionMode` in TypeScript) controls whether the agent asks for approval before using tools:
226226
227| Mode | Behavior | Use case |
228| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
229| `"default"` | Tool calls that need approval and aren't covered by allow rules trigger your `canUseTool` callback; no callback means deny | Interactive applications with a custom approval callback |
230| `"acceptEdits"` | Auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.); other Bash commands follow default rules | You trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory |
231| `"plan"` | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback | You want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made |
232| `"dontAsk"` | Never prompts. Tools pre-approved by [permission rules](/docs/en/settings-reference#permission-settings) run, and so do calls that need no approval in `default` mode, such as file reads inside your working directories; every call that would otherwise prompt is denied. `AskUserQuestion`, connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool) are denied even if you've allowed them | You want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent |
233| `"auto"` | Uses a model classifier to approve or deny permission prompts. See [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) for availability and behavior | Autonomous agents that still want safety guardrails on tool use |
234| `"bypassPermissions"` | Runs all allowed tools without asking, except tools matched by an explicit [`ask` rule](/docs/en/settings-reference#permission-settings), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction. The [cross-session messaging safeguards](/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode) still apply. See [How permissions are evaluated](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) for the precedence order. In the TypeScript SDK, also requires `allowDangerouslySkipPermissions: true` in `options`. Can't be used when running as root on Unix. Use only in isolated environments where the agent's actions can't affect systems you care about | CI, containers, or other isolated environments |
227| Mode | Behavior | Use case |
228| :- | :- | :- |
229| `"default"` | Tool calls that need approval and aren't covered by allow rules trigger your `canUseTool` callback; no callback means deny | Interactive applications with a custom approval callback |
230| `"acceptEdits"` | Auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.); other Bash commands follow default rules | You trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory |
231| `"plan"` | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback | You want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made |
232| `"dontAsk"` | Never prompts. Tools pre-approved by [permission rules](/docs/en/settings-reference#permission-settings) run, and so do calls that need no approval in `default` mode, such as file reads inside your working directories; every call that would otherwise prompt is denied. `AskUserQuestion`, connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool) are denied even if you've allowed them | You want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent |
233| `"auto"` | Uses a model classifier to approve or deny permission prompts. See [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) for availability and behavior | Autonomous agents that still want safety guardrails on tool use |
234| `"bypassPermissions"` | Runs all allowed tools without asking, except tools matched by an explicit [`ask` rule](/docs/en/settings-reference#permission-settings), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), and tools that require user interaction. The [cross-session messaging safeguards](/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode) still apply. See [How permissions are evaluated](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) for the precedence order. In the TypeScript SDK, also requires `allowDangerouslySkipPermissions: true` in `options`. Can't be used when running as root on Unix. Use only in isolated environments where the agent's actions can't affect systems you care about | CI, containers, or other isolated environments |
235235
236236For interactive applications, use `"default"` with a tool approval callback to surface approval prompts. For autonomous agents on a dev machine, `"acceptEdits"` auto-approves file edits and common filesystem commands (`mkdir`, `touch`, `mv`, `cp`, etc.) while still gating other `Bash` commands behind allow rules. Reserve `"bypassPermissions"` for CI, containers, or other isolated environments. See [Permissions](/docs/en/agent-sdk/permissions) for full details.
237237
from line 247
247247
248248Here's how each component affects context in the SDK:
249249
250| Source | When it loads | Impact |
251| :----------------------- | :------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
252| **System prompt** | Every request | Small fixed cost, always present |
253| **CLAUDE.md files** | Session start, via [`settingSources`](/docs/en/agent-sdk/claude-code-features) | Full content in every request (but prompt-cached, so only the first request pays full cost) |
254| **Tool definitions** | Every request; MCP schemas deferred by default | Built-in tool schemas load every request. [Tool search](/docs/en/agent-sdk/mcp#mcp-tool-search) defers MCP tool schemas by default, falling back to upfront loading on unsupported models and certain platforms. See [Configure tool search](/docs/en/agent-sdk/tool-search#configure-tool-search) for the full matrix |
255| **Conversation history** | Accumulates over turns | Grows with each turn: prompts, responses, tool inputs, tool outputs |
256| **Skill descriptions** | Session start, via setting sources | Short summaries; full content loads only when invoked |
250| Source | When it loads | Impact |
251| :- | :- | :- |
252| **System prompt** | Every request | Small fixed cost, always present |
253| **CLAUDE.md files** | Session start, via [`settingSources`](/docs/en/agent-sdk/claude-code-features) | Full content in every request (but prompt-cached, so only the first request pays full cost) |
254| **Tool definitions** | Every request; MCP schemas deferred by default | Built-in tool schemas load every request. [Tool search](/docs/en/agent-sdk/mcp#mcp-tool-search) defers MCP tool schemas by default, falling back to upfront loading on unsupported models and certain platforms. See [Configure tool search](/docs/en/agent-sdk/tool-search#configure-tool-search) for the full matrix |
255| **Conversation history** | Accumulates over turns | Grows with each turn: prompts, responses, tool inputs, tool outputs |
256| **Skill descriptions** | Session start, via setting sources | Short summaries; full content loads only when invoked |
257257
258258Large tool outputs consume significant context. Reading a big file or running a command with verbose output can use thousands of tokens in a single turn. Context accumulates across turns, so longer sessions with many tool calls build up significantly more context than short ones.
259259
from line 310
310310
311311When the loop ends, the `ResultMessage` tells you what happened and gives you the output. The `subtype` field (available in both SDKs) is the primary way to check termination state.
312312
313| Result subtype | What happened | `result` field available? |
314| :------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------: |
315| `success` | Claude finished the task normally | Yes |
316| `error_max_turns` | Hit the `maxTurns` limit before finishing | No |
317| `error_max_budget_usd` | Hit the `maxBudgetUsd` limit before finishing | No |
318| `error_during_execution` | An error interrupted the loop (for example, a cancelled request) | No |
319| `error_max_structured_output_retries` | No valid structured output was produced within the configured retry limit: every attempt failed validation, or a model fallback retracted the completed output with no successful retry | No |
313| Result subtype | What happened | `result` field available? |
314| :- | :- | :-: |
315| `success` | Claude finished the task normally | Yes |
316| `error_max_turns` | Hit the `maxTurns` limit before finishing | No |
317| `error_max_budget_usd` | Hit the `maxBudgetUsd` limit before finishing | No |
318| `error_during_execution` | An error interrupted the loop (for example, a cancelled request) | No |
319| `error_max_structured_output_retries` | No valid structured output was produced within the configured retry limit: every attempt failed validation, or a model fallback retracted the completed output with no successful retry | No |
320320
321321The `result` field holds the final text output and is only present on the `success` variant, so always check the subtype before reading it.
322322
from line 342
342342
343343[Hooks](/docs/en/agent-sdk/hooks) are callbacks that fire at specific points in the loop: before a tool runs, after it returns, when the agent finishes, and so on. Some commonly used hooks are:
344344
345| Hook | When it fires | Common uses |
346| :------------------------------- | :---------------------------------- | :----------------------------------------- |
347| `PreToolUse` | Before a tool executes | Validate inputs, block dangerous commands |
348| `PostToolUse` | After a tool returns | Audit outputs, trigger side effects |
349| `UserPromptSubmit` | When a prompt is sent | Inject additional context into prompts |
350| `Stop` | When the agent finishes | Validate the result, save session state |
351| `SubagentStart` / `SubagentStop` | When a subagent spawns or completes | Track and aggregate parallel task results |
352| `PreCompact` | Before context compaction | Archive full transcript before summarizing |
345| Hook | When it fires | Common uses |
346| :- | :- | :- |
347| `PreToolUse` | Before a tool executes | Validate inputs, block dangerous commands |
348| `PostToolUse` | After a tool returns | Audit outputs, trigger side effects |
349| `UserPromptSubmit` | When a prompt is sent | Inject additional context into prompts |
350| `Stop` | When the agent finishes | Validate the result, save session state |
351| `SubagentStart` / `SubagentStop` | When a subagent spawns or completes | Track and aggregate parallel task results |
352| `PreCompact` | Before context compaction | Archive full transcript before summarizing |
353353
354354Hooks run in your application process, not inside the agent's context window, so they don't consume context. Hooks can also short-circuit the loop: a `PreToolUse` hook that rejects a tool call prevents it from executing, and Claude receives the rejection message instead.
355355
agent-sdk/claude-code-features Changed · +33 / -33 lines
from line 69
6969
7070Each source loads settings from a specific location, where `<cwd>` is the working directory you pass via the `cwd` option, or the process's current directory if unset. For the full type definition, see [`SettingSource`](/docs/en/agent-sdk/typescript#settingsource) (TypeScript) or [`SettingSource`](/docs/en/agent-sdk/python#settingsource) (Python).
7171
72| Source | What it loads | Location |
73| :---------- | :--------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72| Source | What it loads | Location |
73| :- | :- | :- |
7474| `"project"` | Project `settings.json` and hooks; project CLAUDE.md and `.claude/rules/*.md`; project skills, commands, and subagents | `<cwd>/.claude/` for `settings.json` and hooks; `<cwd>` and every parent directory for CLAUDE.md and rules; `<cwd>` and every parent directory up to the repository root for skills, commands, and subagents, plus the `.claude/skills/`, `.claude/commands/`, and `.claude/agents/` folders of each directory you pass through the `additionalDirectories` or `add_dirs` option, which the SDK passes to Claude Code as [`--add-dir`](/docs/en/permissions#additional-directories-grant-file-access-not-configuration) |
75| `"user"` | User `settings.json`; user CLAUDE.md and `~/.claude/rules/*.md`; user skills, commands, and subagents | `~/.claude/` for `settings.json`, CLAUDE.md, and rules; `~/.claude/skills/`, `~/.claude/commands/`, and `~/.claude/agents/` for skills, commands, and subagents |
76| `"local"` | CLAUDE.local.md, `.claude/settings.local.json` | `<cwd>/.claude/` for `settings.local.json`; `<cwd>` and every parent directory for CLAUDE.local.md |
75| `"user"` | User `settings.json`; user CLAUDE.md and `~/.claude/rules/*.md`; user skills, commands, and subagents | `~/.claude/` for `settings.json`, CLAUDE.md, and rules; `~/.claude/skills/`, `~/.claude/commands/`, and `~/.claude/agents/` for skills, commands, and subagents |
76| `"local"` | CLAUDE.local.md, `.claude/settings.local.json` | `<cwd>/.claude/` for `settings.local.json`; `<cwd>` and every parent directory for CLAUDE.local.md |
7777
7878Omitting `settingSources` is equivalent to `["user", "project", "local"]`.
7979
from line 83
8383
8484`settingSources` covers user, project, and local settings. A few inputs are read regardless of its value:
8585
86| Input | Behavior | To disable |
87| :------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
88| Managed policy settings | Endpoint-managed policy, such as an MDM plist, registry policy, or managed settings file, loads from the host. [Server-managed settings](/docs/en/server-managed-settings) are fetched on an [eligible configuration](/docs/en/server-managed-settings#platform-availability) when the session authenticates with a qualifying credential, such as an organization OAuth login, a directly configured API key, or a `user_oauth` [Anthropic profile](/docs/en/authentication#anthropic-profiles-and-federation-credentials) | Endpoint policy: remove the managed settings file, plist, or registry policy from the host. Server-managed settings: an [Owner](/docs/en/server-managed-settings#access-control) in your Claude organization controls them; you can't disable them from the SDK |
89| `~/.claude.json` global config | Always read | Relocate with `CLAUDE_CONFIG_DIR` in `env` |
90| Auto memory at `~/.claude/projects/<project>/memory/` | Loaded into the system prompt at session start. The agent writes new memories there with the standard `Write` and `Edit` tools rather than a dedicated memory tool, so those tools must be enabled for the agent to save memories | Set `autoMemoryEnabled: false` in settings, or `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` in `env` |
91| [claude.ai MCP connectors](/docs/en/mcp#use-mcp-servers-from-claude-ai) | Loaded when the session authenticates with your claude.ai login. Not loaded when `CLAUDE_CODE_OAUTH_TOKEN` holds a token from [`claude setup-token`](/docs/en/authentication#generate-a-long-lived-token), which can only make model requests. Passing `mcpServers: {}` does not suppress the connectors | Set `strictMcpConfig: true`, [`disableClaudeAiConnectors: true`](/docs/en/mcp#disable-claude-ai-connectors) in settings, or `ENABLE_CLAUDEAI_MCP_SERVERS=false` in `env` |
92| [`sandbox.credentials`](/docs/en/sandboxing#protect-credentials) `deny` entries and file `mask` entries in `~/.claude/settings.json` | When the [command sandbox](/docs/en/sandboxing) runs, Claude Code applies the `deny` entries and keeps the `credentials.files` `mask` entries as restrictions even when `settingSources` excludes user settings. Claude Code uses these entries only to narrow what sandboxed commands can access | Remove the entries from `~/.claude/settings.json` |
86| Input | Behavior | To disable |
87| :- | :- | :- |
88| Managed policy settings | Endpoint-managed policy, such as an MDM plist, registry policy, or managed settings file, loads from the host. [Server-managed settings](/docs/en/server-managed-settings) are fetched on an [eligible configuration](/docs/en/server-managed-settings#platform-availability) when the session authenticates with a qualifying credential, such as an organization OAuth login, a directly configured API key, or a `user_oauth` [Anthropic profile](/docs/en/authentication#anthropic-profiles-and-federation-credentials) | Endpoint policy: remove the managed settings file, plist, or registry policy from the host. Server-managed settings: an [Owner](/docs/en/server-managed-settings#access-control) in your Claude organization controls them; you can't disable them from the SDK |
89| `~/.claude.json` global config | Always read | Relocate with `CLAUDE_CONFIG_DIR` in `env` |
90| Auto memory at `~/.claude/projects/<project>/memory/` | Loaded into the system prompt at session start. The agent writes new memories there with the standard `Write` and `Edit` tools rather than a dedicated memory tool, so those tools must be enabled for the agent to save memories | Set `autoMemoryEnabled: false` in settings, or `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` in `env` |
91| [claude.ai MCP connectors](/docs/en/mcp#use-mcp-servers-from-claude-ai) | Loaded when the session authenticates with your claude.ai login. Not loaded when `CLAUDE_CODE_OAUTH_TOKEN` holds a token from [`claude setup-token`](/docs/en/authentication#generate-a-long-lived-token), which can only make model requests. Passing `mcpServers: {}` does not suppress the connectors | Set `strictMcpConfig: true`, [`disableClaudeAiConnectors: true`](/docs/en/mcp#disable-claude-ai-connectors) in settings, or `ENABLE_CLAUDEAI_MCP_SERVERS=false` in `env` |
92| [`sandbox.credentials`](/docs/en/sandboxing#protect-credentials) `deny` entries and file `mask` entries in `~/.claude/settings.json` | When the [command sandbox](/docs/en/sandboxing) runs, Claude Code applies the `deny` entries and keeps the `credentials.files` `mask` entries as restrictions even when `settingSources` excludes user settings. Claude Code uses these entries only to narrow what sandboxed commands can access | Remove the entries from `~/.claude/settings.json` |
9393
9494<Warning>
9595 Do not rely on default `query()` options for multi-tenant isolation. Because the inputs above are read regardless of `settingSources`, an SDK process can pick up host-level configuration and per-directory memory. For multi-tenant deployments, run each tenant in its own filesystem and set `settingSources: []` plus `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` in `env`. [Server-managed settings](/docs/en/server-managed-settings) are fetched when the process authenticates with an organization credential; filesystem isolation does not remove them. See [Secure deployment](/docs/en/agent-sdk/secure-deployment).
from line 101
101101
102102### CLAUDE.md load locations
103103
104| Level | Location | When loaded |
105| :-------------------- | :---------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- |
106| Project (root) | `<cwd>/CLAUDE.md` or `<cwd>/.claude/CLAUDE.md` | `settingSources` includes `"project"` |
107| Project rules | `<cwd>/.claude/rules/*.md` and `.claude/rules/*.md` in every parent directory | `settingSources` includes `"project"` |
108| Project (parent dirs) | `CLAUDE.md` files in directories above `cwd` | `settingSources` includes `"project"`, loaded at session start |
109| Project (child dirs) | `CLAUDE.md` files in subdirectories of `cwd` | `settingSources` includes `"project"`, loaded on demand when the agent reads a file in that subtree |
110| Local | `<cwd>/CLAUDE.local.md` and `CLAUDE.local.md` in every parent directory | `settingSources` includes `"local"` |
111| User | `~/.claude/CLAUDE.md` | `settingSources` includes `"user"` |
112| User rules | `~/.claude/rules/*.md` | `settingSources` includes `"user"` |
104| Level | Location | When loaded |
105| :- | :- | :- |
106| Project (root) | `<cwd>/CLAUDE.md` or `<cwd>/.claude/CLAUDE.md` | `settingSources` includes `"project"` |
107| Project rules | `<cwd>/.claude/rules/*.md` and `.claude/rules/*.md` in every parent directory | `settingSources` includes `"project"` |
108| Project (parent dirs) | `CLAUDE.md` files in directories above `cwd` | `settingSources` includes `"project"`, loaded at session start |
109| Project (child dirs) | `CLAUDE.md` files in subdirectories of `cwd` | `settingSources` includes `"project"`, loaded on demand when the agent reads a file in that subtree |
110| Local | `<cwd>/CLAUDE.local.md` and `CLAUDE.local.md` in every parent directory | `settingSources` includes `"local"` |
111| User | `~/.claude/CLAUDE.md` | `settingSources` includes `"user"` |
112| User rules | `~/.claude/rules/*.md` | `settingSources` includes `"user"` |
113113
114114All levels are additive: if both project and user CLAUDE.md files exist, the agent sees both. There is no hard precedence rule between levels; if instructions conflict, the outcome depends on how Claude interprets them. Write non-conflicting rules, or state precedence explicitly in the more specific file ("These project instructions override any conflicting user-level defaults").
115115
from line 267
267267
268268### When to use which hook type
269269
270| Hook type | Best for |
271| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
272| **Filesystem** (`settings.json`) | Sharing hooks between CLI and SDK sessions. Supports `"command"` (shell scripts), `"http"` (POST to an endpoint), `"mcp_tool"` (call a connected MCP server's tool), `"prompt"` (LLM evaluates a prompt), and `"agent"` (spawns a verifier agent). These fire in the main agent and any subagents it spawns. |
273| **Programmatic** (callbacks in `query()`) | Application-specific logic, structured decisions, and in-process integration. These also fire inside subagents. The hook input, the callback's first argument, carries `agent_id` and `agent_type` fields that identify which agent fired the hook. |
270| Hook type | Best for |
271| :- | :- |
272| **Filesystem** (`settings.json`) | Sharing hooks between CLI and SDK sessions. Supports `"command"` (shell scripts), `"http"` (POST to an endpoint), `"mcp_tool"` (call a connected MCP server's tool), `"prompt"` (LLM evaluates a prompt), and `"agent"` (spawns a verifier agent). These fire in the main agent and any subagents it spawns. |
273| **Programmatic** (callbacks in `query()`) | Application-specific logic, structured decisions, and in-process integration. These also fire inside subagents. The hook input, the callback's first argument, carries `agent_id` and `agent_type` fields that identify which agent fired the hook. |
274274
275275<Note>
276276 The TypeScript SDK supports additional hook events beyond Python, including `SessionStart`, `SessionEnd`, `TeammateIdle`, and `TaskCompleted`. See the [hooks guide](/docs/en/agent-sdk/hooks) for the full event compatibility table.
from line 282
282282
283283The Agent SDK gives you access to several ways to extend your agent's behavior. If you're unsure which to use, this table maps common goals to the right approach.
284284
285| What you want to do | Use | SDK surface |
286| :------------------------------------------------------------------------------------------------ | :-------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- |
287| Set project conventions your agent always follows | [CLAUDE.md](/docs/en/memory) | `settingSources: ["project"]` loads it automatically |
288| Give the agent reference material it loads when relevant | [Skills](/docs/en/agent-sdk/skills) | `settingSources` + `skills` option |
289| Run a reusable workflow (deploy, review, release) | [User-invocable skills](/docs/en/agent-sdk/skills) | `settingSources` + `skills` option |
290| Delegate an isolated subtask to a fresh context (research, review) | [Subagents](/docs/en/agent-sdk/subagents) | `agents` parameter + `allowedTools: ["Agent"]` |
291| Coordinate multiple Claude Code instances with shared task lists and direct inter-agent messaging | [Agent teams](/docs/en/agent-teams) | Not directly configured via SDK options. Agent teams are a CLI feature where one session acts as the team lead, coordinating work across independent teammates |
292| Run deterministic logic on tool calls (audit, block, transform) | [Hooks](/docs/en/agent-sdk/hooks) | `hooks` parameter with callbacks, or shell scripts loaded via `settingSources` |
293| Give Claude structured tool access to an external service | [MCP](/docs/en/agent-sdk/mcp) | `mcpServers` parameter |
285| What you want to do | Use | SDK surface |
286| :- | :- | :- |
287| Set project conventions your agent always follows | [CLAUDE.md](/docs/en/memory) | `settingSources: ["project"]` loads it automatically |
288| Give the agent reference material it loads when relevant | [Skills](/docs/en/agent-sdk/skills) | `settingSources` + `skills` option |
289| Run a reusable workflow (deploy, review, release) | [User-invocable skills](/docs/en/agent-sdk/skills) | `settingSources` + `skills` option |
290| Delegate an isolated subtask to a fresh context (research, review) | [Subagents](/docs/en/agent-sdk/subagents) | `agents` parameter + `allowedTools: ["Agent"]` |
291| Coordinate multiple Claude Code instances with shared task lists and direct inter-agent messaging | [Agent teams](/docs/en/agent-teams) | Not directly configured via SDK options. Agent teams are a CLI feature where one session acts as the team lead, coordinating work across independent teammates |
292| Run deterministic logic on tool calls (audit, block, transform) | [Hooks](/docs/en/agent-sdk/hooks) | `hooks` parameter with callbacks, or shell scripts loaded via `settingSources` |
293| Give Claude structured tool access to an external service | [MCP](/docs/en/agent-sdk/mcp) | `mcpServers` parameter |
294294
295295Every feature you enable adds to your agent's context window. For per-feature costs and how these features layer together, see [Extend Claude Code](/docs/en/features-overview#understand-context-costs).
296296
agent-sdk/configuration Changed · +19 / -19 lines
from line 266
266266
267267The table below maps each option to the feature it configures. For options this page doesn't cover, see the [TypeScript](/docs/en/agent-sdk/typescript#options) and [Python](/docs/en/agent-sdk/python#claudeagentoptions) references. If you know your goal but not which option serves it, start from [Choose the right feature](/docs/en/agent-sdk/claude-code-features#choose-the-right-feature).
268268
269| TypeScript | Python | Controls | Covered in |
270| ------------------------- | --------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
271| `permissionMode` | `permission_mode` | What the agent can do without approval | [Configure permissions](/docs/en/agent-sdk/permissions) |
272| `allowedTools` | `allowed_tools` | Which tool calls are pre-approved | [Configure permissions](/docs/en/agent-sdk/permissions) |
273| `canUseTool` | `can_use_tool` | Your approval callback for tool calls | [Handle tool approval requests](/docs/en/agent-sdk/user-input#handle-tool-approval-requests) |
274| `systemPrompt` | `system_prompt` | The agent's instructions | [Modifying system prompts](/docs/en/agent-sdk/modifying-system-prompts) |
275| `settingSources` | `setting_sources` | Which filesystem settings load | [Use Claude Code features in the SDK](/docs/en/agent-sdk/claude-code-features) |
276| `mcpServers` | `mcp_servers` | External tool servers | [Connect to external tools with MCP](/docs/en/agent-sdk/mcp) |
277| `agents` | `agents` | Subagent definitions | [Subagents](/docs/en/agent-sdk/subagents) |
278| `hooks` | `hooks` | Callbacks at lifecycle points | [Hooks](/docs/en/agent-sdk/hooks) |
279| `skills` | `skills` | Which skills load | [Extend agents with skills](/docs/en/agent-sdk/skills) |
280| `plugins` | `plugins` | Which plugins load | [Plugins](/docs/en/agent-sdk/plugins) |
281| `outputFormat` | `output_format` | Structured output schemas | [Structured outputs](/docs/en/agent-sdk/structured-outputs) |
282| `resume` | `resume` | Continuing a stored session | [Sessions](/docs/en/agent-sdk/sessions) |
283| `forkSession` | `fork_session` | Branching a session | [Sessions](/docs/en/agent-sdk/sessions) |
284| `sessionStore` | `session_store` | External session persistence | [Session storage](/docs/en/agent-sdk/session-storage) |
285| `enableFileCheckpointing` | `enable_file_checkpointing` | Rewindable file edits | [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
286| `effort` | `effort` | How much work Claude puts into responses | [Effort level](/docs/en/agent-sdk/agent-loop#effort-level) |
287| `sandbox` | `sandbox` | Sandbox behavior for tool execution | [TypeScript](/docs/en/agent-sdk/typescript#sandbox-configuration) and [Python](/docs/en/agent-sdk/python#sandbox-configuration) references, with deployment context in [Secure deployment](/docs/en/agent-sdk/secure-deployment) |
269| TypeScript | Python | Controls | Covered in |
270| - | - | - | - |
271| `permissionMode` | `permission_mode` | What the agent can do without approval | [Configure permissions](/docs/en/agent-sdk/permissions) |
272| `allowedTools` | `allowed_tools` | Which tool calls are pre-approved | [Configure permissions](/docs/en/agent-sdk/permissions) |
273| `canUseTool` | `can_use_tool` | Your approval callback for tool calls | [Handle tool approval requests](/docs/en/agent-sdk/user-input#handle-tool-approval-requests) |
274| `systemPrompt` | `system_prompt` | The agent's instructions | [Modifying system prompts](/docs/en/agent-sdk/modifying-system-prompts) |
275| `settingSources` | `setting_sources` | Which filesystem settings load | [Use Claude Code features in the SDK](/docs/en/agent-sdk/claude-code-features) |
276| `mcpServers` | `mcp_servers` | External tool servers | [Connect to external tools with MCP](/docs/en/agent-sdk/mcp) |
277| `agents` | `agents` | Subagent definitions | [Subagents](/docs/en/agent-sdk/subagents) |
278| `hooks` | `hooks` | Callbacks at lifecycle points | [Hooks](/docs/en/agent-sdk/hooks) |
279| `skills` | `skills` | Which skills load | [Extend agents with skills](/docs/en/agent-sdk/skills) |
280| `plugins` | `plugins` | Which plugins load | [Plugins](/docs/en/agent-sdk/plugins) |
281| `outputFormat` | `output_format` | Structured output schemas | [Structured outputs](/docs/en/agent-sdk/structured-outputs) |
282| `resume` | `resume` | Continuing a stored session | [Sessions](/docs/en/agent-sdk/sessions) |
283| `forkSession` | `fork_session` | Branching a session | [Sessions](/docs/en/agent-sdk/sessions) |
284| `sessionStore` | `session_store` | External session persistence | [Session storage](/docs/en/agent-sdk/session-storage) |
285| `enableFileCheckpointing` | `enable_file_checkpointing` | Rewindable file edits | [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
286| `effort` | `effort` | How much work Claude puts into responses | [Effort level](/docs/en/agent-sdk/agent-loop#effort-level) |
287| `sandbox` | `sandbox` | Sandbox behavior for tool execution | [TypeScript](/docs/en/agent-sdk/typescript#sandbox-configuration) and [Python](/docs/en/agent-sdk/python#sandbox-configuration) references, with deployment context in [Secure deployment](/docs/en/agent-sdk/secure-deployment) |
288288
289289## Next steps
290290
agent-sdk/cost-tracking Changed · +5 / -5 lines
from line 85
8585
8686The three result-level fields differ in what they count when the agent spawns [subagents](/docs/en/agent-sdk/subagents). Use `modelUsage`, or `model_usage` in Python, for whole-tree token accounting; the `usage` field undercounts as soon as nesting occurs.
8787
88| Field | Subagent activity |
89| ---------------------------- | ------------------------------------------------------------------------------------------------- |
90| `usage` | Excluded. Counts only the top-level agent loop, so tokens consumed inside subagents are not added |
91| `total_cost_usd` | Included. Counts subagent requests alongside the top-level loop |
92| `modelUsage` / `model_usage` | Included. Counts subagent requests alongside the top-level loop, broken down by model |
88| Field | Subagent activity |
89| - | - |
90| `usage` | Excluded. Counts only the top-level agent loop, so tokens consumed inside subagents are not added |
91| `total_cost_usd` | Included. Counts subagent requests alongside the top-level loop |
92| `modelUsage` / `model_usage` | Included. Counts subagent requests alongside the top-level loop, broken down by model |
9393
9494In [single message input mode](/docs/en/agent-sdk/streaming-vs-single-mode#single-message-input), when background subagents are still running at the end of the final turn, Claude Code waits for them, up to the cap described in [background tasks at exit](/docs/en/headless#background-tasks-at-exit), before emitting the result. The result's `total_cost_usd`, `duration_api_ms`, and `modelUsage`, or `model_usage` in Python, include the work done during that wait.
9595
agent-sdk/custom-tools Changed · +39 / -39 lines
from line 6
66
77## Quick reference
88
9| What you want to do | Do this |
10| :------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
11| Define a tool | Use [`@tool`](/docs/en/agent-sdk/python#tool) (Python) or [`tool()`](/docs/en/agent-sdk/typescript#tool) (TypeScript) with a name, description, schema, and handler. See [Create a custom tool](#create-a-custom-tool). |
12| Register a tool with Claude | Wrap in `create_sdk_mcp_server` / `createSdkMcpServer` and pass to `mcpServers` in `query()`. See [Call a custom tool](#call-a-custom-tool). |
13| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |
14| Remove a built-in tool from Claude's context | Pass a `tools` array listing only the built-ins you want. See [Configure allowed tools](#configure-allowed-tools). |
15| Let Claude call tools in parallel | Set `readOnlyHint: true` on tools with no side effects. See [Add tool annotations](#add-tool-annotations). |
16| Control the error message Claude reads | Return `isError: true` to compose the message instead of surfacing the raw exception. See [Handle errors](#handle-errors). |
17| Return images or files | Use `image` or `resource` blocks in the content array. See [Return images and resources](#return-images-and-resources). |
18| Return a machine-readable JSON result | Set `structuredContent` on the result. See [Return structured data](#return-structured-data). |
19| Scale to many tools | Use [tool search](/docs/en/agent-sdk/tool-search) to load tools on demand. |
9| What you want to do | Do this |
10| :- | :- |
11| Define a tool | Use [`@tool`](/docs/en/agent-sdk/python#tool) (Python) or [`tool()`](/docs/en/agent-sdk/typescript#tool) (TypeScript) with a name, description, schema, and handler. See [Create a custom tool](#create-a-custom-tool). |
12| Register a tool with Claude | Wrap in `create_sdk_mcp_server` / `createSdkMcpServer` and pass to `mcpServers` in `query()`. See [Call a custom tool](#call-a-custom-tool). |
13| Pre-approve a tool | Add to your allowed tools. See [Configure allowed tools](#configure-allowed-tools). |
14| Remove a built-in tool from Claude's context | Pass a `tools` array listing only the built-ins you want. See [Configure allowed tools](#configure-allowed-tools). |
15| Let Claude call tools in parallel | Set `readOnlyHint: true` on tools with no side effects. See [Add tool annotations](#add-tool-annotations). |
16| Control the error message Claude reads | Return `isError: true` to compose the message instead of surfacing the raw exception. See [Handle errors](#handle-errors). |
17| Return images or files | Use `image` or `resource` blocks in the content array. See [Return images and resources](#return-images-and-resources). |
18| Return a machine-readable JSON result | Set `structuredContent` on the result. See [Return structured data](#return-structured-data). |
19| Scale to many tools | Use [tool search](/docs/en/agent-sdk/tool-search) to load tools on demand. |
2020
2121## Create a custom tool
2222
from line 266
266266
267267[Tool annotations](https://modelcontextprotocol.io/docs/concepts/tools#tool-annotations) are optional metadata describing how a tool behaves. Pass them as the fifth argument to `tool()` helper in TypeScript or via the `annotations` keyword argument for the `@tool` decorator in Python. All hint fields are Booleans.
268268
269| Field | Default | Meaning |
270| :---------------- | :------ | :-------------------------------------------------------------------------------------------------------------------- |
271| `readOnlyHint` | `false` | Tool does not modify its environment. Controls whether the tool can be called in parallel with other read-only tools. |
272| `destructiveHint` | `true` | Tool may perform destructive updates. Informational only. |
273| `idempotentHint` | `false` | Repeated calls with the same arguments have no additional effect. Informational only. |
274| `openWorldHint` | `true` | Tool reaches systems outside your process. Informational only. |
269| Field | Default | Meaning |
270| :- | :- | :- |
271| `readOnlyHint` | `false` | Tool does not modify its environment. Controls whether the tool can be called in parallel with other read-only tools. |
272| `destructiveHint` | `true` | Tool may perform destructive updates. Informational only. |
273| `idempotentHint` | `false` | Repeated calls with the same arguments have no additional effect. Informational only. |
274| `openWorldHint` | `true` | Tool reaches systems outside your process. Informational only. |
275275
276276Annotations are metadata, not enforcement. A tool marked `readOnlyHint: true` can still write to disk if that's what the handler does. Keep the annotation accurate to the handler.
277277
from line 318
318318
319319The `tools` option and the allowed/disallowed lists affect two layers: availability, which controls whether a tool appears in Claude's context, and permission, which controls whether a call is approved once Claude attempts it. `tools` and bare-name `disallowedTools` entries change availability. `allowedTools` and scoped `disallowedTools` rules change permission. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability) in `allowedTools`, Claude Code also opts the session in.
320320
321| Option | Layer | Effect |
322| :------------------------ | :----------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
323| `tools: ["Read", "Grep"]` | Availability | Only the listed built-ins are in Claude's context. Unlisted built-ins are removed. MCP tools are unaffected. |
324| `tools: []` | Availability | All built-ins are removed. Claude can only use your MCP tools. |
325| allowed tools | Permission | Listed tools run without a permission prompt. Other unlisted tools remain available; calls go through the [permission flow](/docs/en/agent-sdk/permissions). |
326| disallowed tools | Both | A bare tool name such as `"Bash"` removes the tool from Claude's context, the same as omitting it from `tools`. A scoped rule such as `"Bash(rm *)"` leaves the tool in context and denies only calls that match [as written](/docs/en/permissions#bash-rule-limits). |
321| Option | Layer | Effect |
322| :- | :- | :- |
323| `tools: ["Read", "Grep"]` | Availability | Only the listed built-ins are in Claude's context. Unlisted built-ins are removed. MCP tools are unaffected. |
324| `tools: []` | Availability | All built-ins are removed. Claude can only use your MCP tools. |
325| allowed tools | Permission | Listed tools run without a permission prompt. Other unlisted tools remain available; calls go through the [permission flow](/docs/en/agent-sdk/permissions). |
326| disallowed tools | Both | A bare tool name such as `"Bash"` removes the tool from Claude's context, the same as omitting it from `tools`. A scoped rule such as `"Bash(rm *)"` leaves the tool in context and denies only calls that match [as written](/docs/en/permissions#bash-rule-limits). |
327327
328328To remove a built-in entirely, omit it from `tools` or list its bare name in `disallowedTools` (Python: `disallowed_tools`); both keep the tool out of context so Claude never attempts it. A scoped `disallowedTools` rule blocks matching calls but leaves the tool visible, so Claude may waste a turn trying it. See [Configure permissions](/docs/en/agent-sdk/permissions) for the full evaluation order.
329329
from line 331
331331
332332A handler error doesn't stop the agent loop. The SDK's in-process MCP server catches uncaught exceptions and returns them as error results, so how you report an error determines what Claude reads, not whether the query fails:
333333
334| What happens | Result |
335| :--------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
336| Handler throws an uncaught exception | The MCP server converts it to an error result carrying the raw exception message. Claude sees that message, and the agent loop continues. |
337| Handler catches the error and returns `isError: true` (TS) / `"is_error": True` (Python) | Claude sees the message you compose. You can add context the raw exception lacks, such as which request failed or what to try instead. |
334| What happens | Result |
335| :- | :- |
336| Handler throws an uncaught exception | The MCP server converts it to an error result carrying the raw exception message. Claude sees that message, and the agent loop continues. |
337| Handler catches the error and returns `isError: true` (TS) / `"is_error": True` (Python) | Claude sees the message you compose. You can add context the raw exception lacks, such as which request failed or what to try instead. |
338338
339339In both cases Claude can retry, try a different tool, or explain the failure. Catch errors yourself when the raw exception message isn't enough for Claude to act on.
340340
from line 446
446446
447447An image block carries the image bytes inline, encoded as base64. There is no URL field. To return an image that lives at a URL, fetch it in the handler, read the response bytes, and base64-encode them before returning. A PNG, JPEG, GIF, or WebP image reaches Claude as visual input; an image of any other type is saved to disk and Claude receives its file path as text instead.
448448
449| Field | Type | Notes |
450| :--------- | :-------- | :------------------------------------------------------------------------- |
451| `type` | `"image"` | |
452| `data` | `string` | Base64-encoded bytes. Raw base64 only, no `data:image/...;base64,` prefix |
453| `mimeType` | `string` | Required. For example `image/png`, `image/jpeg`, `image/webp`, `image/gif` |
449| Field | Type | Notes |
450| :- | :- | :- |
451| `type` | `"image"` | |
452| `data` | `string` | Base64-encoded bytes. Raw base64 only, no `data:image/...;base64,` prefix |
453| `mimeType` | `string` | Required. For example `image/png`, `image/jpeg`, `image/webp`, `image/gif` |
454454
455455<CodeGroup>
456456 ```python Python theme={null}
from line 513
513513
514514A resource block embeds a piece of content identified by a URI. The actual content rides in the block's `text` or `blob` field. Use this when your tool produces a generated file or a record from an external system.
515515
516| Field | Type | Notes |
517| :------------------ | :----------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
518| `type` | `"resource"` | |
519| `resource.uri` | `string` | Identifier for the content. Any URI scheme |
520| `resource.text` | `string` | The content, if it's text. Provide this or `blob`, not both |
521| `resource.blob` | `string` | The content base64-encoded, if it's binary. TypeScript only: the Python SDK drops binary resources from the tool result and logs a warning |
522| `resource.mimeType` | `string` | Optional |
516| Field | Type | Notes |
517| :- | :- | :- |
518| `type` | `"resource"` | |
519| `resource.uri` | `string` | Identifier for the content. Any URI scheme |
520| `resource.text` | `string` | The content, if it's text. Provide this or `blob`, not both |
521| `resource.blob` | `string` | The content base64-encoded, if it's binary. TypeScript only: the Python SDK drops binary resources from the tool result and logs a warning |
522| `resource.mimeType` | `string` | Optional |
523523
524524This example shows a resource block returned from inside a tool handler. The SDK doesn't read from the example's URI, `file:///tmp/report.md`.
525525
agent-sdk/file-checkpointing Changed · +10 / -10 lines
from line 140
140140 <Step title="Enable checkpointing">
141141 Configure your SDK options to enable checkpointing and receive checkpoint UUIDs:
142142
143 | Option | Python | TypeScript | Description |
144 | ------------------------ | ------------------------------------------- | --------------------------------------------- | ------------------------------------------------ |
145 | Enable checkpointing | `enable_file_checkpointing=True` | `enableFileCheckpointing: true` | Tracks file changes for rewinding |
143 | Option | Python | TypeScript | Description |
144 | - | - | - | - |
145 | Enable checkpointing | `enable_file_checkpointing=True` | `enableFileCheckpointing: true` | Tracks file changes for rewinding |
146146 | Receive checkpoint UUIDs | `extra_args={"replay-user-messages": None}` | `extraArgs: { 'replay-user-messages': null }` | Required to get user message UUIDs in the stream |
147147
148148 <CodeGroup>
from line 699
699699
700700File checkpointing has the following limitations:
701701
702| Limitation | Description |
703| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
704| Write/Edit/NotebookEdit tools only | Changes made through Bash commands are not tracked |
705| Subagent edits | Edits a [subagent](/docs/en/agent-sdk/subagents) applies aren't tracked or restored, except a skill with `context: fork` running in the foreground; use git to revert untracked edits |
706| Same session | Checkpoints are tied to the session that created them |
707| File content only | Creating, moving, or deleting directories is not undone by rewinding |
708| Local files | Remote or network files are not tracked |
702| Limitation | Description |
703| - | - |
704| Write/Edit/NotebookEdit tools only | Changes made through Bash commands are not tracked |
705| Subagent edits | Edits a [subagent](/docs/en/agent-sdk/subagents) applies aren't tracked or restored, except a skill with `context: fork` running in the foreground; use git to revert untracked edits |
706| Same session | Checkpoints are tied to the session that created them |
707| File content only | Creating, moving, or deleting directories is not undone by rewinding |
708| Local files | Remote or network files are not tracked |
709709
710710## Troubleshooting
711711
agent-sdk/hooks Changed · +44 / -44 lines
from line 140
140140
141141The SDK provides hooks for different stages of agent execution. Some hooks are available in both SDKs, while others are TypeScript-only.
142142
143| Hook Event | Python SDK | TypeScript SDK | What triggers it | Example use case |
144| ------------------------------------------------------ | ---------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
145| `PreToolUse` | Yes | Yes | Tool call request (can block or modify) | Block dangerous shell commands |
146| `PostToolUse` | Yes | Yes | Tool execution result | Log all file changes to audit trail |
147| `PostToolUseFailure` | Yes | Yes | Tool execution failure | Handle or log tool errors |
148| `PostToolBatch` | No | Yes | A full batch of tool calls resolves, once per batch before the next model call | Inject conventions once for the whole batch |
149| `UserPromptSubmit` | Yes | Yes | User prompt submission | Inject additional context into prompts |
150| [`UserPromptExpansion`](/docs/en/hooks#userpromptexpansion) | No | Yes | A user-typed command, or an MCP prompt, expands into a prompt before it reaches Claude. Doesn't fire when Claude invokes a skill itself | Block a command from direct invocation or add context when a skill is typed |
151| `MessageDisplay` | No | Yes | An assistant message with text completes, once per message with the full message text | Redact or reformat the displayed text without changing the transcript |
152| `Stop` | Yes | Yes | Agent execution stop | Save session state before exit |
153| `StopFailure` | No | Yes | The turn ends with an API error instead of a normal stop | Log failures or send alerts |
154| `SubagentStart` | Yes | Yes | Subagent initialization | Track parallel task spawning |
155| `SubagentStop` | Yes | Yes | Subagent completion | Aggregate results from parallel tasks |
156| `PreCompact` | Yes | Yes | Conversation compaction request | Archive full transcript before summarizing |
157| `PostCompact` | No | Yes | Conversation compaction completes | Log the generated summary |
158| [`PreModelSwitch`](/docs/en/hooks#premodelswitch) | No | Yes | A requested model switch, before it happens (can block) | Block switching to a specific model |
159| [`PostModelSwitch`](/docs/en/hooks#postmodelswitch) | No | Yes | The session's model changes, including an automatic fallback | Give Claude model-specific guidance for the new model |
160| `PermissionRequest` | Yes | Yes | A tool call needs a permission decision | Custom permission handling |
161| `PermissionDenied` | No | Yes | Auto mode denies a tool call, including denials without a classifier verdict | Log denials, or tell the model it may retry; Claude Code ignores `retry: true` for no-verdict denials. See [PermissionDenied](/docs/en/hooks#permissiondenied) |
162| `SessionStart` | No | Yes | Session initialization | Initialize logging and telemetry |
163| `SessionEnd` | No | Yes | Session termination | Clean up temporary resources |
164| `Notification` | Yes | Yes | Agent status messages | Send agent status updates to Slack or PagerDuty |
165| `Setup` | No | Yes | Session setup/maintenance | Run initialization tasks |
166| `TeammateIdle` | No | Yes | Teammate becomes idle | Reassign work or notify |
167| `TaskCreated` | No | Yes | A task is created via the `TaskCreate` tool | Enforce task naming conventions |
168| [`TaskCompleted`](/docs/en/hooks#taskcompleted) | No | Yes | A task is marked completed | Require passing tests before a task closes |
169| `Elicitation` | No | Yes | An MCP server requests user input mid-task | Respond to MCP input requests programmatically |
170| `ElicitationResult` | No | Yes | A user responds to an MCP elicitation | Modify or block the response before it returns to the server |
171| `ConfigChange` | No | Yes | Configuration file changes | Reload settings dynamically |
172| `InstructionsLoaded` | No | Yes | A `CLAUDE.md` or rules file is loaded into context | Audit which instruction files load |
173| `WorktreeCreate` | No | Yes | Git worktree created | Track isolated workspaces |
174| `WorktreeRemove` | No | Yes | Git worktree removed | Clean up workspace resources |
175| `CwdChanged` | No | Yes | The working directory changes during a session | Reload environment variables per directory |
176| `FileChanged` | No | Yes | A watched file is modified, created, or deleted | Reload configuration when project files change |
177| `DirectoryAdded` | No | Yes | A working directory is added during a session | Install dependencies for a repository added mid-session |
143| Hook Event | Python SDK | TypeScript SDK | What triggers it | Example use case |
144| - | - | - | - | - |
145| `PreToolUse` | Yes | Yes | Tool call request (can block or modify) | Block dangerous shell commands |
146| `PostToolUse` | Yes | Yes | Tool execution result | Log all file changes to audit trail |
147| `PostToolUseFailure` | Yes | Yes | Tool execution failure | Handle or log tool errors |
148| `PostToolBatch` | No | Yes | A full batch of tool calls resolves, once per batch before the next model call | Inject conventions once for the whole batch |
149| `UserPromptSubmit` | Yes | Yes | User prompt submission | Inject additional context into prompts |
150| [`UserPromptExpansion`](/docs/en/hooks#userpromptexpansion) | No | Yes | A user-typed command, or an MCP prompt, expands into a prompt before it reaches Claude. Doesn't fire when Claude invokes a skill itself | Block a command from direct invocation or add context when a skill is typed |
151| `MessageDisplay` | No | Yes | An assistant message with text completes, once per message with the full message text | Redact or reformat the displayed text without changing the transcript |
152| `Stop` | Yes | Yes | Agent execution stop | Save session state before exit |
153| `StopFailure` | No | Yes | The turn ends with an API error instead of a normal stop | Log failures or send alerts |
154| `SubagentStart` | Yes | Yes | Subagent initialization | Track parallel task spawning |
155| `SubagentStop` | Yes | Yes | Subagent completion | Aggregate results from parallel tasks |
156| `PreCompact` | Yes | Yes | Conversation compaction request | Archive full transcript before summarizing |
157| `PostCompact` | No | Yes | Conversation compaction completes | Log the generated summary |
158| [`PreModelSwitch`](/docs/en/hooks#premodelswitch) | No | Yes | A requested model switch, before it happens (can block) | Block switching to a specific model |
159| [`PostModelSwitch`](/docs/en/hooks#postmodelswitch) | No | Yes | The session's model changes, including an automatic fallback | Give Claude model-specific guidance for the new model |
160| `PermissionRequest` | Yes | Yes | A tool call needs a permission decision | Custom permission handling |
161| `PermissionDenied` | No | Yes | Auto mode denies a tool call, including denials without a classifier verdict | Log denials, or tell the model it may retry; Claude Code ignores `retry: true` for no-verdict denials. See [PermissionDenied](/docs/en/hooks#permissiondenied) |
162| `SessionStart` | No | Yes | Session initialization | Initialize logging and telemetry |
163| `SessionEnd` | No | Yes | Session termination | Clean up temporary resources |
164| `Notification` | Yes | Yes | Agent status messages | Send agent status updates to Slack or PagerDuty |
165| `Setup` | No | Yes | Session setup/maintenance | Run initialization tasks |
166| `TeammateIdle` | No | Yes | Teammate becomes idle | Reassign work or notify |
167| `TaskCreated` | No | Yes | A task is created via the `TaskCreate` tool | Enforce task naming conventions |
168| [`TaskCompleted`](/docs/en/hooks#taskcompleted) | No | Yes | A task is marked completed | Require passing tests before a task closes |
169| `Elicitation` | No | Yes | An MCP server requests user input mid-task | Respond to MCP input requests programmatically |
170| `ElicitationResult` | No | Yes | A user responds to an MCP elicitation | Modify or block the response before it returns to the server |
171| `ConfigChange` | No | Yes | Configuration file changes | Reload settings dynamically |
172| `InstructionsLoaded` | No | Yes | A `CLAUDE.md` or rules file is loaded into context | Audit which instruction files load |
173| `WorktreeCreate` | No | Yes | Git worktree created | Track isolated workspaces |
174| `WorktreeRemove` | No | Yes | Git worktree removed | Clean up workspace resources |
175| `CwdChanged` | No | Yes | The working directory changes during a session | Reload environment variables per directory |
176| `FileChanged` | No | Yes | A watched file is modified, created, or deleted | Reload configuration when project files change |
177| `DirectoryAdded` | No | Yes | A working directory is added during a session | Install dependencies for a repository added mid-session |
178178
179179## Configure hooks
180180
from line 217
217217
218218SDK matchers follow the same rules as [matchers in settings files](/docs/en/hooks#matcher-patterns). That section documents the exact-string and regular-expression evaluation paths, their version requirements, and the matcher values for each event type.
219219
220| Option | Type | Default | Description |
221| --------- | ---------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
222| `matcher` | `string` | `undefined` | Pattern matched against the event's filter field, following the [rules for matchers in settings files](/docs/en/hooks#matcher-patterns). For tool hooks, this is the tool name. Built-in tools include `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent`, and others (see [Tool Input Types](/docs/en/agent-sdk/typescript#tool-input-types) for the full list). MCP tools use the pattern `mcp__<server>__<action>`, where `<server>` is the key you use in the `mcpServers` configuration. |
223| `hooks` | `HookCallback[]` | - | Required. Array of callback functions to execute when the pattern matches |
224| `timeout` | `number` | `undefined` | Timeout in seconds. When omitted, Claude Code applies the [event's default timeout](#hook-timeout). Your SDK callbacks follow the `command` hook defaults |
220| Option | Type | Default | Description |
221| - | - | - | - |
222| `matcher` | `string` | `undefined` | Pattern matched against the event's filter field, following the [rules for matchers in settings files](/docs/en/hooks#matcher-patterns). For tool hooks, this is the tool name. Built-in tools include `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent`, and others (see [Tool Input Types](/docs/en/agent-sdk/typescript#tool-input-types) for the full list). MCP tools use the pattern `mcp__<server>__<action>`, where `<server>` is the key you use in the `mcpServers` configuration. |
223| `hooks` | `HookCallback[]` | - | Required. Array of callback functions to execute when the pattern matches |
224| `timeout` | `number` | `undefined` | Timeout in seconds. When omitted, Claude Code applies the [event's default timeout](#hook-timeout). Your SDK callbacks follow the `command` hook defaults |
225225
226226Use the `matcher` pattern to target specific tools whenever possible. A matcher with `'Bash'` only runs for Bash commands, while omitting the pattern runs your callbacks for every occurrence of the event. Omit it on purpose to log every tool call your session makes.
227227
from line 274
274274 ```
275275</CodeGroup>
276276
277| Field | Type | Description |
278| -------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
279| `async` | `true` | Signals async mode. The agent proceeds without waiting. In Python, use `async_` to avoid the reserved keyword. |
280| `asyncTimeout` | `number` | Optional timeout in milliseconds for the background operation |
277| Field | Type | Description |
278| - | - | - |
279| `async` | `true` | Signals async mode. The agent proceeds without waiting. In Python, use `async_` to avoid the reserved keyword. |
280| `asyncTimeout` | `number` | Optional timeout in milliseconds for the background operation |
281281
282282<Note>
283283 Async outputs can't block, modify, or inject context into the operation since the agent has already moved on. Use them only for side effects like logging, metrics, or notifications.
agent-sdk/hosting Changed · +11 / -11 lines
from line 54
5454
5555Three kinds of agent state live on the container's filesystem by default. None of them survive a container restart, a scale-down, or a move to a different node.
5656
57| State | Default location |
58| --------------------------- | ------------------------------------------------------------------------------------------------ |
59| Session transcripts | `~/.claude/projects/`, or the `projects/` directory under `CLAUDE_CONFIG_DIR` if set |
60| `CLAUDE.md` memory files | `~/.claude/CLAUDE.md` for the user tier and the session's working directory for the project tier |
61| Working-directory artifacts | The session's working directory |
57| State | Default location |
58| - | - |
59| Session transcripts | `~/.claude/projects/`, or the `projects/` directory under `CLAUDE_CONFIG_DIR` if set |
60| `CLAUDE.md` memory files | `~/.claude/CLAUDE.md` for the user tier and the session's working directory for the project tier |
61| Working-directory artifacts | The session's working directory |
6262
6363To persist transcripts across hosts, configure a [`SessionStore` adapter](/docs/en/agent-sdk/session-storage). Memory files and other working-directory artifacts need their own storage strategy, such as a mounted volume or an object-store sync.
6464
from line 339
339339
340340Plan around these in your deployment design.
341341
342| Limitation | What to do |
343| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
344| No top-level session timeout | A session does not time out on its own. Set `maxTurns` in TypeScript or `max_turns` in Python to bound how many tool-use round trips the agent takes before stopping. |
345| Memory growth over long sessions | Cap session length or recycle subprocesses periodically. See [Scaling and concurrency](#scaling-and-concurrency). |
346| Large parallel-subagent fanouts can hit rate limits | Break work into smaller batches rather than issuing one wide dispatch. |
347| No per-subagent wall-clock deadline | Cap each [subagent](/docs/en/agent-sdk/subagents) with `maxTurns` in its `AgentDefinition`. `CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS` sets a stall watchdog that fires when a subagent stops producing output; it isn't a total-runtime deadline. |
342| Limitation | What to do |
343| - | - |
344| No top-level session timeout | A session does not time out on its own. Set `maxTurns` in TypeScript or `max_turns` in Python to bound how many tool-use round trips the agent takes before stopping. |
345| Memory growth over long sessions | Cap session length or recycle subprocesses periodically. See [Scaling and concurrency](#scaling-and-concurrency). |
346| Large parallel-subagent fanouts can hit rate limits | Break work into smaller batches rather than issuing one wide dispatch. |
347| No per-subagent wall-clock deadline | Cap each [subagent](/docs/en/agent-sdk/subagents) with `maxTurns` in its `AgentDefinition`. `CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS` sets a stall watchdog that fires when a subagent stops producing output; it isn't a total-runtime deadline. |
348348
349349## Troubleshoot deployment failures
350350
agent-sdk/mcp Changed · +5 / -5 lines
from line 144
144144
145145Claude Code registers the servers you pass in `options.mcpServers` at startup and emits the [init message](#error-handling) once the first-turn wait, if any, resolves. Whether each `options.mcpServers` server delays the first turn, and when it connects, depends on its type:
146146
147| Server type | Delays the first turn? | First-turn wait timeout |
148| :------------------------------------------------------------------------------------- | :----------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- |
149| stdio server, or HTTP/SSE server without a cached tool list | Yes, until it connects | [`MCP_TIMEOUT`](/docs/en/env-vars), 30 seconds by default; the connection fails at that deadline |
150| Remote server with a cached tool list, saved by Claude Code from a previous connection | No; the cached tools are available from the first turn | None; connects on its first tool call, and that deferred connect has its own timeout |
151| In-process [SDK server](#sdk-mcp-servers) | Yes, until it connects and lists its tools | [`MCP_TIMEOUT`](/docs/en/env-vars), 30 seconds by default, per connect attempt; the connection fails at that deadline |
147| Server type | Delays the first turn? | First-turn wait timeout |
148| :- | :- | :- |
149| stdio server, or HTTP/SSE server without a cached tool list | Yes, until it connects | [`MCP_TIMEOUT`](/docs/en/env-vars), 30 seconds by default; the connection fails at that deadline |
150| Remote server with a cached tool list, saved by Claude Code from a previous connection | No; the cached tools are available from the first turn | None; connects on its first tool call, and that deferred connect has its own timeout |
151| In-process [SDK server](#sdk-mcp-servers) | Yes, until it connects and lists its tools | [`MCP_TIMEOUT`](/docs/en/env-vars), 30 seconds by default, per connect attempt; the connection fails at that deadline |
152152
153153Servers loaded from [settings files](#from-a-config-file) such as `.mcp.json` or from plugins commonly show `pending` in the init message. When `options.mcpServers` holds a stdio, HTTP, or SSE server, the first turn waits for these pending servers too, up to `MCP_TIMEOUT`. When `options.mcpServers` is empty or holds only SDK servers, the first turn waits up to 2 seconds instead:
154154
agent-sdk/migration-guide Changed · +5 / -5 lines
from line 10
1010
1111## What's Changed
1212
13| Aspect | Old | New |
14| :------------------------- | :-------------------------- | :----------------------------------------------------------------------- |
15| **Package Name (TS/JS)** | `@anthropic-ai/claude-code` | `@anthropic-ai/claude-agent-sdk` |
16| **Python Package** | `claude-code-sdk` | `claude-agent-sdk` |
17| **Documentation Location** | Claude Code docs | Claude Code docs → dedicated [Agent SDK](/docs/en/agent-sdk/overview) section |
13| Aspect | Old | New |
14| :- | :- | :- |
15| **Package Name (TS/JS)** | `@anthropic-ai/claude-code` | `@anthropic-ai/claude-agent-sdk` |
16| **Python Package** | `claude-code-sdk` | `claude-agent-sdk` |
17| **Documentation Location** | Claude Code docs | Claude Code docs → dedicated [Agent SDK](/docs/en/agent-sdk/overview) section |
1818
1919## Migration Steps
2020
agent-sdk/modifying-system-prompts Changed · +32 / -31 lines
from line 8
88
99A system prompt is the initial instruction set that shapes how Claude behaves throughout a conversation. The Agent SDK has three starting points for it:
1010
11* **Minimal default**: when you don't set `systemPrompt` in TypeScript or `system_prompt` in Python, the SDK uses a minimal prompt that covers tool calling but omits the rest of the `claude_code` preset's content, including its security and safety instructions and its context about the working directory and environment. This differs from `claude -p`, which uses the Claude Code system prompt by default. If you're migrating from the CLI and want matching behavior, set the `claude_code` preset.
12* **`claude_code` preset**: the system prompt that the Claude Code CLI uses, with tool usage instructions, security and safety instructions, and context about the working directory and environment. Set `systemPrompt: { type: "preset", preset: "claude_code" }` in TypeScript or `system_prompt={"type": "preset", "preset": "claude_code"}` in Python, optionally with `append` to add your own instructions on the end.
11* **Minimal default**: when you don't set `systemPrompt` in TypeScript or `system_prompt` in Python, the SDK uses a minimal prompt that covers tool calling but omits the rest of the `claude_code` preset's content, including its security and safety instructions. This differs from `claude -p`, which uses the Claude Code system prompt by default. If you're migrating from the CLI and want matching behavior, set the `claude_code` preset.
12* **`claude_code` preset**: the system prompt that the Claude Code CLI uses, with tool usage instructions and security and safety instructions. Set `systemPrompt: { type: "preset", preset: "claude_code" }` in TypeScript or `system_prompt={"type": "preset", "preset": "claude_code"}` in Python, optionally with `append` to add your own instructions on the end.
1313* **Custom string**: a prompt you write yourself. The SDK sends only what you provide.
1414
1515### Decide on a starting point
from line 16
1616
1717The deciding factor is how closely your agent resembles Claude Code: a coding agent operating in a repository, with a human watching streaming output and steering the work. The further your product is from that, the more you'll want to write your own prompt.
1818
19| You're building | Use | What you get |
20| :----------------------------------------------------------------------------------------------------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------------------------------- |
21| A CLI or IDE-like coding tool where a human watches and steers, and Claude Code's defaults are what you want | `claude_code` preset | The Claude Code prompt, including tool guidance, safety rules, and environment context |
22| The same kind of tool, plus product-specific rules like coding standards, output format, or domain context | `claude_code` preset with `append` | Everything above, with your instructions added after the preset. Nothing is removed, so this is the lowest-risk customization |
23| An agent with a different surface, identity, or permission model, or a non-coding agent | Custom prompt string | Only what you write. You take responsibility for replacing the tool guidance and safety instructions your agent still needs |
24| A thin tool-calling loop with no agent persona, where you supply all behavior in the user prompt | No `systemPrompt` option | The minimal default: tool-calling support and nothing else |
19| You're building | Use | What you get |
20| :- | :- | :- |
21| A CLI or IDE-like coding tool where a human watches and steers, and Claude Code's defaults are what you want | `claude_code` preset | The Claude Code prompt, including tool guidance and safety rules |
22| The same kind of tool, plus product-specific rules like coding standards, output format, or domain context | `claude_code` preset with `append` | Everything above, with your instructions added after the preset. Nothing is removed, so this is the lowest-risk customization |
23| An agent with a different surface, identity, or permission model, or a non-coding agent | Custom prompt string | Only what you write. You take responsibility for replacing the tool guidance and safety instructions your agent still needs |
24| A thin tool-calling loop with no agent persona, where you supply all behavior in the user prompt | No `systemPrompt` option | The minimal default: tool-calling support and nothing else |
2525
2626"Different from Claude Code" usually means one of the following:
2727
from line 201
201201
202202#### Improve prompt caching across users and machines
203203
204By default, two sessions that use the same `claude_code` preset and `append` text still cannot share a prompt cache entry if they run from different working directories. This is because the preset embeds per-session context in the system prompt ahead of your `append` text: the working directory, whether it's a git repository, the platform, the active shell, the OS version, and auto memory paths. Any difference in that context produces a different system prompt and a cache miss. CLAUDE.md content doesn't affect the system prompt cache because the SDK injects it into the conversation, not the system prompt.
204By default, two sessions that use the same `claude_code` preset and `append` text still can't share a prompt cache entry when their auto memory locations differ. The preset embeds that location in the system prompt ahead of your `append` text. The location defaults to an absolute path under `~/.claude/projects/` named for the repository's path on disk, so it differs across users, machines, and checkouts.
205205
206To make the system prompt identical across sessions, set `excludeDynamicSections: true` in TypeScript or `"exclude_dynamic_sections": True` in Python. The per-session context moves into the first user message, leaving only the static preset and your `append` text in the system prompt so identical configurations share a cache entry across users and machines.
206CLAUDE.md content and environment details such as the working directory, platform, shell, and OS version don't affect the system prompt cache, because Claude Code delivers them in the conversation, not the system prompt.
207207
208To make the system prompt identical across sessions, set `excludeDynamicSections: true` in TypeScript or `"exclude_dynamic_sections": True` in Python. The per-user context moves into the first user message, leaving only the static preset and your `append` text in the system prompt so identical configurations share a cache entry across users and machines.
209
208210<Note>
209211 `excludeDynamicSections` requires `@anthropic-ai/claude-agent-sdk` v0.2.98 or later, or `claude-agent-sdk` v0.1.58 or later for Python. Set it on the preset object form only. The SDK ignores it when you pass a custom prompt instead of the preset; to keep a custom prompt's instructions cached in the TypeScript SDK, see [Cache the static part of a custom prompt](#cache-the-static-part-of-a-custom-prompt).
210212</Note>
211213
212The following example pairs a shared `append` block with `excludeDynamicSections` so a fleet of agents running from different directories can reuse the same cached system prompt:
214The following example pairs a shared `append` block with `excludeDynamicSections` so a fleet of agents can reuse the same cached system prompt:
213215
214216<CodeGroup>
215217 ```typescript TypeScript theme={null}
from line 257
255257 ```
256258</CodeGroup>
257259
258**Tradeoffs:** the working directory, the git-repo flag, the platform, the active shell, the OS version, and auto memory paths still reach Claude, but as part of the first user message rather than the system prompt. Instructions in the user message carry marginally less weight than the same text in the system prompt, so Claude may rely on them less strongly when reasoning about the current directory or auto memory paths. Enable this option when cross-session cache reuse matters more than maximally authoritative environment context.
260**Tradeoffs:** the text that moves out of the system prompt still reaches Claude, but in a user message. That text is at least the auto memory directory's location, and often the whole auto memory section. Instructions in a user message carry marginally less weight than the same text in the system prompt, so Claude may follow its auto memory guidance less consistently. Enable this option when cross-session cache reuse matters more than that.
259261
260262For the equivalent flag in non-interactive CLI mode, see [`--exclude-dynamic-system-prompt-sections`](/docs/en/cli-reference).
261263
from line 419
417419
418420Pass settings keys through the [`settings`](/docs/en/agent-sdk/typescript#options) option in TypeScript or [`settings`](/docs/en/agent-sdk/python#claudeagentoptions) in Python, and environment variables through the `env` option. In TypeScript, [`env`](/docs/en/agent-sdk/typescript#options) replaces the inherited environment, so spread `process.env` into it.
419421
420| Built-in context | How to turn it off |
421| :---------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
422| The built-in commit and pull request instructions and the git status snapshot | Set [`includeGitInstructions`](/docs/en/settings-reference#includegitinstructions) to `false`, or `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1` |
423| The `Co-Authored-By` trailer and the pull request footer | Set [`attribution.commit`](/docs/en/settings-reference#attribution-commit) and [`attribution.pr`](/docs/en/settings-reference#attribution-pr) to your own text, or to empty strings to remove them |
424| The user or project settings source, including its CLAUDE.md | Leave `'user'` or `'project'` out of [`settingSources`](/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources) |
425| Every CLAUDE.md file | Set `CLAUDE_CODE_DISABLE_CLAUDE_MDS=1` |
426| Task list nudges, file-changed notes, and the skill list | Set `CLAUDE_CODE_DISABLE_ATTACHMENTS=1` |
422| Built-in context | How to turn it off |
423| :- | :- |
424| The built-in commit and pull request instructions and the git status snapshot | Set [`includeGitInstructions`](/docs/en/settings-reference#includegitinstructions) to `false`, or `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1` |
425| The `Co-Authored-By` trailer and the pull request footer | Set [`attribution.commit`](/docs/en/settings-reference#attribution-commit) and [`attribution.pr`](/docs/en/settings-reference#attribution-pr) to your own text, or to empty strings to remove them |
426| The user or project settings source, including its CLAUDE.md | Leave `'user'` or `'project'` out of [`settingSources`](/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources) |
427| Every CLAUDE.md file | Set `CLAUDE_CODE_DISABLE_CLAUDE_MDS=1` |
428| Task list nudges, file-changed notes, and the skill list | Set `CLAUDE_CODE_DISABLE_ATTACHMENTS=1` |
427429
428430Claude Code's built-in commit and pull request instructions aren't a reminder. They are part of the Bash tool's description, so they also reach Claude when you pass a custom `systemPrompt`.
429431
from line 496
494496
495497The four customization methods differ in where they live, how they're shared, and what they preserve from the `claude_code` preset.
496498
497| Feature | CLAUDE.md | Output Styles | `systemPrompt` with append | Custom `systemPrompt` |
498| ----------------------- | ---------------- | ------------------------- | -------------------------- | ---------------------- |
499| **Persistence** | Per-project file | Saved as files | Session only | Session only |
500| **Reusability** | Per-project | Across projects | Code duplication | Code duplication |
501| **Management** | On filesystem | CLI + files | In code | In code |
502| **Default tools** | Preserved | Preserved | Preserved | Lost (unless included) |
503| **Built-in safety** | Maintained | Maintained | Maintained | Must be added |
504| **Environment context** | Automatic | Automatic | Automatic | Must be provided |
505| **Customization level** | Additions only | Replace or extend default | Additions only | Complete control |
506| **Version control** | With project | Yes | With code | With code |
507| **Scope** | Project-specific | User or project | Code session | Code session |
499| Feature | CLAUDE.md | Output Styles | `systemPrompt` with append | Custom `systemPrompt` |
500| - | - | - | - | - |
501| **Persistence** | Per-project file | Saved as files | Session only | Session only |
502| **Reusability** | Per-project | Across projects | Code duplication | Code duplication |
503| **Management** | On filesystem | CLI + files | In code | In code |
504| **Default tools** | Preserved | Preserved | Preserved | Lost (unless included) |
505| **Built-in safety** | Maintained | Maintained | Maintained | Must be added |
506| **Customization level** | Additions only | Replace or extend default | Additions only | Complete control |
507| **Version control** | With project | Yes | With code | With code |
508| **Scope** | Project-specific | User or project | Code session | Code session |
508509
509510"With append" means using `systemPrompt: { type: "preset", preset: "claude_code", append: "..." }` in TypeScript or `system_prompt={"type": "preset", "preset": "claude_code", "append": "..."}` in Python. CLAUDE.md doesn't change the system prompt itself: the SDK injects its content into the conversation as project context.
510511
agent-sdk/observability Changed · +10 / -10 lines
from line 24
2424
2525The CLI exports three independent OpenTelemetry signals. Each has its own enable switch and its own exporter, so you can turn on only the ones you need.
2626
27| Signal | What it contains | Enable with |
28| ---------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------- |
29| Metrics | Counters for tokens, cost, sessions, lines of code, and tool decisions | `OTEL_METRICS_EXPORTER` |
30| Log events | Structured records for each prompt, API request, API error, and tool result | `OTEL_LOGS_EXPORTER` |
31| Traces | Spans for each interaction, model request, tool call, and hook (beta) | `OTEL_TRACES_EXPORTER` plus `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` |
27| Signal | What it contains | Enable with |
28| - | - | - |
29| Metrics | Counters for tokens, cost, sessions, lines of code, and tool decisions | `OTEL_METRICS_EXPORTER` |
30| Log events | Structured records for each prompt, API request, API error, and tool result | `OTEL_LOGS_EXPORTER` |
31| Traces | Spans for each interaction, model request, tool call, and hook (beta) | `OTEL_TRACES_EXPORTER` plus `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` |
3232
3333For the complete list of metric names, event names, and attributes, see the Claude Code [Monitoring](/docs/en/monitoring-usage) reference. The Agent SDK emits the same data because it runs the same CLI. Span names are listed in [Read agent traces](#read-agent-traces) below.
3434
from line 230
230230
231231Telemetry is structural by default. Durations, model names, and tool names are recorded on every span; token counts are recorded when the underlying API request returns usage data, so spans for failed or aborted requests may omit them. The content your agent reads and writes is not recorded by default. These opt-in variables add content to the exported data:
232232
233| Variable | Adds |
234| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
235| `OTEL_LOG_USER_PROMPTS=1` | Prompt text on `claude_code.user_prompt` events and on the `claude_code.interaction` span |
236| `OTEL_LOG_TOOL_DETAILS=1` | Tool input arguments (file paths, shell commands, search patterns) on `claude_code.tool_result` events |
237| `OTEL_LOG_TOOL_CONTENT=1` | A [`tool.output` span event](/docs/en/monitoring-usage#tool-output-span-event) on `claude_code.tool` with file contents, Bash output, and what MCP tools, WebFetch, and WebSearch return, truncated at 60 KB by default, configurable via `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH`, which requires Claude Code v2.1.214 or later. Results from MCP tools, WebFetch, and WebSearch require Claude Code v2.1.283 or later. Requires [tracing](#read-agent-traces) to be enabled. Span attributes carry tool content under [their own gates](/docs/en/monitoring-usage#new-context-gates) |
233| Variable | Adds |
234| - | - |
235| `OTEL_LOG_USER_PROMPTS=1` | Prompt text on `claude_code.user_prompt` events and on the `claude_code.interaction` span |
236| `OTEL_LOG_TOOL_DETAILS=1` | Tool input arguments (file paths, shell commands, search patterns) on `claude_code.tool_result` events |
237| `OTEL_LOG_TOOL_CONTENT=1` | A [`tool.output` span event](/docs/en/monitoring-usage#tool-output-span-event) on `claude_code.tool` with file contents, Bash output, and what MCP tools, WebFetch, and WebSearch return, truncated at 60 KB by default, configurable via `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH`, which requires Claude Code v2.1.214 or later. Results from MCP tools, WebFetch, and WebSearch require Claude Code v2.1.283 or later. Requires [tracing](#read-agent-traces) to be enabled. Span attributes carry tool content under [their own gates](/docs/en/monitoring-usage#new-context-gates) |
238238| `OTEL_LOG_RAW_API_BODIES` | Full Anthropic Messages API request and response JSON as `claude_code.api_request_body` and `claude_code.api_response_body` log events. Set to `1` for inline bodies truncated at 60 KB by default, or `file:<dir>` for untruncated bodies on disk with a `body_ref` path in the event. `CLAUDE_CODE_OTEL_CONTENT_MAX_LENGTH` configures the inline truncation limit, and requires Claude Code v2.1.214 or later. Bodies include the entire conversation history and have extended-thinking content redacted. Enabling this implies consent to everything the three variables above would reveal |
239239
240240Leave these unset unless your observability pipeline is approved to store the data your agent handles. See [Security and privacy](/docs/en/monitoring-usage#security-and-privacy) in the Monitoring reference for the full list of attributes and redaction behavior.
agent-sdk/overview Changed · +15 / -15 lines
from line 8
88
99The Agent SDK, the CLI, the Client SDK, and Managed Agents differ in who runs the agent, what comes built in, and how you reach it. Find the row that matches how you want to build and run yours.
1010
11| You want to | Use | What you get |
12| ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13| Embed Claude Code's agent in your own Python or TypeScript application, in a process you operate | **Agent SDK** | A library that runs the Claude Code binary, with Claude Code's [capabilities](#capabilities), such as built-in tools, permissions, sessions, and hooks. |
14| Do interactive development or run one-off tasks from a terminal | [**Claude Code CLI**](/docs/en/overview) | The terminal interface, built for daily interactive use. |
15| Call the Claude API directly from your own code | [**Client SDK**](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) | Direct access to the Claude API from any of the client SDK languages. You write the tool loop yourself, or let the client SDK's beta [tool runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner) drive it. |
16| Have Anthropic host the agent, configured through the Claude API | [**Managed Agents**](https://platform.claude.com/docs/en/managed-agents/overview) | A hosted agent harness that runs the agent loop, with sessions in an Anthropic-managed cloud sandbox or a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes) on your own infrastructure. Use it from the [SDK for your language](https://platform.claude.com/docs/en/managed-agents/quickstart#install-the-sdk), the `ant` CLI, or the REST API. |
11| You want to | Use | What you get |
12| - | - | - |
13| Embed Claude Code's agent in your own Python or TypeScript application, in a process you operate | **Agent SDK** | A library that runs the Claude Code binary, with Claude Code's [capabilities](#capabilities), such as built-in tools, permissions, sessions, and hooks. |
14| Do interactive development or run one-off tasks from a terminal | [**Claude Code CLI**](/docs/en/overview) | The terminal interface, built for daily interactive use. |
15| Call the Claude API directly from your own code | [**Client SDK**](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) | Direct access to the Claude API from any of the client SDK languages. You write the tool loop yourself, or let the client SDK's beta [tool runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner) drive it. |
16| Have Anthropic host the agent, configured through the Claude API | [**Managed Agents**](https://platform.claude.com/docs/en/managed-agents/overview) | A hosted agent harness that runs the agent loop, with sessions in an Anthropic-managed cloud sandbox or a [self-hosted sandbox](https://platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes) on your own infrastructure. Use it from the [SDK for your language](https://platform.claude.com/docs/en/managed-agents/quickstart#install-the-sdk), the `ant` CLI, or the REST API. |
1717
1818To drive the same agent loop from a language other than Python or TypeScript, [run the CLI as a subprocess](/docs/en/headless) with the `-p` flag and `--output-format json`.
1919
from line 21
2121
2222These Claude Code capabilities are available in the SDK:
2323
24| Capability | What it does | Learn more |
25| ---------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26| Built-in tools | Read, write, edit files, run commands, and search the web | [Tools reference](/docs/en/tools-reference) |
27| Hooks | Run custom code at key points in the agent lifecycle | [Hooks](/docs/en/agent-sdk/hooks) |
28| Subagents | Spawn specialized agents for focused subtasks | [Subagents](/docs/en/agent-sdk/subagents) |
29| MCP | Connect external tools and data sources via the Model Context Protocol | [MCP](/docs/en/agent-sdk/mcp) |
30| Permissions | Control which tools run automatically, which need approval | [Permissions](/docs/en/agent-sdk/permissions) |
31| Sessions | Maintain context across exchanges, resume or fork later | [Sessions](/docs/en/agent-sdk/sessions) |
24| Capability | What it does | Learn more |
25| - | - | - |
26| Built-in tools | Read, write, edit files, run commands, and search the web | [Tools reference](/docs/en/tools-reference) |
27| Hooks | Run custom code at key points in the agent lifecycle | [Hooks](/docs/en/agent-sdk/hooks) |
28| Subagents | Spawn specialized agents for focused subtasks | [Subagents](/docs/en/agent-sdk/subagents) |
29| MCP | Connect external tools and data sources via the Model Context Protocol | [MCP](/docs/en/agent-sdk/mcp) |
30| Permissions | Control which tools run automatically, which need approval | [Permissions](/docs/en/agent-sdk/permissions) |
31| Sessions | Maintain context across exchanges, resume or fork later | [Sessions](/docs/en/agent-sdk/sessions) |
3232| Skills, commands, and memory | Load automatically from your project's `.claude/` and from `~/.claude/`, same as Claude Code | [Skills](/docs/en/agent-sdk/skills), [Commands](/docs/en/agent-sdk/skills#commands-in-agent-sdk-sessions), [Memory](/docs/en/agent-sdk/modifying-system-prompts), [Configuration loading](/docs/en/agent-sdk/claude-code-features) |
33| Plugins | Package skills, agents, hooks, and MCP servers, and load them by local path | [Plugins](/docs/en/agent-sdk/plugins) |
33| Plugins | Package skills, agents, hooks, and MCP servers, and load them by local path | [Plugins](/docs/en/agent-sdk/plugins) |
3434
3535## Get started
3636
agent-sdk/permissions Changed · +13 / -13 lines
from line 69
6969
7070`allowed_tools` and `disallowed_tools` (TypeScript: `allowedTools` / `disallowedTools`) add entries to the allow and deny rule lists in the evaluation flow above. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability) in `allowed_tools`, Claude Code also opts the session in. Any other tool not listed in `allowed_tools` is still available to Claude, and a call to it that needs approval falls through to the permission mode. Deny rules behave differently depending on whether they name a tool or scope a pattern within one.
7171
72| Option | Effect |
73| :-------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
74| `allowed_tools=["Read", "Grep"]` | `Read` and `Grep` are auto-approved. Other tools not listed here still exist, and calls to them that need approval fall through to the permission mode and `canUseTool`. |
75| `disallowed_tools=["Bash"]` | The `Bash` tool definition is removed from the request. Claude does not see the tool and cannot attempt it. |
72| Option | Effect |
73| :- | :- |
74| `allowed_tools=["Read", "Grep"]` | `Read` and `Grep` are auto-approved. Other tools not listed here still exist, and calls to them that need approval fall through to the permission mode and `canUseTool`. |
75| `disallowed_tools=["Bash"]` | The `Bash` tool definition is removed from the request. Claude does not see the tool and cannot attempt it. |
7676| `disallowed_tools=["Bash(rm *)"]` | `Bash` stays available. Calls matching `rm *` [as written](/docs/en/permissions#bash-rule-limits) are denied in every permission mode, including `bypassPermissions`. Other `Bash` calls, including `/bin/rm`, fall through to the permission mode. |
77| `disallowed_tools=["*"]` | Every tool definition is removed from the request. Tool-name globs are supported in deny rules: `"*"` matches every tool and `"mcp__*"` matches every MCP tool across all servers. |
77| `disallowed_tools=["*"]` | Every tool definition is removed from the request. Tool-name globs are supported in deny rules: `"*"` matches every tool and `"mcp__*"` matches every MCP tool across all servers. |
7878
7979Allow rules accept tool-name globs only after a literal `mcp__<server>__` prefix. The server segment must be glob-free so the rule names a specific server you configured: `mcp__puppeteer__*` matches every tool from the `puppeteer` server, and `mcp__github__get_*` matches its `get_` tools. An unanchored entry like `allowed_tools=["*"]` or `allowed_tools=["mcp__*"]` is ignored with a startup warning and does not auto-approve anything.
8080
from line 115
115115
116116The SDK supports these permission modes:
117117
118| Mode | Description | Tool behavior |
119| :------------------ | :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
120| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |
121| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied. Calls approved by `allowed_tools` or rules run, and so do calls that need no approval in `default` mode; connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even if you've pre-approved them, as are `rm` and `rmdir` removals targeting a [critical path](/docs/en/permission-modes#critical-paths). `canUseTool` is never called |
122| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |
123| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](/docs/en/permission-modes#actions-no-mode-auto-approves). Use with caution |
124| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |
125| `auto` | Model-classified approvals | A model classifier approves or denies permission prompts. See [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) for availability |
118| Mode | Description | Tool behavior |
119| :- | :- | :- |
120| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |
121| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied. Calls approved by `allowed_tools` or rules run, and so do calls that need no approval in `default` mode; connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and tools that require user interaction are denied even if you've pre-approved them, as are `rm` and `rmdir` removals targeting a [critical path](/docs/en/permission-modes#critical-paths). `canUseTool` is never called |
122| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |
123| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](/docs/en/permission-modes#actions-no-mode-auto-approves). Use with caution |
124| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |
125| `auto` | Model-classified approvals | A model classifier approves or denies permission prompts. See [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) for availability |
126126
127127<Warning>
128128 **Subagent inheritance:** A subagent runs in the parent session's permission mode unless you set `permissionMode` on its [`AgentDefinition`](/docs/en/agent-sdk/typescript#agentdefinition) and the parent session is in `default`, `dontAsk`, or `plan` mode. Even then, Claude Code never applies a `"bypassPermissions"` value. A subagent runs in `bypassPermissions` mode only when the parent session itself does. The `bypassPermissions` exception requires Claude Code v2.1.267 or later.
agent-sdk/python Changed · +435 / -435 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 18
1818
1919The Python SDK provides two ways to interact with Claude Code:
2020
21| Feature | `query()` | `ClaudeSDKClient` |
22| :------------------ | :--------------------------------------------- | :--------------------------------- |
23| **Session** | Creates a new session by default | Reuses same session |
24| **Conversation** | Single exchange | Multiple exchanges in same context |
25| **Connection** | Managed automatically | Manual control |
26| **Streaming Input** | ✅ Supported | ✅ Supported |
27| **Interrupts** | ❌ Not supported | ✅ Supported |
28| **Hooks** | ✅ Supported | ✅ Supported |
29| **Custom Tools** | ✅ Supported | ✅ Supported |
30| **Continue Chat** | Manual via `continue_conversation` or `resume` | ✅ Automatic |
31| **Use Case** | One-off tasks | Continuous conversations |
21| Feature | `query()` | `ClaudeSDKClient` |
22| :- | :- | :- |
23| **Session** | Creates a new session by default | Reuses same session |
24| **Conversation** | Single exchange | Multiple exchanges in same context |
25| **Connection** | Managed automatically | Manual control |
26| **Streaming Input** | ✅ Supported | ✅ Supported |
27| **Interrupts** | ❌ Not supported | ✅ Supported |
28| **Hooks** | ✅ Supported | ✅ Supported |
29| **Custom Tools** | ✅ Supported | ✅ Supported |
30| **Continue Chat** | Manual via `continue_conversation` or `resume` | ✅ Automatic |
31| **Use Case** | One-off tasks | Continuous conversations |
3232
3333Use `ClaudeSDKClient` for interactive applications such as chat interfaces, or when the next action depends on Claude's response.
3434
from line 51
5151
5252#### Parameters
5353
54| Parameter | Type | Description |
55| :---------- | :--------------------------- | :------------------------------------------------------------------------- |
56| `prompt` | `str \| AsyncIterable[dict]` | The input prompt as a string or async iterable for streaming mode |
57| `options` | `ClaudeAgentOptions \| None` | Optional configuration object (defaults to `ClaudeAgentOptions()` if None) |
58| `transport` | `Transport \| None` | Optional custom transport for communicating with the CLI process |
54| Parameter | Type | Description |
55| :- | :- | :- |
56| `prompt` | `str \| AsyncIterable[dict]` | The input prompt as a string or async iterable for streaming mode |
57| `options` | `ClaudeAgentOptions \| None` | Optional configuration object (defaults to `ClaudeAgentOptions()` if None) |
58| `transport` | `Transport \| None` | Optional custom transport for communicating with the CLI process |
5959
6060#### Returns
6161
from line 96
9696
9797#### Parameters
9898
99| Parameter | Type | Description |
100| :------------- | :---------------------------------------------- | :--------------------------------------------------------------------------------------------- |
101| `name` | `str` | Unique identifier for the tool |
102| `description` | `str` | Human-readable description of what the tool does |
103| `input_schema` | `type \| dict[str, Any]` | Schema defining the tool's input parameters. See [Input schema options](#input-schema-options) |
104| `annotations` | [`ToolAnnotations`](#toolannotations)` \| None` | Optional MCP tool annotations providing behavioral hints to clients |
99| Parameter | Type | Description |
100| :- | :- | :- |
101| `name` | `str` | Unique identifier for the tool |
102| `description` | `str` | Human-readable description of what the tool does |
103| `input_schema` | `type \| dict[str, Any]` | Schema defining the tool's input parameters. See [Input schema options](#input-schema-options) |
104| `annotations` | [`ToolAnnotations`](#toolannotations)` \| None` | Optional MCP tool annotations providing behavioral hints to clients |
105105
106106#### Input schema options
107107
from line 147
147147
148148All fields are optional. Clients shouldn't rely on the hints for security decisions.
149149
150| Field | Type | Default | Description |
151| :------------------- | :------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
152| `title` | `str \| None` | `None` | Human-readable title for the tool |
153| `readOnlyHint` | `bool \| None` | `False` | If `True`, the tool does not modify its environment |
154| `destructiveHint` | `bool \| None` | `True` | If `True`, the tool may perform destructive updates (only meaningful when `readOnlyHint` is `False`) |
155| `idempotentHint` | `bool \| None` | `False` | If `True`, repeated calls with the same arguments have no additional effect (only meaningful when `readOnlyHint` is `False`) |
156| `openWorldHint` | `bool \| None` | `True` | If `True`, the tool interacts with external entities (for example, web search). If `False`, the tool's domain is closed (for example, a memory tool) |
157| `maxResultSizeChars` | `int \| None` | `None` | Number of characters up to which Claude Code keeps this tool's text result inline in the conversation instead of saving it to a file, up to 500,000. Results that contain images aren't affected. A Claude Code setting rather than an MCP hint: the SDK sends it in the tool's `_meta` as `anthropic/maxResultSizeChars`. See [Raise the limit for a specific tool](/docs/en/mcp#raise-the-limit-for-a-specific-tool) |
150| Field | Type | Default | Description |
151| :- | :- | :- | :- |
152| `title` | `str \| None` | `None` | Human-readable title for the tool |
153| `readOnlyHint` | `bool \| None` | `False` | If `True`, the tool does not modify its environment |
154| `destructiveHint` | `bool \| None` | `True` | If `True`, the tool may perform destructive updates (only meaningful when `readOnlyHint` is `False`) |
155| `idempotentHint` | `bool \| None` | `False` | If `True`, repeated calls with the same arguments have no additional effect (only meaningful when `readOnlyHint` is `False`) |
156| `openWorldHint` | `bool \| None` | `True` | If `True`, the tool interacts with external entities (for example, web search). If `False`, the tool's domain is closed (for example, a memory tool) |
157| `maxResultSizeChars` | `int \| None` | `None` | Number of characters up to which Claude Code keeps this tool's text result inline in the conversation instead of saving it to a file, up to 500,000. Results that contain images aren't affected. A Claude Code setting rather than an MCP hint: the SDK sends it in the tool's `_meta` as `anthropic/maxResultSizeChars`. See [Raise the limit for a specific tool](/docs/en/mcp#raise-the-limit-for-a-specific-tool) |
158158
159159```python theme={null}
160160from claude_agent_sdk import tool, ToolAnnotations
from line 185
185185
186186#### Parameters
187187
188| Parameter | Type | Default | Description |
189| :-------- | :------------------------------ | :-------- | :---------------------------------------------------- |
190| `name` | `str` | - | Unique identifier for the server |
191| `version` | `str` | `"1.0.0"` | Server version string |
192| `tools` | `list[SdkMcpTool[Any]] \| None` | `None` | List of tool functions created with `@tool` decorator |
188| Parameter | Type | Default | Description |
189| :- | :- | :- | :- |
190| `name` | `str` | - | Unique identifier for the server |
191| `version` | `str` | `"1.0.0"` | Server version string |
192| `tools` | `list[SdkMcpTool[Any]] \| None` | `None` | List of tool functions created with `@tool` decorator |
193193
194194#### Returns
195195
from line 239
239239
240240#### Parameters
241241
242| Parameter | Type | Default | Description |
243| :------------------ | :------------ | :------ | :----------------------------------------------------------------------------------------------- |
244| `directory` | `str \| None` | `None` | Directory to list sessions for. When omitted, returns sessions across all projects |
245| `limit` | `int \| None` | `None` | Maximum number of sessions to return |
246| `offset` | `int` | `0` | Number of sessions to skip from the start of the sorted results. Use with `limit` for pagination |
247| `include_worktrees` | `bool` | `True` | When `directory` is inside a git repository, include sessions from all worktree paths |
242| Parameter | Type | Default | Description |
243| :- | :- | :- | :- |
244| `directory` | `str \| None` | `None` | Directory to list sessions for. When omitted, returns sessions across all projects |
245| `limit` | `int \| None` | `None` | Maximum number of sessions to return |
246| `offset` | `int` | `0` | Number of sessions to skip from the start of the sorted results. Use with `limit` for pagination |
247| `include_worktrees` | `bool` | `True` | When `directory` is inside a git repository, include sessions from all worktree paths |
248248
249249#### Return type: `SDKSessionInfo`
250250
251| Property | Type | Description |
252| :-------------- | :------------ | :--------------------------------------------------------------------------------------- |
253| `session_id` | `str` | Unique session identifier |
254| `summary` | `str` | Display title: custom title, most recent prompt, auto-generated summary, or first prompt |
255| `last_modified` | `int` | Last modified time in milliseconds since epoch |
256| `file_size` | `int \| None` | Session file size in bytes (`None` for remote storage backends) |
257| `custom_title` | `str \| None` | Session title: the user-set title, or the auto-generated title when none is set |
258| `first_prompt` | `str \| None` | First meaningful user prompt in the session |
259| `git_branch` | `str \| None` | Git branch at the end of the session |
260| `cwd` | `str \| None` | Working directory for the session |
261| `tag` | `str \| None` | User-set session tag (see [`tag_session()`](#tag_session)) |
262| `created_at` | `int \| None` | Session creation time in milliseconds since epoch |
251| Property | Type | Description |
252| :- | :- | :- |
253| `session_id` | `str` | Unique session identifier |
254| `summary` | `str` | Display title: custom title, most recent prompt, auto-generated summary, or first prompt |
255| `last_modified` | `int` | Last modified time in milliseconds since epoch |
256| `file_size` | `int \| None` | Session file size in bytes (`None` for remote storage backends) |
257| `custom_title` | `str \| None` | Session title: the user-set title, or the auto-generated title when none is set |
258| `first_prompt` | `str \| None` | First meaningful user prompt in the session |
259| `git_branch` | `str \| None` | Git branch at the end of the session |
260| `cwd` | `str \| None` | Working directory for the session |
261| `tag` | `str \| None` | User-set session tag (see [`tag_session()`](#tag_session)) |
262| `created_at` | `int \| None` | Session creation time in milliseconds since epoch |
263263
264264#### Example
265265
from line 287
287287
288288#### Parameters
289289
290| Parameter | Type | Default | Description |
291| :----------- | :------------ | :------- | :---------------------------------------------------------------- |
292| `session_id` | `str` | required | The session ID to retrieve messages for |
293| `directory` | `str \| None` | `None` | Project directory to look in. When omitted, searches all projects |
294| `limit` | `int \| None` | `None` | Maximum number of messages to return |
295| `offset` | `int` | `0` | Number of messages to skip from the start |
290| Parameter | Type | Default | Description |
291| :- | :- | :- | :- |
292| `session_id` | `str` | required | The session ID to retrieve messages for |
293| `directory` | `str \| None` | `None` | Project directory to look in. When omitted, searches all projects |
294| `limit` | `int \| None` | `None` | Maximum number of messages to return |
295| `offset` | `int` | `0` | Number of messages to skip from the start |
296296
297297#### Return type: `SessionMessage`
298298
299| Property | Type | Description |
300| :------------------- | :----------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
301| `type` | `Literal["user", "assistant"]` | Message role |
302| `uuid` | `str` | Unique message identifier |
303| `session_id` | `str` | Session identifier |
304| `message` | `Any` | Raw message content |
305| `parent_tool_use_id` | `str \| None` | For subagent messages, the id of the spawning `Agent` tool-use block. `None` for main-session messages and older sessions |
306| `parent_agent_id` | `str \| None` | For messages from a [nested subagent](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents), the agent id of the parent subagent. `None` for main-session messages, top-level subagent messages, and older sessions. Requires Python Agent SDK 0.2.140 or later |
299| Property | Type | Description |
300| :- | :- | :- |
301| `type` | `Literal["user", "assistant"]` | Message role |
302| `uuid` | `str` | Unique message identifier |
303| `session_id` | `str` | Session identifier |
304| `message` | `Any` | Raw message content |
305| `parent_tool_use_id` | `str \| None` | For subagent messages, the id of the spawning `Agent` tool-use block. `None` for main-session messages and older sessions |
306| `parent_agent_id` | `str \| None` | For messages from a [nested subagent](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents), the agent id of the parent subagent. `None` for main-session messages, top-level subagent messages, and older sessions. Requires Python Agent SDK 0.2.140 or later |
307307
308308#### Example
309309
from line 330
330330
331331#### Parameters
332332
333| Parameter | Type | Default | Description |
334| :----------- | :------------ | :------- | :--------------------------------------------------------------------- |
335| `session_id` | `str` | required | UUID of the session to look up |
336| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
333| Parameter | Type | Default | Description |
334| :- | :- | :- | :- |
335| `session_id` | `str` | required | UUID of the session to look up |
336| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
337337
338338Returns [`SDKSessionInfo`](#return-type-sdksessioninfo), or `None` if the session is not found.
339339
from line 363
363363
364364#### Parameters
365365
366| Parameter | Type | Default | Description |
367| :----------- | :------------ | :------- | :--------------------------------------------------------------------- |
368| `session_id` | `str` | required | UUID of the session to rename |
369| `title` | `str` | required | New title. Must be non-empty after stripping whitespace |
370| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
366| Parameter | Type | Default | Description |
367| :- | :- | :- | :- |
368| `session_id` | `str` | required | UUID of the session to rename |
369| `title` | `str` | required | New title. Must be non-empty after stripping whitespace |
370| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
371371
372372Raises `ValueError` if `session_id` is not a valid UUID or `title` is empty; `FileNotFoundError` if the session cannot be found.
373373
from line 397
397397
398398#### Parameters
399399
400| Parameter | Type | Default | Description |
401| :----------- | :------------ | :------- | :--------------------------------------------------------------------- |
402| `session_id` | `str` | required | UUID of the session to tag |
403| `tag` | `str \| None` | required | Tag string, or `None` to clear. Unicode-sanitized before storing |
404| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
400| Parameter | Type | Default | Description |
401| :- | :- | :- | :- |
402| `session_id` | `str` | required | UUID of the session to tag |
403| `tag` | `str \| None` | required | Tag string, or `None` to clear. Unicode-sanitized before storing |
404| `directory` | `str \| None` | `None` | Project directory path. When omitted, searches all project directories |
405405
406406Raises `ValueError` if `session_id` is not a valid UUID or `tag` is empty after sanitization; `FileNotFoundError` if the session cannot be found.
407407
from line 450
450450
451451#### Methods
452452
453| Method | Description |
454| :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
455| `__init__(options)` | Initialize the client with optional configuration |
456| `connect(prompt)` | Connect to Claude with an optional initial prompt or message stream |
457| `query(prompt, session_id)` | Send a new request in streaming mode |
458| `receive_messages()` | Receive all messages from Claude as an async iterator |
459| `receive_response()` | Receive messages until and including a ResultMessage |
460| `interrupt()` | Send interrupt signal (only works in streaming mode) |
461| `set_permission_mode(mode)` | Change the permission mode for the current session |
462| `set_model(model)` | Change the model for the current session. Pass `None` to reset to [Claude Code's default model](/docs/en/model-config) |
463| `rewind_files(user_message_id)` | Restore files to their state at the specified user message. Requires `enable_file_checkpointing=True`. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
464| `get_mcp_status()` | Get the status of all configured MCP servers. Returns [`McpStatusResponse`](#mcpstatusresponse) |
465| `reconnect_mcp_server(server_name)` | Retry connecting to an MCP server that failed or was disconnected |
466| `toggle_mcp_server(server_name, enabled)` | Enable or disable an MCP server mid-session. Disabling removes its tools |
467| `stop_task(task_id)` | Stop a running background task. A [`TaskNotificationMessage`](#tasknotificationmessage) with status `"stopped"` follows in the message stream |
468| `get_server_info()` | Get the server's initialization info, including available commands and output styles |
469| `disconnect()` | Disconnect from Claude |
453| Method | Description |
454| :- | :- |
455| `__init__(options)` | Initialize the client with optional configuration |
456| `connect(prompt)` | Connect to Claude with an optional initial prompt or message stream |
457| `query(prompt, session_id)` | Send a new request in streaming mode |
458| `receive_messages()` | Receive all messages from Claude as an async iterator |
459| `receive_response()` | Receive messages until and including a ResultMessage |
460| `interrupt()` | Send interrupt signal (only works in streaming mode) |
461| `set_permission_mode(mode)` | Change the permission mode for the current session |
462| `set_model(model)` | Change the model for the current session. Pass `None` to reset to [Claude Code's default model](/docs/en/model-config) |
463| `rewind_files(user_message_id)` | Restore files to their state at the specified user message. Requires `enable_file_checkpointing=True`. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
464| `get_mcp_status()` | Get the status of all configured MCP servers. Returns [`McpStatusResponse`](#mcpstatusresponse) |
465| `reconnect_mcp_server(server_name)` | Retry connecting to an MCP server that failed or was disconnected |
466| `toggle_mcp_server(server_name, enabled)` | Enable or disable an MCP server mid-session. Disabling removes its tools |
467| `stop_task(task_id)` | Stop a running background task. A [`TaskNotificationMessage`](#tasknotificationmessage) with status `"stopped"` follows in the message stream |
468| `get_server_info()` | Get the server's initialization info, including available commands and output styles |
469| `disconnect()` | Disconnect from Claude |
470470
471471#### Context Manager Support
472472
from line 687
687687 annotations: ToolAnnotations | None = None
688688```
689689
690| Property | Type | Description |
691| :------------- | :---------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- |
692| `name` | `str` | Unique identifier for the tool |
693| `description` | `str` | Human-readable description |
694| `input_schema` | `type[T] \| dict[str, Any]` | Schema for input validation |
695| `handler` | `Callable[[T], Awaitable[dict[str, Any]]]` | Async function that handles tool execution |
696| `annotations` | [`ToolAnnotations`](#toolannotations)` \| None` | Optional tool annotations (for example `readOnlyHint`, `destructiveHint`, `openWorldHint`, `maxResultSizeChars`) |
690| Property | Type | Description |
691| :- | :- | :- |
692| `name` | `str` | Unique identifier for the tool |
693| `description` | `str` | Human-readable description |
694| `input_schema` | `type[T] \| dict[str, Any]` | Schema for input validation |
695| `handler` | `Callable[[T], Awaitable[dict[str, Any]]]` | Async function that handles tool execution |
696| `annotations` | [`ToolAnnotations`](#toolannotations)` \| None` | Optional tool annotations (for example `readOnlyHint`, `destructiveHint`, `openWorldHint`, `maxResultSizeChars`) |
697697
698698### `Transport`
699699
from line 729
729729 async def end_input(self) -> None: ...
730730```
731731
732| Method | Description |
733| :---------------- | :-------------------------------------------------------------------------- |
734| `connect()` | Connect the transport and prepare for communication |
735| `write(data)` | Write raw data (JSON + newline) to the transport |
736| `read_messages()` | Async iterator that yields parsed JSON messages |
737| `close()` | Close the connection and clean up resources |
738| `is_ready()` | Returns `True` if the transport can send and receive |
739| `end_input()` | Close the input stream (for example, close stdin for subprocess transports) |
732| Method | Description |
733| :- | :- |
734| `connect()` | Connect the transport and prepare for communication |
735| `write(data)` | Write raw data (JSON + newline) to the transport |
736| `read_messages()` | Async iterator that yields parsed JSON messages |
737| `close()` | Close the connection and clean up resources |
738| `is_ready()` | Returns `True` if the transport can send and receive |
739| `end_input()` | Close the input stream (for example, close stdin for subprocess transports) |
740740
741741Import: `from claude_agent_sdk import Transport`
742742
from line 798
798798 task_budget: TaskBudget | None = None
799799```
800800
801| Property | Type | Default | Description |
802| :---------------------------- | :------------------------------------------------------------------------------------ | :--------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
803| `tools` | `list[str] \| ToolsPreset \| None` | `None` | Tools configuration. Use `{"type": "preset", "preset": "claude_code"}` for Claude Code's default tools |
804| `allowed_tools` | `list[str]` | `[]` | Tools to auto-approve without prompting. This does not restrict Claude to only these tools. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability) here, Claude Code also opts the session in. Other unlisted tools fall through to `permission_mode` and `can_use_tool`. Use `disallowed_tools` to block tools. See [Permissions](/docs/en/agent-sdk/permissions#allow-and-deny-rules) |
805| `system_prompt` | `str \| SystemPromptPreset \| SystemPromptCustom \| SystemPromptFile \| None` | `None` | System prompt configuration. Pass a string for a custom prompt, `{"type": "preset", "preset": "claude_code"}` for Claude Code's system prompt with optional `"append"`, `{"type": "custom", "prompt": "..."}` for a custom prompt that can also set `"snapshot"`, or `{"type": "file", "path": "..."}` to load a large prompt from disk. See [`SystemPromptPreset`](#systempromptpreset), [`SystemPromptCustom`](#systempromptcustom), and [`SystemPromptFile`](#systempromptfile) |
806| `mcp_servers` | `dict[str, McpServerConfig] \| str \| Path` | `{}` | MCP server configurations or path to config file |
807| `strict_mcp_config` | `bool` | `False` | When `True`, use only the servers passed in `mcp_servers` and ignore project `.mcp.json`, user settings, plugin-provided MCP servers, and [claude.ai connectors](/docs/en/mcp#use-mcp-servers-from-claude-ai). Maps to the CLI `--strict-mcp-config` flag |
808| `permission_mode` | `PermissionMode \| None` | `None` | Permission mode for tool usage |
809| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |
810| `resume` | `str \| None` | `None` | Session ID to resume |
811| `session_id` | `str \| None` | `None` | Use a specific session ID instead of an auto-generated one. Must be a valid UUID. Can't be combined with `continue_conversation` or `resume` unless `fork_session` is also set |
812| `max_turns` | `int \| None` | `None` | Maximum agentic turns (tool-use round trips) |
813| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](/docs/en/agent-sdk/cost-tracking) |
814| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`, for the command [as written](/docs/en/permissions#bash-rule-limits). See [Permissions](/docs/en/agent-sdk/permissions#allow-and-deny-rules) |
815| `enable_file_checkpointing` | `bool` | `False` | Enable file change tracking for rewinding. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
816| `model` | `str \| None` | `None` | Claude model alias or full model name. See [accepted values and provider-specific IDs](/docs/en/model-config#available-models) |
817| `fallback_model` | `str \| None` | `None` | Fallback model to use if the primary model fails. Accepts a comma-separated list. For guidance, see [Choose a model](/docs/en/agent-sdk/configuration#choose-a-model) |
818| `betas` | `list[SdkBeta]` | `[]` | Beta features to enable. See [`SdkBeta`](#sdkbeta) for available options |
819| `output_format` | `dict[str, Any] \| None` | `None` | Output format for structured responses (e.g., `{"type": "json_schema", "schema": {...}}`). See [Structured outputs](/docs/en/agent-sdk/structured-outputs) for details |
820| `permission_prompt_tool_name` | `str \| None` | `None` | MCP tool name for permission prompts |
821| `cwd` | `str \| Path \| None` | `None` | Current working directory |
822| `cli_path` | `str \| Path \| None` | `None` | Custom path to the Claude Code CLI executable |
823| `settings` | `str \| None` | `None` | Path to a settings file or an inline JSON string |
824| `add_dirs` | `list[str \| Path]` | `[]` | Additional directories Claude can access. The SDK passes each entry to Claude Code as `--add-dir`, so with the `project` setting source Claude Code also [loads the directory's skills, commands, and subagents](/docs/en/permissions#additional-directories-grant-file-access-not-configuration) |
825| `env` | `dict[str, str]` | `{}` | Environment variables merged on top of the inherited process environment. See [Environment variables](/docs/en/env-vars) for variables the underlying CLI reads, and [Handle slow or stalled API responses](#handle-slow-or-stalled-api-responses) for timeout-related variables. Set `CLAUDE_AGENT_SDK_CLIENT_APP` to identify your app in the User-Agent header |
826| `extra_args` | `dict[str, str \| None]` | `{}` | Additional CLI arguments to pass directly to the CLI |
827| `max_buffer_size` | `int \| None` | `None` | Maximum bytes when buffering CLI stdout |
828| `debug_stderr` | `Any` | `sys.stderr` | *Deprecated* - The SDK ignores this value. Use the `stderr` callback for CLI stderr output |
829| `stderr` | `Callable[[str], None] \| None` | `None` | Callback function for stderr output from CLI |
830| `can_use_tool` | [`CanUseTool`](#canusetool) ` \| None` | `None` | Tool permission callback, invoked only when the [permission flow](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) falls through to a prompt. Not invoked for calls auto-approved by `allowed_tools`, allow rules, or `permission_mode`. An allow rule doesn't pre-approve the [actions no mode auto-approves](/docs/en/permission-modes#actions-no-mode-auto-approves). See [`CanUseTool`](#canusetool) for details |
831| `hooks` | `dict[HookEvent, list[HookMatcher]] \| None` | `None` | Hook configurations for intercepting events |
832| `user` | `str \| None` | `None` | On POSIX platforms, the OS user account the Claude Code subprocess runs as. Claude Code keeps the parent process's environment, including `HOME`, and runs in `cwd` |
833| `include_partial_messages` | `bool` | `False` | Include partial message streaming events. When enabled, [`StreamEvent`](#streamevent) messages are yielded |
834| `include_hook_events` | `bool` | `False` | Include hook lifecycle events in the message stream as `HookEventMessage` objects |
835| `forward_subagent_text` | `bool` | `False` | Forward subagent text and thinking blocks in the message stream. Without this option, Claude Code emits subagent `tool_use` and `tool_result` blocks but not text or thinking. Requires Python Agent SDK 0.2.140 or later |
836| `verbatim_prompts` | `bool` | `False` | Deliver every prompt as written. The SDK sends each user message with `client_composed` set to `True`. See [`client_composed`](/docs/en/agent-sdk/typescript#sdkusermessage) for what Claude Code skips on those messages. Use this option when your prompt text includes content the end user didn't type. For per-turn control, leave it off and set `"client_composed": True` on individual streamed messages instead. While the option is on, the SDK overwrites any `client_composed` value you set. Requires Python Agent SDK 0.2.158 or later and Claude Code v2.1.248 or later; the CLI bundled with those SDK versions satisfies the Claude Code requirement |
837| `fork_session` | `bool` | `False` | When resuming with `resume`, fork to a new session ID instead of continuing the original session |
838| `resume_session_at` | `str \| None` | `None` | When resuming, load the conversation only up to and including the message with this UUID. Use with `resume`, and usually `fork_session`, to branch from an earlier point. Requires Python Agent SDK 0.2.137 or later |
839| `resume_drops_turn` | `str \| None` | `None` | UUID of the user prompt whose turn a `resume_session_at` truncation discards. When set, the CLI refuses the resume if the discarded range holds entries not attributable to that turn. Requires Python Agent SDK 0.2.137 or later and Claude Code v2.1.223 or later; the CLI bundled with those SDK versions satisfies the Claude Code requirement |
840| `agents` | `dict[str, AgentDefinition] \| None` | `None` | Programmatically defined subagents |
841| `plugins` | `list[SdkPluginConfig]` | `[]` | Load custom plugins from local paths. See [Plugins](/docs/en/agent-sdk/plugins) for details |
842| `sandbox` | [`SandboxSettings`](#sandboxsettings) ` \| None` | `None` | Configure sandbox behavior programmatically. See [Sandbox settings](#sandboxsettings) for details |
843| `setting_sources` | `list[SettingSource] \| None` | `None` (CLI defaults: all sources) | Control which filesystem settings to load. Pass `[]` to disable user, project, and local settings. With `skills` set and this field unset, only user and project sources load. Set `setting_sources` explicitly to keep local settings. Endpoint-managed policy loads regardless; server-managed settings are fetched when the session authenticates with an organization credential on an [eligible configuration](/docs/en/server-managed-settings#platform-availability). For inputs read regardless of this option, see [What settingSources does not control](/docs/en/agent-sdk/claude-code-features#what-settingsources-does-not-control) |
844| `skills` | `list[str] \| Literal["all"] \| None` | `None` | Skills available to the session. Pass `"all"` to enable every discovered skill, or a list of skill names. Pass exact names only. The SDK rejects malformed and wildcard-form names with a `ValueError` before starting the Claude Code process; this check requires Python Agent SDK 0.2.129 or later. When set, the SDK adds the Skill tool to `allowed_tools` automatically. If you also pass `tools`, include `"Skill"` in that list. See [Skills](/docs/en/agent-sdk/skills) |
845| `max_thinking_tokens` | `int \| None` | `None` | *Deprecated* - Maximum tokens for thinking blocks. Use `thinking` instead |
846| `thinking` | [`ThinkingConfig`](#thinkingconfig) ` \| None` | `None` | Controls extended thinking behavior. Takes precedence over `max_thinking_tokens` |
847| `effort` | [`EffortLevel`](#effortlevel) ` \| None` | `None` | Effort level for thinking depth. See [adjust the effort level](/docs/en/model-config#adjust-effort-level) |
848| `session_store` | [`SessionStore`](/docs/en/agent-sdk/session-storage#the-sessionstore-interface) ` \| None` | `None` | Mirror session transcripts to an external backend so another host can resume them. See [Persist sessions to external storage](/docs/en/agent-sdk/session-storage) |
849| `session_store_flush` | `Literal["batched", "eager"]` | `"batched"` | When to flush mirrored transcript entries to `session_store`. `"batched"` flushes once per turn or when the buffer fills; `"eager"` triggers a background flush after every frame. Ignored when `session_store` is `None` |
850| `load_timeout_ms` | `int` | `60000` | Per-call timeout for `session_store.load()` and `list_subkeys()` during resume materialization, in milliseconds |
851| `task_budget` | `TaskBudget \| None` | `None` | API-side token budget. Sent as `output_config.task_budget` with the `task-budgets-2026-03-13` beta header. Pass `{"total": <int>}`. |
801| Property | Type | Default | Description |
802| :- | :- | :- | :- |
803| `tools` | `list[str] \| ToolsPreset \| None` | `None` | Tools configuration. Use `{"type": "preset", "preset": "claude_code"}` for Claude Code's default tools |
804| `allowed_tools` | `list[str]` | `[]` | Tools to auto-approve without prompting. This does not restrict Claude to only these tools. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability) here, Claude Code also opts the session in. Other unlisted tools fall through to `permission_mode` and `can_use_tool`. Use `disallowed_tools` to block tools. See [Permissions](/docs/en/agent-sdk/permissions#allow-and-deny-rules) |
805| `system_prompt` | `str \| SystemPromptPreset \| SystemPromptCustom \| SystemPromptFile \| None` | `None` | System prompt configuration. Pass a string for a custom prompt, `{"type": "preset", "preset": "claude_code"}` for Claude Code's system prompt with optional `"append"`, `{"type": "custom", "prompt": "..."}` for a custom prompt that can also set `"snapshot"`, or `{"type": "file", "path": "..."}` to load a large prompt from disk. See [`SystemPromptPreset`](#systempromptpreset), [`SystemPromptCustom`](#systempromptcustom), and [`SystemPromptFile`](#systempromptfile) |
806| `mcp_servers` | `dict[str, McpServerConfig] \| str \| Path` | `{}` | MCP server configurations or path to config file |
807| `strict_mcp_config` | `bool` | `False` | When `True`, use only the servers passed in `mcp_servers` and ignore project `.mcp.json`, user settings, plugin-provided MCP servers, and [claude.ai connectors](/docs/en/mcp#use-mcp-servers-from-claude-ai). Maps to the CLI `--strict-mcp-config` flag |
808| `permission_mode` | `PermissionMode \| None` | `None` | Permission mode for tool usage |
809| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |
810| `resume` | `str \| None` | `None` | Session ID to resume |
811| `session_id` | `str \| None` | `None` | Use a specific session ID instead of an auto-generated one. Must be a valid UUID. Can't be combined with `continue_conversation` or `resume` unless `fork_session` is also set |
812| `max_turns` | `int \| None` | `None` | Maximum agentic turns (tool-use round trips) |
813| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](/docs/en/agent-sdk/cost-tracking) |
814| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`, for the command [as written](/docs/en/permissions#bash-rule-limits). See [Permissions](/docs/en/agent-sdk/permissions#allow-and-deny-rules) |
815| `enable_file_checkpointing` | `bool` | `False` | Enable file change tracking for rewinding. See [File checkpointing](/docs/en/agent-sdk/file-checkpointing) |
816| `model` | `str \| None` | `None` | Claude model alias or full model name. See [accepted values and provider-specific IDs](/docs/en/model-config#available-models) |
817| `fallback_model` | `str \| None` | `None` | Fallback model to use if the primary model fails. Accepts a comma-separated list. For guidance, see [Choose a model](/docs/en/agent-sdk/configuration#choose-a-model) |
818| `betas` | `list[SdkBeta]` | `[]` | Beta features to enable. See [`SdkBeta`](#sdkbeta) for available options |
819| `output_format` | `dict[str, Any] \| None` | `None` | Output format for structured responses (e.g., `{"type": "json_schema", "schema": {...}}`). See [Structured outputs](/docs/en/agent-sdk/structured-outputs) for details |
820| `permission_prompt_tool_name` | `str \| None` | `None` | MCP tool name for permission prompts |
821| `cwd` | `str \| Path \| None` | `None` | Current working directory |
822| `cli_path` | `str \| Path \| None` | `None` | Custom path to the Claude Code CLI executable |
823| `settings` | `str \| None` | `None` | Path to a settings file or an inline JSON string |
824| `add_dirs` | `list[str \| Path]` | `[]` | Additional directories Claude can access. The SDK passes each entry to Claude Code as `--add-dir`, so with the `project` setting source Claude Code also [loads the directory's skills, commands, and subagents](/docs/en/permissions#additional-directories-grant-file-access-not-configuration) |
825| `env` | `dict[str, str]` | `{}` | Environment variables merged on top of the inherited process environment. See [Environment variables](/docs/en/env-vars) for variables the underlying CLI reads, and [Handle slow or stalled API responses](#handle-slow-or-stalled-api-responses) for timeout-related variables. Set `CLAUDE_AGENT_SDK_CLIENT_APP` to identify your app in the User-Agent header |
826| `extra_args` | `dict[str, str \| None]` | `{}` | Additional CLI arguments to pass directly to the CLI |
827| `max_buffer_size` | `int \| None` | `None` | Maximum bytes when buffering CLI stdout |
828| `debug_stderr` | `Any` | `sys.stderr` | *Deprecated* - The SDK ignores this value. Use the `stderr` callback for CLI stderr output |
829| `stderr` | `Callable[[str], None] \| None` | `None` | Callback function for stderr output from CLI |
830| `can_use_tool` | [`CanUseTool`](#canusetool) ` \| None` | `None` | Tool permission callback, invoked only when the [permission flow](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated) falls through to a prompt. Not invoked for calls auto-approved by `allowed_tools`, allow rules, or `permission_mode`. An allow rule doesn't pre-approve the [actions no mode auto-approves](/docs/en/permission-modes#actions-no-mode-auto-approves). See [`CanUseTool`](#canusetool) for details |
831| `hooks` | `dict[HookEvent, list[HookMatcher]] \| None` | `None` | Hook configurations for intercepting events |
832| `user` | `str \| None` | `None` | On POSIX platforms, the OS user account the Claude Code subprocess runs as. Claude Code keeps the parent process's environment, including `HOME`, and runs in `cwd` |
833| `include_partial_messages` | `bool` | `False` | Include partial message streaming events. When enabled, [`StreamEvent`](#streamevent) messages are yielded |
834| `include_hook_events` | `bool` | `False` | Include hook lifecycle events in the message stream as `HookEventMessage` objects |
835| `forward_subagent_text` | `bool` | `False` | Forward subagent text and thinking blocks in the message stream. Without this option, Claude Code emits subagent `tool_use` and `tool_result` blocks but not text or thinking. Requires Python Agent SDK 0.2.140 or later |
836| `verbatim_prompts` | `bool` | `False` | Deliver every prompt as written. The SDK sends each user message with `client_composed` set to `True`. See [`client_composed`](/docs/en/agent-sdk/typescript#sdkusermessage) for what Claude Code skips on those messages. Use this option when your prompt text includes content the end user didn't type. For per-turn control, leave it off and set `"client_composed": True` on individual streamed messages instead. While the option is on, the SDK overwrites any `client_composed` value you set. Requires Python Agent SDK 0.2.158 or later and Claude Code v2.1.248 or later; the CLI bundled with those SDK versions satisfies the Claude Code requirement |
837| `fork_session` | `bool` | `False` | When resuming with `resume`, fork to a new session ID instead of continuing the original session |
838| `resume_session_at` | `str \| None` | `None` | When resuming, load the conversation only up to and including the message with this UUID. Use with `resume`, and usually `fork_session`, to branch from an earlier point. Requires Python Agent SDK 0.2.137 or later |
839| `resume_drops_turn` | `str \| None` | `None` | UUID of the user prompt whose turn a `resume_session_at` truncation discards. When set, the CLI refuses the resume if the discarded range holds entries not attributable to that turn. Requires Python Agent SDK 0.2.137 or later and Claude Code v2.1.223 or later; the CLI bundled with those SDK versions satisfies the Claude Code requirement |
840| `agents` | `dict[str, AgentDefinition] \| None` | `None` | Programmatically defined subagents |
841| `plugins` | `list[SdkPluginConfig]` | `[]` | Load custom plugins from local paths. See [Plugins](/docs/en/agent-sdk/plugins) for details |
842| `sandbox` | [`SandboxSettings`](#sandboxsettings) ` \| None` | `None` | Configure sandbox behavior programmatically. See [Sandbox settings](#sandboxsettings) for details |
843| `setting_sources` | `list[SettingSource] \| None` | `None` (CLI defaults: all sources) | Control which filesystem settings to load. Pass `[]` to disable user, project, and local settings. With `skills` set and this field unset, only user and project sources load. Set `setting_sources` explicitly to keep local settings. Endpoint-managed policy loads regardless; server-managed settings are fetched when the session authenticates with an organization credential on an [eligible configuration](/docs/en/server-managed-settings#platform-availability). For inputs read regardless of this option, see [What settingSources does not control](/docs/en/agent-sdk/claude-code-features#what-settingsources-does-not-control) |
844| `skills` | `list[str] \| Literal["all"] \| None` | `None` | Skills available to the session. Pass `"all"` to enable every discovered skill, or a list of skill names. Pass exact names only. The SDK rejects malformed and wildcard-form names with a `ValueError` before starting the Claude Code process; this check requires Python Agent SDK 0.2.129 or later. When set, the SDK adds the Skill tool to `allowed_tools` automatically. If you also pass `tools`, include `"Skill"` in that list. See [Skills](/docs/en/agent-sdk/skills) |
845| `max_thinking_tokens` | `int \| None` | `None` | *Deprecated* - Maximum tokens for thinking blocks. Use `thinking` instead |
846| `thinking` | [`ThinkingConfig`](#thinkingconfig) ` \| None` | `None` | Controls extended thinking behavior. Takes precedence over `max_thinking_tokens` |
847| `effort` | [`EffortLevel`](#effortlevel) ` \| None` | `None` | Effort level for thinking depth. See [adjust the effort level](/docs/en/model-config#adjust-effort-level) |
848| `session_store` | [`SessionStore`](/docs/en/agent-sdk/session-storage#the-sessionstore-interface) ` \| None` | `None` | Mirror session transcripts to an external backend so another host can resume them. See [Persist sessions to external storage](/docs/en/agent-sdk/session-storage) |
849| `session_store_flush` | `Literal["batched", "eager"]` | `"batched"` | When to flush mirrored transcript entries to `session_store`. `"batched"` flushes once per turn or when the buffer fills; `"eager"` triggers a background flush after every frame. Ignored when `session_store` is `None` |
850| `load_timeout_ms` | `int` | `60000` | Per-call timeout for `session_store.load()` and `list_subkeys()` during resume materialization, in milliseconds |
851| `task_budget` | `TaskBudget \| None` | `None` | API-side token budget. Sent as `output_config.task_budget` with the `task-budgets-2026-03-13` beta header. Pass `{"total": <int>}`. |
852852
853853#### Handle slow or stalled API responses
854854
from line 887
887887}
888888```
889889
890| Field | Required | Description |
891| :------- | :------- | :------------------------------------------------- |
892| `type` | Yes | Must be `"json_schema"` for JSON Schema validation |
893| `schema` | Yes | JSON Schema definition for output validation |
890| Field | Required | Description |
891| :- | :- | :- |
892| `type` | Yes | Must be `"json_schema"` for JSON Schema validation |
893| `schema` | Yes | JSON Schema definition for output validation |
894894
895895### `SystemPromptPreset`
896896
from line 905
905905 snapshot: NotRequired[bool]
906906```
907907
908| Field | Required | Description |
909| :------------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
910| `type` | Yes | Must be `"preset"` to use a preset system prompt |
911| `preset` | Yes | Must be `"claude_code"` to use Claude Code's system prompt |
912| `append` | No | Additional instructions to append to the preset system prompt |
913| `exclude_dynamic_sections` | No | Move per-session context such as working directory, the git-repo flag, and auto memory paths from the system prompt into the first user message. Improves prompt-cache reuse across users and machines. See [Modify system prompts](/docs/en/agent-sdk/modifying-system-prompts#improve-prompt-caching-across-users-and-machines) |
914| `snapshot` | No | Set to `False` to rebuild the system prompt on every request instead of [reusing the prompt the session recorded on its first request](/docs/en/agent-sdk/modifying-system-prompts#change-the-prompt-of-an-existing-session). Requires `claude-agent-sdk` v0.2.153 or later |
908| Field | Required | Description |
909| :- | :- | :- |
910| `type` | Yes | Must be `"preset"` to use a preset system prompt |
911| `preset` | Yes | Must be `"claude_code"` to use Claude Code's system prompt |
912| `append` | No | Additional instructions to append to the preset system prompt |
913| `exclude_dynamic_sections` | No | Move per-user context, such as the auto memory location, from the system prompt into the first user message. Improves prompt-cache reuse across users and machines. See [Modify system prompts](/docs/en/agent-sdk/modifying-system-prompts#improve-prompt-caching-across-users-and-machines) |
914| `snapshot` | No | Set to `False` to rebuild the system prompt on every request instead of [reusing the prompt the session recorded on its first request](/docs/en/agent-sdk/modifying-system-prompts#change-the-prompt-of-an-existing-session). Requires `claude-agent-sdk` v0.2.153 or later |
915915
916916### `SystemPromptCustom`
917917
from line 924
924924 snapshot: NotRequired[bool]
925925```
926926
927| Field | Required | Description |
928| :--------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------- |
929| `type` | Yes | Must be `"custom"` |
930| `prompt` | Yes | The system prompt text. Passed to the CLI as a command-line argument, so the [command-line length limits](#systempromptfile) apply |
931| `snapshot` | No | Same as [`SystemPromptPreset.snapshot`](#systempromptpreset), applied to `prompt` |
927| Field | Required | Description |
928| :- | :- | :- |
929| `type` | Yes | Must be `"custom"` |
930| `prompt` | Yes | The system prompt text. Passed to the CLI as a command-line argument, so the [command-line length limits](#systempromptfile) apply |
931| `snapshot` | No | Same as [`SystemPromptPreset.snapshot`](#systempromptpreset), applied to `prompt` |
932932
933933### `SystemPromptFile`
934934
from line 940
940940 path: str
941941```
942942
943| Field | Required | Description |
944| :----- | :------- | :-------------------------------------------- |
945| `type` | Yes | Must be `"file"` to load the prompt from disk |
946| `path` | Yes | Path to a file containing the system prompt |
943| Field | Required | Description |
944| :- | :- | :- |
945| `type` | Yes | Must be `"file"` to load the prompt from disk |
946| `path` | Yes | Path to a file containing the system prompt |
947947
948948### `SettingSource`
949949
from line 953
953953SettingSource = Literal["user", "project", "local"]
954954```
955955
956| Value | Description | Location |
957| :---------- | :------------------------------------------------------------------------ | :---------------------------- |
958| `"user"` | Global user settings | `~/.claude/settings.json` |
959| `"project"` | Shared project settings (version controlled) | `.claude/settings.json` |
960| `"local"` | Local project settings, gitignored when Claude Code saves a setting to it | `.claude/settings.local.json` |
956| Value | Description | Location |
957| :- | :- | :- |
958| `"user"` | Global user settings | `~/.claude/settings.json` |
959| `"project"` | Shared project settings (version controlled) | `.claude/settings.json` |
960| `"local"` | Local project settings, gitignored when Claude Code saves a setting to it | `.claude/settings.local.json` |
961961
962962#### Default behavior
963963
from line 1074
10741074 permissionMode: PermissionMode | None = None
10751075```
10761076
1077| Field | Required | Description |
1078| :---------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1079| `description` | Yes | Natural language description of when to use this agent |
1080| `prompt` | Yes | The agent's system prompt |
1081| `tools` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents#available-tools) |
1082| `disallowedTools` | No | Array of tool names to remove from the agent's tool set. MCP server-level patterns are also accepted: `mcp__server` or `mcp__server__*` removes every tool from that server, and `mcp__*` removes every MCP tool from any server |
1083| `model` | No | Model override for this agent. Accepts an alias such as `"sonnet"`, `"opus"`, `"haiku"`, or `"inherit"`, or a full model ID. When you omit it, Claude Code picks the model in the [subagent model order](/docs/en/sub-agents#choose-a-model) |
1084| `skills` | No | List of skill names to preload into the agent's context at startup. Unlisted skills remain invocable through the Skill tool |
1085| `memory` | No | Memory source for this agent: `"user"`, `"project"`, or `"local"` |
1086| `mcpServers` | No | MCP servers available to this agent. Each entry is a server name or an inline `{name: config}` dict |
1087| `initialPrompt` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent |
1088| `maxTurns` | No | Maximum number of agentic turns before the agent stops |
1089| `background` | No | Run this agent as a non-blocking background task when invoked |
1090| `effort` | No | Reasoning effort level for this agent. Accepts a named level or an integer. See [`EffortLevel`](#effortlevel) |
1091| `permissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions#available-modes) decide when it applies. See [`PermissionMode`](#permissionmode) |
1077| Field | Required | Description |
1078| :- | :- | :- |
1079| `description` | Yes | Natural language description of when to use this agent |
1080| `prompt` | Yes | The agent's system prompt |
1081| `tools` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents#available-tools) |
1082| `disallowedTools` | No | Array of tool names to remove from the agent's tool set. MCP server-level patterns are also accepted: `mcp__server` or `mcp__server__*` removes every tool from that server, and `mcp__*` removes every MCP tool from any server |
1083| `model` | No | Model override for this agent. Accepts an alias such as `"sonnet"`, `"opus"`, `"haiku"`, or `"inherit"`, or a full model ID. When you omit it, Claude Code picks the model in the [subagent model order](/docs/en/sub-agents#choose-a-model) |
1084| `skills` | No | List of skill names to preload into the agent's context at startup. Unlisted skills remain invocable through the Skill tool |
1085| `memory` | No | Memory source for this agent: `"user"`, `"project"`, or `"local"` |
1086| `mcpServers` | No | MCP servers available to this agent. Each entry is a server name or an inline `{name: config}` dict |
1087| `initialPrompt` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent |
1088| `maxTurns` | No | Maximum number of agentic turns before the agent stops |
1089| `background` | No | Run this agent as a non-blocking background task when invoked |
1090| `effort` | No | Reasoning effort level for this agent. Accepts a named level or an integer. See [`EffortLevel`](#effortlevel) |
1091| `permissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions#available-modes) decide when it applies. See [`PermissionMode`](#permissionmode) |
10921092
10931093<Note>
10941094 `AgentDefinition` field names use camelCase, such as `disallowedTools`, `permissionMode`, and `maxTurns`. These names map directly to the wire format shared with the TypeScript SDK. This differs from `ClaudeAgentOptions`, which uses Python snake\_case for the equivalent top-level fields such as `disallowed_tools` and `permission_mode`. Because `AgentDefinition` is a dataclass, passing a snake\_case keyword raises a `TypeError` at construction time.
from line 1163
11631163 description: str | None = None
11641164```
11651165
1166| Field | Type | Description |
1167| :---------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1168| `signal` | `Any \| None` | Reserved for future abort signal support |
1169| `suggestions` | `list[PermissionUpdate]` | Permission update suggestions from the CLI. Bash prompts include a suggestion with the `localSettings` destination, so returning it in `updated_permissions` writes the rule to `.claude/settings.local.json` and persists across sessions. |
1170| `tool_use_id` | `str \| None` | Identifier of the specific tool call this prompt is for. Always populated when delivered to `can_use_tool` |
1171| `agent_id` | `str \| None` | Sub-agent ID when the call originates from a subagent; `None` for the main agent |
1172| `blocked_path` | `str \| None` | File path that triggered the permission request, when applicable. For example, when a Bash command tries to access a path outside allowed directories |
1173| `decision_reason` | `str \| None` | Reason this permission request was triggered. Forwarded from a PreToolUse hook's `permissionDecisionReason` when the hook returned `"ask"` |
1174| `title` | `str \| None` | Full permission prompt sentence, such as `Claude wants to read foo.txt`. Use as the primary prompt text when present |
1175| `display_name` | `str \| None` | Short noun phrase for the tool action, such as `Read file`, suitable for button labels |
1176| `description` | `str \| None` | Human-readable subtitle for the permission UI |
1166| Field | Type | Description |
1167| :- | :- | :- |
1168| `signal` | `Any \| None` | Reserved for future abort signal support |
1169| `suggestions` | `list[PermissionUpdate]` | Permission update suggestions from the CLI. Bash prompts include a suggestion with the `localSettings` destination, so returning it in `updated_permissions` writes the rule to `.claude/settings.local.json` and persists across sessions. |
1170| `tool_use_id` | `str \| None` | Identifier of the specific tool call this prompt is for. Always populated when delivered to `can_use_tool` |
1171| `agent_id` | `str \| None` | Sub-agent ID when the call originates from a subagent; `None` for the main agent |
1172| `blocked_path` | `str \| None` | File path that triggered the permission request, when applicable. For example, when a Bash command tries to access a path outside allowed directories |
1173| `decision_reason` | `str \| None` | Reason this permission request was triggered. Forwarded from a PreToolUse hook's `permissionDecisionReason` when the hook returned `"ask"` |
1174| `title` | `str \| None` | Full permission prompt sentence, such as `Claude wants to read foo.txt`. Use as the primary prompt text when present |
1175| `display_name` | `str \| None` | Short noun phrase for the tool action, such as `Read file`, suitable for button labels |
1176| `description` | `str \| None` | Human-readable subtitle for the permission UI |
11771177
11781178### `PermissionResult`
11791179
from line 1195
11951195 updated_permissions: list[PermissionUpdate] | None = None
11961196```
11971197
1198| Field | Type | Default | Description |
1199| :-------------------- | :------------------------------- | :-------- | :---------------------------------------- |
1200| `behavior` | `Literal["allow"]` | `"allow"` | Must be "allow" |
1201| `updated_input` | `dict[str, Any] \| None` | `None` | Modified input to use instead of original |
1202| `updated_permissions` | `list[PermissionUpdate] \| None` | `None` | Permission updates to apply |
1198| Field | Type | Default | Description |
1199| :- | :- | :- | :- |
1200| `behavior` | `Literal["allow"]` | `"allow"` | Must be "allow" |
1201| `updated_input` | `dict[str, Any] \| None` | `None` | Modified input to use instead of original |
1202| `updated_permissions` | `list[PermissionUpdate] \| None` | `None` | Permission updates to apply |
12031203
12041204### `PermissionResultDeny`
12051205
from line 1213
12131213 interrupt: bool = False
12141214```
12151215
1216| Field | Type | Default | Description |
1217| :---------- | :---------------- | :------- | :----------------------------------------- |
1218| `behavior` | `Literal["deny"]` | `"deny"` | Must be "deny" |
1219| `message` | `str` | `""` | Message explaining why the tool was denied |
1220| `interrupt` | `bool` | `False` | Whether to interrupt the current execution |
1216| Field | Type | Default | Description |
1217| :- | :- | :- | :- |
1218| `behavior` | `Literal["deny"]` | `"deny"` | Must be "deny" |
1219| `message` | `str` | `""` | Message explaining why the tool was denied |
1220| `interrupt` | `bool` | `False` | Whether to interrupt the current execution |
12211221
12221222### `PermissionUpdate`
12231223
from line 1243
12431243 ) = None
12441244```
12451245
1246| Field | Type | Description |
1247| :------------ | :---------------------------------------- | :---------------------------------------------- |
1248| `type` | `Literal[...]` | The type of permission update operation |
1249| `rules` | `list[PermissionRuleValue] \| None` | Rules for add/replace/remove operations |
1250| `behavior` | `Literal["allow", "deny", "ask"] \| None` | Behavior for rule-based operations |
1251| `mode` | `PermissionMode \| None` | Mode for setMode operation |
1252| `directories` | `list[str] \| None` | Directories for add/remove directory operations |
1253| `destination` | `Literal[...] \| None` | Where to apply the permission update |
1246| Field | Type | Description |
1247| :- | :- | :- |
1248| `type` | `Literal[...]` | The type of permission update operation |
1249| `rules` | `list[PermissionRuleValue] \| None` | Rules for add/replace/remove operations |
1250| `behavior` | `Literal["allow", "deny", "ask"] \| None` | Behavior for rule-based operations |
1251| `mode` | `PermissionMode \| None` | Mode for setMode operation |
1252| `directories` | `list[str] \| None` | Directories for add/remove directory operations |
1253| `destination` | `Literal[...] \| None` | Where to apply the permission update |
12541254
12551255### `PermissionRuleValue`
12561256
from line 1299
12991299ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
13001300```
13011301
1302| Variant | Fields | Description |
1303| :--------- | :--------------------------------- | :------------------------------------------- |
1304| `adaptive` | `type`, `display` | Claude adaptively decides when to think |
1305| `enabled` | `type`, `budget_tokens`, `display` | Enable thinking with a specific token budget |
1306| `disabled` | `type` | Disable thinking |
1302| Variant | Fields | Description |
1303| :- | :- | :- |
1304| `adaptive` | `type`, `display` | Claude adaptively decides when to think |
1305| `enabled` | `type`, `budget_tokens`, `display` | Enable thinking with a specific token budget |
1306| `disabled` | `type` | Disable thinking |
13071307
13081308The optional `display` field controls whether thinking text is returned `"summarized"` or `"omitted"`. On Claude Opus 4.7 and later, the API default is `"omitted"`, so set `"summarized"` to receive thinking content in [`ThinkingBlock`](#thinkingblock) outputs. Claude Code doesn't send `display` to Amazon Bedrock or Google Cloud's Agent Platform, so on those providers Opus 4.7 and later return empty `ThinkingBlock` outputs even when you set `display` to `"summarized"`.
13091309
from line 1330
13301330 total: int
13311331```
13321332
1333| Field | Type | Description |
1334| :------ | :---- | :------------------------------ |
1333| Field | Type | Description |
1334| :- | :- | :- |
13351335| `total` | `int` | Total token budget for the task |
13361336
13371337Because this is a `TypedDict`, pass it as a plain dict, such as `ClaudeAgentOptions(task_budget={"total": 50000})`.
from line 1439
14391439 tools: NotRequired[list[McpToolInfo]]
14401440```
14411441
1442| Field | Type | Description |
1443| :----------- | :----------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1444| `name` | `str` | Server name |
1445| `status` | `str` | One of `"connected"`, `"failed"`, `"needs-auth"`, `"pending"`, or `"disabled"` |
1446| `serverInfo` | `dict` (optional) | Server name and version (`{"name": str, "version": str}`) |
1447| `error` | `str` (optional) | Error message if the server failed to connect |
1448| `config` | [`McpServerStatusConfig`](#mcpserverstatusconfig) (optional) | Server configuration. Same shape as [`McpServerConfig`](#mcpserverconfig) (stdio, SSE, HTTP, or SDK), plus a `claudeai-proxy` variant for servers connected through claude.ai |
1449| `scope` | `str` (optional) | Configuration scope |
1450| `tools` | `list` (optional) | Tools provided by this server, each with `name`, `description`, and `annotations` fields |
1442| Field | Type | Description |
1443| :- | :- | :- |
1444| `name` | `str` | Server name |
1445| `status` | `str` | One of `"connected"`, `"failed"`, `"needs-auth"`, `"pending"`, or `"disabled"` |
1446| `serverInfo` | `dict` (optional) | Server name and version (`{"name": str, "version": str}`) |
1447| `error` | `str` (optional) | Error message if the server failed to connect |
1448| `config` | [`McpServerStatusConfig`](#mcpserverstatusconfig) (optional) | Server configuration. Same shape as [`McpServerConfig`](#mcpserverconfig) (stdio, SSE, HTTP, or SDK), plus a `claudeai-proxy` variant for servers connected through claude.ai |
1449| `scope` | `str` (optional) | Configuration scope |
1450| `tools` | `list` (optional) | Tools provided by this server, each with `name`, `description`, and `annotations` fields |
14511451
14521452### `SdkPluginConfig`
14531453
from line 1459
14591459 path: str
14601460```
14611461
1462| Field | Type | Description |
1463| :----- | :----------------- | :--------------------------------------------------------- |
1462| Field | Type | Description |
1463| :- | :- | :- |
14641464| `type` | `Literal["local"]` | Must be `"local"` (only local plugins currently supported) |
1465| `path` | `str` | Absolute or relative path to the plugin directory |
1465| `path` | `str` | Absolute or relative path to the plugin directory |
14661466
14671467**Example:**
14681468
from line 1507
15071507 origin: MessageOrigin | None = None
15081508```
15091509
1510| Field | Type | Description |
1511| :------------------- | :-------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1512| `content` | `str \| list[ContentBlock]` | Message content as text or content blocks |
1513| `uuid` | `str \| None` | Unique message identifier |
1514| `parent_tool_use_id` | `str \| None` | Tool use ID if this message is a tool result response |
1515| `tool_use_result` | `dict[str, Any] \| None` | Tool result data if applicable |
1516| `origin` | `MessageOrigin \| None` | Provenance of this message, populated on injected turns such as task notifications and peer messages. `None` when the CLI didn't attribute it. Requires Python Agent SDK 0.2.137 or later |
1510| Field | Type | Description |
1511| :- | :- | :- |
1512| `content` | `str \| list[ContentBlock]` | Message content as text or content blocks |
1513| `uuid` | `str \| None` | Unique message identifier |
1514| `parent_tool_use_id` | `str \| None` | Tool use ID if this message is a tool result response |
1515| `tool_use_result` | `dict[str, Any] \| None` | Tool result data if applicable |
1516| `origin` | `MessageOrigin \| None` | Provenance of this message, populated on injected turns such as task notifications and peer messages. `None` when the CLI didn't attribute it. Requires Python Agent SDK 0.2.137 or later |
15171517
15181518The SDK passes `tool_use_result` through from the CLI unmodified. For a tool on an external MCP server whose result contains `resource_link` blocks, the dict has a `resourceLinks` key holding a list of dicts with the keys of the TypeScript [`SDKMcpResourceLink`](/docs/en/agent-sdk/typescript#sdkmcpresourcelink) type. Claude receives each link as a line of text in the tool result. To render the files the server returned, read `resourceLinks` instead of parsing that text. The `resourceLinks` key requires Python Agent SDK 0.2.150 or later and Claude Code v2.1.257 or later; the CLI bundled with that SDK version satisfies the Claude Code requirement.
15191519
from line 1537
15371537 uuid: str | None = None
15381538```
15391539
1540| Field | Type | Description |
1541| :------------------- | :----------------------------------------------------------- | :----------------------------------------------------------------------------- |
1542| `content` | `list[ContentBlock]` | List of content blocks in the response |
1543| `model` | `str` | Model that generated the response |
1544| `parent_tool_use_id` | `str \| None` | Tool use ID if this is a nested response |
1545| `error` | [`AssistantMessageError`](#assistantmessageerror) ` \| None` | Error type if the response encountered an error |
1546| `usage` | `dict[str, Any] \| None` | Per-message token usage (same keys as [`ResultMessage.usage`](#resultmessage)) |
1547| `message_id` | `str \| None` | API message ID. Multiple messages from one turn share the same ID |
1548| `stop_reason` | `str \| None` | Stop reason from the API (for example, `end_turn`, `tool_use`) |
1549| `session_id` | `str \| None` | ID of the session this message belongs to |
1550| `uuid` | `str \| None` | Unique message identifier within the session transcript |
1540| Field | Type | Description |
1541| :- | :- | :- |
1542| `content` | `list[ContentBlock]` | List of content blocks in the response |
1543| `model` | `str` | Model that generated the response |
1544| `parent_tool_use_id` | `str \| None` | Tool use ID if this is a nested response |
1545| `error` | [`AssistantMessageError`](#assistantmessageerror) ` \| None` | Error type if the response encountered an error |
1546| `usage` | `dict[str, Any] \| None` | Per-message token usage (same keys as [`ResultMessage.usage`](#resultmessage)) |
1547| `message_id` | `str \| None` | API message ID. Multiple messages from one turn share the same ID |
1548| `stop_reason` | `str \| None` | Stop reason from the API (for example, `end_turn`, `tool_use`) |
1549| `session_id` | `str \| None` | ID of the session this message belongs to |
1550| `uuid` | `str \| None` | Unique message identifier within the session transcript |
15511551
15521552### `AssistantMessageError`
15531553
from line 1618
16181618
16191619The `usage` dict covers the main agent loop only and excludes subagent and other nested or auxiliary model calls. In [streaming input mode](/docs/en/agent-sdk/streaming-vs-single-mode), the values are per-turn. Prefer `model_usage` for token and cost accounting. The `usage` dict contains the following keys when present:
16201620
1621| Key | Type | Description |
1622| ----------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1623| `input_tokens` | `int` | Input tokens consumed by the top-level agent loop. [Subagent tokens aren't included](/docs/en/agent-sdk/cost-tracking#get-the-total-cost-of-a-query); use `model_usage` for whole-tree accounting. |
1624| `output_tokens` | `int` | Output tokens generated by the top-level agent loop. Subagent tokens aren't included. |
1625| `cache_creation_input_tokens` | `int` | Tokens used to create new cache entries. |
1626| `cache_read_input_tokens` | `int` | Tokens read from existing cache entries. |
1621| Key | Type | Description |
1622| - | - | - |
1623| `input_tokens` | `int` | Input tokens consumed by the top-level agent loop. [Subagent tokens aren't included](/docs/en/agent-sdk/cost-tracking#get-the-total-cost-of-a-query); use `model_usage` for whole-tree accounting. |
1624| `output_tokens` | `int` | Output tokens generated by the top-level agent loop. Subagent tokens aren't included. |
1625| `cache_creation_input_tokens` | `int` | Tokens used to create new cache entries. |
1626| `cache_read_input_tokens` | `int` | Tokens read from existing cache entries. |
16271627
16281628The `model_usage` dict maps model names to per-model usage. It covers every model call made through the query pipeline: the main loop, subagents, and internal calls such as compaction and Workflow agents. Helper calls outside that pipeline, such as the permission classifier and token-counting requests, are excluded from `model_usage`. Treat `model_usage` as an estimate, not a billing statement.
16291629
from line 1631
16311631
16321632Each value in `model_usage` is a `ModelUsage` TypedDict, imported via `from claude_agent_sdk.types import ModelUsage`. Its keys use camelCase because the SDK passes the value through unmodified from the underlying CLI process, matching the TypeScript [`ModelUsage`](/docs/en/agent-sdk/typescript#modelusage) type:
16331633
1634| Key | Type | Description |
1635| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1636| `inputTokens` | `int` | Input tokens for this model. |
1637| `outputTokens` | `int` | Output tokens for this model. |
1638| `cacheReadInputTokens` | `int` | Cache read tokens for this model. |
1639| `cacheCreationInputTokens` | `int` | Cache creation tokens for this model. |
1640| `webSearchRequests` | `int` | Web search requests made by this model. |
1641| `thinkingTokens` | `int` | Thinking tokens generated by this model, already counted in `outputTokens`. Absent until a turn runs on a Claude Code version that records it, and not declared on the TypedDict, so read it with `.get()`. Requires Python Agent SDK 0.2.150 or later, whose bundled CLI records it. |
1642| `costUSD` | `float` | Estimated cost in USD for this model, computed client-side. See [Track cost and usage](/docs/en/agent-sdk/cost-tracking) for billing caveats. |
1643| `contextWindow` | `int` | Context window size for this model. |
1644| `maxOutputTokens` | `int` | Maximum output token limit for this model. |
1645| `canonicalModel` | `str` | Canonical model ID used for the pricing lookup. May differ from the raw model string the entry is keyed by, such as a provider-specific ID or alias. Not always present. |
1646| `provider` | `str` | API provider that served this model, such as `firstParty`, `bedrock`, `vertex`, `foundry`, `anthropicAws`, `mantle`, or `gateway`. Not always present. |
1634| Key | Type | Description |
1635| - | - | - |
1636| `inputTokens` | `int` | Input tokens for this model. |
1637| `outputTokens` | `int` | Output tokens for this model. |
1638| `cacheReadInputTokens` | `int` | Cache read tokens for this model. |
1639| `cacheCreationInputTokens` | `int` | Cache creation tokens for this model. |
1640| `webSearchRequests` | `int` | Web search requests made by this model. |
1641| `thinkingTokens` | `int` | Thinking tokens generated by this model, already counted in `outputTokens`. Absent until a turn runs on a Claude Code version that records it, and not declared on the TypedDict, so read it with `.get()`. Requires Python Agent SDK 0.2.150 or later, whose bundled CLI records it. |
1642| `costUSD` | `float` | Estimated cost in USD for this model, computed client-side. See [Track cost and usage](/docs/en/agent-sdk/cost-tracking) for billing caveats. |
1643| `contextWindow` | `int` | Context window size for this model. |
1644| `maxOutputTokens` | `int` | Maximum output token limit for this model. |
1645| `canonicalModel` | `str` | Canonical model ID used for the pricing lookup. May differ from the raw model string the entry is keyed by, such as a provider-specific ID or alias. Not always present. |
1646| `provider` | `str` | API provider that served this model, such as `firstParty`, `bedrock`, `vertex`, `foundry`, `anthropicAws`, `mantle`, or `gateway`. Not always present. |
16471647
16481648### `StreamEvent`
16491649
from line 1658
16581658 parent_tool_use_id: str | None = None
16591659```
16601660
1661| Field | Type | Description |
1662| :------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1663| `uuid` | `str` | Unique identifier for this event |
1664| `session_id` | `str` | Session identifier |
1665| `event` | `dict[str, Any]` | The raw Claude API stream event data |
1666| `parent_tool_use_id` | `str \| None` | Always `None`. Stream events are emitted for the main session only. For subagent attribution, use complete messages such as [`AssistantMessage`](#assistantmessage) |
1661| Field | Type | Description |
1662| :- | :- | :- |
1663| `uuid` | `str` | Unique identifier for this event |
1664| `session_id` | `str` | Session identifier |
1665| `event` | `dict[str, Any]` | The raw Claude API stream event data |
1666| `parent_tool_use_id` | `str \| None` | Always `None`. Stream events are emitted for the main session only. For subagent attribution, use complete messages such as [`AssistantMessage`](#assistantmessage) |
16671667
16681668### `RateLimitEvent`
16691669
from line 1677
16771677 session_id: str
16781678```
16791679
1680| Field | Type | Description |
1681| :---------------- | :-------------------------------- | :----------------------- |
1680| Field | Type | Description |
1681| :- | :- | :- |
16821682| `rate_limit_info` | [`RateLimitInfo`](#ratelimitinfo) | Current rate limit state |
1683| `uuid` | `str` | Unique event identifier |
1684| `session_id` | `str` | Session identifier |
1683| `uuid` | `str` | Unique event identifier |
1684| `session_id` | `str` | Session identifier |
16851685
16861686### `RateLimitInfo`
16871687
from line 1706
17061706 raw: dict[str, Any] = field(default_factory=dict)
17071707```
17081708
1709| Field | Type | Description |
1710| :------------------------ | :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1711| `status` | `RateLimitStatus` | Current status, one of `"allowed"`, `"allowed_warning"`, or `"rejected"`. `"allowed_warning"` means approaching the limit; `"rejected"` means the limit was hit |
1712| `resets_at` | `int \| None` | Unix timestamp when the rate limit window resets |
1713| `rate_limit_type` | `RateLimitType \| None` | Which rate limit window applies |
1714| `utilization` | `float \| None` | Fraction of the rate limit consumed (0.0 to 1.0) |
1715| `overage_status` | `RateLimitStatus \| None` | Status of pay-as-you-go overage usage, if applicable |
1716| `overage_resets_at` | `int \| None` | Unix timestamp when the overage window resets |
1717| `overage_disabled_reason` | `str \| None` | Why overage is unavailable, if status is `"rejected"` |
1718| `raw` | `dict[str, Any]` | Full raw dict from the CLI, including fields not modeled above |
1709| Field | Type | Description |
1710| :- | :- | :- |
1711| `status` | `RateLimitStatus` | Current status, one of `"allowed"`, `"allowed_warning"`, or `"rejected"`. `"allowed_warning"` means approaching the limit; `"rejected"` means the limit was hit |
1712| `resets_at` | `int \| None` | Unix timestamp when the rate limit window resets |
1713| `rate_limit_type` | `RateLimitType \| None` | Which rate limit window applies |
1714| `utilization` | `float \| None` | Fraction of the rate limit consumed (0.0 to 1.0) |
1715| `overage_status` | `RateLimitStatus \| None` | Status of pay-as-you-go overage usage, if applicable |
1716| `overage_resets_at` | `int \| None` | Unix timestamp when the overage window resets |
1717| `overage_disabled_reason` | `str \| None` | Why overage is unavailable, if status is `"rejected"` |
1718| `raw` | `dict[str, Any]` | Full raw dict from the CLI, including fields not modeled above |
17191719
17201720### `ConversationResetMessage`
17211721
from line 1729
17291729 session_id: str
17301730```
17311731
1732| Field | Type | Description |
1733| :-------------------- | :---- | :------------------------------------------------------------------------------------------------------------------------- |
1732| Field | Type | Description |
1733| :- | :- | :- |
17341734| `new_conversation_id` | `str` | Opaque identifier for the fresh conversation. Not the `session_id` of subsequent messages; read that from the next message |
1735| `uuid` | `str` | Unique message identifier |
1736| `session_id` | `str` | ID of the session that was reset. Messages after the reset carry a new `session_id` |
1735| `uuid` | `str` | Unique message identifier |
1736| `session_id` | `str` | ID of the session that was reset. Messages after the reset carry a new `session_id` |
17371737
17381738### `TaskStartedMessage`
17391739
from line 1750
17501750 task_type: str | None = None
17511751```
17521752
1753| Field | Type | Description |
1754| :------------ | :------------ | :-------------------------------------------------------------------------------------------------------------------------- |
1755| `task_id` | `str` | Unique identifier for the task |
1756| `description` | `str` | Description of the task |
1757| `uuid` | `str` | Unique message identifier |
1758| `session_id` | `str` | Session identifier |
1759| `tool_use_id` | `str \| None` | Associated tool use ID |
1760| `task_type` | `str \| None` | Which kind of background task: `"local_bash"` for background Bash and Monitor watches, `"local_agent"`, or `"remote_agent"` |
1753| Field | Type | Description |
1754| :- | :- | :- |
1755| `task_id` | `str` | Unique identifier for the task |
1756| `description` | `str` | Description of the task |
1757| `uuid` | `str` | Unique message identifier |
1758| `session_id` | `str` | Session identifier |
1759| `tool_use_id` | `str \| None` | Associated tool use ID |
1760| `task_type` | `str \| None` | Which kind of background task: `"local_bash"` for background Bash and Monitor watches, `"local_agent"`, or `"remote_agent"` |
17611761
17621762### `TaskUsage`
17631763
from line 1786
17861786 last_tool_name: str | None = None
17871787```
17881788
1789| Field | Type | Description |
1790| :--------------- | :------------ | :---------------------------------- |
1791| `task_id` | `str` | Unique identifier for the task |
1792| `description` | `str` | Current status description |
1793| `usage` | `TaskUsage` | Token usage for this task so far |
1794| `uuid` | `str` | Unique message identifier |
1795| `session_id` | `str` | Session identifier |
1796| `tool_use_id` | `str \| None` | Associated tool use ID |
1789| Field | Type | Description |
1790| :- | :- | :- |
1791| `task_id` | `str` | Unique identifier for the task |
1792| `description` | `str` | Current status description |
1793| `usage` | `TaskUsage` | Token usage for this task so far |
1794| `uuid` | `str` | Unique message identifier |
1795| `session_id` | `str` | Session identifier |
1796| `tool_use_id` | `str \| None` | Associated tool use ID |
17971797| `last_tool_name` | `str \| None` | Name of the last tool the task used |
17981798
17991799### `TaskNotificationMessage`
from line 1813
18131813 usage: TaskUsage | None = None
18141814```
18151815
1816| Field | Type | Description |
1817| :------------ | :----------------------- | :----------------------------------------------- |
1818| `task_id` | `str` | Unique identifier for the task |
1819| `status` | `TaskNotificationStatus` | One of `"completed"`, `"failed"`, or `"stopped"` |
1820| `output_file` | `str` | Path to the task output file |
1821| `summary` | `str` | Summary of the task result |
1822| `uuid` | `str` | Unique message identifier |
1823| `session_id` | `str` | Session identifier |
1824| `tool_use_id` | `str \| None` | Associated tool use ID |
1825| `usage` | `TaskUsage \| None` | Final token usage for the task |
1816| Field | Type | Description |
1817| :- | :- | :- |
1818| `task_id` | `str` | Unique identifier for the task |
1819| `status` | `TaskNotificationStatus` | One of `"completed"`, `"failed"`, or `"stopped"` |
1820| `output_file` | `str` | Path to the task output file |
1821| `summary` | `str` | Summary of the task result |
1822| `uuid` | `str` | Unique message identifier |
1823| `session_id` | `str` | Session identifier |
1824| `tool_use_id` | `str \| None` | Associated tool use ID |
1825| `usage` | `TaskUsage \| None` | Final token usage for the task |
18261826
18271827When the CLI [moves a long MCP tool call to the background](/docs/en/mcp#automatic-backgrounding-of-long-tool-calls), the tool result for that call holds only a placeholder and the call's real result arrives in this message. On a `"completed"` notification for such a call, the CLI adds a `resource_links` key listing the files the tool returned by reference, with the same entries and limits as the `resourceLinks` key on [`UserMessage.tool_use_result`](#usermessage). The `resource_links` key requires Python Agent SDK 0.2.150 or later and Claude Code v2.1.257 or later; the CLI bundled with that SDK version satisfies the Claude Code requirement.
18281828
from line 2078
20782078 permission_mode: NotRequired[str]
20792079```
20802080
2081| Field | Type | Description |
2082| :---------------- | :--------------- | :---------------------------------- |
2083| `session_id` | `str` | Current session identifier |
2084| `transcript_path` | `str` | Path to the session transcript file |
2085| `cwd` | `str` | Current working directory |
2086| `permission_mode` | `str` (optional) | Current permission mode |
2081| Field | Type | Description |
2082| :- | :- | :- |
2083| `session_id` | `str` | Current session identifier |
2084| `transcript_path` | `str` | Path to the session transcript file |
2085| `cwd` | `str` | Current working directory |
2086| `permission_mode` | `str` (optional) | Current permission mode |
20872087
20882088### `PreToolUseHookInput`
20892089
from line 2099
20992099 agent_type: NotRequired[str]
21002100```
21012101
2102| Field | Type | Description |
2103| :---------------- | :---------------------- | :----------------------------------------------------------------- |
2104| `hook_event_name` | `Literal["PreToolUse"]` | Always "PreToolUse" |
2105| `tool_name` | `str` | Name of the tool about to be executed |
2106| `tool_input` | `dict[str, Any]` | Input parameters for the tool |
2107| `tool_use_id` | `str` | Unique identifier for this tool use |
2108| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2109| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
2102| Field | Type | Description |
2103| :- | :- | :- |
2104| `hook_event_name` | `Literal["PreToolUse"]` | Always "PreToolUse" |
2105| `tool_name` | `str` | Name of the tool about to be executed |
2106| `tool_input` | `dict[str, Any]` | Input parameters for the tool |
2107| `tool_use_id` | `str` | Unique identifier for this tool use |
2108| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2109| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
21102110
21112111### `PostToolUseHookInput`
21122112
from line 2123
21232123 agent_type: NotRequired[str]
21242124```
21252125
2126| Field | Type | Description |
2127| :---------------- | :----------------------- | :----------------------------------------------------------------- |
2128| `hook_event_name` | `Literal["PostToolUse"]` | Always "PostToolUse" |
2129| `tool_name` | `str` | Name of the tool that was executed |
2130| `tool_input` | `dict[str, Any]` | Input parameters that were used |
2131| `tool_response` | `Any` | Response from the tool execution |
2132| `tool_use_id` | `str` | Unique identifier for this tool use |
2133| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2134| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
2126| Field | Type | Description |
2127| :- | :- | :- |
2128| `hook_event_name` | `Literal["PostToolUse"]` | Always "PostToolUse" |
2129| `tool_name` | `str` | Name of the tool that was executed |
2130| `tool_input` | `dict[str, Any]` | Input parameters that were used |
2131| `tool_response` | `Any` | Response from the tool execution |
2132| `tool_use_id` | `str` | Unique identifier for this tool use |
2133| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2134| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
21352135
21362136### `PostToolUseFailureHookInput`
21372137
from line 2149
21492149 agent_type: NotRequired[str]
21502150```
21512151
2152| Field | Type | Description |
2153| :---------------- | :------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
2154| `hook_event_name` | `Literal["PostToolUseFailure"]` | Always "PostToolUseFailure" |
2155| `tool_name` | `str` | Name of the tool that failed |
2156| `tool_input` | `dict[str, Any]` | Input parameters that were used |
2157| `tool_use_id` | `str` | Unique identifier for this tool use |
2158| `error` | `str` | Error message from the failed execution |
2159| `is_interrupt` | `bool` (optional) | True when the failure reached Claude Code as an abort rather than as an error the tool reported. Cancelling a running tool with `interrupt()` does not fire this hook; the tool result carries the interruption message instead |
2160| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2161| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
2152| Field | Type | Description |
2153| :- | :- | :- |
2154| `hook_event_name` | `Literal["PostToolUseFailure"]` | Always "PostToolUseFailure" |
2155| `tool_name` | `str` | Name of the tool that failed |
2156| `tool_input` | `dict[str, Any]` | Input parameters that were used |
2157| `tool_use_id` | `str` | Unique identifier for this tool use |
2158| `error` | `str` | Error message from the failed execution |
2159| `is_interrupt` | `bool` (optional) | True when the failure reached Claude Code as an abort rather than as an error the tool reported. Cancelling a running tool with `interrupt()` does not fire this hook; the tool result carries the interruption message instead |
2160| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2161| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
21622162
21632163### `UserPromptSubmitHookInput`
21642164
from line 2170
21702170 prompt: str
21712171```
21722172
2173| Field | Type | Description |
2174| :---------------- | :---------------------------- | :-------------------------- |
2175| `hook_event_name` | `Literal["UserPromptSubmit"]` | Always "UserPromptSubmit" |
2176| `prompt` | `str` | The user's submitted prompt |
2173| Field | Type | Description |
2174| :- | :- | :- |
2175| `hook_event_name` | `Literal["UserPromptSubmit"]` | Always "UserPromptSubmit" |
2176| `prompt` | `str` | The user's submitted prompt |
21772177
21782178### `StopHookInput`
21792179
from line 2185
21852185 stop_hook_active: bool
21862186```
21872187
2188| Field | Type | Description |
2189| :----------------- | :---------------- | :------------------------------ |
2190| `hook_event_name` | `Literal["Stop"]` | Always "Stop" |
2191| `stop_hook_active` | `bool` | Whether the stop hook is active |
2188| Field | Type | Description |
2189| :- | :- | :- |
2190| `hook_event_name` | `Literal["Stop"]` | Always "Stop" |
2191| `stop_hook_active` | `bool` | Whether the stop hook is active |
21922192
21932193### `SubagentStopHookInput`
21942194
from line 2203
22032203 agent_type: str
22042204```
22052205
2206| Field | Type | Description |
2207| :---------------------- | :------------------------ | :------------------------------------- |
2208| `hook_event_name` | `Literal["SubagentStop"]` | Always "SubagentStop" |
2209| `stop_hook_active` | `bool` | Whether the stop hook is active |
2210| `agent_id` | `str` | Unique identifier for the subagent |
2211| `agent_transcript_path` | `str` | Path to the subagent's transcript file |
2212| `agent_type` | `str` | Type of the subagent |
2206| Field | Type | Description |
2207| :- | :- | :- |
2208| `hook_event_name` | `Literal["SubagentStop"]` | Always "SubagentStop" |
2209| `stop_hook_active` | `bool` | Whether the stop hook is active |
2210| `agent_id` | `str` | Unique identifier for the subagent |
2211| `agent_transcript_path` | `str` | Path to the subagent's transcript file |
2212| `agent_type` | `str` | Type of the subagent |
22132213
22142214### `PreCompactHookInput`
22152215
from line 2222
22222222 custom_instructions: str | None
22232223```
22242224
2225| Field | Type | Description |
2226| :-------------------- | :-------------------------- | :--------------------------------- |
2227| `hook_event_name` | `Literal["PreCompact"]` | Always "PreCompact" |
2228| `trigger` | `Literal["manual", "auto"]` | What triggered the compaction |
2229| `custom_instructions` | `str \| None` | Custom instructions for compaction |
2225| Field | Type | Description |
2226| :- | :- | :- |
2227| `hook_event_name` | `Literal["PreCompact"]` | Always "PreCompact" |
2228| `trigger` | `Literal["manual", "auto"]` | What triggered the compaction |
2229| `custom_instructions` | `str \| None` | Custom instructions for compaction |
22302230
22312231### `NotificationHookInput`
22322232
from line 2240
22402240 notification_type: str
22412241```
22422242
2243| Field | Type | Description |
2244| :------------------ | :------------------------ | :--------------------------- |
2245| `hook_event_name` | `Literal["Notification"]` | Always "Notification" |
2246| `message` | `str` | Notification message content |
2247| `title` | `str` (optional) | Notification title |
2248| `notification_type` | `str` | Type of notification |
2243| Field | Type | Description |
2244| :- | :- | :- |
2245| `hook_event_name` | `Literal["Notification"]` | Always "Notification" |
2246| `message` | `str` | Notification message content |
2247| `title` | `str` (optional) | Notification title |
2248| `notification_type` | `str` | Type of notification |
22492249
22502250### `SubagentStartHookInput`
22512251
from line 2258
22582258 agent_type: str
22592259```
22602260
2261| Field | Type | Description |
2262| :---------------- | :------------------------- | :--------------------------------- |
2263| `hook_event_name` | `Literal["SubagentStart"]` | Always "SubagentStart" |
2264| `agent_id` | `str` | Unique identifier for the subagent |
2265| `agent_type` | `str` | Type of the subagent |
2261| Field | Type | Description |
2262| :- | :- | :- |
2263| `hook_event_name` | `Literal["SubagentStart"]` | Always "SubagentStart" |
2264| `agent_id` | `str` | Unique identifier for the subagent |
2265| `agent_type` | `str` | Type of the subagent |
22662266
22672267### `PermissionRequestHookInput`
22682268
from line 2278
22782278 agent_type: NotRequired[str]
22792279```
22802280
2281| Field | Type | Description |
2282| :----------------------- | :----------------------------- | :----------------------------------------------------------------- |
2283| `hook_event_name` | `Literal["PermissionRequest"]` | Always "PermissionRequest" |
2284| `tool_name` | `str` | Name of the tool requesting permission |
2285| `tool_input` | `dict[str, Any]` | Input parameters for the tool |
2286| `permission_suggestions` | `list[Any]` (optional) | Suggested permission updates from the CLI |
2287| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2288| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
2281| Field | Type | Description |
2282| :- | :- | :- |
2283| `hook_event_name` | `Literal["PermissionRequest"]` | Always "PermissionRequest" |
2284| `tool_name` | `str` | Name of the tool requesting permission |
2285| `tool_input` | `dict[str, Any]` | Input parameters for the tool |
2286| `permission_suggestions` | `list[Any]` (optional) | Suggested permission updates from the CLI |
2287| `agent_id` | `str` (optional) | Subagent identifier, present when the hook fires inside a subagent |
2288| `agent_type` | `str` (optional) | Subagent type, present when the hook fires inside a subagent |
22892289
22902290### `HookJSONOutput`
22912291
from line 3296
32963296 enableWeakerNestedSandbox: bool
32973297```
32983298
3299| Property | Type | Default | Description |
3300| :-------------------------- | :---------------------------------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
3301| `enabled` | `bool` | `False` | Enable sandbox mode for command execution |
3302| `autoAllowBashIfSandboxed` | `bool` | `True` | Auto-approve bash commands when sandbox is enabled |
3303| `excludedCommands` | `list[str]` | `[]` | Commands that bypass sandbox restrictions, such as `["docker *"]`. These run unsandboxed automatically without model involvement; [`sandbox.excludedCommands`](/docs/en/settings-reference#sandbox-excludedcommands) covers when an entry applies |
3304| `allowUnsandboxedCommands` | `bool` | `True` | Allow the model to request running commands outside the sandbox. When `True`, the model can set `dangerouslyDisableSandbox` in tool input, which falls back to the [permissions system](#permissions-fallback-for-unsandboxed-commands) |
3305| `network` | [`SandboxNetworkConfig`](#sandboxnetworkconfig) | `None` | Network-specific sandbox configuration |
3306| `ignoreViolations` | [`SandboxIgnoreViolations`](#sandboxignoreviolations) | `None` | Configure which sandbox violations to ignore |
3307| `enableWeakerNestedSandbox` | `bool` | `False` | Enable a weaker nested sandbox for compatibility |
3299| Property | Type | Default | Description |
3300| :- | :- | :- | :- |
3301| `enabled` | `bool` | `False` | Enable sandbox mode for command execution |
3302| `autoAllowBashIfSandboxed` | `bool` | `True` | Auto-approve bash commands when sandbox is enabled |
3303| `excludedCommands` | `list[str]` | `[]` | Commands that bypass sandbox restrictions, such as `["docker *"]`. These run unsandboxed automatically without model involvement; [`sandbox.excludedCommands`](/docs/en/settings-reference#sandbox-excludedcommands) covers when an entry applies |
3304| `allowUnsandboxedCommands` | `bool` | `True` | Allow the model to request running commands outside the sandbox. When `True`, the model can set `dangerouslyDisableSandbox` in tool input, which falls back to the [permissions system](#permissions-fallback-for-unsandboxed-commands) |
3305| `network` | [`SandboxNetworkConfig`](#sandboxnetworkconfig) | `None` | Network-specific sandbox configuration |
3306| `ignoreViolations` | [`SandboxIgnoreViolations`](#sandboxignoreviolations) | `None` | Configure which sandbox violations to ignore |
3307| `enableWeakerNestedSandbox` | `bool` | `False` | Enable a weaker nested sandbox for compatibility |
33083308
33093309<Note>
33103310 The sandbox depends on platform support and, on Linux, tools like `bubblewrap` and `socat`. By default, when `enabled` is `True` but the sandbox can't start, commands run unsandboxed with a warning on stderr. This default differs from the TypeScript SDK, where `failIfUnavailable` defaults to `true`.
from line 3364
33643364 socksProxyPort: int
33653365```
33663366
3367| Property | Type | Default | Description |
3368| :------------------------ | :---------- | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
3369| `allowedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes can access |
3370| `deniedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes cannot access. Takes precedence over `allowedDomains` |
3371| `allowManagedDomainsOnly` | `bool` | `False` | Managed-settings only: when set in managed settings, ignore `allowedDomains` and `WebFetch(domain:...)` allow rules from non-managed settings sources. Has no effect when set via SDK options |
3372| `allowUnixSockets` | `list[str]` | `[]` | macOS only: Unix socket paths that processes can access, such as the Docker socket. Ignored on Linux |
3373| `allowAllUnixSockets` | `bool` | `False` | Allow access to all Unix sockets |
3374| `allowLocalBinding` | `bool` | `False` | Allow processes to bind to local ports (for example, for dev servers) |
3375| `allowMachLookup` | `list[str]` | `[]` | macOS only: XPC/Mach service names to allow. Supports a trailing wildcard |
3376| `httpProxyPort` | `int` | `None` | HTTP proxy port for network requests |
3377| `socksProxyPort` | `int` | `None` | SOCKS proxy port for network requests |
3367| Property | Type | Default | Description |
3368| :- | :- | :- | :- |
3369| `allowedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes can access |
3370| `deniedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes cannot access. Takes precedence over `allowedDomains` |
3371| `allowManagedDomainsOnly` | `bool` | `False` | Managed-settings only: when set in managed settings, ignore `allowedDomains` and `WebFetch(domain:...)` allow rules from non-managed settings sources. Has no effect when set via SDK options |
3372| `allowUnixSockets` | `list[str]` | `[]` | macOS only: Unix socket paths that processes can access, such as the Docker socket. Ignored on Linux |
3373| `allowAllUnixSockets` | `bool` | `False` | Allow access to all Unix sockets |
3374| `allowLocalBinding` | `bool` | `False` | Allow processes to bind to local ports (for example, for dev servers) |
3375| `allowMachLookup` | `list[str]` | `[]` | macOS only: XPC/Mach service names to allow. Supports a trailing wildcard |
3376| `httpProxyPort` | `int` | `None` | HTTP proxy port for network requests |
3377| `socksProxyPort` | `int` | `None` | SOCKS proxy port for network requests |
33783378
33793379<Note>
33803380 The built-in sandbox proxy enforces the network allowlist based on the requested hostname and does not terminate or inspect TLS traffic, so techniques such as [domain fronting](https://en.wikipedia.org/wiki/Domain_fronting) can potentially bypass it. See [Sandboxing security limitations](/docs/en/sandboxing#security-limitations) for details and [Secure deployment](/docs/en/agent-sdk/secure-deployment#traffic-forwarding) for configuring a TLS-terminating proxy.
from line 3390
33903390 network: list[str]
33913391```
33923392
3393| Property | Type | Default | Description |
3394| :-------- | :---------- | :------ | :------------------------------------------ |
3395| `file` | `list[str]` | `[]` | File path patterns to ignore violations for |
3396| `network` | `list[str]` | `[]` | Network patterns to ignore violations for |
3393| Property | Type | Default | Description |
3394| :- | :- | :- | :- |
3395| `file` | `list[str]` | `[]` | File path patterns to ignore violations for |
3396| `network` | `list[str]` | `[]` | Network patterns to ignore violations for |
33973397
33983398### Permissions Fallback for Unsandboxed Commands
33993399
34003400
agent-sdk/quickstart Changed · +5 / -5 lines
from line 346
346346
347347**Tools** control what your agent can do:
348348
349| Tools | What the agent can do |
350| -------------------------------------- | ----------------------- |
351| `Read`, `Glob`, `Grep` | Read-only analysis |
352| `Read`, `Edit`, `Glob` | Analyze and modify code |
353| `Read`, `Edit`, `Bash`, `Glob`, `Grep` | Full automation |
349| Tools | What the agent can do |
350| - | - |
351| `Read`, `Glob`, `Grep` | Read-only analysis |
352| `Read`, `Edit`, `Glob` | Analyze and modify code |
353| `Read`, `Edit`, `Bash`, `Glob`, `Grep` | Full automation |
354354
355355**Permission modes** control how much human oversight you want. The SDK evaluates the active mode together with your allow and deny rules in a fixed order, described in [How permissions are evaluated](/docs/en/agent-sdk/permissions#how-permissions-are-evaluated). For the full list of modes, their behavior, and when to use each, see [Permission mode in How the agent loop works](/docs/en/agent-sdk/agent-loop#permission-mode).
356356
agent-sdk/secure-deployment Changed · +45 / -45 lines
from line 37
3737
3838When needed, you can restrict the agent to only the capabilities required for its specific task:
3939
40| Resource | Restriction options |
41| ------------------- | ----------------------------------------------- |
42| Filesystem | Mount only needed directories, prefer read-only |
43| Network | Restrict to specific endpoints via proxy |
44| Credentials | Inject via proxy rather than exposing directly |
45| System capabilities | Drop Linux capabilities in containers |
40| Resource | Restriction options |
41| - | - |
42| Filesystem | Mount only needed directories, prefer read-only |
43| Network | Restrict to specific endpoints via proxy |
44| Credentials | Inject via proxy rather than exposing directly |
45| System capabilities | Drop Linux capabilities in containers |
4646
4747### Defense in depth
4848
from line 63
6363 In all of these configurations, Claude Code (or your Agent SDK application) runs inside the isolation boundary (the sandbox, container, or VM). The security controls described below restrict what the agent can access from within that boundary.
6464</Info>
6565
66| Technology | Isolation strength | Performance overhead | Complexity |
67| ----------------------- | ------------------------------ | -------------------- | ----------- |
68| Sandbox runtime | Good (secure defaults) | Very low | Low |
69| Containers (Docker) | Setup dependent | Low | Medium |
70| gVisor | Excellent (with correct setup) | Medium/High | Medium |
71| VMs (Firecracker, QEMU) | Excellent (with correct setup) | High | Medium/High |
66| Technology | Isolation strength | Performance overhead | Complexity |
67| - | - | - | - |
68| Sandbox runtime | Good (secure defaults) | Very low | Low |
69| Containers (Docker) | Setup dependent | Low | Medium |
70| gVisor | Excellent (with correct setup) | Medium/High | Medium |
71| VMs (Firecracker, QEMU) | Excellent (with correct setup) | High | Medium/High |
7272
7373### Sandbox runtime
7474
from line 124
124124
125125Here's what each option does:
126126
127| Option | Purpose |
128| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
129| `--cap-drop ALL` | Removes Linux capabilities like `NET_ADMIN` and `SYS_ADMIN` that could enable privilege escalation |
130| `--security-opt no-new-privileges` | Prevents processes from gaining privileges through setuid binaries |
131| `--security-opt seccomp=...` | Restricts available syscalls; Docker's default blocks \~44, custom profiles can block more |
132| `--read-only` | Makes the container's root filesystem immutable, preventing the agent from persisting changes |
133| `--tmpfs /tmp:...` | Provides a writable temporary directory that's cleared when the container stops |
134| `--network none` | Removes all network interfaces; the agent communicates through the mounted Unix socket below |
135| `--memory 2g` | Limits memory usage to prevent resource exhaustion |
136| `--pids-limit 100` | Limits process count to prevent fork bombs |
137| `--user 1000:1000` | Runs as a non-root user |
138| `-v ...:/workspace:ro` | Mounts code read-only so the agent can analyze but not modify it. **Avoid mounting sensitive host directories like `~/.ssh`, `~/.aws`, or `~/.config`** |
139| `-v .../proxy.sock:...` | Mounts a Unix socket connected to a proxy running outside the container (see below) |
127| Option | Purpose |
128| - | - |
129| `--cap-drop ALL` | Removes Linux capabilities like `NET_ADMIN` and `SYS_ADMIN` that could enable privilege escalation |
130| `--security-opt no-new-privileges` | Prevents processes from gaining privileges through setuid binaries |
131| `--security-opt seccomp=...` | Restricts available syscalls; Docker's default blocks \~44, custom profiles can block more |
132| `--read-only` | Makes the container's root filesystem immutable, preventing the agent from persisting changes |
133| `--tmpfs /tmp:...` | Provides a writable temporary directory that's cleared when the container stops |
134| `--network none` | Removes all network interfaces; the agent communicates through the mounted Unix socket below |
135| `--memory 2g` | Limits memory usage to prevent resource exhaustion |
136| `--pids-limit 100` | Limits process count to prevent fork bombs |
137| `--user 1000:1000` | Runs as a non-root user |
138| `-v ...:/workspace:ro` | Mounts code read-only so the agent can analyze but not modify it. **Avoid mounting sensitive host directories like `~/.ssh`, `~/.aws`, or `~/.config`** |
139| `-v .../proxy.sock:...` | Mounts a Unix socket connected to a proxy running outside the container (see below) |
140140
141141**Unix socket architecture:**
142142
from line 146
146146
147147**Additional hardening options:**
148148
149| Option | Purpose |
150| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
149| Option | Purpose |
150| - | - |
151151| `--userns-remap` | Maps container root to unprivileged host user; requires daemon configuration but limits damage from container escape |
152| `--ipc private` | Isolates inter-process communication to prevent cross-container attacks |
152| `--ipc private` | Isolates inter-process communication to prevent cross-container attacks |
153153
154154### gVisor
155155
from line 177
177177
178178**Performance considerations:**
179179
180| Workload | Overhead |
181| --------------------- | -------------------------------------------------- |
182| CPU-bound computation | \~0% (no syscall interception) |
183| Simple syscalls | \~2× slower |
184| File I/O intensive | Up to 10-200× slower for heavy open/close patterns |
180| Workload | Overhead |
181| - | - |
182| CPU-bound computation | \~0% (no syscall interception) |
183| Simple syscalls | \~2× slower |
184| File I/O intensive | Up to 10-200× slower for heavy open/close patterns |
185185
186186For multi-tenant environments or when processing untrusted content, the additional isolation is often worth the overhead.
187187
from line 298
298298<Warning>
299299 Even read-only access to a code directory can expose credentials. Common files to exclude or sanitize before mounting:
300300
301 | File | Risk |
302 | ------------------------------------------------------- | ------------------------------------- |
303 | `.env`, `.env.local` | API keys, database passwords, secrets |
304 | `~/.git-credentials` | Git passwords/tokens in plaintext |
305 | `~/.aws/credentials` | AWS access keys |
306 | `~/.config/gcloud/application_default_credentials.json` | Google Cloud ADC tokens |
307 | `~/.azure/` | Azure CLI credentials |
308 | `~/.docker/config.json` | Docker registry auth tokens |
309 | `~/.kube/config` | Kubernetes cluster credentials |
310 | `.npmrc`, `.pypirc` | Package registry tokens |
311 | `*-service-account.json` | GCP service account keys |
312 | `*.pem`, `*.key` | Private keys |
301 | File | Risk |
302 | - | - |
303 | `.env`, `.env.local` | API keys, database passwords, secrets |
304 | `~/.git-credentials` | Git passwords/tokens in plaintext |
305 | `~/.aws/credentials` | AWS access keys |
306 | `~/.config/gcloud/application_default_credentials.json` | Google Cloud ADC tokens |
307 | `~/.azure/` | Azure CLI credentials |
308 | `~/.docker/config.json` | Docker registry auth tokens |
309 | `~/.kube/config` | Kubernetes cluster credentials |
310 | `.npmrc`, `.pypirc` | Package registry tokens |
311 | `*-service-account.json` | GCP service account keys |
312 | `*.pem`, `*.key` | Private keys |
313313
314314 Consider copying only the source files needed, or using `.dockerignore`-style filtering.
315315</Warning>
agent-sdk/session-storage Changed · +13 / -13 lines
from line 88
8888
8989Treat `subpath` as an opaque key suffix; it follows the on-disk layout, for example `subagents/agent-<id>`. When `subpath` is undefined the key refers to the main transcript.
9090
91| Method | Required | Called when |
92| :--------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93| `append` | Yes | After each batch of transcript entries is written locally. Entries are JSON-safe objects, one per line in the local JSONL. |
94| `load` | Yes | Before the subprocess spawns when `resume` is set or `continue: true` resolves the newest store session, and once per session when listing falls back from `listSessionSummaries`. Return `null` if the session is unknown. |
95| `listSessions` | No | By `listSessions({ sessionStore })` and by `query()`/`startup()` with `continue: true`. If undefined, `continue: true` throws, and `listSessions({ sessionStore })` throws unless `listSessionSummaries` is implemented. |
96| `listSessionSummaries` | No | By `listSessions({ sessionStore })` to read metadata for all sessions in one call. Maintain the summaries inside `append`. If undefined, listing falls back to `listSessions` plus a per-session `load`. |
97| `delete` | No | By `deleteSession({ sessionStore })`. Deleting the main key (no `subpath`) must cascade to all subkeys for that session and also remove the session's summary entry, so a deleted session stops appearing in `listSessionSummaries`. If undefined, deletion is a no-op, which suits append-only backends. |
98| `listSubkeys` | No | During resume, to discover subagent transcripts. If undefined, only the main transcript is restored. |
91| Method | Required | Called when |
92| :- | :- | :- |
93| `append` | Yes | After each batch of transcript entries is written locally. Entries are JSON-safe objects, one per line in the local JSONL. |
94| `load` | Yes | Before the subprocess spawns when `resume` is set or `continue: true` resolves the newest store session, and once per session when listing falls back from `listSessionSummaries`. Return `null` if the session is unknown. |
95| `listSessions` | No | By `listSessions({ sessionStore })` and by `query()`/`startup()` with `continue: true`. If undefined, `continue: true` throws, and `listSessions({ sessionStore })` throws unless `listSessionSummaries` is implemented. |
96| `listSessionSummaries` | No | By `listSessions({ sessionStore })` to read metadata for all sessions in one call. Maintain the summaries inside `append`. If undefined, listing falls back to `listSessions` plus a per-session `load`. |
97| `delete` | No | By `deleteSession({ sessionStore })`. Deleting the main key (no `subpath`) must cascade to all subkeys for that session and also remove the session's summary entry, so a deleted session stops appearing in `listSessionSummaries`. If undefined, deletion is a no-op, which suits append-only backends. |
98| `listSubkeys` | No | During resume, to discover subagent transcripts. If undefined, only the main transcript is restored. |
9999
100100In a `SessionSummaryEntry`, `mtime` is the sidecar's storage write time and must share a clock source with the `mtime` values `listSessions` returns. `data` is opaque SDK-owned state; persist it verbatim without interpreting it.
101101
from line 193
193193
194194Both SDK repositories include runnable reference adapters under [`examples/session-stores/`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores) in TypeScript and [`examples/session_stores/`](https://github.com/anthropics/claude-agent-sdk-python/tree/main/examples/session_stores) in Python. There is one adapter per storage type, and each shows how `append` and `load` map onto that kind of backend. They are not published as packages; copy the adapter for the type closest to your backend into your project, install your backend's client, and adapt it.
195195
196| Storage type | Storage model | Example adapter |
197| :------------------------------------ | :-------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
198| Object store | One part file per `append()`; `load()` lists the parts, sorts them, and concatenates. | S3 ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/s3), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/s3_session_store.py)) |
199| Key-value store | One list per transcript that `append()` pushes to and `load()` reads in range, plus a sorted index of sessions. | Redis ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/redis), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/redis_session_store.py)) |
200| Relational database or document store | One row or document per entry, stored as JSON and ordered by a key assigned on insert. | Postgres ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/postgres), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/postgres_session_store.py)) |
196| Storage type | Storage model | Example adapter |
197| :- | :- | :- |
198| Object store | One part file per `append()`; `load()` lists the parts, sorts them, and concatenates. | S3 ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/s3), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/s3_session_store.py)) |
199| Key-value store | One list per transcript that `append()` pushes to and `load()` reads in range, plus a sorted index of sessions. | Redis ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/redis), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/redis_session_store.py)) |
200| Relational database or document store | One row or document per entry, stored as JSON and ordered by a key assigned on insert. | Postgres ([TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/postgres), [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/examples/session_stores/postgres_session_store.py)) |
201201
202202Each adapter takes a pre-configured client instance, so you control credentials, TLS, region, and pooling. The following example wires the object-store adapter into `query()` and then resumes from it on another host:
203203
agent-sdk/sessions Changed · +8 / -8 lines
from line 16
1616
1717How much session handling you need depends on your application's shape. Session management comes into play when you send multiple prompts that should share context. Within a single `query()` call, the agent already takes as many turns as it needs, and permission prompts and `AskUserQuestion` are [handled in-loop](/docs/en/agent-sdk/user-input) (they don't end the call).
1818
19| What you're building | What to use |
20| :------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
21| One-shot task: single prompt, no follow-up | Nothing extra. One `query()` call handles it. |
22| Multi-turn chat in one process | [`ClaudeSDKClient` (Python) or `continue: true` (TypeScript)](#automatic-session-management). The SDK tracks the session for you with no ID handling. |
23| Pick up where you left off after a process restart | `continue_conversation=True` (Python) / `continue: true` (TypeScript). Resumes the most recent session in the directory, no ID needed. |
24| Resume a specific past session (not the most recent) | Capture the session ID and pass it to `resume`. |
25| Try an alternative approach without losing the original | Fork the session. |
26| Stateless task, don't want anything written to disk | Set [`persistSession: false`](/docs/en/agent-sdk/typescript#options) (TypeScript only). The session exists only in memory for the duration of the call. In Python, set [`CLAUDE_CODE_SKIP_PROMPT_HISTORY`](/docs/en/env-vars) in the `env` option to suppress transcript writes instead. |
19| What you're building | What to use |
20| :- | :- |
21| One-shot task: single prompt, no follow-up | Nothing extra. One `query()` call handles it. |
22| Multi-turn chat in one process | [`ClaudeSDKClient` (Python) or `continue: true` (TypeScript)](#automatic-session-management). The SDK tracks the session for you with no ID handling. |
23| Pick up where you left off after a process restart | `continue_conversation=True` (Python) / `continue: true` (TypeScript). Resumes the most recent session in the directory, no ID needed. |
24| Resume a specific past session (not the most recent) | Capture the session ID and pass it to `resume`. |
25| Try an alternative approach without losing the original | Fork the session. |
26| Stateless task, don't want anything written to disk | Set [`persistSession: false`](/docs/en/agent-sdk/typescript#options) (TypeScript only). The session exists only in memory for the duration of the call. In Python, set [`CLAUDE_CODE_SKIP_PROMPT_HISTORY`](/docs/en/env-vars) in the `env` option to suppress transcript writes instead. |
2727
2828### Continue, resume, and fork
2929
agent-sdk/streaming-output Changed · +7 / -7 lines
from line 82
8282
8383The `event` field contains the raw streaming event from the [Claude API](https://platform.claude.com/docs/en/build-with-claude/streaming#event-types). Common event types include:
8484
85| Event Type | Description |
86| :-------------------- | :---------------------------------------------- |
87| `message_start` | Start of a new message |
85| Event Type | Description |
86| :- | :- |
87| `message_start` | Start of a new message |
8888| `content_block_start` | Start of a new content block (text or tool use) |
89| `content_block_delta` | Incremental update to content |
90| `content_block_stop` | End of a content block |
91| `message_delta` | Message-level updates (stop reason, usage) |
92| `message_stop` | End of the message |
89| `content_block_delta` | Incremental update to content |
90| `content_block_stop` | End of a content block |
91| `message_delta` | Message-level updates (stop reason, usage) |
92| `message_stop` | End of the message |
9393
9494## Message flow
9595
agent-sdk/structured-outputs Changed · +3 / -3 lines
from line 378
378378
379379When an error occurs, the result message has a `subtype` indicating what went wrong:
380380
381| Subtype | Meaning |
382| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
383| `success` | Output was generated and validated successfully |
381| Subtype | Meaning |
382| - | - |
383| `success` | Output was generated and validated successfully |
384384| `error_max_structured_output_retries` | No valid output remained after multiple attempts (validation failures, or a model-fallback retraction with no successful retry) |
385385
386386A result can also end with subtype `success` but no `structured_output` value, for example when the run completes without the agent producing a structured output. Treat that case as a failure as well. The troubleshooting entry [structured\_output is None but the result says success](/docs/en/agent-sdk/troubleshooting#structured_output-is-none-but-the-result-says-success) covers this case. The example below treats a result as successful only when the `subtype` is `success` and `structured_output` is present, and handles every other result as a failure:
agent-sdk/subagents Changed · +31 / -31 lines
from line 138
138138
139139### AgentDefinition configuration
140140
141| Field | Type | Required | Description |
142| :---------------- | :---------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143| `description` | `string` | Yes | Natural language description of when to use this agent |
144| `prompt` | `string` | Yes | The agent's system prompt defining its role and behavior |
145| `tools` | `string[]` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents#available-tools) |
146| `disallowedTools` | `string[]` | No | Array of tool names to remove from the agent's tool set. MCP server-level patterns are also accepted: `mcp__server` or `mcp__server__*` removes every tool from that server, and `mcp__*` removes every MCP tool from any server |
147| `model` | `string` | No | Model override for this agent. Accepts an alias such as `'fable'`, `'opus'`, `'sonnet'`, `'haiku'`, `'inherit'`, or a full model ID. `'inherit'` uses the main model. When you omit it, Claude Code picks the model in the [subagent model order](/docs/en/sub-agents#choose-a-model) |
148| `skills` | `string[]` | No | List of skill names to preload into the agent's context at startup. Unlisted skills remain invocable through the Skill tool |
149| `memory` | `'user' \| 'project' \| 'local'` | No | Memory source for this agent |
150| `mcpServers` | `(string \| object)[]` | No | MCP servers available to this agent, by name or inline config |
151| `initialPrompt` | `string` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent. Ignored when the agent is invoked as a subagent |
152| `maxTurns` | `number` | No | Maximum number of agentic turns before the agent stops. When the agent reaches the limit, Claude Code returns its output marked as partial, and you can [resume the agent](#resume-subagents) to continue. The partial marking requires Claude Code v2.1.246 or later |
153| `background` | `boolean` | No | Run this agent as a non-blocking background task when invoked |
154| `omitClaudeMd` | `boolean` | No | Run this agent without the user, project, and local CLAUDE.md files when it runs as a subagent; managed policy files still load. Ignored when the agent runs as the main thread agent. Requires TypeScript Agent SDK v0.3.271 or later. The Python SDK's [`AgentDefinition`](/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
155| `effort` | `'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max' \| number` | No | Reasoning effort level for this agent |
156| `permissionMode` | `PermissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions#available-modes) decide when it applies |
141| Field | Type | Required | Description |
142| :- | :- | :- | :- |
143| `description` | `string` | Yes | Natural language description of when to use this agent |
144| `prompt` | `string` | Yes | The agent's system prompt defining its role and behavior |
145| `tools` | `string[]` | No | Array of allowed tool names. If omitted, inherits every [tool available to subagents](/docs/en/sub-agents#available-tools) |
146| `disallowedTools` | `string[]` | No | Array of tool names to remove from the agent's tool set. MCP server-level patterns are also accepted: `mcp__server` or `mcp__server__*` removes every tool from that server, and `mcp__*` removes every MCP tool from any server |
147| `model` | `string` | No | Model override for this agent. Accepts an alias such as `'fable'`, `'opus'`, `'sonnet'`, `'haiku'`, `'inherit'`, or a full model ID. `'inherit'` uses the main model. When you omit it, Claude Code picks the model in the [subagent model order](/docs/en/sub-agents#choose-a-model) |
148| `skills` | `string[]` | No | List of skill names to preload into the agent's context at startup. Unlisted skills remain invocable through the Skill tool |
149| `memory` | `'user' \| 'project' \| 'local'` | No | Memory source for this agent |
150| `mcpServers` | `(string \| object)[]` | No | MCP servers available to this agent, by name or inline config |
151| `initialPrompt` | `string` | No | Auto-submitted as the first user turn when this agent runs as the main thread agent. Ignored when the agent is invoked as a subagent |
152| `maxTurns` | `number` | No | Maximum number of agentic turns before the agent stops. When the agent reaches the limit, Claude Code returns its output marked as partial, and you can [resume the agent](#resume-subagents) to continue. The partial marking requires Claude Code v2.1.246 or later |
153| `background` | `boolean` | No | Run this agent as a non-blocking background task when invoked |
154| `omitClaudeMd` | `boolean` | No | Run this agent without the user, project, and local CLAUDE.md files when it runs as a subagent; managed policy files still load. Ignored when the agent runs as the main thread agent. Requires TypeScript Agent SDK v0.3.271 or later. The Python SDK's [`AgentDefinition`](/docs/en/agent-sdk/python#agentdefinition) doesn't have this field |
155| `effort` | `'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max' \| number` | No | Reasoning effort level for this agent |
156| `permissionMode` | `PermissionMode` | No | Permission mode for tool execution within this agent. The [subagent inheritance rules](/docs/en/agent-sdk/permissions#available-modes) decide when it applies |
157157
158158In the Python SDK, multi-word field names such as `disallowedTools` and `mcpServers` keep their camelCase spelling to match the wire format rather than following Python's snake\_case convention. See the [`AgentDefinition` reference](/docs/en/agent-sdk/python#agentdefinition) for details.
159159
from line 179
179179
180180The table below lists what a non-fork subagent's context contains and what it leaves out.
181181
182| The subagent receives | The subagent doesn't receive |
183| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------- |
184| Its own system prompt (`AgentDefinition.prompt`) and the Agent tool's prompt | The parent's conversation history or tool results |
182| The subagent receives | The subagent doesn't receive |
183| :- | :- |
184| Its own system prompt (`AgentDefinition.prompt`) and the Agent tool's prompt | The parent's conversation history or tool results |
185185| Project CLAUDE.md (loaded via [`settingSources`](/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources)), unless the agent sets [`omitClaudeMd`](#agentdefinition-configuration) | Preloaded skill content, unless listed in `AgentDefinition.skills` |
186| Tool definitions (inherited from parent or the subset in `tools`, [filtered for background runs](/docs/en/sub-agents#available-tools)) | The parent's system prompt |
186| Tool definitions (inherited from parent or the subset in `tools`, [filtered for background runs](/docs/en/sub-agents#available-tools)) | The parent's system prompt |
187187
188188<Note>
189189 The parent receives the subagent's final message as the Agent tool result, but may summarize it in its own response. To preserve subagent output verbatim in the user-facing response, include an instruction to do so in the prompt or `systemPrompt` option you pass to the main `query()` call.
from line 591
591591
592592### Common tool combinations
593593
594| Use case | Tools | Description |
595| :----------------- | :-------------------------------------- | :----------------------------------------------------------------- |
596| Read-only analysis | `Read`, `Grep`, `Glob` | Can examine code but not modify or execute |
597| Test execution | `Bash`, `Read`, `Grep` | Can run commands and analyze output |
598| Code modification | `Read`, `Edit`, `Write`, `Grep`, `Glob` | Full read/write access without command execution |
599| Full access | All tools | Inherits the tools available to subagents (omit the `tools` field) |
594| Use case | Tools | Description |
595| :- | :- | :- |
596| Read-only analysis | `Read`, `Grep`, `Glob` | Can examine code but not modify or execute |
597| Test execution | `Bash`, `Read`, `Grep` | Can run commands and analyze output |
598| Code modification | `Read`, `Edit`, `Write`, `Grep`, `Glob` | Full read/write access without command execution |
599| Full access | All tools | Inherits the tools available to subagents (omit the `tools` field) |
600600
601601## Cap subagent depth, concurrency, and spend
602602
from line 608
608608
609609You can cap that growth in three ways: how deeply subagents nest, how many run at once, and how much the whole query spends. Set the depth and concurrency limits as environment variables through the [`env`](/docs/en/agent-sdk/typescript#options) option, and the spend limit as a query option:
610610
611| Limit | Set it with | Default | What Claude Code does at the limit |
612| :---------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
613| Depth | [`CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`](/docs/en/env-vars) | `3` layers of subagents below your main agent. `1` stops your subagents from spawning any of their own | Leaves a subagent at the bottom layer unable to spawn, so it does its delegated work itself. See [nested subagents](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents) |
614| Concurrency | [`CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`](/docs/en/env-vars) | `20` subagents running at once, counting every subagent Claude spawns with the Agent tool | Refuses to spawn another subagent, returning `Concurrent subagent limit reached`, until the running count drops below the limit. Sessions with [ultracode](/docs/en/model-config#adjust-effort-level) active are never refused. See the [concurrent subagent limit](/docs/en/sub-agents#concurrent-subagent-limit) |
615| Spend | `maxBudgetUsd` in TypeScript, `max_budget_usd` in Python | No limit. Counts the call's own spend, subagent requests included | Enforces the cap in three ways: refuses to spawn more subagents, returning `Budget limit reached`, stops background subagents that are still running, and ends the query with the `error_max_budget_usd` result subtype. For how the caps behave across a session, see [turns and budget](/docs/en/agent-sdk/agent-loop#turns-and-budget) |
611| Limit | Set it with | Default | What Claude Code does at the limit |
612| :- | :- | :- | :- |
613| Depth | [`CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH`](/docs/en/env-vars) | `3` layers of subagents below your main agent. `1` stops your subagents from spawning any of their own | Leaves a subagent at the bottom layer unable to spawn, so it does its delegated work itself. See [nested subagents](/docs/en/sub-agents#let-subagents-spawn-their-own-subagents) |
614| Concurrency | [`CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`](/docs/en/env-vars) | `20` subagents running at once, counting every subagent Claude spawns with the Agent tool | Refuses to spawn another subagent, returning `Concurrent subagent limit reached`, until the running count drops below the limit. Sessions with [ultracode](/docs/en/model-config#adjust-effort-level) active are never refused. See the [concurrent subagent limit](/docs/en/sub-agents#concurrent-subagent-limit) |
615| Spend | `maxBudgetUsd` in TypeScript, `max_budget_usd` in Python | No limit. Counts the call's own spend, subagent requests included | Enforces the cap in three ways: refuses to spawn more subagents, returning `Budget limit reached`, stops background subagents that are still running, and ends the query with the `error_max_budget_usd` result subtype. For how the caps behave across a session, see [turns and budget](/docs/en/agent-sdk/agent-loop#turns-and-budget) |
616616
617617The two SDKs treat the `env` option differently: the TypeScript SDK replaces the subprocess environment with it, so spread `process.env` into it to keep variables like `PATH`, while the Python SDK merges it into the inherited environment. This example turns nesting off, allows at most five subagents at a time, and stops the query once the estimated spend reaches \$5:
618618