Référence du SDK Agent - Python
Référence API complète du SDK Agent Python, incluant toutes les fonctions, types et classes.
Installation
Installez le package dans un environnement virtuel. Sur les installations récentes de Debian, Ubuntu et Homebrew Python, l'exécution de pip install contre le Python système échoue avec error: externally-managed-environment.
python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdk
Pour uv, Windows PowerShell et la configuration de la clé API, consultez Démarrer dans la vue d'ensemble du Agent SDK.
Choisir entre `query()` et `ClaudeSDKClient`
Le SDK Python offre deux façons d'interagir avec Claude Code :
| Fonctionnalité | query() |
ClaudeSDKClient |
|---|---|---|
| Session | Crée une nouvelle session par défaut | Réutilise la même session |
| Conversation | Échange unique | Plusieurs échanges dans le même contexte |
| Connexion | Gérée automatiquement | Contrôle manuel |
| Entrée en streaming | ✅ Supportée | ✅ Supportée |
| Interruptions | ❌ Non supportées | ✅ Supportées |
| Hooks | ✅ Supportés | ✅ Supportés |
| Outils personnalisés | ✅ Supportés | ✅ Supportés |
| Continuer la conversation | Manuel via continue_conversation ou resume |
✅ Automatique |
| Cas d'usage | Tâches ponctuelles | Conversations continues |
Utilisez ClaudeSDKClient pour les applications interactives telles que les interfaces de chat, ou quand l'action suivante dépend de la réponse de Claude.
Fonctions
Les blocs de signature et les fragments async for / async with nus sur cette page sont illustratifs. Pour les exécuter, enveloppez le corps dans async def main(): ... et appelez asyncio.run(main()).
`query()`
Crée une nouvelle session pour chaque interaction avec Claude Code par défaut. Retourne un itérateur asynchrone qui produit les messages au fur et à mesure qu'ils arrivent. Chaque appel à query() recommence à zéro sans mémoire des interactions précédentes, sauf si vous passez continue_conversation=True ou resume dans ClaudeAgentOptions. Voir Sessions.
async def query(
*,
prompt: str | AsyncIterable[dict[str, Any]],
options: ClaudeAgentOptions | None = None,
transport: Transport | None = None
) -> AsyncIterator[Message]
Paramètres
| Paramètre | Type | Description |
|---|---|---|
prompt |
str | AsyncIterable[dict] |
Le prompt d'entrée sous forme de chaîne ou d'itérable asynchrone pour le mode streaming |
options |
ClaudeAgentOptions | None |
Objet de configuration optionnel (par défaut ClaudeAgentOptions() si None) |
transport |
Transport | None |
Transport personnalisé optionnel pour communiquer avec le processus CLI |
Retours
Retourne un AsyncIterator[Message] qui produit les messages de la conversation.
Exemple - Avec options
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
options = ClaudeAgentOptions(
system_prompt="You are an expert Python developer",
permission_mode="acceptEdits",
)
async for message in query(prompt="Create a Python web server", options=options):
print(message)
asyncio.run(main())
`tool()`
Décorateur pour définir des outils MCP avec sécurité des types.
def tool(
name: str,
description: str,
input_schema: type | dict[str, Any],
annotations: ToolAnnotations | None = None
) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]
Paramètres
| Paramètre | Type | Description |
|---|---|---|
name |
str |
Identifiant unique pour l'outil |
description |
str |
Description lisible de ce que fait l'outil |
input_schema |
type | dict[str, Any] |
Schéma définissant les paramètres d'entrée de l'outil (voir ci-dessous) |
annotations |
ToolAnnotations | None |
Annotations MCP optionnelles fournissant des indices comportementaux aux clients |
Options de schéma d'entrée
-
Mappage de type simple (recommandé) :
{"text": str, "count": int, "enabled": bool} -
Format JSON Schema (pour la validation complexe) :
{ "type": "object", "properties": { "text": {"type": "string"}, "count": {"type": "integer", "minimum": 0}, }, "required": ["text"], }
Retours
Une fonction décorateur qui enveloppe l'implémentation de l'outil et retourne une instance SdkMcpTool.
Exemple
from claude_agent_sdk import tool
from typing import Any
@tool("greet", "Greet a user", {"name": str})
async def greet(args: dict[str, Any]) -> dict[str, Any]:
return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}
`ToolAnnotations`
Indices comportementaux pour un outil, passés comme argument annotations de tool(). ToolAnnotations étend mcp.types.ToolAnnotations du SDK MCP avec un champ maxResultSizeChars, et vous pouvez écrire chaque indice en camelCase ou snake_case : ToolAnnotations(readOnlyHint=True) et ToolAnnotations(read_only_hint=True) sont équivalents. Vous pouvez également passer un mcp.types.ToolAnnotations simple partout où le SDK accepte des annotations.
Les noms snake_case et le champ typé maxResultSizeChars nécessitent Python Agent SDK 0.2.140 ou ultérieur. Les versions 0.1.31 à 0.2.139 réexportent mcp.types.ToolAnnotations inchangé. Sur les versions 0.1.55 à 0.2.139, vous pouvez toujours passer maxResultSizeChars comme argument de mot-clé : la classe MCP accepte les champs supplémentaires, et le SDK transmet la valeur à Claude Code.
Tous les champs sont optionnels. Les clients ne doivent pas s'y fier pour les décisions de sécurité.
| Champ | Type | Par défaut | Description |
|---|---|---|---|
title |
str | None |
None |
Titre lisible pour l'outil |
readOnlyHint |
bool | None |
False |
Si True, l'outil ne modifie pas son environnement |
destructiveHint |
bool | None |
True |
Si True, l'outil peut effectuer des mises à jour destructrices (uniquement significatif quand readOnlyHint est False) |
idempotentHint |
bool | None |
False |
Si True, les appels répétés avec les mêmes arguments n'ont pas d'effet supplémentaire (uniquement significatif quand readOnlyHint est False) |
openWorldHint |
bool | None |
True |
Si True, l'outil interagit avec des entités externes (par exemple, recherche web). Si False, le domaine de l'outil est fermé (par exemple, un outil de mémoire) |
maxResultSizeChars |
int | None |
None |
Nombre de caractères jusqu'auquel Claude Code conserve le résultat textuel de cet outil en ligne dans la conversation au lieu de l'enregistrer dans un fichier, jusqu'à 500 000. Les résultats contenant des images ne sont pas affectés. Un paramètre Claude Code plutôt qu'un indice MCP : le SDK l'envoie dans _meta de l'outil en tant que anthropic/maxResultSizeChars. Voir Augmenter la limite pour un outil spécifique |
from claude_agent_sdk import tool, ToolAnnotations
from typing import Any
@tool(
"search",
"Search the web",
{"query": str},
annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True),
)
async def search(args: dict[str, Any]) -> dict[str, Any]:
return {"content": [{"type": "text", "text": f"Results for: {args['query']}"}]}
`create_sdk_mcp_server()`
Crée un serveur MCP en processus qui s'exécute dans votre application Python.
def create_sdk_mcp_server(
name: str,
version: str = "1.0.0",
tools: list[SdkMcpTool[Any]] | None = None
) -> McpSdkServerConfig
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
name |
str |
- | Identifiant unique pour le serveur |
version |
str |
"1.0.0" |
Chaîne de version du serveur |
tools |
list[SdkMcpTool[Any]] | None |
None |
Liste des fonctions d'outil créées avec le décorateur @tool |
Retours
Retourne un objet McpSdkServerConfig qui peut être passé à ClaudeAgentOptions.mcp_servers.
Exemple
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions
@tool("add", "Add two numbers", {"a": float, "b": float})
async def add(args):
return {"content": [{"type": "text", "text": f"Sum: {args['a'] + args['b']}"}]}
@tool("multiply", "Multiply two numbers", {"a": float, "b": float})
async def multiply(args):
return {"content": [{"type": "text", "text": f"Product: {args['a'] * args['b']}"}]}
calculator = create_sdk_mcp_server(
name="calculator",
version="2.0.0",
tools=[add, multiply], # Pass decorated functions
)
# Use with Claude
options = ClaudeAgentOptions(
mcp_servers={"calc": calculator},
allowed_tools=["mcp__calc__add", "mcp__calc__multiply"],
)
`list_sessions()`
Liste les sessions passées avec métadonnées. Filtrez par répertoire de projet ou listez les sessions dans tous les projets. Synchrone ; retourne immédiatement.
def list_sessions(
directory: str | None = None,
limit: int | None = None,
offset: int = 0,
include_worktrees: bool = True
) -> list[SDKSessionInfo]
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
directory |
str | None |
None |
Répertoire pour lequel lister les sessions. Quand omis, retourne les sessions dans tous les projets |
limit |
int | None |
None |
Nombre maximum de sessions à retourner |
offset |
int |
0 |
Nombre de sessions à ignorer depuis le début des résultats triés. À utiliser avec limit pour la pagination |
include_worktrees |
bool |
True |
Quand directory est à l'intérieur d'un dépôt git, inclure les sessions de tous les chemins worktree |
Type de retour : `SDKSessionInfo`
| Propriété | Type | Description |
|---|---|---|
session_id |
str |
Identifiant de session unique |
summary |
str |
Titre d'affichage : titre personnalisé, résumé généré automatiquement, ou premier prompt |
last_modified |
int |
Heure de dernière modification en millisecondes depuis l'époque |
file_size |
int | None |
Taille du fichier de session en octets (None pour les backends de stockage distant) |
custom_title |
str | None |
Titre de session défini par l'utilisateur |
first_prompt |
str | None |
Premier prompt utilisateur significatif dans la session |
git_branch |
str | None |
Branche git à la fin de la session |
cwd |
str | None |
Répertoire de travail pour la session |
tag |
str | None |
Étiquette de session définie par l'utilisateur (voir tag_session()) |
created_at |
int | None |
Heure de création de la session en millisecondes depuis l'époque |
Exemple
Affiche les 10 sessions les plus récentes pour un projet. Les résultats sont triés par last_modified décroissant, donc le premier élément est le plus récent. Omettez directory pour rechercher dans tous les projets.
from claude_agent_sdk import list_sessions
for session in list_sessions(directory="/path/to/project", limit=10):
print(f"{session.summary} ({session.session_id})")
`get_session_messages()`
Récupère les messages d'une session passée. Synchrone ; retourne immédiatement.
def get_session_messages(
session_id: str,
directory: str | None = None,
limit: int | None = None,
offset: int = 0
) -> list[SessionMessage]
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
session_id |
str |
requis | L'ID de session pour lequel récupérer les messages |
directory |
str | None |
None |
Répertoire de projet à regarder. Quand omis, recherche dans tous les projets |
limit |
int | None |
None |
Nombre maximum de messages à retourner |
offset |
int |
0 |
Nombre de messages à ignorer depuis le début |
Type de retour : `SessionMessage`
| Propriété | Type | Description |
|---|---|---|
type |
Literal["user", "assistant"] |
Rôle du message |
uuid |
str |
Identifiant de message unique |
session_id |
str |
Identifiant de session |
message |
Any |
Contenu du message brut |
parent_tool_use_id |
str | None |
Pour les messages de sous-agent, l'id du bloc Agent tool-use qui l'a généré. None pour les messages de session principale et les sessions plus anciennes |
parent_agent_id |
str | None |
Pour les messages d'un sous-agent imbriqué, l'id d'agent du sous-agent parent. None pour les messages de session principale, les messages de sous-agent de niveau supérieur, et les sessions plus anciennes. Nécessite Python Agent SDK 0.2.140 ou ultérieur |
Exemple
from claude_agent_sdk import list_sessions, get_session_messages
sessions = list_sessions(limit=1)
if sessions:
messages = get_session_messages(sessions[0].session_id)
for msg in messages:
print(f"[{msg.type}] {msg.uuid}")
`get_session_info()`
Lit les métadonnées d'une seule session par ID sans scanner le répertoire de projet complet. Synchrone ; retourne immédiatement.
def get_session_info(
session_id: str,
directory: str | None = None,
) -> SDKSessionInfo | None
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
session_id |
str |
requis | UUID de la session à rechercher |
directory |
str | None |
None |
Chemin du répertoire de projet. Quand omis, recherche dans tous les répertoires de projet |
Retourne SDKSessionInfo, ou None si la session n'est pas trouvée.
Exemple
Recherchez les métadonnées d'une seule session sans scanner le répertoire de projet. Utile quand vous avez déjà un ID de session d'une exécution précédente.
from claude_agent_sdk import get_session_info
info = get_session_info("550e8400-e29b-41d4-a716-446655440000")
if info:
print(f"{info.summary} (branch: {info.git_branch}, tag: {info.tag})")
`rename_session()`
Renomme une session en ajoutant une entrée de titre personnalisé. Les appels répétés sont sûrs ; le titre le plus récent gagne. Synchrone.
def rename_session(
session_id: str,
title: str,
directory: str | None = None,
) -> None
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
session_id |
str |
requis | UUID de la session à renommer |
title |
str |
requis | Nouveau titre. Doit être non-vide après suppression des espaces |
directory |
str | None |
None |
Chemin du répertoire de projet. Quand omis, recherche dans tous les répertoires de projet |
Lève ValueError si session_id n'est pas un UUID valide ou si title est vide ; FileNotFoundError si la session ne peut pas être trouvée.
Exemple
Renommez la session la plus récente pour qu'elle soit plus facile à trouver plus tard. Le nouveau titre apparaît dans SDKSessionInfo.custom_title lors des lectures ultérieures.
from claude_agent_sdk import list_sessions, rename_session
sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
rename_session(sessions[0].session_id, "Refactor auth module")
`tag_session()`
Étiquette une session. Passez None pour effacer l'étiquette. Les appels répétés sont sûrs ; l'étiquette la plus récente gagne. Synchrone.
def tag_session(
session_id: str,
tag: str | None,
directory: str | None = None,
) -> None
Paramètres
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
session_id |
str |
requis | UUID de la session à étiqueter |
tag |
str | None |
requis | Chaîne d'étiquette, ou None pour effacer. Nettoyée Unicode avant stockage |
directory |
str | None |
None |
Chemin du répertoire de projet. Quand omis, recherche dans tous les répertoires de projet |
Lève ValueError si session_id n'est pas un UUID valide ou si tag est vide après nettoyage ; FileNotFoundError si la session ne peut pas être trouvée.
Exemple
Étiquetez une session, puis filtrez par cette étiquette lors d'une lecture ultérieure. Passez None pour effacer une étiquette existante.
from claude_agent_sdk import list_sessions, tag_session
# Tag the most recent session
sessions = list_sessions(directory="/path/to/project", limit=1)
if sessions:
tag_session(sessions[0].session_id, "needs-review")
# Later: find all sessions with that tag
for session in list_sessions(directory="/path/to/project"):
if session.tag == "needs-review":
print(session.summary)
Classes
`ClaudeSDKClient`
Maintient une session de conversation sur plusieurs échanges. C'est l'équivalent Python de la façon dont la fonction query() du SDK TypeScript fonctionne en interne - elle crée un objet client qui peut continuer les conversations. Voir la comparaison avec query().
class ClaudeSDKClient:
def __init__(self, options: ClaudeAgentOptions | None = None, transport: Transport | None = None)
async def connect(self, prompt: str | AsyncIterable[dict] | None = None) -> None
async def query(self, prompt: str | AsyncIterable[dict], session_id: str = "default") -> None
async def receive_messages(self) -> AsyncIterator[Message]
async def receive_response(self) -> AsyncIterator[Message]
async def interrupt(self) -> None
async def set_permission_mode(self, mode: str) -> None
async def set_model(self, model: str | None = None) -> None
async def rewind_files(self, user_message_id: str) -> None
async def get_mcp_status(self) -> McpStatusResponse
async def reconnect_mcp_server(self, server_name: str) -> None
async def toggle_mcp_server(self, server_name: str, enabled: bool) -> None
async def stop_task(self, task_id: str) -> None
async def get_server_info(self) -> dict[str, Any] | None
async def disconnect(self) -> None
Méthodes
| Méthode | Description |
|---|---|
__init__(options) |
Initialise le client avec une configuration optionnelle |
connect(prompt) |
Se connecte à Claude avec un prompt initial optionnel ou un flux de messages |
query(prompt, session_id) |
Envoie une nouvelle requête en mode streaming |
receive_messages() |
Reçoit tous les messages de Claude comme un itérateur asynchrone |
receive_response() |
Reçoit les messages jusqu'à et incluant un ResultMessage |
interrupt() |
Envoie un signal d'interruption (fonctionne uniquement en mode streaming) |
set_permission_mode(mode) |
Change le mode de permission pour la session actuelle |
set_model(model) |
Change le modèle pour la session actuelle. Passez None pour réinitialiser à la valeur par défaut |
rewind_files(user_message_id) |
Restaure les fichiers à leur état au message utilisateur spécifié. Nécessite enable_file_checkpointing=True. Voir File checkpointing |
get_mcp_status() |
Obtient le statut de tous les serveurs MCP configurés. Retourne McpStatusResponse |
reconnect_mcp_server(server_name) |
Réessaye de se connecter à un serveur MCP qui a échoué ou a été déconnecté |
toggle_mcp_server(server_name, enabled) |
Active ou désactive un serveur MCP en cours de session. La désactivation supprime ses outils |
stop_task(task_id) |
Arrête une tâche de fond en cours d'exécution. Un TaskNotificationMessage avec le statut "stopped" suit dans le flux de messages |
get_server_info() |
Obtient les informations du serveur incluant l'ID de session et les capacités |
disconnect() |
Se déconnecte de Claude |
Support du gestionnaire de contexte
Le client peut être utilisé comme un gestionnaire de contexte asynchrone pour la gestion automatique de la connexion :
import asyncio
from claude_agent_sdk import ClaudeSDKClient
async def main():
async with ClaudeSDKClient() as client:
await client.query("Hello Claude")
async for message in client.receive_response():
print(message)
asyncio.run(main())
Important : Lors de l'itération sur les messages, évitez d'utiliser
breakpour quitter tôt car cela peut causer des problèmes de nettoyage asyncio. À la place, laissez l'itération se terminer naturellement ou utilisez des drapeaux pour suivre quand vous avez trouvé ce que vous cherchiez.
Exemple - Continuer une conversation
import asyncio
from claude_agent_sdk import ClaudeSDKClient, AssistantMessage, TextBlock, ResultMessage
async def main():
async with ClaudeSDKClient() as client:
# First question
await client.query("What's the capital of France?")
# Process response
async for message in client.receive_response():
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
# Follow-up question - the session retains the previous context
await client.query("What's the population of that city?")
async for message in client.receive_response():
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
# Another follow-up - still in the same conversation
await client.query("What are some famous landmarks there?")
async for message in client.receive_response():
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
asyncio.run(main())
Exemple - Entrée en streaming avec ClaudeSDKClient
import asyncio
from claude_agent_sdk import ClaudeSDKClient
async def message_stream():
"""Generate messages dynamically."""
yield {
"type": "user",
"message": {"role": "user", "content": "Analyze the following data:"},
}
await asyncio.sleep(0.5)
yield {
"type": "user",
"message": {"role": "user", "content": "Temperature: 25°C, Humidity: 60%"},
}
await asyncio.sleep(0.5)
yield {
"type": "user",
"message": {"role": "user", "content": "What patterns do you see?"},
}
async def main():
async with ClaudeSDKClient() as client:
# Stream input to Claude
await client.query(message_stream())
# Process response
async for message in client.receive_response():
print(message)
# Follow-up in same session
await client.query("Should we be concerned about these readings?")
async for message in client.receive_response():
print(message)
asyncio.run(main())
Exemple - Utiliser les interruptions
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, ResultMessage
async def interruptible_task():
options = ClaudeAgentOptions(allowed_tools=["Bash"], permission_mode="acceptEdits")
async with ClaudeSDKClient(options=options) as client:
# Start a long-running task
await client.query("Count from 1 to 100 slowly, using the bash sleep command")
# Let it run for a bit
await asyncio.sleep(2)
# Interrupt the task
await client.interrupt()
print("Task interrupted!")
# Drain the interrupted task's messages (including its ResultMessage)
async for message in client.receive_response():
if isinstance(message, ResultMessage):
print(f"Interrupted task: terminal_reason={message.terminal_reason!r}")
# terminal_reason is "aborted_streaming" or "aborted_tools"
# for interrupted turns
# Send a new command
await client.query("Just say hello instead")
# Now receive the new response
async for message in client.receive_response():
if isinstance(message, ResultMessage) and message.subtype == "success":
print(f"New result: {message.result}")
asyncio.run(interruptible_task())
Comportement du buffer après interruption : interrupt() envoie un signal d'arrêt mais ne vide pas le buffer de messages. Les messages déjà produits par la tâche interrompue, incluant son ResultMessage, restent dans le flux. Vous devez les vider avec receive_response() avant de lire la réponse à une nouvelle requête. Si vous envoyez une nouvelle requête immédiatement après interrupt() et appelez receive_response() une seule fois, vous recevrez les messages de la tâche interrompue, pas la réponse de la nouvelle requête.
Exemple - Contrôle avancé des permissions
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
from claude_agent_sdk.types import (
PermissionResultAllow,
PermissionResultDeny,
ToolPermissionContext,
)
async def custom_permission_handler(
tool_name: str, input_data: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
"""Custom logic for tool permissions."""
# Block writes to system directories
if tool_name == "Write" and input_data.get("file_path", "").startswith("/system/"):
return PermissionResultDeny(
message="System directory write not allowed", interrupt=True
)
# Redirect sensitive file operations
if tool_name in ["Write", "Edit"] and "config" in input_data.get("file_path", ""):
safe_path = f"./sandbox/{input_data['file_path']}"
return PermissionResultAllow(
updated_input={**input_data, "file_path": safe_path}
)
# Allow everything else
return PermissionResultAllow(updated_input=input_data)
async def main():
# Don't also list the gated tools in allowed_tools: allow rules approve calls before can_use_tool runs
options = ClaudeAgentOptions(can_use_tool=custom_permission_handler)
async with ClaudeSDKClient(options=options) as client:
await client.query("Update the system config file")
async for message in client.receive_response():
# Will use sandbox path instead
print(message)
asyncio.run(main())
Types
@dataclass vs TypedDict : Ce SDK utilise deux types de types. Les classes décorées avec @dataclass (telles que ResultMessage, AgentDefinition, TextBlock) sont des instances d'objet à l'exécution et supportent l'accès par attribut : msg.result. Les classes définies avec TypedDict (telles que ThinkingConfigEnabled, McpStdioServerConfig, SyncHookJSONOutput) sont des dicts simples à l'exécution et nécessitent l'accès par clé : config["budget_tokens"], pas config.budget_tokens. La syntaxe d'appel ClassName(field=value) fonctionne pour les deux, mais seules les dataclasses produisent des objets avec des attributs.
`SdkMcpTool`
Définition pour un outil MCP SDK créé avec le décorateur @tool.
@dataclass
class SdkMcpTool(Generic[T]):
name: str
description: str
input_schema: type[T] | dict[str, Any]
handler: Callable[[T], Awaitable[dict[str, Any]]]
annotations: ToolAnnotations | None = None
| Propriété | Type | Description |
|---|---|---|
name |
str |
Identifiant unique pour l'outil |
description |
str |
Description lisible |
input_schema |
type[T] | dict[str, Any] |
Schéma pour la validation d'entrée |
handler |
Callable[[T], Awaitable[dict[str, Any]]] |
Fonction asynchrone qui gère l'exécution de l'outil |
annotations |
ToolAnnotations | None |
Annotations d'outil optionnelles (par exemple readOnlyHint, destructiveHint, openWorldHint, maxResultSizeChars) |
`Transport`
Classe de base abstraite pour les implémentations de transport personnalisées. Utilisez ceci pour communiquer avec le processus Claude sur un canal personnalisé (par exemple, une connexion distante au lieu d'un sous-processus local).
C'est une API interne de bas niveau. L'interface peut changer dans les versions futures. Les implémentations personnalisées doivent être mises à jour pour correspondre à tout changement d'interface.
from abc import ABC, abstractmethod
from collections.abc import AsyncIterator
from typing import Any
class Transport(ABC):
@abstractmethod
async def connect(self) -> None: ...
@abstractmethod
async def write(self, data: str) -> None: ...
@abstractmethod
def read_messages(self) -> AsyncIterator[dict[str, Any]]: ...
@abstractmethod
async def close(self) -> None: ...
@abstractmethod
def is_ready(self) -> bool: ...
@abstractmethod
async def end_input(self) -> None: ...
| Méthode | Description |
|---|---|
connect() |
Connecte le transport et prépare la communication |
write(data) |
Écrit les données brutes (JSON + nouvelle ligne) dans le transport |
read_messages() |
Itérateur asynchrone qui produit les messages JSON analysés |
close() |
Ferme la connexion et nettoie les ressources |
is_ready() |
Retourne True si le transport peut envoyer et recevoir |
end_input() |
Ferme le flux d'entrée (par exemple, fermer stdin pour les transports de sous-processus) |
Importation : from claude_agent_sdk import Transport
`ClaudeAgentOptions`
Dataclass de configuration pour les requêtes Claude Code.
@dataclass
class ClaudeAgentOptions:
tools: list[str] | ToolsPreset | None = None
allowed_tools: list[str] = field(default_factory=list)
system_prompt: str | SystemPromptPreset | SystemPromptFile | None = None
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
strict_mcp_config: bool = False
permission_mode: PermissionMode | None = None
continue_conversation: bool = False
resume: str | None = None
session_id: str | None = None
max_turns: int | None = None
max_budget_usd: float | None = None
disallowed_tools: list[str] = field(default_factory=list)
model: str | None = None
fallback_model: str | None = None
betas: list[SdkBeta] = field(default_factory=list)
output_format: dict[str, Any] | None = None
permission_prompt_tool_name: str | None = None
cwd: str | Path | None = None
cli_path: str | Path | None = None
settings: str | None = None
add_dirs: list[str | Path] = field(default_factory=list)
env: dict[str, str] = field(default_factory=dict)
extra_args: dict[str, str | None] = field(default_factory=dict)
max_buffer_size: int | None = None
debug_stderr: Any = sys.stderr # Deprecated
stderr: Callable[[str], None] | None = None
can_use_tool: CanUseTool | None = None
hooks: dict[HookEvent, list[HookMatcher]] | None = None
user: str | None = None
include_partial_messages: bool = False
include_hook_events: bool = False
forward_subagent_text: bool = False
fork_session: bool = False
resume_session_at: str | None = None
resume_drops_turn: str | None = None
agents: dict[str, AgentDefinition] | None = None
setting_sources: list[SettingSource] | None = None
skills: list[str] | Literal["all"] | None = None
sandbox: SandboxSettings | None = None
plugins: list[SdkPluginConfig] = field(default_factory=list)
max_thinking_tokens: int | None = None # Deprecated: use thinking instead
thinking: ThinkingConfig | None = None
effort: EffortLevel | None = None
enable_file_checkpointing: bool = False
session_store: SessionStore | None = None
session_store_flush: SessionStoreFlushMode = "batched"
load_timeout_ms: int = 60_000
task_budget: TaskBudget | None = None
| Propriété | Type | Par défaut | Description |
|---|---|---|---|
tools |
list[str] | ToolsPreset | None |
None |
Configuration des outils. Utilisez {"type": "preset", "preset": "claude_code"} pour les outils par défaut de Claude Code |
allowed_tools |
list[str] |
[] |
Outils à approuver automatiquement sans demander. Ceci ne restreint pas Claude à seulement ces outils. Si vous nommez l'un des outils de suivi des tâches ici, Claude Code opte également la session. Les autres outils non listés passent par permission_mode et can_use_tool. Utilisez disallowed_tools pour bloquer les outils. Voir Permissions |
system_prompt |
str | SystemPromptPreset | SystemPromptFile | None |
None |
Configuration du prompt système. Passez une chaîne pour un prompt personnalisé, {"type": "preset", "preset": "claude_code"} pour le prompt système de Claude Code avec "append" optionnel, ou {"type": "file", "path": "..."} pour charger un grand prompt depuis le disque. Voir SystemPromptPreset et SystemPromptFile |
mcp_servers |
dict[str, McpServerConfig] | str | Path |
{} |
Configurations de serveur MCP ou chemin vers le fichier de configuration |
strict_mcp_config |
bool |
False |
Quand True, utilisez uniquement les serveurs passés dans mcp_servers et ignorez le projet .mcp.json, les paramètres utilisateur, les serveurs MCP fournis par les plugins, et les connecteurs claude.ai. Correspond à l'indicateur CLI --strict-mcp-config |
permission_mode |
PermissionMode | None |
None |
Mode de permission pour l'utilisation des outils |
continue_conversation |
bool |
False |
Continuer la conversation la plus récente |
resume |
str | None |
None |
ID de session à reprendre |
session_id |
str | None |
None |
Utilisez un ID de session spécifique au lieu d'un généré automatiquement. Doit être un UUID valide. Ne peut pas être combiné avec continue_conversation ou resume sauf si fork_session est également défini |
max_turns |
int | None |
None |
Nombre maximum de tours agentiques (allers-retours d'utilisation d'outils) |
max_budget_usd |
float | None |
None |
Arrêtez la requête quand l'estimation du coût côté client atteint cette valeur USD. Comparé à la même estimation que total_cost_usd ; voir Suivi du coût et de l'utilisation pour les avertissements de précision |
disallowed_tools |
list[str] |
[] |
Outils à refuser. Un nom simple tel que "Bash" supprime l'outil du contexte de Claude. Une règle délimitée telle que "Bash(rm *)" laisse l'outil disponible et refuse les appels correspondants dans chaque mode de permission, y compris bypassPermissions. Voir Permissions |
enable_file_checkpointing |
bool |
False |
Activez le suivi des modifications de fichiers pour le rembobinage. Voir Sauvegarde de points de contrôle de fichiers |
model |
str | None |
None |
Alias de modèle Claude ou nom de modèle complet. Voir valeurs acceptées et identifiants spécifiques au fournisseur |
fallback_model |
str | None |
None |
Modèle de secours à utiliser si le modèle principal échoue |
betas |
list[SdkBeta] |
[] |
Fonctionnalités bêta à activer. Voir SdkBeta pour les options disponibles |
output_format |
dict[str, Any] | None |
None |
Format de sortie pour les réponses structurées (par exemple, {"type": "json_schema", "schema": {...}}). Voir Sorties structurées pour les détails |
permission_prompt_tool_name |
str | None |
None |
Nom de l'outil MCP pour les prompts de permission |
cwd |
str | Path | None |
None |
Répertoire de travail actuel |
cli_path |
str | Path | None |
None |
Chemin personnalisé vers l'exécutable CLI de Claude Code |
settings |
str | None |
None |
Chemin vers le fichier de paramètres |
add_dirs |
list[str | Path] |
[] |
Répertoires supplémentaires auxquels Claude peut accéder. Le SDK passe chaque entrée à Claude Code comme --add-dir, donc avec la source de paramètre project Claude Code charge également les compétences, commandes et sous-agents du répertoire |
env |
dict[str, str] |
{} |
Variables d'environnement fusionnées au-dessus de l'environnement de processus hérité. Voir Variables d'environnement pour les variables que le CLI sous-jacent lit, et Gérer les réponses API lentes ou bloquées pour les variables liées aux délais d'expiration |
extra_args |
dict[str, str | None] |
{} |
Arguments CLI supplémentaires à passer directement au CLI |
max_buffer_size |
int | None |
None |
Octets maximum lors de la mise en buffer de la sortie standard du CLI |
debug_stderr |
Any |
sys.stderr |
Déprécié - Objet de type fichier pour la sortie de débogage. Utilisez plutôt le callback stderr |
stderr |
Callable[[str], None] | None |
None |
Fonction de callback pour la sortie stderr du CLI |
can_use_tool |
CanUseTool | None |
None |
Fonction de callback de permission d'outil, invoquée uniquement quand le flux de permission aboutit à un prompt. Non invoquée pour les appels pré-approuvés par allowed_tools, les règles d'autorisation, ou permission_mode. Une règle d'autorisation ne pré-approuve pas les actions qu'aucun mode n'approuve automatiquement. Voir CanUseTool pour les détails |
hooks |
dict[HookEvent, list[HookMatcher]] | None |
None |
Configurations de hook pour intercepter les événements |
user |
str | None |
None |
Identifiant utilisateur |
include_partial_messages |
bool |
False |
Inclure les événements de streaming de messages partiels. Quand activé, les messages StreamEvent sont produits |
include_hook_events |
bool |
False |
Inclure les événements du cycle de vie des hooks dans le flux de messages en tant qu'objets HookEventMessage |
forward_subagent_text |
bool |
False |
Transférez les blocs de texte et de réflexion des sous-agents dans le flux de messages. Par défaut, seuls les blocs tool_use et tool_result des sous-agents sont émis. Nécessite Python Agent SDK 0.2.140 ou ultérieur |
fork_session |
bool |
False |
Quand reprendre avec resume, bifurquer vers un nouvel ID de session au lieu de continuer la session originale |
resume_session_at |
str | None |
None |
Quand reprendre, charger la conversation uniquement jusqu'à et y compris le message avec cet UUID. Utilisez avec resume, et généralement fork_session, pour brancher à partir d'un point antérieur. Nécessite Python Agent SDK 0.2.137 ou ultérieur |
resume_drops_turn |
str | None |
None |
UUID du prompt utilisateur dont le tour une troncature resume_session_at rejette. Quand défini, le CLI refuse la reprise si la plage rejetée contient des entrées non attribuables à ce tour. Nécessite Python Agent SDK 0.2.137 ou ultérieur et Claude Code v2.1.223 ou ultérieur ; le CLI fourni avec ces versions du SDK satisfait l'exigence de Claude Code |
agents |
dict[str, AgentDefinition] | None |
None |
Sous-agents définis programmatiquement |
plugins |
list[SdkPluginConfig] |
[] |
Charger les plugins personnalisés à partir de chemins locaux. Voir Plugins pour les détails |
sandbox |
SandboxSettings | None |
None |
Configurez le comportement du sandbox programmatiquement. Voir Paramètres du sandbox pour les détails |
setting_sources |
list[SettingSource] | None |
None (CLI defaults: all sources) |
Contrôlez quels paramètres du système de fichiers charger. Passez [] pour désactiver les paramètres utilisateur, projet et locaux. Les paramètres de politique gérée se chargent indépendamment ; les paramètres gérés par le serveur sont récupérés quand la session s'authentifie avec une credential d'organisation sur une configuration éligible. Voir Utiliser les fonctionnalités de Claude Code pour les entrées qui sont lues indépendamment de cette option, et comment les désactiver |
skills |
list[str] | Literal["all"] | None |
None |
Compétences disponibles pour la session. Passez "all" pour activer chaque compétence découverte, ou une liste de noms de compétences. Passez uniquement les noms exacts. Le SDK rejette les noms mal formés et de forme wildcard avec une ValueError avant de démarrer le processus Claude Code ; cette vérification nécessite Python Agent SDK 0.2.129 ou ultérieur. Quand défini, le SDK ajoute l'outil Skill à allowed_tools automatiquement. Si vous passez aussi tools, incluez "Skill" dans cette liste. Voir Compétences |
max_thinking_tokens |
int | None |
None |
Déprécié - Tokens maximum pour les blocs de réflexion. Utilisez thinking à la place |
thinking |
ThinkingConfig | None |
None |
Contrôle le comportement de la réflexion étendue. Prend la priorité sur max_thinking_tokens |
effort |
EffortLevel | None |
None |
Niveau d'effort pour la profondeur de réflexion. Voir ajuster le niveau d'effort |
session_store |
SessionStore | None |
None |
Miroir les transcriptions de session vers un backend externe pour que n'importe quel hôte puisse les reprendre. Voir Persister les sessions vers un stockage externe |
session_store_flush |
Literal["batched", "eager"] |
"batched" |
Quand vider les entrées de transcription en miroir vers session_store. "batched" vide une fois par tour ou quand le buffer se remplit ; "eager" déclenche un vidage en arrière-plan après chaque frame. Ignoré quand session_store est None |
load_timeout_ms |
int |
60000 |
Délai d'expiration par appel pour session_store.load() et list_subkeys() lors de la matérialisation de la reprise, en millisecondes |
task_budget |
TaskBudget | None |
None |
Budget de tokens côté API. Envoyé comme output_config.task_budget avec l'en-tête bêta task-budgets-2026-03-13. Passez {"total": <int>}. |
Gérer les réponses API lentes ou bloquées
Le sous-processus CLI lit plusieurs variables d'environnement qui contrôlent les délais d'expiration de l'API et la détection de blocage. Passez-les via ClaudeAgentOptions.env :
from claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions(
env={
"API_TIMEOUT_MS": "120000",
"CLAUDE_CODE_MAX_RETRIES": "2",
"CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS": "120000",
},
)
-
API_TIMEOUT_MS: délai d'expiration par requête sur le client Anthropic, en millisecondes. Par défaut600000. S'applique à la boucle principale et à tous les sous-agents. -
CLAUDE_CODE_MAX_RETRIES: nombre maximum de tentatives API. Par défaut10, limité à15. Chaque tentative obtient sa propre fenêtreAPI_TIMEOUT_MS, donc le pire temps mural est approximativementAPI_TIMEOUT_MS × (CLAUDE_CODE_MAX_RETRIES + 1)plus le backoff. Pour les exécutions sans surveillance qui doivent attendre des pannes plus longues, définissezCLAUDE_CODE_RETRY_WATCHDOG=1: il réessaye les erreurs de capacité transitoires indéfiniment et, à partir de Claude Code v2.1.199, augmente la valeur par défaut pour les autres erreurs transitoires à300et supprime le plafond sur cette variable. -
CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: chien de garde de blocage pour les sous-agents. Pendant que le chien de garde de flux est activé, la valeur par défaut estCLAUDE_STREAM_IDLE_TIMEOUT_MSplus 5 minutes, ce qui donne600000sauf si vous augmentez cette variable. Avec le chien de garde de flux désactivé, la valeur par défaut est600000. Avant v2.1.257, la valeur par défaut était toujours600000.Le minuteur se réinitialise à chaque événement de flux. En cas de blocage, Claude Code abandonne le sous-agent et signale le blocage au parent. Pour un sous-agent en arrière-plan, il marque également la tâche comme échouée et attache tout résultat partiel.
-
CLAUDE_ENABLE_STREAM_WATCHDOGavecCLAUDE_STREAM_IDLE_TIMEOUT_MS: chien de garde de flux qui abandonne la requête quand les en-têtes sont arrivés mais le corps de la réponse cesse de faire du streaming. Le chien de garde est activé par défaut pour tous les fournisseurs ; définissezCLAUDE_ENABLE_STREAM_WATCHDOG=0pour le désactiver.CLAUDE_STREAM_IDLE_TIMEOUT_MSpar défaut à300000et est limité à ce minimum. Après l'abandon, Les tentatives automatiques couvre ce que Claude Code fait, en fonction de la progression de la réponse.Pendant que le chien de garde attend une réponse qu'une passerelle derrière
ANTHROPIC_BASE_URLmaintient ouverte avec des pings de maintien de connexion, un hôte qui définitinclude_partial_messagescontinue de recevoir des messagesStreamEventdeping. Lisez ces frames comme une vivacité plutôt que de chronométrer la session sur le silence. Avant v2.1.257, les frames s'arrêtaient 5 minutes après le dernier événement de flux réel.
`OutputFormat`
Configuration pour la validation de sortie structurée. Passez ceci comme un dict au champ output_format sur ClaudeAgentOptions :
# Expected dict shape for output_format
{
"type": "json_schema",
"schema": {...}, # Your JSON Schema definition
}
| Champ | Requis | Description |
|---|---|---|
type |
Oui | Doit être "json_schema" pour la validation JSON Schema |
schema |
Oui | Définition JSON Schema pour la validation de sortie |
`SystemPromptPreset`
Configuration pour utiliser le preset de prompt système de Claude Code avec des ajouts optionnels.
class SystemPromptPreset(TypedDict):
type: Literal["preset"]
preset: Literal["claude_code"]
append: NotRequired[str]
exclude_dynamic_sections: NotRequired[bool]
| Champ | Requis | Description |
|---|---|---|
type |
Oui | Doit être "preset" pour utiliser un preset de prompt système |
preset |
Oui | Doit être "claude_code" pour utiliser le prompt système de Claude Code |
append |
Non | Instructions supplémentaires à ajouter au preset de prompt système |
exclude_dynamic_sections |
Non | Déplacez le contexte par session comme le répertoire de travail, le statut git et les chemins de mémoire du prompt système vers le premier message utilisateur. Améliore la réutilisation du cache de prompt entre les utilisateurs et les machines. Voir Modifier les prompts système |
`SystemPromptFile`
Configuration pour charger un prompt système personnalisé à partir d'un fichier au lieu de le passer en tant que chaîne. Le SDK mappe ceci à l'indicateur CLI --system-prompt-file. Utilisez la forme fichier quand le prompt est volumineux : le SDK passe un system_prompt chaîne sur l'argv du sous-processus CLI, qui est soumis aux limites de longueur de ligne de commande du système d'exploitation avant que le SDK n'envoie une requête API. Sur Linux, un seul argument plus long que environ 128 KB échoue au spawn du processus avec Argument list too long. Sur Windows, la ligne de commande entière est limitée à environ 32 KB, donc la forme chaîne échoue à un seuil inférieur.
class SystemPromptFile(TypedDict):
type: Literal["file"]
path: str
| Champ | Requis | Description |
|---|---|---|
type |
Oui | Doit être "file" pour charger le prompt depuis le disque |
path |
Oui | Chemin vers un fichier contenant le prompt système |
`SettingSource`
Contrôle quelles sources de configuration basées sur le système de fichiers le SDK charge les paramètres à partir de.
SettingSource = Literal["user", "project", "local"]
| Valeur | Description | Emplacement |
|---|---|---|
"user" |
Paramètres utilisateur globaux | ~/.claude/settings.json |
"project" |
Paramètres de projet partagés (contrôle de version) | .claude/settings.json |
"local" |
Paramètres de projet locaux, gitignorés quand Claude Code enregistre un paramètre dedans | .claude/settings.local.json |
Comportement par défaut
Quand setting_sources est omis ou None, query() charge les mêmes paramètres du système de fichiers que le CLI Claude Code : utilisateur, projet et local. Les paramètres de politique gérée sont chargés dans tous les cas ; les paramètres gérés par le serveur sont récupérés quand la session s'authentifie avec une credential d'organisation sur une configuration éligible. Voir Ce que settingSources ne contrôle pas pour les entrées qui sont lues indépendamment de cette option, et comment les désactiver.
Pourquoi utiliser setting\_sources
Désactiver les paramètres du système de fichiers :
# Do not load user, project, or local settings from disk
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Analyze this code",
options=ClaudeAgentOptions(
setting_sources=[]
),
):
print(message)
asyncio.run(main())
Dans le SDK Python 0.1.59 et antérieur, une liste vide était traitée de la même manière que l'omission de l'option, donc setting_sources=[] n'a pas désactivé les paramètres du système de fichiers. Mettez à niveau vers une version plus récente si vous avez besoin qu'une liste vide prenne effet. Le SDK TypeScript n'est pas affecté.
Charger uniquement des sources de paramètres spécifiques :
# Load only project settings, ignore user and local
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Run CI checks",
options=ClaudeAgentOptions(
setting_sources=["project"] # Only .claude/settings.json
),
):
print(message)
asyncio.run(main())
Applications SDK uniquement :
# Define everything programmatically.
# Pass [] to opt out of filesystem setting sources.
import asyncio
from claude_agent_sdk import AgentDefinition, ClaudeAgentOptions, query
async def main():
async for message in query(
prompt="Review this PR",
options=ClaudeAgentOptions(
setting_sources=[],
agents={
"code-reviewer": AgentDefinition(
description="Reviews code changes",
prompt="You are a code reviewer. Report issues in the diff.",
),
},
allowed_tools=["Read", "Grep", "Glob"],
),
):
print(message)
asyncio.run(main())
Pour charger les instructions de projet CLAUDE.md, incluez "project" dans setting_sources. Voir Modifier les prompts système pour comment le chargement de CLAUDE.md interagit avec les options de prompt système.
Précédence des paramètres
Quand plusieurs sources sont chargées, les paramètres sont fusionnés avec cette précédence (la plus haute à la plus basse) :
- Paramètres locaux (
.claude/settings.local.json) - Paramètres de projet (
.claude/settings.json) - Paramètres utilisateur (
~/.claude/settings.json)
Les options programmatiques telles que agents et allowed_tools remplacent les paramètres du système de fichiers utilisateur, projet et local. Les paramètres de politique gérée prennent la priorité sur les options programmatiques.
`AgentDefinition`
Configuration pour un sous-agent défini programmatiquement.
@dataclass
class AgentDefinition:
description: str
prompt: str
tools: list[str] | None = None
disallowedTools: list[str] | None = None
model: str | None = None
skills: list[str] | None = None
memory: Literal["user", "project", "local"] | None = None
mcpServers: list[str | dict[str, Any]] | None = None
initialPrompt: str | None = None
maxTurns: int | None = None
background: bool | None = None
effort: EffortLevel | int | None = None
permissionMode: PermissionMode | None = None
| Champ | Requis | Description |
|---|---|---|
description |
Oui | Description en langage naturel de quand utiliser cet agent |
prompt |
Oui | Le prompt système de l'agent |
tools |
Non | Tableau des noms d'outils autorisés. Si omis, hérite de tous les outils disponibles pour les sous-agents |
disallowedTools |
Non | Tableau des noms d'outils à supprimer de l'ensemble d'outils de l'agent. Les motifs au niveau du serveur MCP sont également acceptés : mcp__server ou mcp__server__* supprime chaque outil de ce serveur, et mcp__* supprime chaque outil MCP de n'importe quel serveur |
model |
Non | Remplacement de modèle pour cet agent. Accepte un alias tel que "sonnet", "opus", "haiku", ou "inherit", ou un ID de modèle complet. Quand vous l'omettez, Claude Code choisit le modèle dans l'ordre de modèle des sous-agents |
skills |
Non | Liste des noms de compétences à précharger dans le contexte de l'agent au démarrage. Les compétences non listées restent invocables via l'outil Skill |
memory |
Non | Source de mémoire pour cet agent : "user", "project", ou "local" |
mcpServers |
Non | Serveurs MCP disponibles pour cet agent. Chaque entrée est un nom de serveur ou un dict {name: config} en ligne |
initialPrompt |
Non | Auto-soumis comme le premier tour utilisateur quand cet agent s'exécute comme l'agent du fil principal |
maxTurns |
Non | Nombre maximum de tours agentiques avant que l'agent s'arrête |
background |
Non | Exécutez cet agent comme une tâche de fond non-bloquante quand invoqué |
effort |
Non | Niveau d'effort de raisonnement pour cet agent. Accepte un niveau nommé ou un entier. Voir EffortLevel |
permissionMode |
Non | Mode de permission pour l'exécution des outils dans cet agent. Voir PermissionMode |
Les noms de champs AgentDefinition utilisent camelCase, tels que disallowedTools, permissionMode, et maxTurns. Ces noms correspondent directement au format de fil partagé avec le SDK TypeScript. Ceci diffère de ClaudeAgentOptions, qui utilise Python snake_case pour les champs de niveau supérieur équivalents tels que disallowed_tools et permission_mode. Parce que AgentDefinition est une dataclass, passer un mot-clé snake_case lève une TypeError au moment de la construction.
`PermissionMode`
Modes de permission pour contrôler l'exécution des outils.
PermissionMode = Literal[
"default", # Standard permission behavior
"acceptEdits", # Auto-accept file edits
"plan", # Planning mode - explore without editing
"dontAsk", # Deny anything not pre-approved instead of prompting
"bypassPermissions", # Bypass permission checks; explicit ask rules still prompt (use with caution)
"auto", # Model classifier approves or denies permission prompts
]
`EffortLevel`
Niveaux d'effort pour guider la profondeur de réflexion.
EffortLevel = Literal[
"low", # Minimal thinking, fastest responses
"medium", # Moderate thinking
"high", # Deep reasoning
"xhigh", # Extended reasoning; falls back to "high" on models that don't support it
"max", # Maximum effort
]
`CanUseTool`
Alias de type pour les fonctions de callback de permission d'outil.
CanUseTool = Callable[
[str, dict[str, Any], ToolPermissionContext], Awaitable[PermissionResult]
]
Le callback reçoit :
tool_name: Nom de l'outil en cours d'appelinput_data: Les paramètres d'entrée de l'outilcontext: UnToolPermissionContextavec des informations supplémentaires
Retourne un PermissionResult (soit PermissionResultAllow soit PermissionResultDeny).
Le callback est le remplacement SDK pour le prompt de permission interactif : il est invoqué uniquement quand le flux d'évaluation de permission aboutit à un prompt. Les appels d'outil déjà approuvés par une entrée allowed_tools, une règle d'autorisation des paramètres, ou le mode de permission, tel que acceptEdits ou bypassPermissions, ne l'invoquent jamais. Pour contrôler chaque appel d'outil, utilisez un hook PreToolUse à la place.
Une règle d'autorisation ne pré-approuve pas les actions qu'aucun mode n'approuve automatiquement ; voir Comment les permissions sont évaluées pour lesquelles les atteignent et ce qui se passe en mode dontAsk et auto.
`ToolPermissionContext`
Informations de contexte passées aux callbacks de permission d'outil.
@dataclass
class ToolPermissionContext:
signal: Any | None = None # Future: abort signal support
suggestions: list[PermissionUpdate] = field(default_factory=list)
tool_use_id: str | None = None
agent_id: str | None = None
blocked_path: str | None = None
decision_reason: str | None = None
title: str | None = None
display_name: str | None = None
description: str | None = None
| Champ | Type | Description |
|---|---|---|
signal |
Any | None |
Réservé pour le support futur du signal d'abandon |
suggestions |
list[PermissionUpdate] |
Suggestions de mise à jour de permission du CLI. Les prompts Bash incluent une suggestion avec la destination localSettings, donc la retourner dans updated_permissions écrit la règle dans .claude/settings.local.json et persiste entre les sessions. |
tool_use_id |
str | None |
Identifiant de l'appel d'outil spécifique pour lequel ce prompt est destiné. Toujours rempli quand livré à can_use_tool |
agent_id |
str | None |
ID du sous-agent quand l'appel provient d'un sous-agent ; None pour l'agent principal |
blocked_path |
str | None |
Chemin de fichier qui a déclenché la demande de permission, le cas échéant. Par exemple, quand une commande Bash essaie d'accéder à un chemin en dehors des répertoires autorisés |
decision_reason |
str | None |
Raison pour laquelle cette demande de permission a été déclenchée. Transférée depuis le permissionDecisionReason d'un hook PreToolUse quand le hook a retourné "ask" |
title |
str | None |
Phrase complète du prompt de permission, telle que Claude wants to read foo.txt. Utilisez comme texte du prompt principal quand présent |
display_name |
str | None |
Phrase nominale courte pour l'action de l'outil, telle que Read file, appropriée pour les étiquettes de bouton |
description |
str | None |
Sous-titre lisible pour l'interface utilisateur de permission |
`PermissionResult`
Type union pour les résultats de callback de permission.
PermissionResult = PermissionResultAllow | PermissionResultDeny
`PermissionResultAllow`
Résultat indiquant que l'appel d'outil doit être autorisé.
@dataclass
class PermissionResultAllow:
behavior: Literal["allow"] = "allow"
updated_input: dict[str, Any] | None = None
updated_permissions: list[PermissionUpdate] | None = None
| Champ | Type | Par défaut | Description |
|---|---|---|---|
behavior |
Literal["allow"] |
"allow" |
Doit être « allow » |
updated_input |
dict[str, Any] | None |
None |
Entrée modifiée à utiliser à la place de l'original |
updated_permissions |
list[PermissionUpdate] | None |
None |
Mises à jour de permission à appliquer |
`PermissionResultDeny`
Résultat indiquant que l'appel d'outil doit être refusé.
@dataclass
class PermissionResultDeny:
behavior: Literal["deny"] = "deny"
message: str = ""
interrupt: bool = False
| Champ | Type | Par défaut | Description |
|---|---|---|---|
behavior |
Literal["deny"] |
"deny" |
Doit être « deny » |
message |
str |
"" |
Message expliquant pourquoi l'outil a été refusé |
interrupt |
bool |
False |
S'il faut interrompre l'exécution actuelle |
`PermissionUpdate`
Configuration pour mettre à jour les permissions programmatiquement.
@dataclass
class PermissionUpdate:
type: Literal[
"addRules",
"replaceRules",
"removeRules",
"setMode",
"addDirectories",
"removeDirectories",
]
rules: list[PermissionRuleValue] | None = None
behavior: Literal["allow", "deny", "ask"] | None = None
mode: PermissionMode | None = None
directories: list[str] | None = None
destination: (
Literal["userSettings", "projectSettings", "localSettings", "session"] | None
) = None
| Champ | Type | Description |
|---|---|---|
type |
Literal[...] |
Le type d'opération de mise à jour de permission |
rules |
list[PermissionRuleValue] | None |
Règles pour les opérations d'ajout/remplacement/suppression |
behavior |
Literal["allow", "deny", "ask"] | None |
Comportement pour les opérations basées sur les règles |
mode |
PermissionMode | None |
Mode pour l'opération setMode |
directories |
list[str] | None |
Répertoires pour les opérations d'ajout/suppression de répertoire |
destination |
Literal[...] | None |
Où appliquer la mise à jour de permission |
`PermissionRuleValue`
Une règle à ajouter, remplacer ou supprimer dans une mise à jour de permission.
@dataclass
class PermissionRuleValue:
tool_name: str
rule_content: str | None = None
`ToolsPreset`
Configuration des outils preset pour utiliser l'ensemble d'outils par défaut de Claude Code.
class ToolsPreset(TypedDict):
type: Literal["preset"]
preset: Literal["claude_code"]
`ThinkingConfig`
Contrôle le comportement de la réflexion étendue. Une union de trois configurations :
ThinkingDisplay = Literal["summarized", "omitted"]
class ThinkingConfigAdaptive(TypedDict):
type: Literal["adaptive"]
display: NotRequired[ThinkingDisplay]
class ThinkingConfigEnabled(TypedDict):
type: Literal["enabled"]
budget_tokens: int
display: NotRequired[ThinkingDisplay]
class ThinkingConfigDisabled(TypedDict):
type: Literal["disabled"]
ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
| Variante | Champs | Description |
|---|---|---|
adaptive |
type, display |
Claude décide de manière adaptative quand réfléchir |
enabled |
type, budget_tokens, display |
Activez la réflexion avec un budget de tokens spécifique |
disabled |
type |
Désactivez la réflexion |
Le champ optionnel display contrôle si le texte de réflexion est retourné "summarized" ou "omitted". Sur Claude Opus 4.7 et ultérieur, la valeur par défaut de l'API est "omitted", donc définissez "summarized" pour recevoir le contenu de réflexion dans les sorties ThinkingBlock. Claude Code n'envoie pas display à Amazon Bedrock ou à la plateforme Agent de Google Cloud, donc sur ces fournisseurs Opus 4.7 et ultérieur retournent des sorties ThinkingBlock vides même quand vous définissez display à "summarized".
Parce que ce sont des classes TypedDict, ce sont des dicts simples à l'exécution. Construisez-les soit comme des littéraux dict soit appelez la classe comme un constructeur ; les deux produisent un dict. Accédez aux champs avec config["budget_tokens"], pas config.budget_tokens :
from claude_agent_sdk import ClaudeAgentOptions, ThinkingConfigEnabled
# Option 1: dict literal (recommended, no import needed)
options = ClaudeAgentOptions(thinking={"type": "enabled", "budget_tokens": 20000})
# Option 2: constructor-style (returns a plain dict)
config = ThinkingConfigEnabled(type="enabled", budget_tokens=20000)
print(config["budget_tokens"]) # 20000
# config.budget_tokens would raise AttributeError
`TaskBudget`
Budget de tâche côté API en tokens, utilisé avec le champ task_budget dans ClaudeAgentOptions.
class TaskBudget(TypedDict):
total: int
| Champ | Type | Description |
|---|---|---|
total |
int |
Budget de tokens total pour la tâche |
Parce que c'est une TypedDict, passez-la comme un dict simple, tel que ClaudeAgentOptions(task_budget={"total": 50000}).
`SdkBeta`
Type littéral pour les fonctionnalités bêta du SDK.
SdkBeta = Literal["context-1m-2025-08-07"]
Utilisez avec le champ betas dans ClaudeAgentOptions pour activer les fonctionnalités bêta.
La bêta context-1m-2025-08-07 est retirée à partir du 30 avril 2026. Passer cet en-tête avec Claude Sonnet 4.5 ou Sonnet 4 n'a aucun effet, et les requêtes qui dépassent la fenêtre de contexte standard de 200 000 tokens retournent une erreur. Pour utiliser une fenêtre de contexte de 1 million de tokens, migrez vers Claude Opus 5, Claude Sonnet 5, Claude Sonnet 4.6, Claude Opus 4.6, Claude Opus 4.7, ou Claude Opus 4.8, qui incluent 1 million de contexte à prix standard sans en-tête bêta requis.
`McpSdkServerConfig`
Configuration pour les serveurs MCP SDK créés avec create_sdk_mcp_server().
class McpSdkServerConfig(TypedDict):
type: Literal["sdk"]
name: str
instance: Any # MCP Server instance
`McpServerConfig`
Type union pour les configurations de serveur MCP.
McpServerConfig = (
McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig
)
`McpStdioServerConfig`
class McpStdioServerConfig(TypedDict):
type: NotRequired[Literal["stdio"]] # Optional for backwards compatibility
command: str
args: NotRequired[list[str]]
env: NotRequired[dict[str, str]]
`McpSSEServerConfig`
class McpSSEServerConfig(TypedDict):
type: Literal["sse"]
url: str
headers: NotRequired[dict[str, str]]
`McpHttpServerConfig`
class McpHttpServerConfig(TypedDict):
type: Literal["http"]
url: str
headers: NotRequired[dict[str, str]]
`McpServerStatusConfig`
La configuration d'un serveur MCP telle que rapportée par get_mcp_status(). C'est l'union de toutes les variantes de transport McpServerConfig plus une variante de sortie uniquement claudeai-proxy pour les serveurs proxifiés via claude.ai.
McpServerStatusConfig = (
McpStdioServerConfig
| McpSSEServerConfig
| McpHttpServerConfig
| McpSdkServerConfigStatus
| McpClaudeAIProxyServerConfig
)
McpSdkServerConfigStatus est la forme sérialisable de McpSdkServerConfig avec seulement les champs type ("sdk") et name (str) ; l'instance en processus est omise. McpClaudeAIProxyServerConfig a les champs type ("claudeai-proxy"), url (str), et id (str).
`McpStatusResponse`
Réponse de ClaudeSDKClient.get_mcp_status(). Enveloppe la liste des statuts de serveur sous la clé mcpServers.
class McpStatusResponse(TypedDict):
mcpServers: list[McpServerStatus]
`McpServerStatus`
Statut d'un serveur MCP connecté, contenu dans McpStatusResponse.
class McpServerStatus(TypedDict):
name: str
status: McpServerConnectionStatus # "connected" | "failed" | "needs-auth" | "pending" | "disabled"
serverInfo: NotRequired[McpServerInfo]
error: NotRequired[str]
config: NotRequired[McpServerStatusConfig]
scope: NotRequired[str]
tools: NotRequired[list[McpToolInfo]]
| Champ | Type | Description |
|---|---|---|
name |
str |
Nom du serveur |
status |
str |
L'un de "connected", "failed", "needs-auth", "pending", ou "disabled" |
serverInfo |
dict (optionnel) |
Nom et version du serveur ({"name": str, "version": str}) |
error |
str (optionnel) |
Message d'erreur si le serveur n'a pas pu se connecter |
config |
McpServerStatusConfig (optionnel) |
Configuration du serveur. Même forme que McpServerConfig (stdio, SSE, HTTP, ou SDK), plus une variante claudeai-proxy pour les serveurs connectés via claude.ai |
scope |
str (optionnel) |
Portée de la configuration |
tools |
list (optionnel) |
Outils fournis par ce serveur, chacun avec les champs name, description, et annotations |
`SdkPluginConfig`
Configuration pour charger les plugins dans le SDK.
class SdkPluginConfig(TypedDict):
type: Literal["local"]
path: str
| Champ | Type | Description |
|---|---|---|
type |
Literal["local"] |
Doit être "local" (seuls les plugins locaux sont actuellement supportés) |
path |
str |
Chemin absolu ou relatif vers le répertoire du plugin |
Exemple :
plugins = [
{"type": "local", "path": "./my-plugin"},
{"type": "local", "path": "/absolute/path/to/plugin"},
]
Pour des informations complètes sur la création et l'utilisation de plugins, voir Plugins.
Types de messages
`Message`
Type union de tous les messages possibles.
Message = (
UserMessage
| AssistantMessage
| SystemMessage
| ResultMessage
| StreamEvent
| RateLimitEvent
| ConversationResetMessage
)
`UserMessage`
Message d'entrée utilisateur.
@dataclass
class UserMessage:
content: str | list[ContentBlock]
uuid: str | None = None
parent_tool_use_id: str | None = None
tool_use_result: dict[str, Any] | None = None
origin: MessageOrigin | None = None
| Champ | Type | Description |
|---|---|---|
content |
str | list[ContentBlock] |
Contenu du message sous forme de texte ou de blocs de contenu |
uuid |
str | None |
Identifiant de message unique |
parent_tool_use_id |
str | None |
ID d'utilisation d'outil si ce message est une réponse de résultat d'outil |
tool_use_result |
dict[str, Any] | None |
Données de résultat d'outil si applicable |
origin |
MessageOrigin | None |
Provenance de ce message, remplie sur les tours injectés tels que les notifications de tâche et les messages de pairs. None quand le CLI ne l'a pas attribué. Nécessite Python Agent SDK 0.2.137 ou ultérieur |
Le SDK transmet tool_use_result inchangé depuis le CLI. Pour un outil sur un serveur MCP externe dont le résultat contient des blocs resource_link, le dict a une clé resourceLinks contenant une liste de dicts avec les clés du type TypeScript SDKMcpResourceLink. Claude reçoit chaque lien sous forme de ligne de texte dans le résultat de l'outil. Pour afficher les fichiers que le serveur a retournés, lisez resourceLinks au lieu d'analyser ce texte. La clé resourceLinks nécessite Python Agent SDK 0.2.150 ou ultérieur et Claude Code v2.1.257 ou ultérieur ; le CLI fourni avec cette version du SDK satisfait l'exigence de Claude Code.
Le CLI omet la clé quand le résultat n'a pas de liens et sur les résultats des sous-agents. Le CLI conserve au maximum 50 liens par résultat et arrête d'ajouter des liens une fois que la liste atteint 64 KiB de JSON sérialisé. Un outil que vous définissez en processus avec tool() ne produit jamais la clé, car le SDK aplatit ses blocs resource_link en texte avant que le CLI ne voie le résultat.
`AssistantMessage`
Message de réponse d'assistant avec blocs de contenu.
@dataclass
class AssistantMessage:
content: list[ContentBlock]
model: str
parent_tool_use_id: str | None = None
error: AssistantMessageError | None = None
usage: dict[str, Any] | None = None
message_id: str | None = None
stop_reason: str | None = None
session_id: str | None = None
uuid: str | None = None
| Champ | Type | Description |
|---|---|---|
content |
list[ContentBlock] |
Liste des blocs de contenu dans la réponse |
model |
str |
Modèle qui a généré la réponse |
parent_tool_use_id |
str | None |
ID d'utilisation d'outil si c'est une réponse imbriquée |
error |
AssistantMessageError | None |
Type d'erreur si la réponse a rencontré une erreur |
usage |
dict[str, Any] | None |
Utilisation de tokens par message (mêmes clés que ResultMessage.usage) |
message_id |
str | None |
ID de message API. Plusieurs messages d'un tour partagent le même ID |
stop_reason |
str | None |
Raison d'arrêt de l'API (par exemple end_turn, tool_use) |
session_id |
str | None |
ID de la session à laquelle ce message appartient |
uuid |
str | None |
Identifiant de message unique dans la transcription de session |
`AssistantMessageError`
Types d'erreur possibles pour les messages d'assistant.
AssistantMessageError = Literal[
"authentication_failed",
"billing_error",
"rate_limit",
"invalid_request",
"server_error",
"unknown",
]
Le processus CLI sous-jacent peut émettre des types d'erreur que ce Literal ne liste pas, tels que max_output_tokens. Le SDK transmet la valeur inchangée, donc traitez les chaînes en dehors de cette liste de la même manière que vous traitez unknown. Le type TypeScript SDKAssistantMessageError liste l'ensemble complet des valeurs que le CLI peut émettre.
`SystemMessage`
Message système avec métadonnées.
@dataclass
class SystemMessage:
subtype: str
data: dict[str, Any]
`ResultMessage`
Message de résultat final avec informations de coût et d'utilisation.
@dataclass
class ResultMessage:
subtype: str
duration_ms: int
duration_api_ms: int
is_error: bool
num_turns: int
session_id: str
stop_reason: str | None = None
total_cost_usd: float | None = None
usage: dict[str, Any] | None = None
result: str | None = None
structured_output: Any = None
model_usage: dict[str, ModelUsage] | None = None
permission_denials: list[Any] | None = None
deferred_tool_use: DeferredToolUse | None = None
errors: list[str] | None = None
api_error_status: int | None = None
uuid: str | None = None
terminal_reason: str | None = None
origin: MessageOrigin | None = None
Le champ subtype détermine quels autres champs sont remplis. C'est l'un de "success", "error_during_execution", "error_max_turns", "error_max_budget_usd", ou "error_max_structured_output_retries". La dataclass Python aplatit toutes les variantes en une seule forme, donc les champs qui ne s'appliquent pas au sous-type retourné sont None.
Plusieurs champs portent des détails de diagnostic sur la façon dont la conversation s'est terminée :
is_error:Truequand la conversation s'est terminée dans un état d'erreur. ToujoursTruesur les sous-typeserror_*. Sursubtype="success"c'estTruequand la dernière demande de modèle a échoué, ce qui signifie que la boucle d'agent s'est terminée mais le dernier appel API a retourné une erreur.api_error_status: le code de statut HTTP de l'erreur API terminale.Nonequand le tour s'est terminé sans une. Rempli uniquement sursubtype="success".result: texte du message d'assistant final sursubtype="success", ouNonesur les sous-typeserror_*. Quandsubtype="success"etis_error=True, ceci contient la chaîne d'erreur API si une est disponible mais peut être vide, donc vérifiezapi_error_statuset le contenuAssistantMessageprécédent pour plus de détails.errors: chaînes d'erreur au niveau de la boucle telles que le message max-turns. Rempli uniquement sur les sous-typeserror_*.terminal_reason: pourquoi la boucle de requête s'est terminée, telle que"completed","max_turns","api_error","aborted_streaming", ou"aborted_tools". Une valeur de"aborted_streaming"ou"aborted_tools"signifie que le tour a été interrompu avant de se terminer. Les causes courantes sontinterrupt()et un rappel de permission retournantPermissionResultDenyavecinterrupt=True.Nonesur les versions CLI qui précèdent le champ, sur les résultats des commandes locales telles que/voiceou/usage, qui contournent la boucle de requête, ou sur les résultats d'erreur synthétisés émis quand la session échoue fatalement. Reflète leSDKResultMessage.terminal_reasondu SDK TypeScript, qui liste l'ensemble complet des valeurs.origin: origine du message utilisateur qui a déclenché ce tour. En mode d'entrée en streaming, vérifiez ceci pour distinguer le résultat de votre propre invite, oùoriginestNoneou{"kind": "human"}, du résultat d'un tour injecté tel qu'une notification de tâche de fond. Nécessite Python Agent SDK 0.2.137 ou ultérieur.
Le dict usage couvre uniquement la boucle d'agent principal et exclut les sous-agents et autres appels de modèle imbriqués ou auxiliaires. En mode d'entrée en streaming, les valeurs sont par tour. Préférez model_usage pour la comptabilité des tokens et des coûts. Le dict usage contient les clés suivantes quand présentes :
| Clé | Type | Description |
|---|---|---|
input_tokens |
int |
Tokens d'entrée consommés par la boucle d'agent de haut niveau. Les tokens de sous-agent ne sont pas inclus ; utilisez model_usage pour la comptabilité de l'arborescence complète. |
output_tokens |
int |
Tokens de sortie générés par la boucle d'agent de haut niveau. Les tokens de sous-agent ne sont pas inclus. |
cache_creation_input_tokens |
int |
Tokens utilisés pour créer de nouvelles entrées de cache. |
cache_read_input_tokens |
int |
Tokens lus à partir des entrées de cache existantes. |
Le dict model_usage mappe les noms de modèles à l'utilisation par modèle. Il couvre chaque appel de modèle effectué via le pipeline de requête : la boucle principale, les sous-agents, et les appels internes tels que la compaction et les agents Workflow. Les appels d'assistance en dehors de ce pipeline, tels que le classificateur de permission et les demandes de comptage de tokens, sont exclus de model_usage. Traitez model_usage comme une estimation, pas une déclaration de facturation.
En mode d'entrée en streaming, model_usage et total_cost_usd sont cumulatifs entre les tours, donc lisez le dernier résultat plutôt que de faire la somme entre les résultats. Voir Suivre les coûts en mode d'entrée en streaming pour les réinitialisations et Récupérer les totaux après un crash de session pour les résultats remis à zéro.
Chaque valeur dans model_usage est un TypedDict ModelUsage, importé via from claude_agent_sdk.types import ModelUsage. Ses clés utilisent camelCase car le SDK transmet la valeur inchangée du processus CLI sous-jacent, correspondant au type TypeScript ModelUsage :
| Clé | Type | Description |
|---|---|---|
inputTokens |
int |
Tokens d'entrée pour ce modèle. |
outputTokens |
int |
Tokens de sortie pour ce modèle. |
cacheReadInputTokens |
int |
Tokens de lecture de cache pour ce modèle. |
cacheCreationInputTokens |
int |
Tokens de création de cache pour ce modèle. |
webSearchRequests |
int |
Requêtes de recherche web effectuées par ce modèle. |
thinkingTokens |
int |
Tokens de réflexion générés par ce modèle, déjà comptés dans outputTokens. Absent jusqu'à ce qu'un tour s'exécute sur une version de Claude Code qui l'enregistre, et non déclaré sur le TypedDict, donc lisez-le avec .get(). Nécessite Python Agent SDK 0.2.150 ou ultérieur, dont le CLI fourni l'enregistre. |
costUSD |
float |
Coût estimé en USD pour ce modèle, calculé côté client. Voir Suivre le coût et l'utilisation pour les avertissements de facturation. |
contextWindow |
int |
Taille de la fenêtre de contexte pour ce modèle. |
maxOutputTokens |
int |
Limite de tokens de sortie maximum pour ce modèle. |
canonicalModel |
str |
ID de modèle canonique utilisé pour la recherche de tarification. Peut différer de la chaîne de modèle brute par laquelle l'entrée est indexée, telle qu'un ID spécifique au fournisseur ou un alias. Pas toujours présent. |
provider |
str |
Fournisseur d'API qui a servi ce modèle, tel que firstParty, bedrock, vertex, foundry, anthropicAws, mantle, ou gateway. Pas toujours présent. |
`StreamEvent`
Événement de flux pour les mises à jour de messages partiels pendant le streaming. Reçu uniquement quand include_partial_messages=True dans ClaudeAgentOptions. Importez via from claude_agent_sdk.types import StreamEvent.
@dataclass
class StreamEvent:
uuid: str
session_id: str
event: dict[str, Any] # The raw Claude API stream event
parent_tool_use_id: str | None = None
| Champ | Type | Description |
|---|---|---|
uuid |
str |
Identifiant unique pour cet événement |
session_id |
str |
Identifiant de session |
event |
dict[str, Any] |
Les données d'événement de flux Claude API brutes |
parent_tool_use_id |
str | None |
Toujours None. Les événements de flux sont émis pour la session principale uniquement. Pour l'attribution de sous-agent, utilisez des messages complets tels que AssistantMessage |
`RateLimitEvent`
Émis quand le statut de limite de débit change (par exemple, de "allowed" à "allowed_warning"). Utilisez ceci pour avertir les utilisateurs avant qu'ils ne frappent une limite dure, ou pour reculer quand le statut est "rejected".
@dataclass
class RateLimitEvent:
rate_limit_info: RateLimitInfo
uuid: str
session_id: str
| Champ | Type | Description |
|---|---|---|
rate_limit_info |
RateLimitInfo |
État actuel de la limite de débit |
uuid |
str |
Identifiant d'événement unique |
session_id |
str |
Identifiant de session |
`RateLimitInfo`
État de limite de débit porté par RateLimitEvent.
RateLimitStatus = Literal["allowed", "allowed_warning", "rejected"]
RateLimitType = Literal[
"five_hour", "seven_day", "seven_day_opus", "seven_day_sonnet", "overage"
]
@dataclass
class RateLimitInfo:
status: RateLimitStatus
resets_at: int | None = None
rate_limit_type: RateLimitType | None = None
utilization: float | None = None
overage_status: RateLimitStatus | None = None
overage_resets_at: int | None = None
overage_disabled_reason: str | None = None
raw: dict[str, Any] = field(default_factory=dict)
| Champ | Type | Description |
|---|---|---|
status |
RateLimitStatus |
Statut actuel. "allowed_warning" signifie approcher la limite ; "rejected" signifie que la limite a été atteinte |
resets_at |
int | None |
Timestamp Unix quand la fenêtre de limite de débit se réinitialise |
rate_limit_type |
RateLimitType | None |
Quelle fenêtre de limite de débit s'applique |
utilization |
float | None |
Fraction de la limite de débit consommée (0,0 à 1,0) |
overage_status |
RateLimitStatus | None |
Statut de l'utilisation de dépassement à l'usage, si applicable |
overage_resets_at |
int | None |
Timestamp Unix quand la fenêtre de dépassement se réinitialise |
overage_disabled_reason |
str | None |
Pourquoi le dépassement est indisponible, si le statut est "rejected" |
raw |
dict[str, Any] |
Dict brut complet du CLI, incluant les champs non modélisés ci-dessus |
`ConversationResetMessage`
Émis quand la conversation est remplacée sans terminer la connexion, par exemple après /clear. Voir Suivre les coûts en mode d'entrée en streaming pour la façon dont une réinitialisation affecte les totaux en cours d'exécution sur les objets ResultMessage ultérieurs. Nécessite Python Agent SDK 0.2.137 ou ultérieur.
@dataclass
class ConversationResetMessage:
new_conversation_id: str
uuid: str
session_id: str
| Champ | Type | Description |
|---|---|---|
new_conversation_id |
str |
Identifiant opaque pour la conversation fraîche. Pas le session_id des messages ultérieurs ; lisez-le à partir du message suivant |
uuid |
str |
Identifiant de message unique |
session_id |
str |
ID de la session qui a été réinitialisée. Les messages après la réinitialisation portent un nouveau session_id |
`TaskStartedMessage`
Émis quand une tâche de fond démarre. Une tâche de fond est tout ce qui est suivi en dehors du tour principal : une commande Bash en arrière-plan, une montre Monitor, un sous-agent généré via l'outil Agent, ou un agent distant. Le champ task_type vous dit lequel. Ce nommage n'est pas lié au renommage de l'outil Task-à-Agent.
@dataclass
class TaskStartedMessage(SystemMessage):
task_id: str
description: str
uuid: str
session_id: str
tool_use_id: str | None = None
task_type: str | None = None
| Champ | Type | Description |
|---|---|---|
task_id |
str |
Identifiant unique pour la tâche |
description |
str |
Description de la tâche |
uuid |
str |
Identifiant de message unique |
session_id |
str |
Identifiant de session |
tool_use_id |
str | None |
ID d'utilisation d'outil associé |
task_type |
str | None |
Quel type de tâche de fond : "local_bash" pour Bash en arrière-plan et les montres Monitor, "local_agent", ou "remote_agent" |
`TaskUsage`
Données de tokens et de timing pour une tâche de fond.
class TaskUsage(TypedDict):
total_tokens: int
tool_uses: int
duration_ms: int
`TaskProgressMessage`
Émis périodiquement avec les mises à jour de progression pour une tâche de fond en cours d'exécution.
@dataclass
class TaskProgressMessage(SystemMessage):
task_id: str
description: str
usage: TaskUsage
uuid: str
session_id: str
tool_use_id: str | None = None
last_tool_name: str | None = None
| Champ | Type | Description |
|---|---|---|
task_id |
str |
Identifiant unique pour la tâche |
description |
str |
Description du statut actuel |
usage |
TaskUsage |
Utilisation de tokens pour cette tâche jusqu'à présent |
uuid |
str |
Identifiant de message unique |
session_id |
str |
Identifiant de session |
tool_use_id |
str | None |
ID d'utilisation d'outil associé |
last_tool_name |
str | None |
Nom du dernier outil utilisé par la tâche |
`TaskNotificationMessage`
Émis quand une tâche de fond se termine, échoue, ou est arrêtée. Les tâches de fond incluent les commandes Bash run_in_background, les montres Monitor, et les sous-agents en arrière-plan.
@dataclass
class TaskNotificationMessage(SystemMessage):
task_id: str
status: TaskNotificationStatus # "completed" | "failed" | "stopped"
output_file: str
summary: str
uuid: str
session_id: str
tool_use_id: str | None = None
usage: TaskUsage | None = None
| Champ | Type | Description |
|---|---|---|
task_id |
str |
Identifiant unique pour la tâche |
status |
TaskNotificationStatus |
L'un de "completed", "failed", ou "stopped" |
output_file |
str |
Chemin vers le fichier de sortie de la tâche |
summary |
str |
Résumé du résultat de la tâche |
uuid |
str |
Identifiant de message unique |
session_id |
str |
Identifiant de session |
tool_use_id |
str | None |
ID d'utilisation d'outil associé |
usage |
TaskUsage | None |
Utilisation de tokens finale pour la tâche |
Quand le CLI déplace un long appel d'outil MCP en arrière-plan, le résultat de l'outil pour cet appel ne contient qu'un espace réservé et le résultat réel de l'appel arrive dans ce message. Sur une notification "completed" pour un tel appel, le CLI ajoute une clé resource_links listant les fichiers que l'outil a retournés par référence, avec les mêmes entrées et limites que la clé resourceLinks sur UserMessage.tool_use_result. La clé resource_links nécessite Python Agent SDK 0.2.150 ou ultérieur et Claude Code v2.1.257 ou ultérieur ; le CLI fourni avec cette version du SDK satisfait l'exigence de Claude Code.
La dataclass n'a pas de champ pour resource_links. Lisez-le à partir du dict data que le message hérite de SystemMessage : message.data.get("resource_links"). Faites correspondre la notification à l'appel avec tool_use_id. Le CLI omet la clé quand le résultat n'avait pas de liens et sur les notifications pour les tâches qui ne sont pas des appels d'outil MCP.
Types de blocs de contenu
`ContentBlock`
Type union de tous les blocs de contenu.
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock
`TextBlock`
Bloc de contenu texte.
@dataclass
class TextBlock:
text: str
`ThinkingBlock`
Bloc de contenu de réflexion (pour les modèles avec capacité de réflexion).
@dataclass
class ThinkingBlock:
thinking: str
signature: str
`ToolUseBlock`
Bloc de requête d'utilisation d'outil.
@dataclass
class ToolUseBlock:
id: str
name: str
input: dict[str, Any]
`ToolResultBlock`
Bloc de résultat d'exécution d'outil.
@dataclass
class ToolResultBlock:
tool_use_id: str
content: str | list[dict[str, Any]] | None = None
is_error: bool | None = None
Types d'erreur
Les types ci-dessous définissent ce que votre code capture. Pour les entrées associées aux messages d'erreur que ces types lèvent, avec la cause et la correction pour chacun, consultez Dépannage.
`ClaudeSDKError`
Classe d'exception de base pour toutes les erreurs du SDK.
class ClaudeSDKError(Exception):
"""Base error for Claude SDK."""
Quand une requête query() unique se termine par un résultat d'erreur, par exemple une erreur de limite de tours, le SDK lève une ResultError après avoir cédé le message de résultat final. Les versions du Python Agent SDK antérieures à 0.2.140 levaient une Exception simple qui n'était pas une sous-classe de ClaudeSDKError.
`CLINotFoundError`
Levée quand Claude Code CLI n'est pas installé ou introuvable.
class CLINotFoundError(CLIConnectionError):
def __init__(
self, message: str = "Claude Code not found", cli_path: str | None = None
):
"""
Args:
message: Error message (default: "Claude Code not found")
cli_path: Optional path to the CLI that was not found
"""
`CLIConnectionError`
Levée quand la connexion à Claude Code échoue.
class CLIConnectionError(ClaudeSDKError):
"""Failed to connect to Claude Code."""
`ProcessError`
Levée quand le processus Claude Code échoue.
class ProcessError(ClaudeSDKError):
def __init__(
self, message: str, exit_code: int | None = None, stderr: str | None = None
):
self.exit_code = exit_code
self.stderr = stderr
`ResultError`
Levée après le ResultMessage final quand le processus Claude Code se termine parce que l'exécution s'est terminée par un résultat d'erreur, comme une erreur de limite de tours ou une erreur API. ResultError est une sous-classe de ProcessError, donc un gestionnaire except ProcessError existant la capture également. Ses attributs portent les champs de ce message de résultat, vous pouvez donc vous brancher sur la raison de l'échec de l'exécution sans analyser le texte du message. Nécessite Python Agent SDK 0.2.140 ou version ultérieure.
class ResultError(ProcessError):
subtype: str | None # "error_max_turns", "error_during_execution", ...; "success" when the run ended on a failed request
errors: list[str] # an empty list when the result message reported none
result: str | None
api_error_status: int | None
terminal_reason: str | None # "max_turns", "api_error", ...; check this before subtype
session_id: str | None
data: dict[str, Any] # the raw result message payload
Pour distinguer les échecs, vérifiez terminal_reason avant subtype. Quand la requête finale échoue, par exemple sur une erreur API, Claude Code rapporte subtype "success" avec la cause dans terminal_reason, par exemple "api_error" ; quand une limite que vous avez définie termine l'exécution, comme max_turns ou max_budget_usd, il rapporte un sous-type error_*.
`CLIJSONDecodeError`
Levée quand l'analyse JSON échoue.
class CLIJSONDecodeError(ClaudeSDKError):
def __init__(self, line: str, original_error: Exception):
"""
Args:
line: The line that failed to parse
original_error: The original JSON decode exception
"""
self.line = line
self.original_error = original_error
Types de hooks
Pour un guide complet sur l'utilisation des hooks avec des exemples et des modèles courants, voir le guide Hooks.
`HookEvent`
Types d'événements de hook supportés.
HookEvent = Literal[
"PreToolUse", # Called before tool execution
"PostToolUse", # Called after tool execution
"PostToolUseFailure", # Called when a tool execution fails
"UserPromptSubmit", # Called when user submits a prompt
"Stop", # Called when stopping execution
"SubagentStop", # Called when a subagent stops
"PreCompact", # Called before message compaction
"Notification", # Called for notification events
"SubagentStart", # Called when a subagent starts
"PermissionRequest", # Called when a permission decision is needed
]
Le SDK TypeScript supporte des événements de hook supplémentaires non encore disponibles en Python. Voir le tableau de disponibilité des hooks pour le support par SDK.
`HookCallback`
Définition de type pour les fonctions de callback de hook.
HookCallback = Callable[[HookInput, str | None, HookContext], Awaitable[HookJSONOutput]]
Paramètres :
input: Entrée de hook fortement typée avec unions discriminées basées surhook_event_name(voirHookInput)tool_use_id: Identifiant d'utilisation d'outil optionnel (pour les hooks liés aux outils)context: Contexte de hook avec des informations supplémentaires
Retourne un HookJSONOutput.
`HookContext`
Informations de contexte passées aux callbacks de hook.
class HookContext(TypedDict):
signal: Any | None # Future: abort signal support
`HookMatcher`
Configuration pour faire correspondre les hooks à des événements ou des outils spécifiques.
@dataclass
class HookMatcher:
matcher: str | None = (
None # Tool name or pattern to match (e.g., "Bash", "Write|Edit")
)
hooks: list[HookCallback] = field(
default_factory=list
) # List of callbacks to execute
timeout: float | None = (
None # Timeout in seconds. When omitted, the per-event default applies:
# 600 for most events, 30 for UserPromptSubmit
)
`HookInput`
Type union de tous les types d'entrée de hook. Le type réel dépend du champ hook_event_name.
HookInput = (
PreToolUseHookInput
| PostToolUseHookInput
| PostToolUseFailureHookInput
| UserPromptSubmitHookInput
| StopHookInput
| SubagentStopHookInput
| PreCompactHookInput
| NotificationHookInput
| SubagentStartHookInput
| PermissionRequestHookInput
)
`BaseHookInput`
Champs de base présents dans tous les types d'entrée de hook.
class BaseHookInput(TypedDict):
session_id: str
transcript_path: str
cwd: str
permission_mode: NotRequired[str]
| Champ | Type | Description |
|---|---|---|
session_id |
str |
Identifiant de session actuel |
transcript_path |
str |
Chemin vers le fichier de transcription de session |
cwd |
str |
Répertoire de travail actuel |
permission_mode |
str (optionnel) |
Mode de permission actuel |
`PreToolUseHookInput`
Données d'entrée pour les événements de hook PreToolUse.
class PreToolUseHookInput(BaseHookInput):
hook_event_name: Literal["PreToolUse"]
tool_name: str
tool_input: dict[str, Any]
tool_use_id: str
agent_id: NotRequired[str]
agent_type: NotRequired[str]
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["PreToolUse"] |
Toujours « PreToolUse » |
tool_name |
str |
Nom de l'outil sur le point d'être exécuté |
tool_input |
dict[str, Any] |
Paramètres d'entrée pour l'outil |
tool_use_id |
str |
Identifiant unique pour cette utilisation d'outil |
agent_id |
str (optionnel) |
Identifiant de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
agent_type |
str (optionnel) |
Type de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
`PostToolUseHookInput`
Données d'entrée pour les événements de hook PostToolUse.
class PostToolUseHookInput(BaseHookInput):
hook_event_name: Literal["PostToolUse"]
tool_name: str
tool_input: dict[str, Any]
tool_response: Any
tool_use_id: str
agent_id: NotRequired[str]
agent_type: NotRequired[str]
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["PostToolUse"] |
Toujours « PostToolUse » |
tool_name |
str |
Nom de l'outil qui a été exécuté |
tool_input |
dict[str, Any] |
Paramètres d'entrée qui ont été utilisés |
tool_response |
Any |
Réponse de l'exécution de l'outil |
tool_use_id |
str |
Identifiant unique pour cette utilisation d'outil |
agent_id |
str (optionnel) |
Identifiant de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
agent_type |
str (optionnel) |
Type de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
`PostToolUseFailureHookInput`
Données d'entrée pour les événements de hook PostToolUseFailure. Appelé quand l'exécution d'un outil échoue.
class PostToolUseFailureHookInput(BaseHookInput):
hook_event_name: Literal["PostToolUseFailure"]
tool_name: str
tool_input: dict[str, Any]
tool_use_id: str
error: str
is_interrupt: NotRequired[bool]
agent_id: NotRequired[str]
agent_type: NotRequired[str]
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["PostToolUseFailure"] |
Toujours « PostToolUseFailure » |
tool_name |
str |
Nom de l'outil qui a échoué |
tool_input |
dict[str, Any] |
Paramètres d'entrée qui ont été utilisés |
tool_use_id |
str |
Identifiant unique pour cette utilisation d'outil |
error |
str |
Message d'erreur de l'exécution échouée |
is_interrupt |
bool (optionnel) |
Vrai quand l'échec a atteint Claude Code comme une interruption plutôt que comme une erreur signalée par l'outil. L'annulation d'un outil en cours d'exécution avec interrupt() ne déclenche pas ce hook ; le résultat de l'outil porte le message d'interruption à la place |
agent_id |
str (optionnel) |
Identifiant de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
agent_type |
str (optionnel) |
Type de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
`UserPromptSubmitHookInput`
Données d'entrée pour les événements de hook UserPromptSubmit.
class UserPromptSubmitHookInput(BaseHookInput):
hook_event_name: Literal["UserPromptSubmit"]
prompt: str
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["UserPromptSubmit"] |
Toujours « UserPromptSubmit » |
prompt |
str |
Le prompt soumis par l'utilisateur |
`StopHookInput`
Données d'entrée pour les événements de hook Stop.
class StopHookInput(BaseHookInput):
hook_event_name: Literal["Stop"]
stop_hook_active: bool
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["Stop"] |
Toujours « Stop » |
stop_hook_active |
bool |
Si le hook d'arrêt est actif |
`SubagentStopHookInput`
Données d'entrée pour les événements de hook SubagentStop.
class SubagentStopHookInput(BaseHookInput):
hook_event_name: Literal["SubagentStop"]
stop_hook_active: bool
agent_id: str
agent_transcript_path: str
agent_type: str
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["SubagentStop"] |
Toujours « SubagentStop » |
stop_hook_active |
bool |
Si le hook d'arrêt est actif |
agent_id |
str |
Identifiant unique pour le sous-agent |
agent_transcript_path |
str |
Chemin vers le fichier de transcription du sous-agent |
agent_type |
str |
Type du sous-agent |
`PreCompactHookInput`
Données d'entrée pour les événements de hook PreCompact.
class PreCompactHookInput(BaseHookInput):
hook_event_name: Literal["PreCompact"]
trigger: Literal["manual", "auto"]
custom_instructions: str | None
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["PreCompact"] |
Toujours « PreCompact » |
trigger |
Literal["manual", "auto"] |
Ce qui a déclenché la compaction |
custom_instructions |
str | None |
Instructions personnalisées pour la compaction |
`NotificationHookInput`
Données d'entrée pour les événements de hook Notification.
class NotificationHookInput(BaseHookInput):
hook_event_name: Literal["Notification"]
message: str
title: NotRequired[str]
notification_type: str
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["Notification"] |
Toujours « Notification » |
message |
str |
Contenu du message de notification |
title |
str (optionnel) |
Titre de la notification |
notification_type |
str |
Type de notification |
`SubagentStartHookInput`
Données d'entrée pour les événements de hook SubagentStart.
class SubagentStartHookInput(BaseHookInput):
hook_event_name: Literal["SubagentStart"]
agent_id: str
agent_type: str
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["SubagentStart"] |
Toujours « SubagentStart » |
agent_id |
str |
Identifiant unique pour le sous-agent |
agent_type |
str |
Type du sous-agent |
`PermissionRequestHookInput`
Données d'entrée pour les événements de hook PermissionRequest. Permet aux hooks de gérer les décisions de permission programmatiquement.
class PermissionRequestHookInput(BaseHookInput):
hook_event_name: Literal["PermissionRequest"]
tool_name: str
tool_input: dict[str, Any]
permission_suggestions: NotRequired[list[Any]]
agent_id: NotRequired[str]
agent_type: NotRequired[str]
| Champ | Type | Description |
|---|---|---|
hook_event_name |
Literal["PermissionRequest"] |
Toujours « PermissionRequest » |
tool_name |
str |
Nom de l'outil demandant la permission |
tool_input |
dict[str, Any] |
Paramètres d'entrée pour l'outil |
permission_suggestions |
list[Any] (optionnel) |
Mises à jour de permission suggérées du CLI |
agent_id |
str (optionnel) |
Identifiant de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
agent_type |
str (optionnel) |
Type de sous-agent, présent quand le hook se déclenche à l'intérieur d'un sous-agent |
`HookJSONOutput`
Type union pour les valeurs de retour de callback de hook.
HookJSONOutput = AsyncHookJSONOutput | SyncHookJSONOutput
`SyncHookJSONOutput`
Sortie de hook synchrone avec champs de contrôle et de décision.
class SyncHookJSONOutput(TypedDict):
# Control fields
continue_: NotRequired[bool] # Whether to proceed (default: True)
suppressOutput: NotRequired[bool] # Hide stdout from transcript
stopReason: NotRequired[str] # Message when continue is False
# Decision fields
decision: NotRequired[Literal["block"]]
systemMessage: NotRequired[str] # Warning message for user
reason: NotRequired[str] # Feedback for Claude
# Hook-specific output
hookSpecificOutput: NotRequired[HookSpecificOutput]
Utilisez continue_ (avec trait de soulignement) dans le code Python. Il est automatiquement converti en continue quand envoyé au CLI.
`HookSpecificOutput`
Une union discriminée de types de sortie spécifiques à l'événement TypedDict. Le champ hookEventName détermine quels champs sont valides. Pour les détails complets sur les champs disponibles par événement de hook, voir Contrôler l'exécution avec les hooks.
class PreToolUseHookSpecificOutput(TypedDict):
hookEventName: Literal["PreToolUse"]
permissionDecision: NotRequired[Literal["allow", "deny", "ask", "defer"]]
permissionDecisionReason: NotRequired[str]
updatedInput: NotRequired[dict[str, Any]]
additionalContext: NotRequired[str]
class PostToolUseHookSpecificOutput(TypedDict):
hookEventName: Literal["PostToolUse"]
additionalContext: NotRequired[str]
updatedToolOutput: NotRequired[Any]
updatedMCPToolOutput: NotRequired[Any] # Deprecated: use updatedToolOutput, which works for all tools
class PostToolUseFailureHookSpecificOutput(TypedDict):
hookEventName: Literal["PostToolUseFailure"]
additionalContext: NotRequired[str]
class UserPromptSubmitHookSpecificOutput(TypedDict):
hookEventName: Literal["UserPromptSubmit"]
additionalContext: NotRequired[str]
class NotificationHookSpecificOutput(TypedDict):
hookEventName: Literal["Notification"]
additionalContext: NotRequired[str]
class SubagentStartHookSpecificOutput(TypedDict):
hookEventName: Literal["SubagentStart"]
additionalContext: NotRequired[str]
class PermissionRequestHookSpecificOutput(TypedDict):
hookEventName: Literal["PermissionRequest"]
decision: dict[str, Any]
HookSpecificOutput = (
PreToolUseHookSpecificOutput
| PostToolUseHookSpecificOutput
| PostToolUseFailureHookSpecificOutput
| UserPromptSubmitHookSpecificOutput
| NotificationHookSpecificOutput
| SubagentStartHookSpecificOutput
| PermissionRequestHookSpecificOutput
)
`AsyncHookJSONOutput`
Sortie de hook asynchrone qui diffère l'exécution du hook.
class AsyncHookJSONOutput(TypedDict):
async_: Literal[True] # Set to True to defer execution
asyncTimeout: NotRequired[int] # Timeout in milliseconds
Utilisez async_ (avec trait de soulignement) dans le code Python. Il est automatiquement converti en async quand envoyé au CLI.
Exemple d'utilisation de hook
Cet exemple enregistre deux hooks : l'un qui bloque les commandes bash dangereuses comme rm -rf /, et un autre qui enregistre toute l'utilisation d'outils pour l'audit. Le hook de sécurité s'exécute uniquement sur les commandes Bash (via le matcher), tandis que le hook de journalisation s'exécute sur tous les outils.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, HookContext
from typing import Any
async def validate_bash_command(
input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
"""Validate and potentially block dangerous bash commands."""
if input_data["tool_name"] == "Bash":
command = input_data["tool_input"].get("command", "")
if "rm -rf /" in command:
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Dangerous command blocked",
}
}
return {}
async def log_tool_use(
input_data: dict[str, Any], tool_use_id: str | None, context: HookContext
) -> dict[str, Any]:
"""Log all tool usage for auditing."""
print(f"Tool used: {input_data.get('tool_name')}")
return {}
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(
matcher="Bash", hooks=[validate_bash_command], timeout=120
), # 2 min for validation
HookMatcher(
hooks=[log_tool_use]
), # Applies to all tools (per-event default timeout)
],
"PostToolUse": [HookMatcher(hooks=[log_tool_use])],
}
)
async def main():
async for message in query(prompt="Analyze this codebase", options=options):
print(message)
asyncio.run(main())
Types d'entrée/sortie d'outil
Documentation des schémas d'entrée/sortie pour tous les outils Claude Code intégrés. Bien que le SDK Python n'exporte pas ceux-ci en tant que types, ils représentent la structure des entrées et sorties d'outils dans les messages.
Agent
Nom de l'outil : Agent. Le nom précédent Task est toujours accepté comme alias, et la liste tools dans le SystemMessage d'initialisation rapporte cet outil comme Task pour la compatibilité rétroactive.
Entrée :
{
"description": str, # A short (3-5 word) description of the task
"prompt": str, # The task for the agent to perform
"subagent_type": str | None, # The type of specialized agent to use
"model": "sonnet" | "opus" | "haiku" | "fable" | None, # Model override for this agent
"run_in_background": bool | None, # Agents run in the background by default; set to False to run synchronously
"name": str | None, # Name for the spawned agent
"team_name": str | None, # Deprecated; ignored
"mode": "acceptEdits" | "auto" | "bypassPermissions" | "default" | "dontAsk" | "plan" | None, # Deprecated; ignored. Subagents inherit the parent session's permission mode; agent-definition frontmatter may override it
"isolation": "worktree" | "remote" | None, # Isolation mode for the agent's changes
}
Lance un nouvel agent pour gérer des tâches complexes et multi-étapes de manière autonome.
Sortie (statut : "completed") :
{
"status": "completed",
"agentId": str, # ID of the agent that ran
"agentType": str | None, # The subagent type that handled the task
"content": [ # Result content blocks
{
"type": "text",
"text": str,
"citations": list | None,
}
],
"resolvedModel": str | None, # Model the subagent started on
"modelsUsed": list[str] | None, # Models used in order, with consecutive repeats collapsed
"totalToolUseCount": int, # Number of tool calls the agent made
"totalDurationMs": int, # Execution duration in milliseconds
"totalTokens": int, # Token count from the final API request, not the whole run
"usage": { # Token usage statistics
"input_tokens": int,
"output_tokens": int,
"cache_creation_input_tokens": int | None,
"cache_read_input_tokens": int | None,
"server_tool_use": {"web_search_requests": int, "web_fetch_requests": int} | None,
"service_tier": str | None,
"cache_creation": {"ephemeral_1h_input_tokens": int, "ephemeral_5m_input_tokens": int} | None,
"inference_geo": str | None,
"speed": str | None,
"iterations": Any | None,
"output_tokens_details": {"thinking_tokens": int | None} | None,
},
"toolStats": { # Aggregate tool activity for the run
"readCount": int,
"searchCount": int,
"bashCount": int,
"editFileCount": int,
"linesAdded": int,
"linesRemoved": int,
"otherToolCount": int,
"frameCount": int | None,
} | None,
"prompt": str, # The prompt the agent ran
"worktreePath": str | None, # Present when Claude Code kept the subagent's worktree
"worktreeBranch": str | None, # Present when Claude Code created that worktree with git
}
Sortie (statut : "async_launched") :
{
"status": "async_launched",
"isAsync": bool | None, # True on background launches
"agentId": str, # ID of the launched agent
"description": str, # The task description
"resolvedModel": str | None, # Model in use at the backgrounding transition
"modelsUsed": list[str] | None, # Models used before backgrounding, in order, with consecutive repeats collapsed
"prompt": str, # The prompt the agent runs
"outputFile": str, # File path where the agent's output is written
"canReadOutputFile": bool | None, # Whether the output file can be read directly
}
Sortie (statut : "remote_launched") :
{
"status": "remote_launched",
"taskId": str, # ID of the remote task
"sessionUrl": str, # Link to the remote cloud session
"description": str, # The task description
"prompt": str, # The prompt the agent runs
"outputFile": str, # File path where the agent's output is written
}
Retourne le résultat du sous-agent. La sortie est discriminée sur le champ status : "completed" pour les tâches terminées, "async_launched" pour les tâches en arrière-plan, et "remote_launched" pour les tâches que Claude Code a envoyées à une session cloud distante, où sessionUrl renvoie à cette session et taskId l'identifie. Si Claude Code a conservé la worktree isolée du sous-agent, worktreePath sur la variante completed est l'endroit où la trouver, et worktreeBranch est sa branche lorsque Claude Code a créé la worktree avec git.
Sur la variante completed, resolvedModel nomme le modèle sur lequel le sous-agent a démarré, qui peut différer du model d'entrée demandé lorsque availableModels ou une autre substitution s'applique. Ce champ nécessite Claude Code v2.1.174 ou ultérieur. Sur la variante async_launched, resolvedModel nomme le modèle en cours d'utilisation lorsque l'agent s'est déplacé en arrière-plan, donc un échange qui s'est produit avant la mise en arrière-plan est reflété là. Le champ modelsUsed sur les deux variantes répertorie les modèles utilisés dans l'ordre, avec les répétitions consécutives réduites ; il est défini uniquement lorsque le modèle a été échangé en cours d'exécution. modelsUsed et le comportement resolvedModel au moment de la mise en arrière-plan nécessitent Claude Code v2.1.212 ou ultérieur.
Claude Code remplit usage et totalTokens à partir de la dernière demande API du sous-agent, pas de l'ensemble de l'exécution. Lorsqu'il est présent, thinking_tokens sous output_tokens_details dans usage est le nombre de jetons de sortie de cette demande qui étaient des jetons de réflexion. La clé output_tokens_details nécessite le SDK Python v0.2.136 ou ultérieur, qui regroupe Claude Code v2.1.228.
AskUserQuestion
Nom de l'outil : AskUserQuestion
Pose des questions de clarification à l'utilisateur pendant l'exécution. Voir Gérer les approbations et les entrées utilisateur pour les détails d'utilisation.
Entrée :
{
"questions": [ # Questions to ask the user (1-4 questions)
{
"question": str, # The complete question to ask the user
"header": str, # Very short label displayed as a chip/tag (max 12 chars)
"options": [ # The available choices (2-4 options)
{
"label": str, # Display text for this option (1-5 words)
"description": str, # Explanation of what this option means
"preview": str | None, # Preview content rendered when the option is focused
}
],
"multiSelect": bool, # Set to true to allow multiple selections
}
],
"answers": dict[str, str] | None,
# User answers populated by the permission system. Multi-select
# answers are a comma-joined string of the selected labels; a
# list of labels is accepted on input and coerced to that form
"annotations": dict[str, dict] | None,
# Per-question annotations from the user, keyed by question text.
# Each value can carry "preview" (the selected option's preview
# content) and "notes" (free-text notes on the selection)
"metadata": dict | None, # Analytics metadata, such as {"source": "remember"}; not displayed to the user
}
Sortie :
{
"questions": [ # The questions that were asked
{
"question": str,
"header": str,
"options": [{"label": str, "description": str, "preview": str | None}],
"multiSelect": bool,
}
],
"answers": dict[str, str], # Maps question text to answer string
# Multi-select answers are comma-separated
"response": str | None,
# Freeform reply typed instead of answering the questions; when set,
# Claude receives "The user responded: ..." in place of the answer list
"annotations": dict[str, dict] | None, # Per-question "preview" and "notes" from the user's selections
"afkTimeoutMs": int | None, # Set when the dialog auto-resolved after this many milliseconds of user inactivity; absent when the user answered
}
Bash
Nom de l'outil : Bash
Entrée :
{
"command": str, # The command to execute
"timeout": int | None, # Optional timeout in milliseconds (max 600000; higher values are clamped to the max)
"description": str | None, # Clear, concise description (5-10 words)
"run_in_background": bool | None, # Set to true to run in background
}
Sortie :
{
"stdout": str, # The command's output; stdout and stderr arrive merged into this one interleaved stream
"stderr": str, # Notices the tool itself adds, not the command's stderr
"interrupted": bool, # Whether the command was interrupted
"isImage": bool | None, # Whether stdout contains image data
"backgroundTaskId": str | None, # ID of the background task if command is running in background
}
Monitor
Nom de l'outil : Monitor
Exécute une source de fond et livre chaque événement à Claude pour qu'il puisse réagir sans interrogation : command exécute un script et émet un événement par ligne stdout, et ws ouvre une WebSocket et émet un événement par trame texte. Fournissez exactement l'un de command ou ws.
Lorsque Monitor exécute une commande, il suit les mêmes règles de permission que Bash ; une surveillance WebSocket demande une approbation séparément. La source ws nécessite Claude Code v2.1.195 ou ultérieur. Voir la référence de l'outil Monitor pour le comportement et la disponibilité du fournisseur.
Entrée :
{
"command": str | None, # Shell script; each stdout line is an event, exit ends the watch
"ws": dict | None, # WebSocket source: {"url": str, "protocols": list[str] | None}; each text frame is an event
"description": str, # Short description shown in notifications
"timeout_ms": int | None, # Kill after this deadline (default 300000, max 3600000)
"persistent": bool | None, # Run for the lifetime of the session; stop with TaskStop
}
Sortie :
{
"taskId": str, # ID of the background monitor task
"timeoutMs": int, # Timeout deadline in milliseconds (0 when persistent)
"persistent": bool | None, # True when running until TaskStop or session end
}
Edit
Nom de l'outil : Edit
Entrée :
{
"file_path": str, # The absolute path to the file to modify
"old_string": str, # The text to replace
"new_string": str, # The text to replace it with
"replace_all": bool | None, # Replace all occurrences (default False)
}
Sortie :
{
"message": str, # Confirmation message
"replacements": int, # Number of replacements made
"file_path": str, # File path that was edited
}
Read
Nom de l'outil : Read
Entrée :
{
"file_path": str, # The absolute path to the file to read
"offset": int | None, # The line number to start reading from
"limit": int | None, # The number of lines to read
}
Sortie (fichiers texte) :
{
"content": str, # File contents with line numbers
"total_lines": int, # Total number of lines in file
"lines_returned": int, # Lines actually returned
}
Sortie (images) :
{
"image": str, # Base64 encoded image data
"mime_type": str, # Image MIME type
"file_size": int, # File size in bytes
}
Write
Nom de l'outil : Write
Entrée :
{
"file_path": str, # The absolute path to the file to write
"content": str, # The content to write to the file
}
Sortie :
{
"message": str, # Success message
"bytes_written": int, # Number of bytes written
"file_path": str, # File path that was written
}
Glob
Nom de l'outil : Glob
Entrée :
{
"pattern": str, # The glob pattern to match files against
"path": str | None, # The directory to search in (defaults to cwd)
}
Sortie :
{
"matches": list[str], # Array of matching file paths
"count": int, # Number of matches found
"search_path": str, # Search directory used
}
Grep
Nom de l'outil : Grep
Entrée :
{
"pattern": str, # The regular expression pattern
"path": str | None, # File or directory to search in
"glob": str | None, # Glob pattern to filter files
"type": str | None, # File type to search
"output_mode": str | None, # "content", "files_with_matches", or "count"
"-i": bool | None, # Case insensitive search
"-n": bool | None, # Show line numbers
"-B": int | None, # Lines to show before each match
"-A": int | None, # Lines to show after each match
"-C": int | None, # Lines to show before and after
"head_limit": int | None, # Limit output to first N lines/entries
"multiline": bool | None, # Enable multiline mode
}
Sortie (mode contenu) :
{
"matches": [
{
"file": str,
"line_number": int | None,
"line": str,
"before_context": list[str] | None,
"after_context": list[str] | None,
}
],
"total_matches": int,
}
Sortie (mode fichiers_avec_correspondances) :
{
"files": list[str], # Files containing matches
"count": int, # Number of files with matches
}
NotebookEdit
Nom de l'outil : NotebookEdit
Entrée :
{
"notebook_path": str, # Absolute path to the Jupyter notebook
"cell_id": str | None, # The ID of the cell to edit
"new_source": str, # The new source for the cell
"cell_type": "code" | "markdown" | None, # The type of the cell
"edit_mode": "replace" | "insert" | "delete" | None, # Edit operation type
}
Sortie :
{
"message": str, # Success message
"edit_type": "replaced" | "inserted" | "deleted", # Type of edit performed
"cell_id": str | None, # Cell ID that was affected
"total_cells": int, # Total cells in notebook after edit
}
WebFetch
Nom de l'outil : WebFetch
Entrée :
{
"url": str, # The URL to fetch content from
"prompt": str, # The prompt to run on the fetched content
}
Sortie :
{
"bytes": int, # Size of the fetched content in bytes
"code": int, # HTTP response code
"codeText": str, # HTTP response code text
"result": str, # Processed result from applying the prompt to the content
"durationMs": int, # Time to fetch and process the content, in milliseconds
"url": str, # URL that was fetched
}
WebSearch
Nom de l'outil : WebSearch
Entrée :
{
"query": str, # The search query to use
"allowed_domains": list[str] | None, # Only include results from these domains
"blocked_domains": list[str] | None, # Never include results from these domains
}
Sortie :
{
"query": str, # The search query
"results": list[str | {"tool_use_id": str, "content": list[{"title": str, "url": str}]}],
"durationSeconds": float, # Search duration in seconds
}
TodoWrite
Nom de l'outil : TodoWrite
À partir du SDK Agent Python 0.2.139, la restriction suivante s'applique.
The following tools aren't available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, or later versions of those families unless you opt in:
TodoWriteTaskCreateTaskGetTaskUpdateTaskList
On other models, Claude Code provides the Task tools by default and TodoWrite only when you set CLAUDE_CODE_ENABLE_TASKS=0.
Voir Disponibilité du modèle pour vous inscrire.
Entrée :
{
"todos": [
{
"content": str, # The task description
"status": "pending" | "in_progress" | "completed", # Task status
"activeForm": str, # Active form of the description
}
]
}
Sortie :
{
"message": str, # Success message
"stats": {"total": int, "pending": int, "in_progress": int, "completed": int},
}
TaskCreate
Nom de l'outil : TaskCreate
Entrée :
{
"subject": str, # Short task title
"description": str, # Detailed task body
"activeForm": str | None, # Present-tense label shown while in progress
"metadata": dict | None, # Arbitrary caller metadata
}
Sortie :
{
"task": {"id": str, "subject": str}, # Created task with assigned ID
}
TaskUpdate
Nom de l'outil : TaskUpdate
Entrée :
{
"taskId": str, # ID of the task to patch
"status": Literal["pending", "in_progress", "completed", "deleted"] | None,
"subject": str | None,
"description": str | None,
"activeForm": str | None,
"addBlocks": list[str] | None, # Task IDs this task now blocks
"addBlockedBy": list[str] | None, # Task IDs that now block this task
"owner": str | None,
"metadata": dict | None,
}
Sortie :
{
"success": bool,
"taskId": str,
"updatedFields": list[str], # Names of fields that changed
"error": str | None,
"statusChange": {"from": str, "to": str} | None,
}
TaskGet
Nom de l'outil : TaskGet
Entrée :
{
"taskId": str, # ID of the task to read
}
Sortie :
{
"task": {
"id": str,
"subject": str,
"description": str,
"status": Literal["pending", "in_progress", "completed"],
"blocks": list[str],
"blockedBy": list[str],
} | None, # None when the ID is not found
}
TaskList
Nom de l'outil : TaskList
Entrée :
{}
Sortie :
{
"tasks": [
{
"id": str,
"subject": str,
"status": Literal["pending", "in_progress", "completed"],
"owner": str | None,
"blockedBy": list[str],
}
],
}
TaskOutput
Nom de l'outil : TaskOutput. Le nom précédent BashOutput est toujours accepté comme alias.
TaskOutput est déprécié ; préférez Read sur le chemin du fichier de sortie de la tâche. Les schémas ci-dessous restent valides pour les hooks et les gestionnaires de permission qui rencontrent l'outil.
Entrée :
{
"task_id": str, # The task ID to get output from
"block": bool, # Whether to wait for completion (default True)
"timeout": int, # Max wait time in ms (default 30000)
}
Sortie :
{
"retrieval_status": "success" | "timeout" | "not_ready", # Whether the output was retrieved
"task": dict | None, # Task details: task_id, task_type, status, description, output, plus type-specific fields such as exitCode
}
TaskStop
Nom de l'outil : TaskStop. Les noms précédents KillShell et KillBash sont toujours acceptés comme alias.
Entrée :
{
"task_id": str | None, # The ID of the background task to stop
"shell_id": str | None, # Deprecated: use task_id instead
}
Sortie :
{
"message": str, # Status message about the operation
"task_id": str, # The ID of the task that was stopped
"task_type": str, # The type of the task that was stopped
"command": str | None, # The command or description of the stopped task
}
ExitPlanMode
Nom de l'outil : ExitPlanMode
Entrée :
{
"plan": str # The plan to run by the user for approval
}
Sortie :
{
"message": str, # Confirmation message
"approved": bool | None, # Whether user approved the plan
}
ListMcpResources
Nom de l'outil : ListMcpResourcesTool
Entrée :
{
"server": str | None # Optional server name to filter resources by
}
Sortie :
{
"resources": [
{
"uri": str,
"name": str,
"description": str | None,
"mimeType": str | None,
"server": str,
}
],
"total": int,
}
ReadMcpResource
Nom de l'outil : ReadMcpResourceTool
Entrée :
{
"server": str, # The MCP server name
"uri": str, # The resource URI to read
}
Sortie :
{
"contents": [
{"uri": str, "mimeType": str | None, "text": str | None, "blob": str | None}
],
"server": str,
}
Construire une interface de conversation continue
L'exemple suivant maintient un seul ClaudeSDKClient connecté à travers les tours, afin que Claude se souvienne des messages antérieurs. Tapez new pour vous déconnecter et vous reconnecter pour une nouvelle session, ou exit pour terminer la conversation.
from claude_agent_sdk import (
ClaudeSDKClient,
ClaudeAgentOptions,
AssistantMessage,
TextBlock,
)
import asyncio
class ConversationSession:
"""Maintains a single conversation session with Claude."""
def __init__(self, options: ClaudeAgentOptions | None = None):
self.client = ClaudeSDKClient(options)
self.turn_count = 0
async def start(self):
await self.client.connect()
print("Starting conversation session. Claude will remember context.")
print(
"Commands: 'exit' to quit, 'interrupt' to stop current task, 'new' for new session"
)
while True:
user_input = input(f"\n[Turn {self.turn_count + 1}] You: ")
if user_input.lower() == "exit":
break
elif user_input.lower() == "interrupt":
await self.client.interrupt()
print("Task interrupted!")
continue
elif user_input.lower() == "new":
# Disconnect and reconnect for a fresh session
await self.client.disconnect()
await self.client.connect()
self.turn_count = 0
print("Started new conversation session (previous context cleared)")
continue
# Send message - the session retains all previous messages
await self.client.query(user_input)
self.turn_count += 1
# Process response
print(f"[Turn {self.turn_count}] Claude: ", end="")
async for message in self.client.receive_response():
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text, end="")
print() # New line after response
await self.client.disconnect()
print(f"Conversation ended after {self.turn_count} turns.")
async def main():
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"], permission_mode="acceptEdits"
)
session = ConversationSession(options)
await session.start()
# Example conversation:
# Turn 1 - You: "Create a file called hello.py"
# Turn 1 - Claude: "I'll create a hello.py file for you..."
# Turn 2 - You: "What's in that file?"
# Turn 2 - Claude: "The hello.py file I just created contains..." (remembers!)
# Turn 3 - You: "Add a main function to it"
# Turn 3 - Claude: "I'll add a main function to hello.py..." (knows which file!)
asyncio.run(main())
Gestion des erreurs
L'exemple suivant encapsule un appel query() dans des gestionnaires pour quatre des types d'erreurs que le SDK lève.
Cet exemple capture ResultError, qui nécessite Python Agent SDK 0.2.140 ou version ultérieure.
import asyncio
from claude_agent_sdk import (
query,
CLINotFoundError,
ProcessError,
ResultError,
CLIJSONDecodeError,
)
async def main():
try:
async for message in query(prompt="Hello"):
print(message)
except CLINotFoundError:
print(
"Claude Code CLI not found. Try reinstalling: pip install --force-reinstall claude-agent-sdk"
)
# Catch ResultError before ProcessError, which it subclasses. Its message
# carries the error text. A failed final request, such as an API error,
# arrives with subtype "success", so branch on terminal_reason first.
except ResultError as e:
if e.terminal_reason == "api_error":
print(f"API request failed: {e}")
else:
print(f"Query ended with an error result ({e.terminal_reason or e.subtype}): {e}")
except ProcessError as e:
print(f"Process failed with exit code: {e.exit_code}")
except CLIJSONDecodeError as e:
print(f"Failed to parse response: {e}")
asyncio.run(main())
Configuration du sandbox
`SandboxSettings`
Configuration pour le comportement du sandbox. Utilisez ceci pour activer le sandboxing des commandes et configurer les restrictions réseau programmatiquement.
class SandboxSettings(TypedDict, total=False):
enabled: bool
autoAllowBashIfSandboxed: bool
excludedCommands: list[str]
allowUnsandboxedCommands: bool
network: SandboxNetworkConfig
ignoreViolations: SandboxIgnoreViolations
enableWeakerNestedSandbox: bool
| Propriété | Type | Par défaut | Description |
|---|---|---|---|
enabled |
bool |
False |
Activez le mode sandbox pour l'exécution des commandes |
autoAllowBashIfSandboxed |
bool |
True |
Approuvez automatiquement les commandes bash quand le sandbox est activé |
excludedCommands |
list[str] |
[] |
Commandes qui contournent toujours les restrictions du sandbox (par exemple, ["docker"]). Celles-ci s'exécutent sans sandbox automatiquement sans implication du modèle |
allowUnsandboxedCommands |
bool |
True |
Permettez au modèle de demander l'exécution de commandes en dehors du sandbox. Quand True, le modèle peut définir dangerouslyDisableSandbox dans l'entrée d'outil, qui revient au système de permissions |
network |
SandboxNetworkConfig |
None |
Configuration de sandbox spécifique au réseau |
ignoreViolations |
SandboxIgnoreViolations |
None |
Configurez quelles violations de sandbox ignorer |
enableWeakerNestedSandbox |
bool |
False |
Activez un sandbox imbriqué plus faible pour la compatibilité |
Le sandbox dépend du support de la plateforme et, sur Linux, d'outils comme bubblewrap et socat. Par défaut, quand enabled est True mais que le sandbox ne peut pas démarrer, les commandes s'exécutent sans sandbox avec un avertissement sur stderr. Ce comportement par défaut diffère du SDK TypeScript, où failIfUnavailable est par défaut true.
Définissez "failIfUnavailable": True dans vos paramètres de sandbox pour arrêter à la place. La clé n'est pas encore déclarée sur SandboxSettings, mais le SDK la transmet à Claude Code, qui la respecte. query() rapporte alors un ResultMessage avec subtype="error_during_execution" et la raison dans errors. Comme il s'agit d'un appel query() unique, le SDK lève une exception après avoir produit ce résultat d'erreur, donc enveloppez la boucle dans un bloc try pour continuer au-delà. Voir Gérer le résultat pour le contrat d'erreur.
Exemple d'utilisation
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
sandbox_settings = {
"enabled": True,
"autoAllowBashIfSandboxed": True,
"failIfUnavailable": True,
"network": {"allowLocalBinding": True},
}
async def main():
try:
async for message in query(
prompt="Build and test my project",
options=ClaudeAgentOptions(sandbox=sandbox_settings),
):
print(message)
except Exception as error:
# A single-shot query() raises after yielding an error result,
# such as when failIfUnavailable is set and the sandbox can't start.
print(f"Session ended with an error: {error}")
asyncio.run(main())
Sécurité des sockets Unix : L'option allowUnixSockets peut accorder l'accès à des services système qui s'étendent en dehors du sandbox. Par exemple, permettre /var/run/docker.sock accorde effectivement un accès complet au système hôte via l'API Docker, contournant l'isolation du sandbox. Autorisez uniquement les sockets Unix strictement nécessaires et comprenez les implications de sécurité de chacun.
`SandboxNetworkConfig`
Configuration spécifique au réseau pour le mode sandbox. Ces paramètres s'appliquent aux commandes Bash en sandbox quand enabled est True dans le parent SandboxSettings. Ils ne restreignent pas l'outil WebFetch, qui utilise à la place des règles de permission.
class SandboxNetworkConfig(TypedDict, total=False):
allowedDomains: list[str]
deniedDomains: list[str]
allowManagedDomainsOnly: bool
allowUnixSockets: list[str]
allowAllUnixSockets: bool
allowLocalBinding: bool
allowMachLookup: list[str]
httpProxyPort: int
socksProxyPort: int
| Propriété | Type | Par défaut | Description |
|---|---|---|---|
allowedDomains |
list[str] |
[] |
Noms de domaine auxquels les processus en sandbox peuvent accéder |
deniedDomains |
list[str] |
[] |
Noms de domaine auxquels les processus en sandbox ne peuvent pas accéder. Prend la priorité sur allowedDomains |
allowManagedDomainsOnly |
bool |
False |
Paramètres gérés uniquement : quand défini dans les paramètres gérés, ignorez allowedDomains et les règles d'autorisation WebFetch(domain:...) des sources de paramètres non gérées. N'a aucun effet quand défini via les options SDK |
allowUnixSockets |
list[str] |
[] |
Chemins de socket Unix auxquels les processus peuvent accéder (par exemple, socket Docker) |
allowAllUnixSockets |
bool |
False |
Permettez l'accès à tous les sockets Unix |
allowLocalBinding |
bool |
False |
Permettez aux processus de se lier aux ports locaux (par exemple, pour les serveurs de développement) |
allowMachLookup |
list[str] |
[] |
macOS uniquement : noms de services XPC/Mach à autoriser. Supporte un caractère générique à la fin |
httpProxyPort |
int |
None |
Port du proxy HTTP pour les requêtes réseau |
socksProxyPort |
int |
None |
Port du proxy SOCKS pour les requêtes réseau |
Le proxy sandbox intégré applique la liste blanche réseau en fonction du nom d'hôte demandé et ne termine pas ou n'inspecte pas le trafic TLS, donc des techniques telles que le domain fronting peuvent potentiellement le contourner. Voir Limitations de sécurité du sandboxing pour les détails et Déploiement sécurisé pour configurer un proxy qui termine TLS.
`SandboxIgnoreViolations`
Configuration pour ignorer les violations de sandbox spécifiques.
class SandboxIgnoreViolations(TypedDict, total=False):
file: list[str]
network: list[str]
| Propriété | Type | Par défaut | Description |
|---|---|---|---|
file |
list[str] |
[] |
Modèles de chemin de fichier pour ignorer les violations |
network |
list[str] |
[] |
Modèles réseau pour ignorer les violations |
Fallback de permissions pour les commandes sans sandbox
Quand allowUnsandboxedCommands est activé, le modèle peut demander l'exécution de commandes en dehors du sandbox en définissant dangerouslyDisableSandbox: True dans l'entrée d'outil. Ces requêtes reviennent au système de permissions existant, ce qui signifie que votre gestionnaire can_use_tool sera invoqué, vous permettant d'implémenter une logique d'autorisation personnalisée. Les commandes listées dans excludedCommands contournent à la place le sandbox automatiquement, sans implication du modèle ; voir SandboxSettings.
L'exemple suivant enregistre chaque requête sans sandbox et la refuse sauf si votre propre logique d'autorisation l'autorise :
import asyncio
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
HookMatcher,
PermissionResultAllow,
PermissionResultDeny,
ToolPermissionContext,
)
def is_command_authorized(command: str | None) -> bool:
# Replace with your own authorization logic
return False
async def can_use_tool(
tool: str, input: dict, context: ToolPermissionContext
) -> PermissionResultAllow | PermissionResultDeny:
# Check if the model is requesting to bypass the sandbox
if tool == "Bash" and input.get("dangerouslyDisableSandbox"):
# The model is requesting to run this command outside the sandbox
print(f"Unsandboxed command requested: {input.get('command')}")
if is_command_authorized(input.get("command")):
return PermissionResultAllow()
return PermissionResultDeny(
message="Command not authorized for unsandboxed execution"
)
return PermissionResultAllow()
# Required: dummy hook keeps the stream open for can_use_tool
async def dummy_hook(input_data, tool_use_id, context):
return {"continue_": True}
async def prompt_stream():
yield {
"type": "user",
"message": {"role": "user", "content": "Deploy my application"},
}
async def main():
async for message in query(
prompt=prompt_stream(),
options=ClaudeAgentOptions(
sandbox={
"enabled": True,
"allowUnsandboxedCommands": True, # Model can request unsandboxed execution
},
permission_mode="default",
can_use_tool=can_use_tool,
hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
),
):
print(message)
asyncio.run(main())
Les commandes s'exécutant avec dangerouslyDisableSandbox: True ont un accès complet au système. Assurez-vous que votre gestionnaire can_use_tool valide ces requêtes avec soin.
Si permission_mode est défini sur bypassPermissions et allow_unsandboxed_commands est activé, le modèle peut exécuter de manière autonome des commandes en dehors du sandbox sans aucun prompt d'approbation, à part les actions qu'aucun mode n'approuve automatiquement. Cette combinaison permet effectivement au modèle d'échapper à l'isolation du sandbox silencieusement.
Voir aussi
- Vue d'ensemble du SDK - Concepts généraux du SDK
- Référence du SDK TypeScript - Documentation du SDK TypeScript
- Outils personnalisés - Définir des outils MCP en processus pour que Claude appelle
- Référence CLI - Interface de ligne de commande
- Flux de travail courants - Guides étape par étape