PHPackages                             mohamed-ashraf-elsaed/claude-agent-sdk-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. mohamed-ashraf-elsaed/claude-agent-sdk-laravel

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

mohamed-ashraf-elsaed/claude-agent-sdk-laravel
==============================================

Anthropic Claude Agent SDK for PHP &amp; Laravel — build AI agents with tool use, sandboxing, MCP servers, subagents, hooks, and structured output via the Claude Code CLI

v1.3.1(3mo ago)171.1k↓82.1%4MITPHPPHP ^8.1|^8.2|^8.3|^8.4CI passing

Since Feb 22Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[ Packagist](https://packagist.org/packages/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[ Docs](https://github.com/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[ GitHub Sponsors](https://github.com/mohamed-ashraf-elsaed)[ RSS](/packages/mohamed-ashraf-elsaed-claude-agent-sdk-laravel/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (3)Dependencies (12)Versions (11)Used By (0)

Claude Agent SDK for Laravel
============================

[](#claude-agent-sdk-for-laravel)

[![Tests](https://github.com/mohamed-ashraf-elsaed/claude-agent-sdk-laravel/actions/workflows/tests.yml/badge.svg)](https://github.com/mohamed-ashraf-elsaed/claude-agent-sdk-laravel/actions)[![Latest Version](https://camo.githubusercontent.com/b7302e1aeff4e8c3923cd3761d0092fef8466ed7972f328f5c090748f1921ec1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f68616d65642d6173687261662d656c736165642f636c617564652d6167656e742d73646b2d6c61726176656c2e737667)](https://packagist.org/packages/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[![Total Downloads](https://camo.githubusercontent.com/659e40d73cc0201606b9e08ddc8ceed740f0fc4d1a40dda2126047ff50d1f1bc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f68616d65642d6173687261662d656c736165642f636c617564652d6167656e742d73646b2d6c61726176656c2e737667)](https://packagist.org/packages/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[![PHP Version](https://camo.githubusercontent.com/9fb31e1aafad92ba6fc5bad564c6ec84536fefdd278556fae51fbe377d58605b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d6f68616d65642d6173687261662d656c736165642f636c617564652d6167656e742d73646b2d6c61726176656c2e737667)](https://packagist.org/packages/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)[![Laravel](https://camo.githubusercontent.com/57b3a863c6bd691c3566277f0e9aaa31fdb411989eaf71edfb4249e03303e535/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532302537432532303131253230253743253230313225323025374325323031332d7265642e737667)](https://laravel.com)[![License](https://camo.githubusercontent.com/42f6b1b30972c5e2c70b08fbaa73c5169fd23628fbb42c5cfec8228f04374af1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d6f68616d65642d6173687261662d656c736165642f636c617564652d6167656e742d73646b2d6c61726176656c2e737667)](LICENSE)

Build AI agents with Claude Code as a library in your Laravel applications. This SDK wraps the Claude Code CLI to give your app access to file operations, bash commands, code editing, web search, subagents, and more.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, or 12 and 13
- Claude Code CLI (`npm install -g @anthropic-ai/claude-code`)
- Anthropic API key

Installation
------------

[](#installation)

```
composer require mohamed-ashraf-elsaed/claude-agent-sdk-laravel
```

Publish the config:

```
php artisan vendor:publish --tag=claude-agent-config
```

Add your API key to `.env`:

```
ANTHROPIC_API_KEY=your-api-key
```

Quick Start
-----------

[](#quick-start)

### Simple Query

[](#simple-query)

```
use ClaudeAgentSDK\Facades\ClaudeAgent;

$result = ClaudeAgent::query('What files are in this directory?');

echo $result->text();       // Final text result
echo $result->costUsd();    // Cost in USD
echo $result->sessionId;    // Session ID for resuming
```

### With Options (Fluent API)

[](#with-options-fluent-api)

```
use ClaudeAgentSDK\Options\ClaudeAgentOptions;

$options = ClaudeAgentOptions::make()
    ->tools(['Read', 'Edit', 'Bash', 'Grep', 'Glob'])
    ->permission('acceptEdits')
    ->maxTurns(10)
    ->maxBudgetUsd(5.00)
    ->cwd('/path/to/project');

$result = ClaudeAgent::query('Find and fix the bug in auth.php', $options);

if ($result->isSuccess()) {
    echo $result->text();
}
```

### Streaming Responses

[](#streaming-responses)

```
use ClaudeAgentSDK\Messages\AssistantMessage;
use ClaudeAgentSDK\Messages\ResultMessage;

foreach (ClaudeAgent::stream('Refactor the User model') as $message) {
    if ($message instanceof AssistantMessage) {
        echo $message->text();
    }

    if ($message instanceof ResultMessage) {
        echo "\nDone! Cost: $" . $message->totalCostUsd;
    }
}
```

### Stream with Callback

[](#stream-with-callback)

```
$result = ClaudeAgent::streamCollect(
    prompt: 'Create a REST API for products',
    onMessage: function ($message) {
        if ($message instanceof AssistantMessage) {
            Log::info($message->text());
        }
    },
    options: ClaudeAgentOptions::make()->tools(['Read', 'Write', 'Bash']),
);

echo $result->text();
```

Options Reference
-----------------

[](#options-reference)

### Fluent Builder

[](#fluent-builder)

```
$options = ClaudeAgentOptions::make()
    ->tools(['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob'])
    ->disallow(['WebFetch'])
    ->model('claude-sonnet-4-5-20250929')
    ->permission('acceptEdits')
    ->maxTurns(15)
    ->maxBudgetUsd(10.00)
    ->maxThinkingTokens(8000)
    ->fallbackModel('claude-haiku-4-5')
    ->cwd('/path/to/project')
    ->env('MY_VAR', 'value')
    ->settingSources(['project'])
    ->useClaudeCodePrompt('Also follow PSR-12.')
    ->betas(['context-1m-2025-08-07'])
    ->permissionPromptToolName('my_custom_tool')
    ->resumeSessionAt('2025-01-15T10:30:00Z')
    ->allowDangerouslySkipPermissions();
```

### From Array

[](#from-array)

```
$options = ClaudeAgentOptions::fromArray([
    'allowed_tools' => ['Read', 'Bash'],
    'permission_mode' => 'bypassPermissions',
    'max_turns' => 5,
    'max_budget_usd' => 5.00,
    'max_thinking_tokens' => 10000,
]);
```

### System Prompts

[](#system-prompts)

```
// Custom string
$options->systemPrompt('You are a Laravel expert. Always use Eloquent.');

// Claude Code preset (includes default agent behavior)
$options->useClaudeCodePrompt();

// Claude Code preset with additions
$options->useClaudeCodePrompt('Follow PSR-12 and use strict types.');
```

### Permission Modes

[](#permission-modes)

ModeBehavior`default`Ask for permission on each tool use`acceptEdits`Auto-accept file edits, ask for others`dontAsk`Don't ask but log decisions`bypassPermissions`Skip all permission checks`plan`Create a plan but don't execute### Custom Permission Handler

[](#custom-permission-handler)

For fine-grained control over tool permissions, use `canUseTool()` to register a callback that approves, denies, or modifies each tool invocation:

```
use ClaudeAgentSDK\Permissions\PermissionResultAllow;
use ClaudeAgentSDK\Permissions\PermissionResultDeny;

$options = ClaudeAgentOptions::make()
    ->canUseTool(function (string $toolName, array $input) {
        if ($toolName === 'Bash' && str_contains($input['command'] ?? '', 'rm -rf')) {
            return new PermissionResultDeny('Destructive commands not allowed');
        }
        if ($toolName === 'Write') {
            return new PermissionResultAllow(
                updatedInput: array_merge($input, ['file_path' => '/sandbox' . $input['file_path']])
            );
        }
        return new PermissionResultAllow();
    });
```

Return `PermissionResultAllow` to approve (optionally with modified input), or `PermissionResultDeny` with a reason to block the tool call.

Hooks
-----

[](#hooks)

Run shell commands before or after Claude uses tools. The SDK supports all 12 hook events:

`PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `UserPromptSubmit`, `Notification`, `SessionStart`, `SessionEnd`, `Stop`, `SubagentStart`, `SubagentStop`, `PreCompact`, `PermissionRequest`

```
use ClaudeAgentSDK\Hooks\HookEvent;
use ClaudeAgentSDK\Hooks\HookMatcher;

$options = ClaudeAgentOptions::make()
    ->tools(['Read', 'Edit', 'Bash'])
    // Shorthand methods
    ->preToolUse('php artisan lint:check', '/Edit|Write/', 30)
    ->postToolUse('php artisan test:affected')
    // Or use hook() directly for any event
    ->hook(HookEvent::Stop, HookMatcher::command('php /hooks/cleanup.php'))
    ->hook(HookEvent::SessionStart, HookMatcher::command('php /hooks/init.php'))
    ->hook(HookEvent::SubagentStop, HookMatcher::command('php /hooks/subagent-done.php'));

$result = ClaudeAgent::query('Refactor the User model', $options);
```

### HookMatcher Factory Methods

[](#hookmatcher-factory-methods)

```
// From a shell command
$matcher = HookMatcher::command('eslint --fix', '/Edit|Write/', 60);

// From a PHP script
$matcher = HookMatcher::phpScript('/hooks/validate.php', '/Bash/', 10);

// Full control
$matcher = new HookMatcher(
    matcher: '/Edit|Write/',
    hooks: ['php /hooks/lint.php', 'php /hooks/backup.php'],
    timeout: 30,
);
```

Subagents
---------

[](#subagents)

Define specialized agents that Claude delegates tasks to:

```
use ClaudeAgentSDK\Agents\AgentDefinition;

$options = ClaudeAgentOptions::make()
    ->tools(['Read', 'Grep', 'Glob', 'Task'])
    ->agent('security-reviewer', new AgentDefinition(
        description: 'Security code review specialist',
        prompt: 'You are a security expert. Find vulnerabilities in PHP/Laravel code.',
        tools: ['Read', 'Grep', 'Glob'],
        model: 'sonnet',
    ))
    ->agent('test-writer', new AgentDefinition(
        description: 'PHPUnit test writer',
        prompt: 'Write comprehensive PHPUnit tests for Laravel applications.',
        tools: ['Read', 'Write', 'Bash'],
    ));

$result = ClaudeAgent::query('Review the auth module for security issues', $options);
```

Structured Output
-----------------

[](#structured-output)

Get validated JSON responses matching a schema:

```
$options = ClaudeAgentOptions::make()
    ->tools(['Read', 'Grep', 'Glob'])
    ->outputFormat([
        'type' => 'object',
        'properties' => [
            'issues' => [
                'type' => 'array',
                'items' => [
                    'type' => 'object',
                    'properties' => [
                        'file' => ['type' => 'string'],
                        'line' => ['type' => 'number'],
                        'severity' => ['type' => 'string', 'enum' => ['low', 'medium', 'high']],
                        'description' => ['type' => 'string'],
                    ],
                    'required' => ['file', 'severity', 'description'],
                ],
            ],
            'total' => ['type' => 'number'],
        ],
        'required' => ['issues', 'total'],
    ]);

$result = ClaudeAgent::query('Find all TODO comments in src/', $options);
$data = $result->structured(); // Validated array matching schema
```

Session Resumption
------------------

[](#session-resumption)

Continue conversations across multiple queries:

```
// First query
$result = ClaudeAgent::query('Read the auth module');
$sessionId = $result->sessionId;

// Resume later with full context
$result2 = ClaudeAgent::query(
    'Now find all places that call it',
    ClaudeAgentOptions::make()->resume($sessionId),
);

// Fork a session to try different approaches
$result3 = ClaudeAgent::query(
    'Try refactoring it with a different pattern',
    ClaudeAgentOptions::make()->resume($sessionId, fork: true),
);
```

MCP Servers
-----------

[](#mcp-servers)

Connect external tools via Model Context Protocol:

```
use ClaudeAgentSDK\Tools\McpServerConfig;

// Stdio transport
$options = ClaudeAgentOptions::make()
    ->mcpServer('database', McpServerConfig::stdio(
        command: 'npx',
        args: ['@modelcontextprotocol/server-database'],
        env: ['DB_URL' => config('database.url')],
    ))
    ->tools(['mcp__database__query', 'Read']);

$result = ClaudeAgent::query('Show me the latest users', $options);

// SSE transport
$options = ClaudeAgentOptions::make()
    ->mcpServer('api', McpServerConfig::sse(
        url: 'http://localhost:3000/mcp',
        headers: ['Authorization' => 'Bearer ' . config('services.mcp.token')],
    ));

// HTTP transport
$options = ClaudeAgentOptions::make()
    ->mcpServer('api', McpServerConfig::http(
        url: 'http://localhost:3000/mcp',
        headers: ['Authorization' => 'Bearer ' . config('services.mcp.token')],
    ));
```

Working with Results
--------------------

[](#working-with-results)

```
$result = ClaudeAgent::query('Analyze this codebase');

// Basic info
$result->text();              // Final text result
$result->isSuccess();         // bool — true if subtype is 'success'
$result->isError();           // bool — true if error or no result
$result->costUsd();           // float|null — total cost in USD
$result->turns();             // int — number of conversation turns
$result->durationMs();        // int — total duration in milliseconds
$result->sessionId;           // string|null — for session resumption

// Error types
$result->subtype();              // 'success', 'error_max_turns', 'error_max_budget_usd', etc.
$result->isMaxTurnsError();      // true if stopped at turn limit
$result->isBudgetError();        // true if budget exceeded
$result->permissionDenials();    // array of denied tool uses
$result->errors();               // array of execution errors

// Session introspection
$result->model();                // Model used
$result->availableTools();       // Tools available
$result->mcpServerStatus();      // MCP server statuses
$result->supportedCommands();    // Available slash commands

// Messages
$result->messages;            // All Message objects
$result->assistantMessages(); // AssistantMessage[] only
$result->fullText();          // Concatenated text from all assistant messages
$result->toolUses();          // All ToolUseBlock objects across messages
$result->structured();        // Structured output array (if outputFormat set)

// Per-model usage & cache metrics
$result->modelUsage();        // array — per-model breakdown
$result->cacheReadTokens();   // int — total cache-read tokens across all models
$result->cacheCreationTokens(); // int — total cache-creation tokens

foreach ($result->modelUsage() as $model => $usage) {
    echo "{$model}: {$usage->inputTokens} in, {$usage->outputTokens} out\n";
    echo "  Cache hit rate: " . round($usage->cacheHitRate() * 100) . "%\n";
    echo "  Cost: \${$usage->costUsd}\n";
}
```

Working with Messages
---------------------

[](#working-with-messages)

```
use ClaudeAgentSDK\Messages\AssistantMessage;
use ClaudeAgentSDK\Messages\SystemMessage;
use ClaudeAgentSDK\Messages\ResultMessage;

foreach (ClaudeAgent::stream('Do something') as $message) {
    match (true) {
        $message instanceof SystemMessage => handleSystem($message),
        $message instanceof AssistantMessage => handleAssistant($message),
        $message instanceof ResultMessage => handleResult($message),
        default => null,
    };
}

function handleAssistant(AssistantMessage $msg): void
{
    // Text content
    echo $msg->text();

    // Tool calls made by Claude
    foreach ($msg->toolUses() as $toolUse) {
        echo "Tool: {$toolUse->name}, Input: " . json_encode($toolUse->input);
    }

    // Metadata
    echo $msg->model;            // Model used
    echo $msg->id;               // Message ID
    echo $msg->parentToolUseId;  // If this is a subagent response
}
```

Default Options via Config
--------------------------

[](#default-options-via-config)

Set defaults in `config/claude-agent.php` or `.env`:

```
CLAUDE_AGENT_MODEL=claude-sonnet-4-5-20250929
CLAUDE_AGENT_PERMISSION_MODE=acceptEdits
CLAUDE_AGENT_MAX_TURNS=10
CLAUDE_AGENT_MAX_BUDGET_USD=10.00
CLAUDE_AGENT_MAX_THINKING_TOKENS=8000
CLAUDE_AGENT_CWD=/var/www/project
CLAUDE_AGENT_TIMEOUT=300
CLAUDE_AGENT_CLI_PATH=/usr/local/bin/claude
```

Options passed to `query()` override config defaults.

Advanced: Sandbox, Plugins &amp; Betas
--------------------------------------

[](#advanced-sandbox-plugins--betas)

```
// Run in a sandboxed environment with command isolation
$options = ClaudeAgentOptions::make()
    ->sandbox([
        'enabled' => true,
        'autoAllowBashIfSandboxed' => true,
        'excludedCommands' => ['docker'],
        'network' => [
            'allowLocalBinding' => true,
            'allowUnixSockets' => ['/var/run/docker.sock'],
        ],
    ]);

// Load a local plugin
$options = ClaudeAgentOptions::make()
    ->plugin('/path/to/my-plugin');

// Enable beta features
$options = ClaudeAgentOptions::make()
    ->betas(['context-1m-2025-08-07']);

// Set a fallback model
$options = ClaudeAgentOptions::make()
    ->model('claude-sonnet-4-5-20250929')
    ->fallbackModel('claude-haiku-4-5');
```

### Stderr Monitoring

[](#stderr-monitoring)

Capture diagnostic output from the Claude CLI process:

```
$options = ClaudeAgentOptions::make()
    ->stderr(function (string $data) {
        Log::warning('Claude CLI stderr: ' . $data);
    });
```

### Interrupt &amp; Lifecycle

[](#interrupt--lifecycle)

Control a running Claude process programmatically:

```
$manager = app('claude-agent');
$manager->interrupt();    // Graceful interrupt (sends SIGINT to the process)
$manager->isRunning();    // Check if a process is currently running
```

Error Handling
--------------

[](#error-handling)

```
use ClaudeAgentSDK\Exceptions\CliNotFoundException;
use ClaudeAgentSDK\Exceptions\ProcessException;
use ClaudeAgentSDK\Exceptions\JsonParseException;
use ClaudeAgentSDK\Exceptions\ClaudeAgentException;

try {
    $result = ClaudeAgent::query('Do something');
} catch (CliNotFoundException $e) {
    // Claude Code CLI not installed
    // $e->getMessage() includes install instructions
} catch (ProcessException $e) {
    echo $e->exitCode;   // Process exit code
    echo $e->stderr;     // Standard error output
} catch (JsonParseException $e) {
    echo $e->rawLine;    // The malformed JSON line
    echo $e->originalError; // The underlying JsonException
} catch (ClaudeAgentException $e) {
    // General SDK error
}
```

Testing
-------

[](#testing)

```
composer test
```

To run with coverage:

```
vendor/bin/phpunit --coverage-html coverage/
```

Support
-------

[](#support)

If you find this package useful, please consider giving it a star on GitHub. It helps others discover the package and motivates continued development.

[![GitHub stars](https://camo.githubusercontent.com/9713317363a5456d0f5a36b6e1f98eb561641a0c463f310f3a8bb025cfaf8fb1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6f68616d65642d6173687261662d656c736165642f636c617564652d6167656e742d73646b2d6c61726176656c3f7374796c653d736f6369616c)](https://github.com/mohamed-ashraf-elsaed/claude-agent-sdk-laravel)

Contributing
------------

[](#contributing)

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE) for details.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance82

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 96.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

7

Last Release

109d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cc554f2d0e27d196758e968c9aca637d84850c4bad1b4f490f9edfe38877862e?d=identicon)[MohamedAshrafElsaed](/maintainers/MohamedAshrafElsaed)

---

Top Contributors

[![mohamed-ashraf-elsaed](https://avatars.githubusercontent.com/u/110828041?v=4)](https://github.com/mohamed-ashraf-elsaed "mohamed-ashraf-elsaed (31 commits)")[![minhnhut](https://avatars.githubusercontent.com/u/6104383?v=4)](https://github.com/minhnhut "minhnhut (1 commits)")

---

Tags

agentic-aiaiai-agentai-sdkai-toolsanthropicanthropic-sdkclaudeclaude-agentclaude-apiclaude-codeclaude-laravellaravellaravel-packagellmmcpphpphp-aiphp-sdksdklaravelsdkautomationmcpailaravel-packageAgentphp-sdkcode-generationclaudellmanthropicAI SDKai-agentclaude-codephp aiai-toolsagentic-aianthropic-sdkclaude-agentclaude-apiclaude-laravel

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mohamed-ashraf-elsaed-claude-agent-sdk-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/mohamed-ashraf-elsaed-claude-agent-sdk-laravel/health.svg)](https://phpackages.com/packages/mohamed-ashraf-elsaed-claude-agent-sdk-laravel)
```

###  Alternatives

[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k95.4M307](/packages/laravel-horizon)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77022.3M151](/packages/laravel-mcp)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M201](/packages/laravel-ai)[illuminate/process

The Illuminate Process package.

44869.2k99](/packages/illuminate-process)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
