PHPackages                             ashikkaiser/laravelmcp - 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. ashikkaiser/laravelmcp

ActiveLibrary

ashikkaiser/laravelmcp
======================

Laravel implementation of the Model Context Protocol (MCP) SDK

1.0(10mo ago)02MITPHPPHP ^8.2CI failing

Since Jun 24Pushed 10mo agoCompare

[ Source](https://github.com/ashikkaiser/laravel-mcp-sdk)[ Packagist](https://packagist.org/packages/ashikkaiser/laravelmcp)[ Docs](https://github.com/laravelmcp/mcp)[ RSS](/packages/ashikkaiser-laravelmcp/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (14)Versions (2)Used By (0)

Laravel MCP
===========

[](#laravel-mcp)

A Laravel package for implementing the Model Context Protocol (MCP) in Laravel applications. This protocol facilitates communication between AI models and Laravel applications through standardized interfaces.

📚 **[View Full Documentation](https://mohamedahmed01.github.io/laravel-mcp-sdk/)**

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

[](#requirements)

### System Requirements

[](#system-requirements)

- PHP 8.2 or higher
- Laravel 10.x, 11.x, or 12.x
- Composer 2.x
- OpenSSL PHP Extension
- PDO PHP Extension
- Mbstring PHP Extension
- XML PHP Extension
- Ctype PHP Extension
- JSON PHP Extension
- ReactPHP (for HTTP/WebSocket transport)
- ext-json (for JSON handling)

### Optional Requirements

[](#optional-requirements)

- Redis (for WebSocket scaling)
- Supervisor (for process management)
- ext-pcntl (for signal handling)
- ext-posix (for process management)

Features
--------

[](#features)

- **Multiple Transport Options**
    - HTTP Transport (RESTful API) ✅
    - WebSocket Transport (Real-time) ⚠️ [See WebSocket Guide](WEBSOCKET.md)
    - Stdio Transport (Command-line) ✅
    - Configurable host and port settings

> **Note**: WebSocket transport requires additional setup for Laravel 12 compatibility. See [WEBSOCKET.md](WEBSOCKET.md) for details.

- **Server Capabilities**

    - Tool registration and execution
    - Resource management
    - Prompt handling
    - Progress tracking
    - Logging system
    - Model preferences configuration
- **Tool System**

    - Register custom tools with parameters
    - Handle tool calls with arguments
    - Return structured responses
    - Error handling and validation
- **Resource Management**

    - URI-based resource access
    - Resource templates
    - Dynamic resource handling
    - Content type support
- **Prompt System**

    - Template-based prompts
    - Dynamic argument handling
    - Context management
    - Message history support
- **Progress Tracking**

    - Real-time progress updates
    - Token-based tracking
    - Total progress support
    - Client notification system
- **Logging System**

    - Multiple log levels
    - Logger identification
    - Structured logging
    - Transport-agnostic logging

Documentation
-------------

[](#documentation)

The project includes comprehensive PHPDoc documentation for all classes and methods. The documentation is available directly in the source code and covers:

### Core Components

[](#core-components)

- **Server Capabilities** (`src/Capabilities/ServerCapabilities.php`)

    - Server feature management
    - Experimental features configuration
    - Logging configuration
    - Component capabilities (prompts, resources, tools)
- **Client Capabilities** (`src/Capabilities/ClientCapabilities.php`)

    - Feature flag management
    - Root directory configuration
    - State serialization/deserialization

### Component Capabilities

[](#component-capabilities)

- **Tools Capability** (`src/Capabilities/ToolsCapability.php`)

    - Tool list change tracking
    - State management
    - Change notification support
- **Resources Capability** (`src/Capabilities/ResourcesCapability.php`)

    - Resource subscription management
    - Change tracking
    - State serialization
- **Prompts Capability** (`src/Capabilities/PromptsCapability.php`)

    - Prompt list change tracking
    - State management
    - Change notifications
- **Roots Capability** (`src/Capabilities/RootsCapability.php`)

    - Root directory management
    - Directory configuration
    - Access control settings

### Server Management

[](#server-management)

- **MCP Server Command** (`src/Commands/MCPServerCommand.php`)
    - Server startup configuration
    - Transport selection
    - Signal handling
    - Graceful shutdown

Each component includes:

- Detailed class descriptions
- Feature lists and capabilities
- Configuration examples
- Usage examples
- Method documentation
- Parameter descriptions
- Return value documentation

To explore the documentation:

1. Browse the source files in the `src/` directory
2. Use your IDE's PHPDoc integration
3. Generate HTML documentation using phpDocumentor (optional)

To generate HTML documentation:

```
composer require --dev phpdocumentor/phpdocumentor
vendor/bin/phpdoc -d src/ -t docs/
```

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

[](#installation)

Install via Composer:

```
composer require laravelmcp/mcp
```

The package will automatically register its service provider and facade.

Configuration
-------------

[](#configuration)

1. Publish the configuration:

```
php artisan vendor:publish --provider="LaravelMCP\MCP\MCPServiceProvider" --tag="config"
```

2. Configure environment variables:

```
MCP_SERVER_HOST=127.0.0.1
MCP_SERVER_PORT=8080
MCP_SERVER_TRANSPORT=http
```

Basic Usage
-----------

[](#basic-usage)

### Starting the Server

[](#starting-the-server)

```
# Start the server with default HTTP transport
php artisan mcp:serve

# Start with specific transport and options
php artisan mcp:serve --transport=websocket --host=0.0.0.0 --port=8081

# Start with stdio transport (useful for CLI applications)
php artisan mcp:serve --transport=stdio
```

### Server Setup

[](#server-setup)

```
use LaravelMCP\MCP\Server\MCPServer;
use LaravelMCP\MCP\Transport\HttpTransport;

// Create and configure server
$server = new MCPServer();

// Configure transport
$transport = new HttpTransport($server, [
    'host' => '127.0.0.1',
    'port' => 8080
]);

$server->setTransport($transport);
$server->initialize();

// Start the server
$server->start();
```

### Using Different Transports

[](#using-different-transports)

```
use LaravelMCP\MCP\Transport\WebSocketTransport;
use LaravelMCP\MCP\Transport\StdioTransport;
use LaravelMCP\MCP\Transport\TransportFactory;

// Using WebSocket transport
$wsTransport = new WebSocketTransport($server, [
    'host' => '0.0.0.0',
    'port' => 8081
]);

// Using Stdio transport (for CLI applications)
$stdioTransport = new StdioTransport($server);

// Using transport factory
$factory = new TransportFactory();
$transport = $factory->create('http', $server, [
    'host' => '127.0.0.1',
    'port' => 8080
]);
```

### Registering Tools

[](#registering-tools)

```
use LaravelMCP\MCP\Server\FastMCP;
use LaravelMCP\MCP\Facades\MCP;

// Using FastMCP (recommended)
$mcp = new FastMCP();

// Register a simple calculation tool
$mcp->tool('calculate', [
    'num1' => ['type' => 'number', 'required' => true],
    'num2' => ['type' => 'number', 'required' => true],
    'operation' => ['type' => 'string', 'required' => true]
])(function ($args) {
    $num1 = $args['num1'];
    $num2 = $args['num2'];
    $operation = $args['operation'];

    return match ($operation) {
        '+' => ['result' => $num1 + $num2],
        '-' => ['result' => $num1 - $num2],
        '*' => ['result' => $num1 * $num2],
        '/' => $num2 != 0 ? ['result' => $num1 / $num2] : ['error' => 'Division by zero'],
        default => ['error' => 'Invalid operation']
    };
});

// Register a tool with error handling
$mcp->tool('process-data', [
    'items' => ['type' => 'array', 'required' => true],
    'token' => ['type' => 'string', 'required' => false]
])(function ($args) use ($mcp) {
    try {
        $items = $args['items'];
        $token = $args['token'] ?? uniqid();

        foreach ($items as $index => $item) {
            // Process item
            $progress = ($index + 1) / count($items);
            MCP::sendProgress($progress, $token, count($items));
            MCP::sendLog("Processing item {$index + 1}", 'info', 'processor');
        }

        return ['processed' => count($items)];
    } catch (\Exception $e) {
        MCP::sendLog($e->getMessage(), 'error', 'processor');
        return ['error' => $e->getMessage()];
    }
});
```

### Managing Resources

[](#managing-resources)

```
// Register a file resource
$mcp->resource('file://{path}')(function ($matches) {
    $path = $matches['path'] ?? null;
    if (!$path || !file_exists($path)) {
        return ['error' => 'File not found'];
    }

    return [
        'content' => file_get_contents($path),
        'metadata' => [
            'size' => filesize($path),
            'modified' => filemtime($path),
            'mime' => mime_content_type($path)
        ]
    ];
});

// Register a database resource
$mcp->resource('db://{table}/{id}')(function ($matches) {
    $table = $matches['table'] ?? null;
    $id = $matches['id'] ?? null;

    if (!$table || !$id) {
        return ['error' => 'Invalid parameters'];
    }

    try {
        $record = DB::table($table)->find($id);
        return $record ? ['data' => $record] : ['error' => 'Record not found'];
    } catch (\Exception $e) {
        return ['error' => $e->getMessage()];
    }
});

// Register a health check resource
$mcp->resource('/health')(function () {
    return ['status' => 'ok'];
});
```

### Handling Prompts

[](#handling-prompts)

```
// Basic prompt template
$mcp->prompt('code-review', [
    'language' => ['type' => 'string', 'required' => true],
    'code' => ['type' => 'string', 'required' => true]
])(function ($args) {
    return [
        ['role' => 'system', 'content' => 'You are a code review assistant.'],
        ['role' => 'user', 'content' => "Please review this {$args['language']} code:\n\n{$args['code']}"]
    ];
});

// Prompt with context
$mcp->prompt('chat', [
    'message' => ['type' => 'string', 'required' => true],
    'context' => ['type' => 'array', 'required' => false]
])(function ($args) {
    $messages = $args['context'] ?? [];
    $messages[] = [
        'role' => 'user',
        'content' => $args['message']
    ];
    return $messages;
});
```

### Progress and Logging

[](#progress-and-logging)

```
use LaravelMCP\MCP\Facades\MCP;

// Send progress updates
MCP::sendProgress(0.5, 'task_123', 1.0);

// Send logs with different levels
MCP::sendLog('Processing started', 'info', 'processor');
MCP::sendLog('Warning: Rate limit approaching', 'warning', 'rate-limiter');
MCP::sendLog('Error occurred: Invalid input', 'error', 'validator');
MCP::sendLog('Debug: Request payload', 'debug', 'http');
```

### Model Preferences

[](#model-preferences)

```
use LaravelMCP\MCP\Sampling\ModelPreferences;

// Basic model preferences
$preferences = new ModelPreferences(
    costPriority: 0.5,
    intelligencePriority: 0.8,
    speedPriority: 0.3
);
MCP::setModelPreferences($preferences);

// Model preferences with hints
$preferences = new ModelPreferences(
    costPriority: 0.7,
    intelligencePriority: 0.9,
    speedPriority: 0.4,
    hints: ['creative', 'concise']
);
MCP::setModelPreferences($preferences);

// Create from array
$preferences = ModelPreferences::create([
    'costPriority' => 0.6,
    'intelligencePriority' => 0.8,
    'speedPriority' => 0.5,
    'hints' => ['detailed', 'technical']
]);
MCP::setModelPreferences($preferences);
```

### Error Handling

[](#error-handling)

```
use LaravelMCP\MCP\Facades\MCP;

try {
    // Initialize server
    $server = new MCPServer();

    if (!$server->getTransport()) {
        throw new RuntimeException('Transport not initialized');
    }

    // Handle tool call
    $result = $server->handleToolCall('test_tool', [
        'param1' => 'value1',
        'param2' => 'value2'
    ]);

    // Handle resource request
    $resource = $server->handleResourceRequest('test://resource');

    // Handle prompt request
    $prompt = $server->handlePromptRequest('test_prompt', [
        'arg1' => 'value1'
    ]);

} catch (RuntimeException $e) {
    MCP::sendLog("Runtime error: {$e->getMessage()}", 'error', 'server');
} catch (\Exception $e) {
    MCP::sendLog("Unexpected error: {$e->getMessage()}", 'error', 'server');
}
```

### Fun with LLMs: Building a Code Review Assistant

[](#fun-with-llms-building-a-code-review-assistant)

Here's a complete example of building a code review assistant that can analyze code, suggest improvements, and even fix bugs:

```
use LaravelMCP\MCP\Server\FastMCP;
use LaravelMCP\MCP\Facades\MCP;
use Illuminate\Support\Facades\Storage;

$mcp = new FastMCP();

// Register a tool for analyzing code complexity
$mcp->tool('analyze-complexity', [
    'code' => ['type' => 'string', 'required' => true],
    'language' => ['type' => 'string', 'required' => true]
])(function ($args) {
    // Simulate complexity analysis
    $metrics = [
        'cyclomatic' => random_int(1, 10),
        'cognitive' => random_int(1, 15),
        'lines' => count(explode("\n", $args['code']))
    ];

    return [
        'metrics' => $metrics,
        'suggestion' => $metrics['cyclomatic'] > 5 ? 'Consider breaking down this function' : 'Complexity is acceptable'
    ];
});

// Register a code improvement prompt
$mcp->prompt('suggest-improvements', [
    'code' => ['type' => 'string', 'required' => true],
    'language' => ['type' => 'string', 'required' => true],
    'context' => ['type' => 'string', 'required' => false]
])(function ($args) {
    $messages = [
        [
            'role' => 'system',
            'content' => "You are an expert {$args['language']} developer. Analyze the code and suggest improvements for:
                         1. Performance
                         2. Readability
                         3. Best practices
                         4. Potential bugs
                         Be specific and provide examples."
        ],
        [
            'role' => 'user',
            'content' => "Here's the code to review:\n\n```{$args['language']}\n{$args['code']}\n```"
        ]
    ];

    if (isset($args['context'])) {
        $messages[] = [
            'role' => 'user',
            'content' => "Additional context: {$args['context']}"
        ];
    }

    return $messages;
});

// Register a resource for storing review history
$mcp->resource('reviews://{file_hash}')(function ($matches) {
    $hash = $matches['file_hash'] ?? null;
    if (!$hash) return ['error' => 'Invalid file hash'];

    $reviewPath = "reviews/{$hash}.json";
    if (!Storage::exists($reviewPath)) {
        return ['error' => 'No review history found'];
    }

    return ['history' => json_decode(Storage::get($reviewPath), true)];
});

// Create a fun code review workflow
$mcp->tool('review-code', [
    'code' => ['type' => 'string', 'required' => true],
    'language' => ['type' => 'string', 'required' => true],
    'style' => ['type' => 'string', 'enum' => ['serious', 'fun', 'sarcastic'], 'default' => 'serious']
])(function ($args) use ($mcp) {
    $fileHash = md5($args['code']);
    $reviewToken = uniqid('review_');

    try {
        // Step 1: Analyze complexity
        MCP::sendProgress(0.2, $reviewToken, "Analyzing code complexity...");
        $complexity = $mcp->call('analyze-complexity', [
            'code' => $args['code'],
            'language' => $args['language']
        ]);

        // Step 2: Get improvement suggestions
        MCP::sendProgress(0.5, $reviewToken, "Getting expert suggestions...");
        $personality = match($args['style']) {
            'fun' => "Be playful and use coding puns, but maintain professionalism.",
            'sarcastic' => "Use witty, sarcastic humor (but stay constructive and kind).",
            default => "Be direct and professional."
        };

        $suggestions = $mcp->prompt('suggest-improvements', [
            'code' => $args['code'],
            'language' => $args['language'],
            'context' => "Please {$personality}\nComplexity metrics: " . json_encode($complexity['metrics'])
        ]);

        // Step 3: Store review history
        MCP::sendProgress(0.8, $reviewToken, "Saving review history...");
        Storage::put("reviews/{$fileHash}.json", json_encode([
            'timestamp' => now(),
            'complexity' => $complexity,
            'suggestions' => $suggestions,
            'style' => $args['style']
        ]));

        // Step 4: Format response
        MCP::sendProgress(1.0, $reviewToken, "Done!");

        $funnyComments = [
            'fun' => [
                "🎮 Game Over! Your code review is ready!",
                "🎯 Hit the target! Here's your review!",
                "🎪 Step right up to see your code review!"
            ],
            'sarcastic' => [
                "🎭 Oh look, another masterpiece to review...",
                "🎪 Ladies and gentlemen, behold this code!",
                "🎯 Well, well, well... what do we have here?"
            ],
            'serious' => [
                "✅ Code review completed",
                "📋 Analysis complete",
                "🔍 Review finished"
            ]
        ];

        return [
            'message' => $funnyComments[$args['style']][array_rand($funnyComments[$args['style']])],
            'complexity' => $complexity,
            'suggestions' => $suggestions,
            'history_uri' => "reviews://{$fileHash}"
        ];

    } catch (\Exception $e) {
        MCP::sendLog("Review error: {$e->getMessage()}", 'error', 'reviewer');
        return ['error' => "Oops! The code reviewer needs coffee! ({$e->getMessage()})"];
    }
});

// Example usage:
$result = $mcp->call('review-code', [
    'code' => '
        function fibonacci($n) {
            if ($n
