PHP code example of php-mcp / client

1. Go to this page and download the library: Download php-mcp/client library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

php-mcp / client example snippets




hpMcp\Client\Client;
use PhpMcp\Client\Enum\TransportType;
use PhpMcp\Client\Model\Capabilities as ClientCapabilities;
use PhpMcp\Client\ServerConfig;
use PhpMcp\Client\Exception\McpClientException;

$clientCapabilities = ClientCapabilities::forClient(); // Default client caps

$userHome = $_SERVER['HOME'] ?? $_SERVER['USERPROFILE'] ?? getcwd();
$fsServerConfig = new ServerConfig(
    name: 'local_filesystem',
    transport: TransportType::Stdio,
    timeout: 15,
    command: 'npx',
    args: [
        '-y',
        '@modelcontextprotocol/server-filesystem',
        $userHome . '/Documents',
    ],
    workingDir: $userHome
);

$fsClient = Client::make()
    ->withClientInfo('MyFileSystemApp', '1.0')
    ->withCapabilities($clientCapabilities)
    // ->withLogger(new MyPsrLogger()) // Optional
    ->withServerConfig($fsServerConfig)
    ->build();

try {
    // Initialize Connection (BLOCKING)
    $fsClient->initialize();

    // Interact (Synchronously)
    $tools = $fsClient->listTools(); // Blocking call
    foreach ($tools as $tool) {
        echo "- Tool: {$tool->name}\n";
    }

    // ... Call other methods like $fsClient->callTool(...) ...

} catch (McpClientException $e) {
    echo "[MCP ERROR] " . get_class($e) . ": " . $e->getMessage() . "\n";
    // Check $e->getPrevious() for underlying transport/process errors
} catch (\Throwable $e) {
    echo "[UNEXPECTED ERROR] " . $e->getMessage() . "\n";
} finally {
    // Disconnect (BLOCKING)
    if (isset($fsClient)) {
        $fsClient->disconnect();
    }
}

use PhpMcp\Client\Model\Capabilities as ClientCapabilities;

// Client supports sampling requests from the server
$clientCapabilities = ClientCapabilities::forClient(supportsSampling: true);

// Client does NOT support sampling
$clientCapabilities = ClientCapabilities::forClient(supportsSampling: false);

// TODO: Add support for declaring 'roots' capability if needed

use PhpMcp\Client\Enum\TransportType;
use PhpMcp\Client\ServerConfig;

// Example: Stdio Server
$stdioConfig = new ServerConfig(
    name: 'local_file_server',       // Required: Unique ID for this config
    transport: TransportType::Stdio, // Required: Transport type
    timeout: 15.0,                   // Optional: Request timeout (seconds)
    command: 'npx',                  // Required for Stdio: Executable
    args: [                          // Optional for Stdio: Arguments array
        '-y',
        '@modelcontextprotocol/server-filesystem',
        '/path/to/project'
    ],
    workingDir: '/path/to/project',  // Optional for Stdio: Working directory
    env: ['DEBUG' => 'mcp*']         // Optional for Stdio: Environment variables
);

// Example: HTTP Server
$httpConfig = new ServerConfig(
    name: 'remote_web_agent',        // Required: Unique ID
    transport: TransportType::Http,  // Required: Transport type
    timeout: 45.0,                   // Optional: Request timeout
    url: 'http://localhost:8080/sse',// Required for Http: SSE URL
    headers: [                       // Optional for Http: Auth/Custom headers
        'Authorization' => 'Bearer xyz789'
    ],
);

use PhpMcp\Client\ServerConfig;
use PhpMcp\Client\Exception\ConfigurationException;

$jsonConfig = '{
    "mcpServers": {
        "stdio_files": {
            "command": "php",
            "args": ["/app/mcp/file_server.php"],
            "timeout": 10
        },
        "http_api": {
            "url": "https://api.example.com/mcp/sse",
            "transport": "http",
            "headers": {"X-API-Key": "secret"}
        }
    }
}';

$decodedConfig = json_decode($jsonConfig, true)['mcpServers'] ?? [];

$serverConfigs = [];
foreach ($decodedConfig as $name => $data) {
    try {
        $serverConfigs[$name] = ServerConfig::fromArray($name, $data);
    } catch (ConfigurationException $e) {
        echo "Error parsing config for '{$name}': {$e->getMessage()}\n";
    }
}

// Now $serverConfigs['stdio_files'] and $serverConfigs['http_api']
// contain ServerConfig objects.

use PhpMcp\Client\Client;
// ... other use statements for Config, Logger etc...

$client = Client::make()
    ->withClientInfo($clientName, $clientVersion) // Required
    ->withCapabilities($clientCapabilities)       // Optional (defaults provided)
    ->withServerConfig($stdioConfig)              // Required: Config for THE server
    ->withLogger($myLogger)                       // Optional
    ->withCache($myCache, 3600)                   // Optional (cache + TTL)
    ->withEventDispatcher($myDispatcher)          // Optional
    ->withIdGenerator($myIdGenerator)             // Optional
    ->withLoop($myEventLoop)                      // Optional (defaults to Loop::get())
    ->build();

// Synchronous (Blocking)
try {
    $client->initialize(); // Connects, performs handshake, waits until ready
    echo "Connection Ready!";
} catch (Throwable $e) {
    echo "Initialization failed: " . $e->getMessage();
    // Handle error... client is likely in Error state
}

// Asynchronous (Promise-based)
$client->initializeAsync()->then(
    function(Client $readyClient) { /* Ready */ },
    function(Throwable $error) { /* Handle init failure */ }
);
// Requires running the event loop ($client->getLoop()->run())

    try {
        if ($client->isReady()) { // Check status
            $tools = $client->listTools();
            $result = $client->callTool('myTool', ['param' => 'value']);
        }
    } catch (Throwable $e) { /* Handle errors */ }
    

    use function React\Promise\all;

    if ($client->isReady()) {
        $p1 = $client->listToolsAsync();
        $p2 = $client->readResourceAsync('config://settings');

        all([$p1, $p2])->then(
            function(array $results) {
                [$tools, $readResult] = $results;
                // Process async results...
            },
            function(Throwable $error) {
                // Handle async error...
            }
        );
        // $client->getLoop()->run(); // Need to run the loop
    }
    

// Synchronous
$client->disconnect(); // Blocks until closed or timeout

// Asynchronous
$client->disconnectAsync()->then(function() { echo "Disconnected async"; });
// $loop->run();
bash
composer