AgentStack
MCP verified MIT Self-run

Llm Agents Php Mcp Server

mcp-llm-agents-php-mcp-server · by llm-agents-php

Create production-ready MCP servers in PHP with modern architecture, and flexible transport options.

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add mcp-llm-agents-php-mcp-server

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Llm Agents Php Mcp Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

PHP MCP Server SDK

[](https://packagist.org/packages/llm/mcp-server) [](https://packagist.org/packages/llm/mcp-server) [](LICENSE) [](https://packagist.org/packages/llm/mcp-server)

A comprehensive PHP SDK for building Model Context Protocol (MCP) servers. Create production-ready MCP servers in PHP with modern architecture, flexible transport options, and comprehensive feature support.

Table of Contents

  • [Requirements](#requirements)
  • [Installation](#installation)
  • [Framework Integration](#framework-integration)
  • [Quick Start](#quick-start)
  • [Core Concepts](#core-concepts)
  • [Transport Options](#transport-options)
  • [STDIO Transport](#stdio-transport-recommended-for-cli)
  • [HTTP Transport with SSE](#http-transport-with-sse)
  • [Streamable HTTP Transport](#streamable-http-transport)
  • [Working with Tools](#working-with-tools)
  • [Basic Tool Registration](#basic-tool-registration)
  • [Advanced Tool with Multiple Content Types](#advanced-tool-with-multiple-content-types)
  • [Error Handling in Tools](#error-handling-in-tools)
  • [Working with Resources](#working-with-resources)
  • [Working with Prompts](#working-with-prompts)
  • [HTTP Middleware](#http-middleware)
  • [Built-in Middleware](#built-in-middleware)
  • [CORS Middleware](#cors-middleware)
  • [Authentication Middleware](#authentication-middleware)
  • [Custom Middleware](#custom-middleware)
  • [Advanced Configuration](#advanced-configuration)
  • [Complete Server Setup](#complete-server-setup)
  • [Event Store for Resumability](#event-store-for-resumability)
  • [Common Patterns](#common-patterns)
  • [Handler Factory Pattern](#handler-factory-pattern)
  • [Decorator Pattern for Handlers](#decorator-pattern-for-handlers)
  • [Class-Based Tool Handlers with Schema Mapping](#class-based-tool-handlers-with-schema-mapping)
  • [Ecosystem & Extensions](#ecosystem--extensions)
  • [Contributing](#contributing)
  • [License](#license)
  • [Acknowledgments](#acknowledgments)

> This SDK implements the MCP 2025-03-26 specification with full backward compatibility support.

Features

  • Complete MCP Implementation: Full support for tools, resources, prompts, and logging
  • Multiple Transport Options: STDIO, HTTP with SSE, and streamable HTTP transports
  • Session Management: Built-in session handling with configurable storage backends
  • Event-Driven Architecture: ReactPHP-powered asynchronous operations
  • Middleware Support: PSR-15 compatible HTTP middleware system
  • Type Safety: Full PHP 8.3+ type declarations and comprehensive error handling
  • Extensible Design: Pluggable components with clear interfaces
  • Production Ready: Comprehensive logging, error handling, and testing support

What's NOT Included

This SDK focuses on core MCP functionality and intentionally does not include:

  • Resource Discovery: Automatic scanning and registration of resources from filesystem or annotations
  • Schema Generation: Automatic generation of JSON schemas from PHP code or docblocks
  • Request Validation: Built-in validation of incoming requests against defined schemas
  • Framework Integration: Direct integration with web frameworks (Laravel, Symfony, etc.)

Why? These features are better implemented as separate packages or framework-specific bridges that can:

  • Provide opinionated conventions for specific use cases
  • Integrate deeply with framework ecosystems
  • Offer different approaches to schema management
  • Maintain focused, single-responsibility packages

Requirements

  • PHP >= 8.3 (required for advanced type features and performance)
  • Extensions: json, mbstring, pcre (typically bundled with PHP)

Installation

composer require llm/mcp-server

Framework Integration

For enhanced developer experience with automatic discovery and validation:

Spiral Framework: Use the spiral/mcp-server bridge

composer require spiral/mcp-server

Other Frameworks: Framework-specific bridges are planned. Contributions welcome!

Quick Start

Here's a minimal working example that demonstrates core functionality:

 ['type' => 'string', 'description' => 'Name to greet']],
);

$greetHandler = new CallableHandler(function($args) {
    return [TextContent::make("Hello, " . ($args['name'] ?? 'World') . "!")];
});

$registry->registerTool($greetTool, $greetHandler);

// Create and start server
$server = new Server($protocol, $sessionManager, $logger);
$transport = new StdioServerTransport();
$server->listen($transport);

Expected Output: The server will listen on STDIN/STDOUT and respond to MCP requests.

To Test: Save as server.php and run php server.php, then send MCP messages via STDIN.

Core Concepts

Architecture Overview

The SDK follows a layered architecture:

┌─────────────────┐
│    Transport    │  (STDIO, HTTP, Streamable HTTP)
├─────────────────┤
│    Protocol     │  (MCP message handling)
├─────────────────┤
│   Dispatcher    │  (Route requests to handlers)
├─────────────────┤
│    Registry     │  (Tools, Resources, Prompts)
├─────────────────┤
│   Handlers      │  (Your business logic)
└─────────────────┘

Key Components

  • Server: Main orchestrator that binds protocol to transport
  • Protocol: Handles MCP message parsing and session management
  • Registry: Manages tools, resources, and prompts registration
  • Transport: Communication layer (STDIO, HTTP, etc.)
  • Session Manager: Handles client sessions and state persistence

Transport Options

STDIO Transport (Recommended for CLI)

Perfect for command-line tools and process-based communication:

use Mcp\Server\Transports\StdioServerTransport;

$transport = new StdioServerTransport();
$server->listen($transport);

Use Cases: CLI tools, subprocess communication, development/testing

HTTP Transport with SSE

For web-based applications with real-time communication:

use Mcp\Server\Transports\HttpServer;
use Mcp\Server\Transports\HttpServerTransport;
use React\EventLoop\Loop;

$loop = Loop::get();
$httpServer = new HttpServer($loop, '127.0.0.1', 8080, '/mcp');
$transport = new HttpServerTransport($httpServer);
$server->listen($transport);

Use Cases: Web applications, browser-based clients, dashboard integrations

Streamable HTTP Transport

Advanced HTTP transport with JSON response and resumability support:

use Mcp\Server\Transports\StreamableHttpServerTransport;
use Mcp\Server\Defaults\InMemoryEventStore;

$eventStore = new InMemoryEventStore();
$transport = new StreamableHttpServerTransport(
    httpServer: $httpServer,
    enableJsonResponse: true,
    stateless: false,
    eventStore: $eventStore
);
$server->listen($transport);

Use Cases: High-performance applications, stateless deployments, fault-tolerant systems

Working with Tools

Tools are executable functions that AI assistants can call to perform actions.

Basic Tool Registration

use PhpMcp\Schema\Tool;
use Mcp\Server\Defaults\CallableHandler;
use PhpMcp\Schema\Content\TextContent;

// Define tool schema
$calculatorTool = Tool::make(
    name: 'calculator',
    description: 'Performs basic mathematical operations',
    inputSchema: [
        'operation' => [
            'type' => 'string',
            'enum' => ['add', 'subtract', 'multiply', 'divide'],
            'description' => 'The operation to perform'
        ],
        'a' => ['type' => 'number', 'description' => 'First number'],
        'b' => ['type' => 'number', 'description' => 'Second number']
    ]
);

// Create handler
$calculatorHandler = new CallableHandler(function($args) {
    $a = $args['a'];
    $b = $args['b'];
    $operation = $args['operation'];
    
    $result = match($operation) {
        'add' => $a + $b,
        'subtract' => $a - $b,
        'multiply' => $a * $b,
        'divide' => $b !== 0 ? $a / $b : throw new InvalidArgumentException('Division by zero'),
        default => throw new InvalidArgumentException('Unknown operation')
    };
    
    return [TextContent::make("Result: $result")];
});

$registry->registerTool($calculatorTool, $calculatorHandler);

Advanced Tool with Multiple Content Types

use PhpMcp\Schema\Content\ImageContent;
use PhpMcp\Schema\Content\BlobResourceContents;

$imageProcessorHandler = new CallableHandler(function($args) {
    $imagePath = $args['image_path'];
    
    // Process image (example)
    $imageData = file_get_contents($imagePath);
    $base64Image = base64_encode($imageData);
    
    return [
        TextContent::make("Processed image: $imagePath"),
        ImageContent::make($base64Image, 'image/jpeg'),
    ];
});

Error Handling in Tools

use Mcp\Server\Exception\ValidationException;

$validatedToolHandler = new CallableHandler(function($args) {
    if (!isset($args['required_param'])) {
        throw new ValidationException([
            [
                'pointer' => '/required_param',
                'keyword' => 'required',
                'message' => 'This parameter is required'
            ]
        ]);
    }
    
    // Tool logic here
    return [TextContent::make('Success!')];
});

Working with Resources

Resources provide read-only access to data that AI assistants can reference.

Static Resources

use PhpMcp\Schema\Resource;
use PhpMcp\Schema\Content\TextResourceContents;

$docResource = Resource::make(
    uri: 'file:///docs/readme.txt',
    name: 'README Documentation',
    description: 'Application documentation',
    mimeType: 'text/plain'
);

$docHandler = new CallableHandler(function($args) {
    $content = file_get_contents(__DIR__ . '/README.txt');
    return [TextResourceContents::make($args['uri'], 'text/plain', $content)];
});

$registry->registerResource($docResource, $docHandler);

Dynamic Resource Templates

Resource templates use URI patterns to handle multiple similar resources:

use PhpMcp\Schema\ResourceTemplate;

$userTemplate = ResourceTemplate::make(
    uriTemplate: 'user://{user_id}/profile',
    name: 'User Profile Template',
    description: 'Access user profile data',
    mimeType: 'application/json'
);

$userHandler = new CallableHandler(function($args) {
    $userId = $args['user_id'];
    
    // Fetch user data from database/API
    $userData = getUserData($userId);
    
    return [TextResourceContents::make(
        $args['uri'],
        'application/json',
        json_encode($userData)
    )];
});

$registry->registerResourceTemplate($userTemplate, $userHandler);

Resource with Completion Providers

use Mcp\Server\Defaults\ListCompletionProvider;

$completionProvider = new ListCompletionProvider(['admin', 'user', 'guest']);

$registry->registerResourceTemplate(
    $userTemplate,
    $userHandler,
    completionProviders: ['user_id' => $completionProvider]
);

Working with Prompts

Prompts provide templated text generation for AI assistants.

Basic Prompt

use PhpMcp\Schema\Prompt;
use PhpMcp\Schema\Content\PromptMessage;
use PhpMcp\Schema\Enum\Role;

$codeReviewPrompt = Prompt::make(
    name: 'code_review',
    description: 'Generate code review prompt',
    arguments: [
        'code' => ['type' => 'string', 'required' => true, 'description' => 'Code to review'],
        'language' => ['type' => 'string', 'description' => 'Programming language']
    ]
);

$codeReviewHandler = new CallableHandler(function($args) {
    $code = $args['code'];
    $language = $args['language'] ?? 'unknown';
    
    $systemPrompt = "You are a senior software engineer reviewing {$language} code.";
    $userPrompt = "Please review this code:\n\n```{$language}\n{$code}\n```";
    
    return [
        PromptMessage::make(Role::User, TextContent::make($systemPrompt)),
        PromptMessage::make(Role::User, TextContent::make($userPrompt))
    ];
});

$registry->registerPrompt($codeReviewPrompt, $codeReviewHandler);

Advanced Prompt with Multiple Message Types

$conversationPrompt = new CallableHandler(function($args) {
    $context = $args['context'];
    $question = $args['question'];
    
    return [
        [
            'role' => 'user',
            'content' => [
                'type' => 'text',
                'text' => "Context: $context"
            ]
        ],
        [
            'role' => 'user', 
            'content' => [
                'type' => 'text',
                'text' => "Question: $question"
            ]
        ]
    ];
});

Session Management

Custom Session Handlers

Implement the SessionHandlerInterface for custom storage:

use Mcp\Server\Contracts\SessionHandlerInterface;

class DatabaseSessionHandler implements SessionHandlerInterface
{
    public function __construct(private PDO $pdo) {}
    
    public function read(string $id): string|false
    {
        $stmt = $this->pdo->prepare('SELECT data FROM sessions WHERE id = ?');
        $stmt->execute([$id]);
        return $stmt->fetchColumn() ?: false;
    }
    
    public function write(string $id, string $data): bool
    {
        $stmt = $this->pdo->prepare(
            'INSERT INTO sessions (id, data, updated_at) VALUES (?, ?, NOW()) 
             ON DUPLICATE KEY UPDATE data = VALUES(data), updated_at = NOW()'
        );
        return $stmt->execute([$id, $data]);
    }
    
    public function destroy(string $id): bool
    {
        $stmt = $this->pdo->prepare('DELETE FROM sessions WHERE id = ?');
        return $stmt->execute([$id]);
    }
    
    public function gc(int $maxLifetime): array
    {
        $stmt = $this->pdo->prepare(
            'DELETE FROM sessions WHERE updated_at execute([$maxLifetime]);
        return []; // Return deleted session IDs if needed
    }
}

Cache-Based Session Storage

use Mcp\Server\Session\CacheSessionHandler;
use Mcp\Server\Defaults\FileCache;

$cache = new FileCache('/tmp/mcp_sessions.cache');
$sessionHandler = new CacheSessionHandler($cache, ttl: 7200);
$sessionManager = new SessionManager($sessionHandler, $logger, $loop);

HTTP Middleware

Built-in Middleware

CORS Middleware
use Mcp\Server\Transports\Middleware\CorsMiddleware;

$corsMiddleware = new CorsMiddleware(
    allowedOrigins: ['https://myapp.com', 'https://localhost:3000'],
    allowedMethods: ['GET', 'POST', 'DELETE', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization', 'Mcp-Session-Id'],
    maxAge: 86400,
);

$httpServer = new HttpServer(
    $loop,
    '127.0.0.1',
    8080,
    '/mcp',
    middleware: [$corsMiddleware],
);
Authentication Middleware
use Mcp\Server\Transports\Middleware\AuthenticationMiddleware;

$authMiddleware = new AuthenticationMiddleware(
    authenticator: function($request, $authHeader) {
        // Bearer token validation
        if (!str_starts_with($authHeader, 'Bearer ')) {
            return false;
        }
        
        $token = substr($authHeader, 7);
        return validateToken($token); // Your validation logic
    },
    protectedPaths: ['/mcp']
);

Custom Middleware

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class LoggingMiddleware implements MiddlewareInterface
{
    public function __construct(private LoggerInterface $logger) {}
    
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $start = microtime(true);
        
        $this->logger->info('Request started', [
            'method' => $request->getMethod(),
            'path' => $request->getUri()->getPath()
        ]);
        
        $response = $handler->handle($request);
        
        $duration = microtim

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [llm-agents-php](https://github.com/llm-agents-php)
- **Source:** [llm-agents-php/mcp-server](https://github.com/llm-agents-php/mcp-server)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.