1. Conduid
  2. Developer Tools
  3. Claude Code SDK Php
MCP server · Developer Tools

Claude Code SDK Php

PHP SDK for Claude Code

Unclaimed devtools
39Low

Scored 7 months ago · breakdown

About Claude Code SDK Php

Claude Code SDK Php is an MCP server in the Developer Tools category: pHP SDK for Claude Code.

Install

From source
git clone https://github.com/HelgeSverre/claude-code-sdk-php

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Claude Code SDK Php

Powered by Claude · Grounded in docs

I know everything about Claude Code SDK Php. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

Claude Code SDK for PHP

Latest Version on Packagist Total Downloads

PHP wrapper for Claude Code. Fun fact: This SDK was built by using Claude Code to port its own Python SDK to PHP. 🤖

Stream Claude's responses, track token usage, hook into events, and integrate AI coding assistance into your PHP apps.

Installation

composer require helgesverre/claude-code-sdk

Make sure Claude Code CLI is installed:

npm install -g @anthropic-ai/claude-code

Quick Start

Basic Usage

<?php

use HelgeSverre\ClaudeCode\ClaudeCode;
use HelgeSverre\ClaudeCode\Types\Messages\AssistantMessage;
use HelgeSverre\ClaudeCode\Types\Messages\SystemMessage;
use HelgeSverre\ClaudeCode\Types\Messages\ResultMessage;
use HelgeSverre\ClaudeCode\Types\ContentBlocks\TextBlock;

// Send a query to Claude
$messages = ClaudeCode::query("What files are in the current directory?");

// Process the streaming response
foreach ($messages as $message) {
    match (true) {
        $message instanceof SystemMessage => 
            echo "[SYSTEM] {$message->subtype}\n",
            
        $message instanceof AssistantMessage => 
            array_map(function ($block) {
                if ($block instanceof TextBlock) {
                    echo "[CLAUDE] {$block->text}\n";
                }
            }, $message->content),
            
        $message instanceof ResultMessage => 
            echo "[DONE] Cost: \${$message->totalCostUsd} | Time: {$message->durationMs}ms\n",
            
        default => null
    };
}

With Options

use HelgeSverre\ClaudeCode\ClaudeCode;
use HelgeSverre\ClaudeCode\Types\Config\Options;
use HelgeSverre\ClaudeCode\Types\Enums\PermissionMode;

$options = new Options(
    systemPrompt: "You are a helpful coding assistant",
    allowedTools: ['Read', 'Write', 'Edit'],
    permissionMode: PermissionMode::acceptEdits,
    maxTurns: 5,
);


/**
 * A generator is returned, allowing you to stream messages as they are generated.
 * @var Generator<HelgeSverre\ClaudeCode\Types\Messages\Message> $messages 
 */
$messages = ClaudeCode::query("Help me refactor this code", $options);


foreach ($messages as $message) {
    if ($message instanceof AssistantMessage) {
        foreach ($message->content as $block) {
            if ($block instanceof TextBlock) {
                echo "[CLAUDE] {$block->text}\n";
            }
        }
    } elseif ($message instanceof ResultMessage) {
        echo "[DONE] Total Cost: \${$message->totalCostUsd}\n";
    }
}



Usage in Laravel

Configuration

Publish the configuration file:

php artisan vendor:publish --tag=claude-code-config

Configure your settings in config/claude-code.php or use environment variables:

CLAUDE_CODE_SYSTEM_PROMPT="You are a Laravel expert"
CLAUDE_CODE_ALLOWED_TOOLS=Read,Write,Edit
CLAUDE_CODE_PERMISSION_MODE=acceptEdits
CLAUDE_CODE_MODEL=claude-3-sonnet

Using the Facade

use HelgeSverre\ClaudeCode\Laravel\Facades\ClaudeCode;

// Simple query
$messages = ClaudeCode::query("Create a new Laravel controller");

// With custom options
$options = ClaudeCode::options()
    ->systemPrompt("You are a Laravel expert")
    ->allowedTools(['Read', 'Write', 'Edit'])
    ->maxTurns(10);

$messages = ClaudeCode::query("Help me build a REST API", $options);

Dependency Injection

use Illuminate\Support\Facades\App;

class MyService
{
    private $claude;
    
    public function __construct()
    {
        $this->claude = App::make('claude-code');
    }

    public function generateCode(string $prompt): void
    {
        $messages = $this->claude->query($prompt);
        
        foreach ($messages as $message) {
            // Process messages...
        }
    }
}

Configuration Options

Options

All configuration options available:

$options = new Options(
    // System prompt to set context
    systemPrompt: "You are a helpful assistant",
    
    // Additional system prompt to append
    appendSystemPrompt: "Always be concise",
    
    // Tools Claude can use
    allowedTools: ['Read', 'Write', 'Edit', 'Bash'],
    
    // Tools Claude cannot use
    disallowedTools: ['Delete'],
    
    // Permission handling mode
    permissionMode: PermissionMode::acceptEdits,
    
    // Custom permission prompt tool
    permissionPromptToolName: "MyCustomPrompt",
    
    // Continue existing conversation
    continueConversation: true,
    
    // Resume from session ID
    resume: "session-abc123",
    
    // Maximum conversation turns
    maxTurns: 10,
    
    // Claude model to use
    model: "claude-3-sonnet",
    
    // Working directory
    cwd: "/path/to/project",
    
    // MCP server configurations
    mcpServers: [
        'my-server' => new \HelgeSverre\ClaudeCode\Types\ServerConfigs\StdioServerConfig('node', ['server.js']),
    ],
);

Message Types

The SDK provides strongly-typed message classes with proper DTOs:

SystemMessage

System events with typed data for initialization:

use HelgeSverre\ClaudeCode\Types\Messages\SystemMessage;
use HelgeSverre\ClaudeCode\Types\Config\SystemInitData;

if ($message instanceof SystemMessage && $message->subtype === 'init') {
    // Strongly typed init data
    $initData = $message->data; // SystemInitData instance
    echo "Session ID: {$initData->sessionId}\n";
    echo "Model: {$initData->model}\n";
    echo "Tools: " . implode(', ', $initData->tools) . "\n";
    echo "Working Directory: {$initData->cwd}\n";
}

AssistantMessage

Contains content blocks with Claude's responses:

use HelgeSverre\ClaudeCode\Types\Messages\AssistantMessage;
use HelgeSverre\ClaudeCode\Types\ContentBlocks\{TextBlock, ToolUseBlock, ToolResultBlock};

foreach ($message->content as $block) {
    match (true) {
        $block instanceof TextBlock => 
            echo "Text: {$block->text}\n",
            
        $block instanceof ToolUseBlock => 
            echo "Tool: {$block->name} with " . json_encode($block->input) . "\n",
            
        $block instanceof ToolResultBlock => 
            echo "Result: {$block->content} (Error: " . ($block->isError ? 'Yes' : 'No') . ")\n",
    };
}

UserMessage

User input and tool feedback:

use HelgeSverre\ClaudeCode\Types\Messages\UserMessage;
use HelgeSverre\ClaudeCode\Types\ContentBlocks\ToolResultBlock;

// Simple text message
$message = new UserMessage("Hello Claude!");

// Tool feedback (from Claude's perspective)
if (is_array($message->content)) {
    foreach ($message->content as $block) {
        if ($block instanceof ToolResultBlock) {
            echo "Tool feedback: {$block->content}\n";
            echo "Tool ID: {$block->toolUseId}\n";
            echo "Is Error: " . ($block->isError ? 'Yes' : 'No') . "\n";
        }
    }
}

ResultMessage

Session completion with usage metrics:

use HelgeSverre\ClaudeCode\Types\Messages\ResultMessage;

echo "Total Cost: \${$message->totalCostUsd}\n";
echo "Duration: {$message->durationMs}ms\n";
echo "API Time: {$message->durationApiMs}ms\n";
echo "Turns: {$message->numTurns}\n";
echo "Session ID: {$message->sessionId}\n";
echo "Input Tokens: {$message->usage['input_tokens']}\n";
echo "Output Tokens: {$message->usage['output_tokens']}\n";

MCP Server Configuration

Configure Model Context Protocol servers:

use HelgeSverre\ClaudeCode\Types\ServerConfigs\StdioServerConfig;
use HelgeSverre\ClaudeCode\Types\ServerConfigs\SSEServerConfig;
use HelgeSverre\ClaudeCode\Types\ServerConfigs\HTTPServerConfig;

$options = new Options(
    mcpServers: [
        // Stdio server
        'filesystem' => new StdioServerConfig(
            command: 'node',
            args: ['mcp-server-filesystem.js'],
            env: ['NODE_ENV' => 'production']
        ),
        
        // SSE server
        'weather' => new SSEServerConfig(
            url: 'https://api.example.com/mcp/sse',
            headers: ['Authorization' => 'Bearer token']
        ),
        
        // HTTP server
        'database' => new HTTPServerConfig(
            url: 'https://api.example.com/mcp',
            headers: ['API-Key' => 'secret']
        ),
    ]
);

Interceptors

Note: This is NOT related to or the same as Claude Code Hooks

The SDK supports interceptors that allow you to tap into various events during the Claude Code lifecycle. This is useful for logging, monitoring, debugging, or building real-time UI updates.

Available Hook Points

  • onQueryStart - Fired when a query begins
  • onRawMessage - Fired when raw JSON is received from Claude Code CLI
  • onMessageParsed - Fired after a message is parsed into a typed object
  • onQueryComplete - Fired when the query completes successfully
  • onError - Fired when an error occurs

Basic Usage

use HelgeSverre\ClaudeCode\ClaudeCode;
use HelgeSverre\ClaudeCode\Types\Config\Options;

// Simple logging interceptor
$logger = function(string $event, mixed $data) {
    echo "[{$event}] " . json_encode($data) . PHP_EOL;
};

$options = new Options(
    interceptors: [$logger]
);

$messages = ClaudeCode::query("Help me code", $options);

Example Interceptors

File Logger

use HelgeSverre\ClaudeCode\Examples\Interceptors\FileLoggerInterceptor;

$options = new Options(
    interceptors: [
        new FileLoggerInterceptor('/tmp/claude.log')
    ]
);

Metrics Collector

use HelgeSverre\ClaudeCode\Examples\Interceptors\MetricsInterceptor;

$options = new Options(
    interceptors: [
        new MetricsInterceptor() // Tracks token usage, costs, and timing
    ]
);

Webhook Dispatcher

use HelgeSverre\ClaudeCode\Examples\Interceptors\WebhookInterceptor;

$options = new Options(
    interceptors: [
        new WebhookInterceptor('https://api.example.com/claude-events')
    ]
);

Custom Interceptor

// Token usage tracker
$tokenTracker = function(string $event, mixed $data) use (&$totalTokens) {
    if ($event === 'onMessageParsed' && $data['message'] instanceof ResultMessage) {
        $totalTokens += $data['message']->usage['input_tokens'] ?? 0;
        $totalTokens += $data['message']->usage['output_tokens'] ?? 0;
    }
};

// Real-time progress indicator
$progressTracker = function(string $event, mixed $data) {
    switch ($event) {
        case 'onQueryStart':
            echo "Starting query: {$data['prompt']}\n";
            break;
        case 'onMessageParsed':
            echo "."; // Progress dot for each message
            break;
        case 'onQueryComplete':
            echo "\nQuery completed!\n";
            break;
    }
};

$options = new Options(
    interceptors: [$tokenTracker, $progressTracker]
);

Laravel Integration

// In a service provider
$this->app->bind(Options::class, function ($app) {
    $interceptors = [];
    
    // Add logging if enabled
    if (config('claude-code.logging.enabled')) {
        $interceptors[] = new FileLoggerInterceptor(
            storage_path('logs/claude-code.log')
        );
    }
    
    // Add metrics collection
    if (config('claude-code.metrics.enabled')) {
        $interceptors[] = new MetricsInterceptor();
    }
    
    return new Options(
        interceptors: $interceptors,
        // ... other options
    );
});

Error Handling

The SDK provides specific exception types for different failure scenarios:

use HelgeSverre\ClaudeCode\ClaudeCode;
use HelgeSverre\ClaudeCode\Exceptions\CLINotFoundException;
use HelgeSverre\ClaudeCode\Exceptions\CLIConnectionException;
use HelgeSverre\ClaudeCode\Exceptions\ProcessException;

try {
    $messages = ClaudeCode::query("Help me code");
} catch (CLINotFoundException $e) {
    echo "Claude Code CLI not found. Install with: npm install -g @anthropic-ai/claude-code";
} catch (CLIConnectionException $e) {
    echo "Failed to connect to Claude Code: {$e->getMessage()}";
} catch (ProcessException $e) {
    echo "Process failed with exit code {$e->exitCode}: {$e->stderr}";
}

License

This SDK is open-source software licensed under the MIT license.

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Claude Code SDK Php

How do I install Claude Code SDK Php?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Claude Code SDK Php safe to use with an AI agent?

Its trust score is 39 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Claude Code SDK Php still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.