Download the PHP package icdev/claude-agent-sdk-php without Composer

On this page you can find all versions of the php package icdev/claude-agent-sdk-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package claude-agent-sdk-php

claude-agent-sdk-php

Port en PHP de @anthropic-ai/claude-agent-sdk.

Framework-agnóstico a propósito. Sin dependencias más allá de php >= 8.2 y ext-json. Pensado como base sobre la que montar integraciones (Laravel, Symfony, CLI propio) en paquetes separados.

La idea clave

El SDK de TypeScript no es un cliente de la API. Es un envoltorio de ~1.3 MB alrededor del binario claude (Claude Code), al que lanza como subproceso y con el que habla NDJSON por stdin/stdout:

El harness del agente —el bucle, las herramientas integradas (Read, Write, Edit, Bash, Glob, Grep, WebFetch…), la compactación de contexto, los subagentes, los permisos, las sesiones— vive dentro del binario. Por eso portarlo a PHP no significa reimplementar un agente: significa implementar dos protocolos.

1. Protocolo de mensajes (NDJSON, una línea por objeto)

Dirección Tipos
PHP → CLI user
CLI → PHP system (subtype: init), assistant, user (tool_result), stream_event, result, rate_limit_event

2. Protocolo de control (bidireccional, sobre el mismo canal)

PHP → CLI: initialize, interrupt, set_permission_mode, set_model, mcp_set_servers CLI → PHP: can_use_tool, hook_callback, mcp_message

initialize es obligatorio y es donde viajan systemPrompt, appendSystemPrompt, agents, settingSources, hooks y sdkMcpServers — no son flags de CLI.

Uso

Multi-turno con sesión viva:

Herramientas MCP dentro del proceso PHP (con tu Eloquent / PDO / contenedor DI):

Subagentes, plugins y sandbox

Los tres son opciones tipadas. Cada uno viaja por un canal distinto — ese es el detalle que hay que respetar:

Opción Tipo Canal
agents array<string, Agent> payload de initialize
plugins list<Plugin> flags --plugin-dir / --plugin-dir-no-mcp
sandbox Sandbox JSON inline en --settings, bajo la clave sandbox

Atajos: Sandbox::enabled() y Sandbox::locked(allowedDomains: [...], allowWrite: [...]).

Enums para lo que era string: PermissionMode, Effort, MemoryScope.

Credenciales

Sandbox::$credentials está tipado por completo. deny bloquea la lectura; mask muestra un centinela dentro del sandbox y el proxy del host sustituye centinela→real al salir hacia injectHosts.

Enums: CredentialMode, DecodeFormat, NoMatchBehavior, Sigv4Policy.

Las reglas se validan al construir, no al arrancar el CLI (que es permisivo con settings y descarta entradas inválidas en silencio). Ojo con la asimetría entre files y envVars, que es real en upstream:

Regla files envVars
extract necesita ≥1 grupo de captura sí sí
maskClaims requiere decode y claims no vacíos sí sí
extract + decode juntos permitido (extract afina el localizador JWT) prohibido
onExtractNoMatch fail-closed con decode permitido prohibido (decode es fail-open)
maskDuplicates sí no existe
mask sobre directorio (path con / final) prohibido n/a
Nombre válido ^[A-Za-z_][A-Za-z0-9_]*$ n/a sí
Cada var en un solo slot de awsPairs — sí (dentro y entre pares)

En una entrada deny los campos solo-de-mask son "aceptados pero ignorados" upstream, así que no se validan — rechazarlos descartaría configs que el CLI acepta.

Trampas que cuestan horas

  1. canUseTool no se dispara sin --permission-prompt-tool stdio. Sin ese flag el callback queda muerto y no hay error. Lo emite Options solo.
  2. allowedTools auto-aprueba. Si pones Bash ahí, canUseTool nunca se invoca para Bash. Para restringir qué herramientas existen usa tools; para pre-aprobar usa allowedTools. Son ejes distintos.
  3. Las notificaciones MCP necesitan envelope. Un notifications/initialized respondido con {} deja el servidor en status: "failed" y las herramientas nunca aparecen. Hay que devolver {"mcp_response":{"jsonrpc":"2.0","result":{},"id":0}}.
  4. Los servidores MCP en-proceso no van en --mcp-config. Solo en la lista sdkMcpServers del initialize.
  5. stderr hay que drenarlo. Si se llena el pipe y tú bloqueas leyendo stdout, deadlock. CliTransport usa stream_select sobre ambos descriptores.
  6. El CLI puede pedirte algo mientras esperas tu propia respuesta de control. Si no atiendes ese control_request intermedio, deadlock. Client::control() lo maneja y encola los mensajes SDK que lleguen fuera de orden.
  7. sandbox y una ruta de settings son excluyentes. Ambos usan --settings. Options lo detecta al construir los args, no al arrancar. Si pasas $settings como JSON inline, se hace merge y sandbox gana.
  8. enabled: true fuerza failIfUnavailable: true. Igual que upstream: activar el sandbox sin decir qué pasa si no está disponible no debe terminar ejecutando sin sandbox. Si falta bubblewrap, el CLI aborta en el initialize.
  9. El tool de despacho de subagentes es Agent, no Task, desde CLI 2.1.x.

Limitaciones de esta versión

¿Es esto lo que necesitas?

Seams para envolverlo desde un framework

Lo relevante si vas a construir una capa encima:

Punto de extensión Cómo
Construcción del cliente new Client(Options $options) — inyectable tal cual; Options es un value object con props promovidas públicas.
Config declarativa Options solo tiene constructor con named args. Si vas a mapear desde un array de config, añade un Options::fromArray() en la capa de arriba, no aquí.
Logging Options::$onStderr es un Closure(string): void. Ahí engancha un PSR-3 sin que este paquete dependa de PSR-3.
Binario Options::$cliPath fuerza la ruta; si no, CliTransport::locateCli() escanea PATH en PHP puro.
Herramientas de dominio SdkMcpServer corre en tu proceso: los handlers pueden resolver del contenedor DI.
Ciclo de vida Client::start() es idempotente y lazy; close() mata el subproceso. Un job largo puede mantener la sesión abierta entre turnos.

Dos cosas a tener presentes en contexto web (php-fpm), ya cubiertas aquí: proc_open debe estar habilitada (se valida con un error claro), y la resolución del binario no usa shell_exec porque suele estar en disable_functions.

Tests

Los unitarios no tocan la red. tests/Fixtures/fake-cli.php es un doble del binario claude que habla el mismo protocolo NDJSON + control, elegido por escenario con FAKE_CLI_SCENARIO, y Options::$cliPath lo enchufa. Eso permite probar el protocolo de control de verdad —incluidos los deadlocks— sin gastar tokens.

Los de integración se saltan solos salvo que definas CLAUDE_SDK_INTEGRATION=1.

Cuatro tests cubren las trampas de arriba, y verifiqué por mutación que fallan si se quita la protección:

Test Mutación aplicada Resultado
testAFloodOfStderrDoesNotDeadlock… quitar stderr de stream_select cuelga
testTheCliMayAskSomethingWhileWeAwait… ignorar control_request reentrante cuelga
testSdkMessagesArrivingBefore…AreNotLost descartar la cola fuera de orden falla
testMcpRequestsAndNotifications… responder {} a notificaciones MCP falla

Requisitos

PHP ≥ 8.2 y el binario claude en el PATH:

Verificado contra

Claude Code CLI 2.1.240 · PHP 8.5 · protocolo del SDK TS 0.3.235

agents, plugins, sandbox y credentials se verificaron por diff contra el SDK de TypeScript real: se lanza el SDK TS con un ejecutable falso que captura su argv y su initialize, se genera la misma config en PHP, y se comparan. Resultado: --settings (sandbox + credentials completo) y el payload agents son idénticos. La única diferencia de argv es --thinking adaptive, que este puerto añade por defecto y upstream omite.

Esa comparación es necesaria porque el CLI no valida el schema de settings: acepta credentials.envVars[].mode: "bogus" sin protestar. Un arranque exitoso no prueba que la config esté bien formada.


All versions of claude-agent-sdk-php with dependencies

PHP Build Version
Package Version
Requires php Version >=8.2
ext-json Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package icdev/claude-agent-sdk-php contains the following files

Loading the files please wait ...