Loading...
    • Guía para desarrolladores
    • Referencia de API
    • MCP
    • Recursos
    • Notas de la versión
    Search...
    ⌘K
    Primeros pasos
    Introducción a ClaudeInicio rápido
    Modelos y precios
    Descripción general de modelosElegir un modeloNovedades en Claude 4.5Migración a Claude 4.5Deprecación de modelosPrecios
    Construir con Claude
    Descripción general de característicasUsar la API de MessagesVentanas de contextoMejores prácticas de prompting
    Capacidades
    Almacenamiento en caché de promptsEdición de contextoPensamiento extendidoEsfuerzoStreaming de MessagesProcesamiento por lotesCitasSoporte multilingüeConteo de tokensEmbeddingsVisiónSoporte de PDFAPI de FilesResultados de búsquedaSalidas estructuradas
    Herramientas
    Descripción generalCómo implementar el uso de herramientasStreaming de herramientas de grano finoHerramienta BashHerramienta de ejecución de códigoLlamada de herramientas programáticaHerramienta de uso de computadoraHerramienta de editor de textoHerramienta de búsqueda webHerramienta de búsqueda webHerramienta de memoriaHerramienta de búsqueda de herramientas
    Agent Skills
    Descripción generalInicio rápidoMejores prácticasUsar Skills con la API
    Agent SDK
    Descripción generalInicio rápidoSDK de TypeScriptTypeScript V2 (vista previa)SDK de PythonGuía de migración
    MCP en la API
    Conector MCPServidores MCP remotos
    Claude en plataformas de terceros
    Amazon BedrockMicrosoft FoundryVertex AI
    Ingeniería de prompts
    Descripción generalGenerador de promptsUsar plantillas de promptsMejorador de promptsSer claro y directoUsar ejemplos (prompting multishot)Dejar que Claude piense (CoT)Usar etiquetas XMLDar un rol a Claude (prompts del sistema)Rellenar la respuesta de ClaudeEncadenar prompts complejosConsejos de contexto largoConsejos de pensamiento extendido
    Probar y evaluar
    Definir criterios de éxitoDesarrollar casos de pruebaUsar la herramienta de evaluaciónReducir latencia
    Fortalecer protecciones
    Reducir alucinacionesAumentar consistencia de salidaMitigar ataques de jailbreakRechazos de streamingReducir fuga de promptsMantener a Claude en personaje
    Administración y monitoreo
    Descripción general de Admin APIAPI de uso y costoAPI de Claude Code Analytics
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Agent SDK

    Referencia del SDK del Agente - Python

    Referencia completa de la API del SDK del Agente de Python, incluyendo todas las funciones, tipos y clases.
    • Instalación
    • Elegir entre query() y ClaudeSDKClient
    • Comparación rápida
    • Cuándo usar query() (Nueva sesión cada vez)
    • Cuándo usar ClaudeSDKClient (Conversación continua)
    • Funciones
    • query()
    • tool()
    • create_sdk_mcp_server()
    • Clases
    • ClaudeSDKClient
    • Tipos
    • SdkMcpTool
    • ClaudeAgentOptions
    • OutputFormat
    • SystemPromptPreset
    • SettingSource
    • AgentDefinition
    • PermissionMode
    • McpSdkServerConfig
    • McpServerConfig
    • SdkPluginConfig
    • Tipos de mensaje
    • Message
    • UserMessage
    • AssistantMessage
    • SystemMessage
    • ResultMessage
    • Tipos de Bloque de Contenido
    • ContentBlock
    • TextBlock
    • ThinkingBlock
    • ToolUseBlock
    • ToolResultBlock
    • Tipos de Error
    • ClaudeSDKError
    • CLINotFoundError
    • CLIConnectionError
    • ProcessError
    • CLIJSONDecodeError
    • Tipos de Hook
    • HookEvent
    • HookCallback
    • HookContext
    • HookMatcher
    • Ejemplo de Uso de Hook
    • Tipos de Entrada/Salida de Herramienta
    • Task
    • Bash
    • Edit
    • Read
    • Write
    • Glob
    • Grep
    • NotebookEdit
    • WebFetch
    • WebSearch
    • TodoWrite
    • BashOutput
    • KillBash
    • ExitPlanMode
    • ListMcpResources
    • ReadMcpResource
    • Características Avanzadas con ClaudeSDKClient
    • Construir una Interfaz de Conversación Continua
    • Usar Hooks para Modificación de Comportamiento
    • Monitoreo de Progreso en Tiempo Real
    • Uso de Ejemplo
    • Operaciones básicas de archivo (usando query)
    • Manejo de errores
    • Modo de transmisión con cliente
    • Usar herramientas personalizadas con ClaudeSDKClient
    • Configuración de Sandbox
    • SandboxSettings
    • SandboxNetworkConfig
    • SandboxIgnoreViolations
    • Fallback de Permisos para Comandos Sin Sandbox
    • Ver también

    Instalación

    pip install claude-agent-sdk

    Elegir entre query() y ClaudeSDKClient

    El SDK de Python proporciona dos formas de interactuar con Claude Code:

    Comparación rápida

    Característicaquery()ClaudeSDKClient
    SesiónCrea una nueva sesión cada vezReutiliza la misma sesión
    ConversaciónIntercambio únicoMúltiples intercambios en el mismo contexto
    ConexiónGestionada automáticamenteControl manual
    Entrada de transmisión✅ Compatible✅ Compatible
    Interrupciones❌ No compatible✅ Compatible
    Hooks❌ No compatible✅ Compatible
    Herramientas personalizadas❌ No compatible✅ Compatible
    Continuar chat❌ Nueva sesión cada vez✅ Mantiene la conversación
    Caso de usoTareas puntualesConversaciones continuas

    Cuándo usar query() (Nueva sesión cada vez)

    Mejor para:

    • Preguntas puntuales donde no necesitas historial de conversación
    • Tareas independientes que no requieren contexto de intercambios anteriores
    • Scripts de automatización simple
    • Cuando quieres un inicio fresco cada vez

    Cuándo usar ClaudeSDKClient (Conversación continua)

    Mejor para:

    • Continuar conversaciones - Cuando necesitas que Claude recuerde el contexto
    • Preguntas de seguimiento - Construyendo sobre respuestas anteriores
    • Aplicaciones interactivas - Interfaces de chat, REPLs
    • Lógica impulsada por respuestas - Cuando la siguiente acción depende de la respuesta de Claude
    • Control de sesión - Gestionar explícitamente el ciclo de vida de la conversación

    Funciones

    query()

    Crea una nueva sesión para cada interacción con Claude Code. Devuelve un iterador asincrónico que produce mensajes a medida que llegan. Cada llamada a query() comienza de nuevo sin memoria de interacciones anteriores.

    async def query(
        *,
        prompt: str | AsyncIterable[dict[str, Any]],
        options: ClaudeAgentOptions | None = None
    ) -> AsyncIterator[Message]

    Parámetros

    ParámetroTipoDescripción
    promptstr | AsyncIterable[dict]El prompt de entrada como una cadena o iterable asincrónico para modo de transmisión
    optionsClaudeAgentOptions | NoneObjeto de configuración opcional (por defecto ClaudeAgentOptions() si es None)

    Devuelve

    Devuelve un AsyncIterator[Message] que produce mensajes de la conversación.

    Ejemplo - Con opciones

    
    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',
            cwd="/home/user/project"
        )
    
        async for message in query(
            prompt="Create a Python web server",
            options=options
        ):
            print(message)
    
    
    asyncio.run(main())

    tool()

    Decorador para definir herramientas MCP con seguridad de tipos.

    def tool(
        name: str,
        description: str,
        input_schema: type | dict[str, Any]
    ) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]

    Parámetros

    ParámetroTipoDescripción
    namestrIdentificador único para la herramienta
    descriptionstrDescripción legible por humanos de lo que hace la herramienta
    input_schematype | dict[str, Any]Esquema que define los parámetros de entrada de la herramienta (ver abajo)

    Opciones de esquema de entrada

    1. Mapeo de tipo simple (recomendado):

      {"text": str, "count": int, "enabled": bool}
    2. Formato JSON Schema (para validación compleja):

      {
          "type": "object",
          "properties": {
              "text": {"type": "string"},
              "count": {"type": "integer", "minimum": 0}
          },
          "required": ["text"]
      }

    Devuelve

    Una función decoradora que envuelve la implementación de la herramienta y devuelve una instancia de SdkMcpTool.

    Ejemplo

    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']}!"
            }]
        }

    create_sdk_mcp_server()

    Crea un servidor MCP en proceso que se ejecuta dentro de tu aplicación Python.

    def create_sdk_mcp_server(
        name: str,
        version: str = "1.0.0",
        tools: list[SdkMcpTool[Any]] | None = None
    ) -> McpSdkServerConfig

    Parámetros

    ParámetroTipoPor defectoDescripción
    namestr-Identificador único para el servidor
    versionstr"1.0.0"Cadena de versión del servidor
    toolslist[SdkMcpTool[Any]] | NoneNoneLista de funciones de herramienta creadas con el decorador @tool

    Devuelve

    Devuelve un objeto McpSdkServerConfig que puede pasarse a ClaudeAgentOptions.mcp_servers.

    Ejemplo

    from claude_agent_sdk import tool, create_sdk_mcp_server
    
    @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"]
    )

    Clases

    ClaudeSDKClient

    Mantiene una sesión de conversación en múltiples intercambios. Este es el equivalente en Python de cómo funciona internamente la función query() del SDK de TypeScript - crea un objeto cliente que puede continuar conversaciones.

    Características clave

    • Continuidad de sesión: Mantiene el contexto de conversación en múltiples llamadas a query()
    • Misma conversación: Claude recuerda los mensajes anteriores en la sesión
    • Soporte de interrupciones: Puede detener a Claude a mitad de la ejecución
    • Ciclo de vida explícito: Controlas cuándo comienza y termina la sesión
    • Flujo impulsado por respuestas: Puede reaccionar a respuestas y enviar seguimientos
    • Herramientas personalizadas y hooks: Admite herramientas personalizadas (creadas con el decorador @tool) y hooks
    class ClaudeSDKClient:
        def __init__(self, options: ClaudeAgentOptions | 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 rewind_files(self, user_message_uuid: str) -> None
        async def disconnect(self) -> None

    Métodos

    MétodoDescripción
    __init__(options)Inicializa el cliente con configuración opcional
    connect(prompt)Conecta a Claude con un prompt inicial opcional o flujo de mensajes
    query(prompt, session_id)Envía una nueva solicitud en modo de transmisión
    receive_messages()Recibe todos los mensajes de Claude como un iterador asincrónico
    receive_response()Recibe mensajes hasta e incluyendo un ResultMessage
    interrupt()Envía señal de interrupción (solo funciona en modo de transmisión)
    rewind_files(user_message_uuid)Restaura archivos a su estado en el mensaje de usuario especificado. Requiere . Ver

    Soporte del gestor de contexto

    El cliente puede usarse como un gestor de contexto asincrónico para la gestión automática de conexiones:

    async with ClaudeSDKClient() as client:
        await client.query("Hello Claude")
        async for message in client.receive_response():
            print(message)

    Importante: Al iterar sobre mensajes, evita usar break para salir temprano ya que esto puede causar problemas de limpieza de asyncio. En su lugar, deja que la iteración se complete naturalmente o usa banderas para rastrear cuándo has encontrado lo que necesitas.

    Ejemplo - Continuando una conversación

    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 - Claude remembers 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())

    Ejemplo - Entrada de transmisión con ClaudeSDKClient

    import asyncio
    from claude_agent_sdk import ClaudeSDKClient
    
    async def message_stream():
        """Generate messages dynamically."""
        yield {"type": "text", "text": "Analyze the following data:"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "Temperature: 25°C"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "Humidity: 60%"}
        await asyncio.sleep(0.5)
        yield {"type": "text", "text": "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())

    Ejemplo - Usando interrupciones

    import asyncio
    from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
    
    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")
    
            # Let it run for a bit
            await asyncio.sleep(2)
    
            # Interrupt the task
            await client.interrupt()
            print("Task interrupted!")
    
            # Send a new command
            await client.query("Just say hello instead")
    
            async for message in client.receive_response():
                # Process the new response
                pass
    
    asyncio.run(interruptible_task())

    Ejemplo - Control de permisos avanzado

    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions
    )
    
    async def custom_permission_handler(
        tool_name: str,
        input_data: dict,
        context: dict
    ):
        """Custom logic for tool permissions."""
    
        # Block writes to system directories
        if tool_name == "Write" and input_data.get("file_path", "").startswith("/system/"):
            return {
                "behavior": "deny",
                "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 {
                "behavior": "allow",
                "updatedInput": {**input_data, "file_path": safe_path}
            }
    
        # Allow everything else
        return {
            "behavior": "allow",
            "updatedInput": input_data
        }
    
    async def main():
        options = ClaudeAgentOptions(
            can_use_tool=custom_permission_handler,
            allowed_tools=["Read", "Write", "Edit"]
        )
    
        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())

    Tipos

    SdkMcpTool

    Definición para una herramienta MCP del SDK creada con el decorador @tool.

    @dataclass
    class SdkMcpTool(Generic[T]):
        name: str
        description: str
        input_schema: type[T] | dict[str, Any]
        handler: Callable[[T], Awaitable[dict[str, Any]]]
    PropiedadTipoDescripción
    namestrIdentificador único para la herramienta
    descriptionstrDescripción legible por humanos
    input_schematype[T] | dict[str, Any]Esquema para validación de entrada
    handlerCallable[[T], Awaitable[dict[str, Any]]]Función asincrónica que maneja la ejecución de la herramienta

    ClaudeAgentOptions

    Clase de datos de configuración para consultas de Claude Code.

    @dataclass
    class ClaudeAgentOptions:
        allowed_tools: list[str] = field(default_factory=list)
        system_prompt: str | SystemPromptPreset | None = None
        mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
        permission_mode: PermissionMode | None = None
        continue_conversation: bool = False
        resume: str | None = None
        max_turns: int | None = None
        disallowed_tools: list[str] = field(default_factory=list)
        model: str | None = None
        output_format: OutputFormat | None = None
        permission_prompt_tool_name: str | None = None
        cwd: 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
        fork_session: bool = False
        agents: dict[str, AgentDefinition] | None = None
        setting_sources: list[SettingSource] | None = None
    PropiedadTipoPor defectoDescripción
    allowed_toolslist[str][]Lista de nombres de herramientas permitidas
    system_promptstr | SystemPromptPreset | NoneNoneConfiguración del prompt del sistema. Pasa una cadena para un prompt personalizado, o usa {"type": "preset", "preset": "claude_code"} para el prompt del sistema de Claude Code. Agrega "append" para extender el preset
    mcp_serversdict[str, McpServerConfig] | str | Path

    OutputFormat

    Configuración para validación de salida estructurada.

    class OutputFormat(TypedDict):
        type: Literal["json_schema"]
        schema: dict[str, Any]
    CampoRequeridoDescripción
    typeSíDebe ser "json_schema" para validación de JSON Schema
    schemaSíDefinición de JSON Schema para validación de salida

    SystemPromptPreset

    Configuración para usar el prompt del sistema preestablecido de Claude Code con adiciones opcionales.

    class SystemPromptPreset(TypedDict):
        type: Literal["preset"]
        preset: Literal["claude_code"]
        append: NotRequired[str]
    CampoRequeridoDescripción
    typeSíDebe ser "preset" para usar un prompt del sistema preestablecido
    presetSíDebe ser "claude_code" para usar el prompt del sistema de Claude Code
    appendNoInstrucciones adicionales a agregar al prompt del sistema preestablecido

    SettingSource

    Controla qué fuentes de configuración basadas en el sistema de archivos carga el SDK.

    SettingSource = Literal["user", "project", "local"]
    ValorDescripciónUbicación
    "user"Configuración global del usuario~/.claude/settings.json
    "project"Configuración compartida del proyecto (controlada por versión).claude/settings.json
    "local"Configuración local del proyecto (ignorada por git).claude/settings.local.json

    Comportamiento por defecto

    Cuando setting_sources está omitido o es None, el SDK no carga ninguna configuración del sistema de archivos. Esto proporciona aislamiento para aplicaciones del SDK.

    ¿Por qué usar setting_sources?

    Cargar todas las configuraciones del sistema de archivos (comportamiento heredado):

    # Load all settings like SDK v0.0.x did
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async for message in query(
        prompt="Analyze this code",
        options=ClaudeAgentOptions(
            setting_sources=["user", "project", "local"]  # Load all settings
        )
    ):
        print(message)

    Cargar solo fuentes de configuración específicas:

    # Load only project settings, ignore user and local
    async for message in query(
        prompt="Run CI checks",
        options=ClaudeAgentOptions(
            setting_sources=["project"]  # Only .claude/settings.json
        )
    ):
        print(message)

    Entornos de prueba e integración continua:

    # Ensure consistent behavior in CI by excluding local settings
    async for message in query(
        prompt="Run tests",
        options=ClaudeAgentOptions(
            setting_sources=["project"],  # Only team-shared settings
            permission_mode="bypassPermissions"
        )
    ):
        print(message)

    Aplicaciones solo del SDK:

    # Define everything programmatically (default behavior)
    # No filesystem dependencies - setting_sources defaults to None
    async for message in query(
        prompt="Review this PR",
        options=ClaudeAgentOptions(
            # setting_sources=None is the default, no need to specify
            agents={ /* ... */ },
            mcp_servers={ /* ... */ },
            allowed_tools=["Read", "Grep", "Glob"]
        )
    ):
        print(message)

    Cargando instrucciones del proyecto CLAUDE.md:

    # Load project settings to include CLAUDE.md files
    async for message in query(
        prompt="Add a new feature following project conventions",
        options=ClaudeAgentOptions(
            system_prompt={
                "type": "preset",
                "preset": "claude_code"  # Use Claude Code's system prompt
            },
            setting_sources=["project"],  # Required to load CLAUDE.md from project
            allowed_tools=["Read", "Write", "Edit"]
        )
    ):
        print(message)

    Precedencia de configuración

    Cuando se cargan múltiples fuentes, las configuraciones se fusionan con esta precedencia (mayor a menor):

    1. Configuración local (.claude/settings.local.json)
    2. Configuración del proyecto (.claude/settings.json)
    3. Configuración del usuario (~/.claude/settings.json)

    Las opciones programáticas (como agents, allowed_tools) siempre anulan las configuraciones del sistema de archivos.

    AgentDefinition

    Configuración para un suagente definido programáticamente.

    @dataclass
    class AgentDefinition:
        description: str
        prompt: str
        tools: list[str] | None = None
        model: Literal["sonnet", "opus", "haiku", "inherit"] | None = None
    CampoRequeridoDescripción
    descriptionSíDescripción en lenguaje natural de cuándo usar este agente
    toolsNoMatriz de nombres de herramientas permitidas. Si se omite, hereda todas las herramientas
    promptSíEl prompt del sistema del agente
    modelNoAnulación de modelo para este agente. Si se omite, usa el modelo principal

    PermissionMode

    Modos de permiso para controlar la ejecución de herramientas.

    PermissionMode = Literal[
        "default",           # Standard permission behavior
        "acceptEdits",       # Auto-accept file edits
        "plan",              # Planning mode - no execution
        "bypassPermissions"  # Bypass all permission checks (use with caution)
    ]

    McpSdkServerConfig

    Configuración para servidores MCP del SDK creados con create_sdk_mcp_server().

    class McpSdkServerConfig(TypedDict):
        type: Literal["sdk"]
        name: str
        instance: Any  # MCP Server instance

    McpServerConfig

    Tipo de unión para configuraciones de servidor 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]]

    SdkPluginConfig

    Configuración para cargar plugins en el SDK.

    class SdkPluginConfig(TypedDict):
        type: Literal["local"]
        path: str
    CampoTipoDescripción
    typeLiteral["local"]Debe ser "local" (actualmente solo se admiten plugins locales)
    pathstrRuta absoluta o relativa al directorio del plugin

    Ejemplo:

    plugins=[
        {"type": "local", "path": "./my-plugin"},
        {"type": "local", "path": "/absolute/path/to/plugin"}
    ]

    Para información completa sobre cómo crear y usar plugins, ver Plugins.

    Tipos de mensaje

    Message

    Tipo de unión de todos los mensajes posibles.

    Message = UserMessage | AssistantMessage | SystemMessage | ResultMessage

    UserMessage

    Mensaje de entrada del usuario.

    @dataclass
    class UserMessage:
        content: str | list[ContentBlock]

    AssistantMessage

    Mensaje de respuesta del asistente con bloques de contenido.

    @dataclass
    class AssistantMessage:
        content: list[ContentBlock]
        model: str

    SystemMessage

    Mensaje del sistema con metadatos.

    @dataclass
    class SystemMessage:
        subtype: str
        data: dict[str, Any]

    ResultMessage

    Mensaje de resultado final con información de costo y uso.

    @dataclass
    class ResultMessage:
        subtype: str
        duration_ms: int
        duration_api_ms: int
        is_error: bool
        num_turns: int
        session_id: str
        total_cost_usd: float | None = None
        usage: dict[str, Any] | None = None
        result: str | None = None

    Tipos de Bloque de Contenido

    ContentBlock

    Tipo de unión de todos los bloques de contenido.

    ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock

    TextBlock

    Bloque de contenido de texto.

    @dataclass
    class TextBlock:
        text: str

    ThinkingBlock

    Bloque de contenido de pensamiento (para modelos con capacidad de pensamiento).

    @dataclass
    class ThinkingBlock:
        thinking: str
        signature: str

    ToolUseBlock

    Bloque de solicitud de uso de herramienta.

    @dataclass
    class ToolUseBlock:
        id: str
        name: str
        input: dict[str, Any]

    ToolResultBlock

    Bloque de resultado de ejecución de herramienta.

    @dataclass
    class ToolResultBlock:
        tool_use_id: str
        content: str | list[dict[str, Any]] | None = None
        is_error: bool | None = None

    Tipos de Error

    ClaudeSDKError

    Clase de excepción base para todos los errores del SDK.

    class ClaudeSDKError(Exception):
        """Error base para Claude SDK."""

    CLINotFoundError

    Se genera cuando Claude Code CLI no está instalado o no se encuentra.

    class CLINotFoundError(CLIConnectionError):
        def __init__(self, message: str = "Claude Code not found", cli_path: str | None = None):
            """
            Args:
                message: Mensaje de error (predeterminado: "Claude Code not found")
                cli_path: Ruta opcional a la CLI que no se encontró
            """

    CLIConnectionError

    Se genera cuando la conexión a Claude Code falla.

    class CLIConnectionError(ClaudeSDKError):
        """Error al conectar con Claude Code."""

    ProcessError

    Se genera cuando el proceso de Claude Code falla.

    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

    CLIJSONDecodeError

    Se genera cuando el análisis JSON falla.

    class CLIJSONDecodeError(ClaudeSDKError):
        def __init__(self, line: str, original_error: Exception):
            """
            Args:
                line: La línea que no se pudo analizar
                original_error: La excepción original de decodificación JSON
            """
            self.line = line
            self.original_error = original_error

    Tipos de Hook

    Para una guía completa sobre el uso de hooks con ejemplos y patrones comunes, consulte la guía de Hooks.

    HookEvent

    Tipos de eventos de hook admitidos. Tenga en cuenta que debido a limitaciones de configuración, el SDK de Python no admite hooks de SessionStart, SessionEnd y Notification.

    HookEvent = Literal[
        "PreToolUse",      # Se llama antes de la ejecución de la herramienta
        "PostToolUse",     # Se llama después de la ejecución de la herramienta
        "UserPromptSubmit", # Se llama cuando el usuario envía un mensaje
        "Stop",            # Se llama cuando se detiene la ejecución
        "SubagentStop",    # Se llama cuando un subaagente se detiene
        "PreCompact"       # Se llama antes de la compactación de mensajes
    ]

    HookCallback

    Definición de tipo para funciones de devolución de llamada de hook.

    HookCallback = Callable[
        [dict[str, Any], str | None, HookContext],
        Awaitable[dict[str, Any]]
    ]

    Parámetros:

    • input_data: Datos de entrada específicos del hook (consulte guía de Hooks)
    • tool_use_id: Identificador de uso de herramienta opcional (para hooks relacionados con herramientas)
    • context: Contexto del hook con información adicional

    Devuelve un diccionario que puede contener:

    • decision: "block" para bloquear la acción
    • systemMessage: Mensaje del sistema para agregar a la transcripción
    • hookSpecificOutput: Datos de salida específicos del hook

    HookContext

    Información de contexto pasada a las devoluciones de llamada de hook.

    @dataclass
    class HookContext:
        signal: Any | None = None  # Futuro: soporte de señal de aborto

    HookMatcher

    Configuración para hacer coincidir hooks con eventos o herramientas específicas.

    @dataclass
    class HookMatcher:
        matcher: str | None = None        # Nombre de herramienta o patrón a coincidir (p. ej., "Bash", "Write|Edit")
        hooks: list[HookCallback] = field(default_factory=list)  # Lista de devoluciones de llamada a ejecutar
        timeout: float | None = None        # Tiempo de espera en segundos para todos los hooks en este matcher (predeterminado: 60)

    Ejemplo de Uso de Hook

    Este ejemplo registra dos hooks: uno que bloquea comandos bash peligrosos como rm -rf /, y otro que registra todo el uso de herramientas para auditoría. El hook de seguridad solo se ejecuta en comandos Bash (a través del matcher), mientras que el hook de registro se ejecuta en todas las herramientas.

    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]:
        """Validar y potencialmente bloquear comandos bash peligrosos."""
        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': 'Comando peligroso bloqueado'
                    }
                }
        return {}
    
    async def log_tool_use(
        input_data: dict[str, Any],
        tool_use_id: str | None,
        context: HookContext
    ) -> dict[str, Any]:
        """Registrar todo el uso de herramientas para auditoría."""
        print(f"Herramienta utilizada: {input_data.get('tool_name')}")
        return {}
    
    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                HookMatcher(matcher='Bash', hooks=[validate_bash_command], timeout=120),  # 2 min para validación
                HookMatcher(hooks=[log_tool_use])  # Se aplica a todas las herramientas (tiempo de espera predeterminado de 60s)
            ],
            'PostToolUse': [
                HookMatcher(hooks=[log_tool_use])
            ]
        }
    )
    
    async for message in query(
        prompt="Analizar este repositorio de código",
        options=options
    ):
        print(message)

    Tipos de Entrada/Salida de Herramienta

    Documentación de esquemas de entrada/salida para todas las herramientas integradas de Claude Code. Aunque el SDK de Python no exporta estos como tipos, representan la estructura de entradas y salidas de herramientas en mensajes.

    Task

    Nombre de herramienta: Task

    Entrada:

    {
        "description": str,      # Una descripción breve (3-5 palabras) de la tarea
        "prompt": str,           # La tarea para que el agente realice
        "subagent_type": str     # El tipo de agente especializado a utilizar
    }

    Salida:

    {
        "result": str,                    # Resultado final del subaagente
        "usage": dict | None,             # Estadísticas de uso de tokens
        "total_cost_usd": float | None,  # Costo total en USD
        "duration_ms": int | None         # Duración de ejecución en milisegundos
    }

    Bash

    Nombre de herramienta: Bash

    Entrada:

    {
        "command": str,                  # El comando a ejecutar
        "timeout": int | None,           # Tiempo de espera opcional en milisegundos (máximo 600000)
        "description": str | None,       # Descripción clara y concisa (5-10 palabras)
        "run_in_background": bool | None # Establecer en true para ejecutar en segundo plano
    }

    Salida:

    {
        "output": str,              # Salida combinada de stdout y stderr
        "exitCode": int,            # Código de salida del comando
        "killed": bool | None,      # Si el comando fue terminado debido a tiempo de espera
        "shellId": str | None       # ID de shell para procesos en segundo plano
    }

    Edit

    Nombre de herramienta: Edit

    Entrada:

    {
        "file_path": str,           # La ruta absoluta del archivo a modificar
        "old_string": str,          # El texto a reemplazar
        "new_string": str,          # El texto para reemplazarlo
        "replace_all": bool | None  # Reemplazar todas las ocurrencias (predeterminado False)
    }

    Salida:

    {
        "message": str,      # Mensaje de confirmación
        "replacements": int, # Número de reemplazos realizados
        "file_path": str     # Ruta del archivo que fue editado
    }

    Read

    Nombre de herramienta: Read

    Entrada:

    {
        "file_path": str,       # La ruta absoluta del archivo a leer
        "offset": int | None,   # El número de línea desde donde comenzar a leer
        "limit": int | None     # El número de líneas a leer
    }

    Salida (Archivos de texto):

    {
        "content": str,         # Contenido del archivo con números de línea
        "total_lines": int,     # Número total de líneas en el archivo
        "lines_returned": int   # Líneas realmente devueltas
    }

    Salida (Imágenes):

    {
        "image": str,       # Datos de imagen codificados en Base64
        "mime_type": str,   # Tipo MIME de imagen
        "file_size": int    # Tamaño del archivo en bytes
    }

    Write

    Nombre de herramienta: Write

    Entrada:

    {
        "file_path": str,  # La ruta absoluta del archivo a escribir
        "content": str     # El contenido a escribir en el archivo
    }

    Salida:

    {
        "message": str,        # Mensaje de éxito
        "bytes_written": int,  # Número de bytes escritos
        "file_path": str       # Ruta del archivo que fue escrito
    }

    Glob

    Nombre de herramienta: Glob

    Entrada:

    {
        "pattern": str,       # El patrón glob para coincidir archivos
        "path": str | None    # El directorio a buscar (predeterminado al cwd)
    }

    Salida:

    {
        "matches": list[str],  # Matriz de rutas de archivos coincidentes
        "count": int,          # Número de coincidencias encontradas
        "search_path": str     # Directorio de búsqueda utilizado
    }

    Grep

    Nombre de herramienta: Grep

    Entrada:

    {
        "pattern": str,                    # El patrón de expresión regular
        "path": str | None,                # Archivo o directorio a buscar
        "glob": str | None,                # Patrón glob para filtrar archivos
        "type": str | None,                # Tipo de archivo a buscar
        "output_mode": str | None,         # "content", "files_with_matches", o "count"
        "-i": bool | None,                 # Búsqueda sin distinción de mayúsculas/minúsculas
        "-n": bool | None,                 # Mostrar números de línea
        "-B": int | None,                  # Líneas a mostrar antes de cada coincidencia
        "-A": int | None,                  # Líneas a mostrar después de cada coincidencia
        "-C": int | None,                  # Líneas a mostrar antes y después
        "head_limit": int | None,          # Limitar salida a las primeras N líneas/entradas
        "multiline": bool | None           # Habilitar modo multilínea
    }

    Salida (modo content):

    {
        "matches": [
            {
                "file": str,
                "line_number": int | None,
                "line": str,
                "before_context": list[str] | None,
                "after_context": list[str] | None
            }
        ],
        "total_matches": int
    }

    Salida (modo files_with_matches):

    {
        "files": list[str],  # Archivos que contienen coincidencias
        "count": int         # Número de archivos con coincidencias
    }

    NotebookEdit

    Nombre de herramienta: NotebookEdit

    Entrada:

    {
        "notebook_path": str,                     # Ruta absoluta al cuaderno Jupyter
        "cell_id": str | None,                    # El ID de la celda a editar
        "new_source": str,                        # La nueva fuente para la celda
        "cell_type": "code" | "markdown" | None,  # El tipo de celda
        "edit_mode": "replace" | "insert" | "delete" | None  # Tipo de operación de edición
    }

    Salida:

    {
        "message": str,                              # Mensaje de éxito
        "edit_type": "replaced" | "inserted" | "deleted",  # Tipo de edición realizada
        "cell_id": str | None,                       # ID de celda que fue afectado
        "total_cells": int                           # Total de celdas en el cuaderno después de la edición
    }

    WebFetch

    Nombre de herramienta: WebFetch

    Entrada:

    {
        "url": str,     # La URL de la que obtener contenido
        "prompt": str   # El mensaje a ejecutar en el contenido obtenido
    }

    Salida:

    {
        "response": str,           # Respuesta del modelo de IA al mensaje
        "url": str,                # URL que fue obtenida
        "final_url": str | None,   # URL final después de redirecciones
        "status_code": int | None  # Código de estado HTTP
    }

    WebSearch

    Nombre de herramienta: WebSearch

    Entrada:

    {
        "query": str,                        # La consulta de búsqueda a utilizar
        "allowed_domains": list[str] | None, # Solo incluir resultados de estos dominios
        "blocked_domains": list[str] | None  # Nunca incluir resultados de estos dominios
    }

    Salida:

    {
        "results": [
            {
                "title": str,
                "url": str,
                "snippet": str,
                "metadata": dict | None
            }
        ],
        "total_results": int,
        "query": str
    }

    TodoWrite

    Nombre de herramienta: TodoWrite

    Entrada:

    {
        "todos": [
            {
                "content": str,                              # La descripción de la tarea
                "status": "pending" | "in_progress" | "completed",  # Estado de la tarea
                "activeForm": str                            # Forma activa de la descripción
            }
        ]
    }

    Salida:

    {
        "message": str,  # Mensaje de éxito
        "stats": {
            "total": int,
            "pending": int,
            "in_progress": int,
            "completed": int
        }
    }

    BashOutput

    Nombre de herramienta: BashOutput

    Entrada:

    {
        "bash_id": str,       # El ID del shell en segundo plano
        "filter": str | None  # Expresión regular opcional para filtrar líneas de salida
    }

    Salida:

    {
        "output": str,                                      # Nueva salida desde la última verificación
        "status": "running" | "completed" | "failed",       # Estado actual del shell
        "exitCode": int | None                              # Código de salida cuando se completa
    }

    KillBash

    Nombre de herramienta: KillBash

    Entrada:

    {
        "shell_id": str  # El ID del shell en segundo plano a terminar
    }

    Salida:

    {
        "message": str,  # Mensaje de éxito
        "shell_id": str  # ID del shell terminado
    }

    ExitPlanMode

    Nombre de herramienta: ExitPlanMode

    Entrada:

    {
        "plan": str  # El plan a ejecutar por el usuario para aprobación
    }

    Salida:

    {
        "message": str,          # Mensaje de confirmación
        "approved": bool | None  # Si el usuario aprobó el plan
    }

    ListMcpResources

    Nombre de herramienta: ListMcpResources

    Entrada:

    {
        "server": str | None  # Nombre de servidor opcional para filtrar recursos por
    }

    Salida:

    {
        "resources": [
            {
                "uri": str,
                "name": str,
                "description": str | None,
                "mimeType": str | None,
                "server": str
            }
        ],
        "total": int
    }

    ReadMcpResource

    Nombre de herramienta: ReadMcpResource

    Entrada:

    {
        "server": str,  # El nombre del servidor MCP
        "uri": str      # El URI del recurso a leer
    }

    Salida:

    {
        "contents": [
            {
                "uri": str,
                "mimeType": str | None,
                "text": str | None,
                "blob": str | None
            }
        ],
        "server": str
    }

    Características Avanzadas con ClaudeSDKClient

    Construir una Interfaz de Conversación Continua

    from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock
    import asyncio
    
    class ConversationSession:
        """Mantiene una única sesión de conversación con Claude."""
    
        def __init__(self, options: ClaudeAgentOptions = None):
            self.client = ClaudeSDKClient(options)
            self.turn_count = 0
    
        async def start(self):
            await self.client.connect()
            print("Iniciando sesión de conversación. Claude recordará el contexto.")
            print("Comandos: 'exit' para salir, 'interrupt' para detener la tarea actual, 'new' para nueva sesión")
    
            while True:
                user_input = input(f"\n[Turno {self.turn_count + 1}] Tú: ")
    
                if user_input.lower() == 'exit':
                    break
                elif user_input.lower() == 'interrupt':
                    await self.client.interrupt()
                    print("¡Tarea interrumpida!")
                    continue
                elif user_input.lower() == 'new':
                    # Desconectar y reconectar para una sesión nueva
                    await self.client.disconnect()
                    await self.client.connect()
                    self.turn_count = 0
                    print("Sesión de conversación nueva iniciada (contexto anterior borrado)")
                    continue
    
                # Enviar mensaje - Claude recuerda todos los mensajes anteriores en esta sesión
                await self.client.query(user_input)
                self.turn_count += 1
    
                # Procesar respuesta
                print(f"[Turno {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()  # Nueva línea después de la respuesta
    
            await self.client.disconnect()
            print(f"Conversación finalizada después de {self.turn_count} turnos.")
    
    async def main():
        options = ClaudeAgentOptions(
            allowed_tools=["Read", "Write", "Bash"],
            permission_mode="acceptEdits"
        )
        session = ConversationSession(options)
        await session.start()
    
    # Ejemplo de conversación:
    # Turno 1 - Tú: "Crear un archivo llamado hello.py"
    # Turno 1 - Claude: "Crearé un archivo hello.py para ti..."
    # Turno 2 - Tú: "¿Qué hay en ese archivo?"
    # Turno 2 - Claude: "El archivo hello.py que acabo de crear contiene..." (¡recuerda!)
    # Turno 3 - Tú: "Agregar una función main a él"
    # Turno 3 - Claude: "Agregaré una función main a hello.py..." (¡sabe qué archivo!)
    
    asyncio.run(main())

    Usar Hooks para Modificación de Comportamiento

    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions,
        HookMatcher,
        HookContext
    )
    import asyncio
    from typing import Any
    
    async def pre_tool_logger(
        input_data: dict[str, Any],
        tool_use_id: str | None,
        context: HookContext
    ) -> dict[str, Any]:
        """Registrar todo el uso de herramientas antes de la ejecución."""
        tool_name = input_data.get('tool_name', 'unknown')
        print(f"[PRE-TOOL] A punto de usar: {tool_name}")
    
        # Puedes modificar o bloquear la ejecución de la herramienta aquí
        if tool_name == "Bash" and "rm -rf" in str(input_data.get('tool_input', {})):
            return {
                'hookSpecificOutput': {
                    'hookEventName': 'PreToolUse',
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Comando peligroso bloqueado'
                }
            }
        return {}
    
    async def post_tool_logger(
        input_data: dict[str, Any],
        tool_use_id: str | None,
        context: HookContext
    ) -> dict[str, Any]:
        """Registrar resultados después de la ejecución de la herramienta."""
        tool_name = input_data.get('tool_name', 'unknown')
        print(f"[POST-TOOL] Completado: {tool_name}")
        return {}
    
    async def user_prompt_modifier(
        input_data: dict[str, Any],
        tool_use_id: str | None,
        context: HookContext
    ) -> dict[str, Any]:
        """Agregar contexto a los mensajes del usuario."""
        original_prompt = input_data.get('prompt', '')
    
        # Agregar marca de tiempo a todos los mensajes
        from datetime import datetime
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
        return {
            'hookSpecificOutput': {
                'hookEventName': 'UserPromptSubmit',
                'updatedPrompt': f"[{timestamp}] {original_prompt}"
            }
        }
    
    async def main():
        options = ClaudeAgentOptions(
            hooks={
                'PreToolUse': [
                    HookMatcher(hooks=[pre_tool_logger]),
                    HookMatcher(matcher='Bash', hooks=[pre_tool_logger])
                ],
                'PostToolUse': [
                    HookMatcher(hooks=[post_tool_logger])
                ],
                'UserPromptSubmit': [
                    HookMatcher(hooks=[user_prompt_modifier])
                ]
            },
            allowed_tools=["Read", "Write", "Bash"]
        )
    
        async with ClaudeSDKClient(options=options) as client:
            await client.query("Listar archivos en el directorio actual")
    
            async for message in client.receive_response():
                # Los hooks registrarán automáticamente el uso de herramientas
                pass
    
    asyncio.run(main())

    Monitoreo de Progreso en Tiempo Real

    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions,
        AssistantMessage,
        ToolUseBlock,
        ToolResultBlock,
        TextBlock
    )
    import asyncio
    
    async def monitor_progress():
        options = ClaudeAgentOptions(
            allowed_tools=["Write", "Bash"],
            permission_mode="acceptEdits"
        )
    
        async with ClaudeSDKClient(options=options) as client:
            await client.query(
                "Crear 5 archivos Python con diferentes algoritmos de ordenamiento"
            )
    
            # Monitorear progreso en tiempo real
            files_created = []
            async for message in client.receive_messages():
                if isinstance(message, AssistantMessage):
                    for block in message.content:
                        if isinstance(block, ToolUseBlock):
                            if block.name == "Write":
                                file_path = block.input.get("file_path", "")
                                print(f"🔨 Creando: {file_path}")
                        elif isinstance(block, ToolResultBlock):
                            print(f"✅ Ejecución de herramienta completada")
                        elif isinstance(block, TextBlock):
                            print(f"💭 Claude dice: {block.text[:100]}...")
    
                # Verificar si hemos recibido el resultado final
                if hasattr(message, 'subtype') and message.subtype in ['success', 'error']:
                    print(f"\n🎯 ¡Tarea completada!")
                    break
    
    asyncio.run(monitor_progress())

    Uso de Ejemplo

    Operaciones básicas de archivo (usando query)

    from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ToolUseBlock
    import asyncio
    
    async def create_project():
        options = ClaudeAgentOptions(
            allowed_tools=["Read", "Write", "Bash"],
            permission_mode='acceptEdits',
            cwd="/home/user/project"
        )
    
        async for message in query(
            prompt="Crear una estructura de proyecto Python con setup.py",
            options=options
        ):
            if isinstance(message, AssistantMessage):
                for block in message.content:
                    if isinstance(block, ToolUseBlock):
                        print(f"Usando herramienta: {block.name}")
    
    asyncio.run(create_project())

    Manejo de errores

    from claude_agent_sdk import (
        query,
        CLINotFoundError,
        ProcessError,
        CLIJSONDecodeError
    )
    
    try:
        async for message in query(prompt="Hola"):
            print(message)
    except CLINotFoundError:
        print("Por favor instala Claude Code: npm install -g @anthropic-ai/claude-code")
    except ProcessError as e:
        print(f"El proceso falló con código de salida: {e.exit_code}")
    except CLIJSONDecodeError as e:
        print(f"Error al analizar la respuesta: {e}")

    Modo de transmisión con cliente

    from claude_agent_sdk import ClaudeSDKClient
    import asyncio
    
    async def interactive_session():
        async with ClaudeSDKClient() as client:
            # Enviar mensaje inicial
            await client.query("¿Cómo está el clima?")
    
            # Procesar respuestas
            async for msg in client.receive_response():
                print(msg)
    
            # Enviar seguimiento
            await client.query("Cuéntame más sobre eso")
    
            # Procesar respuesta de seguimiento
            async for msg in client.receive_response():
                print(msg)
    
    asyncio.run(interactive_session())

    Usar herramientas personalizadas con ClaudeSDKClient

    from claude_agent_sdk import (
        ClaudeSDKClient,
        ClaudeAgentOptions,
        tool,
        create_sdk_mcp_server,
        AssistantMessage,
        TextBlock
    )
    import asyncio
    from typing import Any
    
    # Definir herramientas personalizadas con decorador @tool
    @tool("calculate", "Realizar cálculos matemáticos", {"expression": str})
    async def calculate(args: dict[str, Any]) -> dict[str, Any]:
        try:
            result = eval(args["expression"], {"__builtins__": {}})
            return {
                "content": [{
                    "type": "text",
                    "text": f"Resultado: {result}"
                }]
            }
        except Exception as e:
            return {
                "content": [{
                    "type": "text",
                    "text": f"Error: {str(e)}"
                }],
                "is_error": True
            }
    
    @tool("get_time", "Obtener la hora actual", {})
    async def get_time(args: dict[str, Any]) -> dict[str, Any]:
        from datetime import datetime
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        return {
            "content": [{
                "type": "text",
                "text": f"Hora actual: {current_time}"
            }]
        }
    
    async def main():
        # Crear servidor SDK MCP con herramientas personalizadas
        my_server = create_sdk_mcp_server(
            name="utilities",
            version="1.0.0",
            tools=[calculate, get_time]
        )
    
        # Configurar opciones con el servidor
        options = ClaudeAgentOptions(
            mcp_servers={"utils": my_server},
            allowed_tools=[
                "mcp__utils__calculate",
                "mcp__utils__get_time"
            ]
        )
    
        # Usar ClaudeSDKClient para uso interactivo de herramientas
        async with ClaudeSDKClient(options=options) as client:
            await client.query("¿Cuánto es 123 * 456?")
    
            # Procesar respuesta de cálculo
            async for message in client.receive_response():
                if isinstance(message, AssistantMessage):
                    for block in message.content:
                        if isinstance(block, TextBlock):
                            print(f"Cálculo: {block.text}")
    
            # Seguimiento con consulta de hora
            await client.query("¿Qué hora es ahora?")
    
            async for message in client.receive_response():
                if isinstance(message, AssistantMessage):
                    for block in message.content:
                        if isinstance(block, TextBlock):
                            print(f"Hora: {block.text}")
    
    asyncio.run(main())

    Configuración de Sandbox

    SandboxSettings

    Configuración para el comportamiento del sandbox. Utiliza esto para habilitar el sandboxing de comandos y configurar restricciones de red mediante programación.

    class SandboxSettings(TypedDict, total=False):
        enabled: bool
        autoAllowBashIfSandboxed: bool
        excludedCommands: list[str]
        allowUnsandboxedCommands: bool
        network: SandboxNetworkConfig
        ignoreViolations: SandboxIgnoreViolations
        enableWeakerNestedSandbox: bool
    PropiedadTipoPredeterminadoDescripción
    enabledboolFalseHabilitar modo sandbox para ejecución de comandos
    autoAllowBashIfSandboxedboolFalseAprobar automáticamente comandos bash cuando el sandbox está habilitado
    excludedCommandslist[str][]Comandos que siempre omiten restricciones de sandbox (p. ej., ["docker"]). Estos se ejecutan sin sandbox automáticamente sin intervención del modelo

    Las restricciones de acceso al sistema de archivos y red NO se configuran a través de la configuración de sandbox. En su lugar, se derivan de reglas de permisos:

    • Restricciones de lectura del sistema de archivos: Reglas de denegación de lectura
    • Restricciones de escritura del sistema de archivos: Reglas de permiso/denegación de edición
    • Restricciones de red: Reglas de permiso/denegación de WebFetch

    Utiliza la configuración de sandbox para sandboxing de ejecución de comandos, y reglas de permisos para control de acceso al sistema de archivos y red.

    Ejemplo de uso

    from claude_agent_sdk import query, ClaudeAgentOptions, SandboxSettings
    
    sandbox_settings: SandboxSettings = {
        "enabled": True,
        "autoAllowBashIfSandboxed": True,
        "excludedCommands": ["docker"],
        "network": {
            "allowLocalBinding": True,
            "allowUnixSockets": ["/var/run/docker.sock"]
        }
    }
    
    async for message in query(
        prompt="Construir y probar mi proyecto",
        options=ClaudeAgentOptions(sandbox=sandbox_settings)
    ):
        print(message)

    SandboxNetworkConfig

    Configuración específica de red para modo sandbox.

    class SandboxNetworkConfig(TypedDict, total=False):
        allowLocalBinding: bool
        allowUnixSockets: list[str]
        allowAllUnixSockets: bool
        httpProxyPort: int
        socksProxyPort: int
    PropiedadTipoPredeterminadoDescripción
    allowLocalBindingboolFalsePermitir que los procesos se vinculen a puertos locales (p. ej., para servidores de desarrollo)
    allowUnixSocketslist[str][]Rutas de socket Unix que los procesos pueden acceder (p. ej., socket de Docker)
    allowAllUnixSocketsboolFalsePermitir acceso a todos los sockets Unix

    SandboxIgnoreViolations

    Configuración para ignorar violaciones de sandbox específicas.

    class SandboxIgnoreViolations(TypedDict, total=False):
        file: list[str]
        network: list[str]
    PropiedadTipoPredeterminadoDescripción
    filelist[str][]Patrones de ruta de archivo para ignorar violaciones
    networklist[str][]Patrones de red para ignorar violaciones

    Fallback de Permisos para Comandos Sin Sandbox

    Cuando allowUnsandboxedCommands está habilitado, el modelo puede solicitar ejecutar comandos fuera del sandbox estableciendo dangerouslyDisableSandbox: True en la entrada de la herramienta. Estas solicitudes vuelven al sistema de permisos existente, lo que significa que se invocará tu manejador can_use_tool, permitiéndote implementar lógica de autorización personalizada.

    excludedCommands vs allowUnsandboxedCommands:

    • excludedCommands: Una lista estática de comandos que siempre omiten el sandbox automáticamente (p. ej., ["docker"]). El modelo no tiene control sobre esto.
    • allowUnsandboxedCommands: Permite que el modelo decida en tiempo de ejecución si solicitar ejecución sin sandbox estableciendo dangerouslyDisableSandbox: True en la entrada de la herramienta.
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async def can_use_tool(tool: str, input: dict) -> bool:
        # Verificar si el modelo está solicitando omitir el sandbox
        if tool == "Bash" and input.get("dangerouslyDisableSandbox"):
            # El modelo quiere ejecutar este comando fuera del sandbox
            print(f"Comando sin sandbox solicitado: {input.get('command')}")
    
            # Devolver True para permitir, False para denegar
            return is_command_authorized(input.get("command"))
        return True
    
    async def main():
        async for message in query(
            prompt="Desplegar mi aplicación",
            options=ClaudeAgentOptions(
                sandbox={
                    "enabled": True,
                    "allowUnsandboxedCommands": True  # El modelo puede solicitar ejecución sin sandbox
                },
                permission_mode="default",
                can_use_tool=can_use_tool
            )
        ):
            print(message)

    Este patrón te permite:

    • Auditar solicitudes del modelo: Registrar cuándo el modelo solicita ejecución sin sandbox
    • Implementar listas de permitidos: Solo permitir que comandos específicos se ejecuten sin sandbox
    • Agregar flujos de trabajo de aprobación: Requerir autorización explícita para operaciones privilegiadas

    Los comandos que se ejecutan con dangerouslyDisableSandbox: True tienen acceso completo al sistema. Asegúrate de que tu manejador can_use_tool valide estas solicitudes cuidadosamente.

    Ver también

    • Guía del SDK de Python - Tutorial y ejemplos
    • Descripción general del SDK - Conceptos generales del SDK
    • Referencia del SDK de TypeScript - Documentación del SDK de TypeScript
    • Referencia de CLI - Interfaz de línea de comandos
    • Flujos de trabajo comunes - Guías paso a paso
    enable_file_checkpointing=True
    Punto de control de archivos
    disconnect()Desconecta de Claude
    {}
    Configuraciones del servidor MCP o ruta al archivo de configuración
    permission_modePermissionMode | NoneNoneModo de permiso para el uso de herramientas
    continue_conversationboolFalseContinuar la conversación más reciente
    resumestr | NoneNoneID de sesión a reanudar
    max_turnsint | NoneNoneMáximo de turnos de conversación
    disallowed_toolslist[str][]Lista de nombres de herramientas no permitidas
    enable_file_checkpointingboolFalseHabilitar seguimiento de cambios de archivos para rebobinar. Ver Punto de control de archivos
    modelstr | NoneNoneModelo de Claude a usar
    output_formatOutputFormat | NoneNoneDefinir formato de salida para resultados del agente. Ver Salidas estructuradas para detalles
    permission_prompt_tool_namestr | NoneNoneNombre de herramienta MCP para prompts de permiso
    cwdstr | Path | NoneNoneDirectorio de trabajo actual
    settingsstr | NoneNoneRuta al archivo de configuración
    add_dirslist[str | Path][]Directorios adicionales a los que Claude puede acceder
    envdict[str, str]{}Variables de entorno
    extra_argsdict[str, str | None]{}Argumentos CLI adicionales a pasar directamente a la CLI
    max_buffer_sizeint | NoneNoneMáximo de bytes al almacenar en búfer la salida estándar de CLI
    debug_stderrAnysys.stderrDeprecado - Objeto similar a un archivo para salida de depuración. Usa el callback stderr en su lugar
    stderrCallable[[str], None] | NoneNoneFunción de callback para salida de stderr desde CLI
    can_use_toolCanUseTool | NoneNoneFunción de callback de permiso de herramienta
    hooksdict[HookEvent, list[HookMatcher]] | NoneNoneConfiguraciones de hook para interceptar eventos
    userstr | NoneNoneIdentificador de usuario
    include_partial_messagesboolFalseIncluir eventos de transmisión de mensajes parciales
    fork_sessionboolFalseAl reanudar con resume, bifurcar a un nuevo ID de sesión en lugar de continuar la sesión original
    agentsdict[str, AgentDefinition] | NoneNoneSuagentes definidos programáticamente
    pluginslist[SdkPluginConfig][]Cargar plugins personalizados desde rutas locales. Ver Plugins para detalles
    sandboxSandboxSettings | NoneNoneConfigurar el comportamiento del sandbox programáticamente. Ver Configuración del sandbox para detalles
    setting_sourceslist[SettingSource] | NoneNone (sin configuración)Controlar qué configuraciones del sistema de archivos cargar. Cuando se omite, no se carga ninguna configuración. Nota: Debe incluir "project" para cargar archivos CLAUDE.md
    allowUnsandboxedCommandsboolFalsePermitir que el modelo solicite ejecutar comandos fuera del sandbox. Cuando es True, el modelo puede establecer dangerouslyDisableSandbox en la entrada de la herramienta, que vuelve al sistema de permisos
    networkSandboxNetworkConfigNoneConfiguración de sandbox específica de red
    ignoreViolationsSandboxIgnoreViolationsNoneConfigurar qué violaciones de sandbox ignorar
    enableWeakerNestedSandboxboolFalseHabilitar un sandbox anidado más débil para compatibilidad
    httpProxyPort
    int
    None
    Puerto proxy HTTP para solicitudes de red
    socksProxyPortintNonePuerto proxy SOCKS para solicitudes de red