PHP MCP Server for Laravel

by php-mcp

473 370 downloads Not rated yet MIT

About

A Laravel wrapper for the php-mcp/server library to expose Laravel applications as MCP servers.

Details

License
MIT

Explore

- Laravel-Native Integration: Deep integration with Laravel's service container, configuration, caching, logging, sessions, and Artisan console
- Fluent Element Definition: Define MCP elements with an elegant, Laravel-style API using the Mcp facade
- Attribute-Based Discovery: Use PHP 8 attributes (#[McpTool], #[McpResource], etc.) with automatic discovery and caching
- Advanced Session Management: Laravel-native session handlers (file, database, cache, redis) with automatic garbage collection
- Flexible Transport Options:
- Integrated HTTP: Serve through Laravel routes with middleware support
- Dedicated HTTP Server: High-performance standalone ReactPHP server
- STDIO: Command-line interface for direct client integration
- Streamable Transport: Enhanced HTTP transport with resumability and event sourcing
- Artisan Commands: Commands for serving, discovery, and element management
- Full Test Coverage: Comprehensive test suite ensuring reliability

This package supports the 2025-03-26 version of the Model Context Protocol.

- PHP >= 8.1
- Laravel >= 10.0
- Extensions: json, mbstring, pcre (typically enabled by default)

Laravel MCP offers three transport options, each optimized for different deployment scenarios:

php artisan mcp:serve --transport=http \
--host=0.0.0.0 \
--port=8091 \
--path-prefix=mcp_api


Configuration Options:

php
'http_dedicated' => [
'enabled' => true,
'host' => '127.0.0.1', // Bind address
'port' => 8090, // Port number
'path_prefix' => 'mcp', // URL path prefix
'legacy' => false, // Use legacy transport
'enable_json_response' => false, // JSON mode vs SSE streaming
'event_store' => null, // Event store for resumability
'ssl_context_options' => [], // SSL configuration
],

Transport Modes:

- Streamable Mode (legacy: false): Enhanced transport with resumability and event sourcing
- Legacy Mode (legacy: true): Deprecated HTTP+SSE transport.

JSON Response Mode:

php
'enable_json_response' => true, // Returns immediate JSON responses
'enable_json_response' => false, // Uses SSE streaming (default)

- JSON Mode: Returns immediate responses, best for fast-executing tools
- SSE Mode: Streams responses, ideal for long-running operations

Production Deployment:

This creates a long-running process that should be managed with:

- Supervisor (recommended)
- systemd
- Docker containers
- Process managers

Example Supervisor configuration:

ini
[program:laravel-mcp]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/laravel/artisan mcp:serve --transport=http
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/laravel-mcp.log

For comprehensive production deployment guides, see the php-mcp/server documentation.

bash

composer install

Laravel MCP Server SDK

Latest Version on Packagist
Total Downloads
License

A comprehensive Laravel SDK for building Model Context Protocol (MCP) servers with enterprise-grade features and Laravel-native integrations.

This SDK provides a Laravel-optimized wrapper for the powerful php-mcp/server library, enabling you to expose your Laravel application's functionality as standardized MCP Tools, Resources, Prompts, and Resource Templates for AI assistants like Anthropic's Claude, Cursor IDE, OpenAI's ChatGPT, and others.

Key Features

- Laravel-Native Integration: Deep integration with Laravel's service container, configuration, caching, logging, sessions, and Artisan console
- Fluent Element Definition: Define MCP elements with an elegant, Laravel-style API using the Mcp facade
- Attribute-Based Discovery: Use PHP 8 attributes (#[McpTool], #[McpResource], etc.) with automatic discovery and caching
- Advanced Session Management: Laravel-native session handlers (file, database, cache, redis) with automatic garbage collection
- Flexible Transport Options:
- Integrated HTTP: Serve through Laravel routes with middleware support
- Dedicated HTTP Server: High-performance standalone ReactPHP server
- STDIO: Command-line interface for direct client integration
- Streamable Transport: Enhanced HTTP transport with resumability and event sourcing
- Artisan Commands: Commands for serving, discovery, and element management
- Full Test Coverage: Comprehensive test suite ensuring reliability

This package supports the 2025-03-26 version of the Model Context Protocol.

Requirements

- PHP >= 8.1
- Laravel >= 10.0
- Extensions: json, mbstring, pcre (typically enabled by default)

Installation

Install the package via Composer:

composer require php-mcp/laravel:^3.0 -W

Publish the configuration file:

php artisan vendor:publish --provider="PhpMcp\Laravel\McpServiceProvider" --tag="mcp-config"

For database session storage, publish the migration:

php artisan vendor:publish --provider="PhpMcp\Laravel\McpServiceProvider" --tag="mcp-migrations"
php artisan migrate

Configuration

All MCP server settings are managed through config/mcp.php, which contains comprehensive documentation for each option. The configuration covers server identity, capabilities, discovery settings, session management, transport options, caching, and logging. All settings support environment variables for easy deployment management.

Key configuration areas include:
- Server Info: Name, version, and basic identity
- Capabilities: Control which MCP features are enabled (tools, resources, prompts, etc.)
- Discovery: How elements are found and cached from your codebase
- Session Management: Multiple storage backends (file, database, cache, redis) with automatic garbage collection
- Transports: STDIO, integrated HTTP, and dedicated HTTP server options
- Performance: Caching strategies and pagination limits

Review the published config/mcp.php file for detailed documentation of all available options and their environment variable overrides.

Defining MCP Elements

Laravel MCP provides two powerful approaches for defining MCP elements: Manual Registration (using the fluent Mcp facade) and Attribute-Based Discovery (using PHP 8 attributes). Both can be combined, with manual registrations taking precedence.

Element Types

- Tools: Executable functions/actions (e.g., calculate, send_email, query_database)
- Resources: Static content/data accessible via URI (e.g., config://settings, file://readme.txt)
- Resource Templates: Dynamic resources with URI patterns (e.g., user://{id}/profile)
- Prompts: Conversation starters/templates (e.g., summarize, translate)

1. Manual Registration

Define your MCP elements using the elegant Mcp facade in routes/mcp.php:

<?php

use PhpMcp\Laravel\Facades\Mcp;
use App\Services\{CalculatorService, UserService, EmailService, PromptService};

// Register a simple tool
Mcp::tool([CalculatorService::class, 'add'])
->name('add_numbers')
->description('Add two numbers together');

// Register an invokable class as a tool
Mcp::tool(EmailService::class)
->description('Send emails to users');

// Register a closure as a tool with custom input schema
Mcp::tool(function(float $x, float $y): float {
return $x $y;
})
->name('multiply')
->description('Multiply two numbers')
->inputSchema([
'type' => 'object',
'properties' => [
'x' => ['type' => 'number', 'description' => 'First number'],
'y' => ['type' => 'number', 'description' => 'Second number'],
],
'required' => ['x', 'y'],
]);

// Register a resource with metadata
Mcp::resource('config://app/settings', [UserService::class, 'getAppSettings'])
->name('app_settings')
->description('Application configuration settings')
->mimeType('application/json')
->size(1024);

// Register a closure as a resource
Mcp::resource('system://time', function(): string {
return now()->toISOString();
})
->name('current_time')
->description('Get current server time')
->mimeType('text/plain');

// Register a resource template for dynamic content
Mcp::resourceTemplate('user://{userId}/profile', [UserService::class, 'getUserProfile'])
->name('user_profile')
->description('Get user profile by ID')
->mimeType('application/json');

// Register a closure as a resource template
Mcp::resourceTemplate('file://{path}', function(string $path): string {
if (!file_exists($path) || !is_readable($path)) {
throw new \InvalidArgumentException("File not found or not readable: {$path}");
}
return file_get_contents($path);
})
->name('file_reader')
->description('Read file contents by path')
->mimeType('text/plain');

// Register a prompt generator
Mcp::prompt([PromptService::class, 'generateWelcome'])
->name('welcome_user')
->description('Generate a personalized welcome message');

// Register a closure as a prompt
Mcp::prompt(function(string $topic, string $tone = 'professional'): array {
return [
[
'role' => 'user',
'content' => "Write a {$tone} summary about {$topic}. Make it informative and engaging."
]
];
})
->name('topic_summary')
->description('Generate topic summary prompts');

Available Fluent Methods:

For All Elements:
- name(string $name): Override the inferred name
- description(string $description): Set a custom description

For Tools:
- annotations(ToolAnnotations $annotations): Add MCP tool annotations
- inputSchema(array $schema): Define custom JSON schema for parameters

For Resources:
- mimeType(string $mimeType): Specify content type
- size(int $size): Set content size in bytes
- annotations(Annotations $annotations): Add MCP annotations

For Resource Templates:
- mimeType(string $mimeType): Specify content type
- annotations(Annotations $annotations): Add MCP annotations

Handler Formats:
- [ClassName::class, 'methodName'] - Class method
- InvokableClass::class - Invokable class with __invoke() method
- function(...) { ... } - Callables (v3.2+)

2. Attribute-Based Discovery

Alternatively, you can use PHP 8 attributes to mark your methods or classes as MCP elements, in which case, you don't have to register them in them routes/mcp.php:

<?php

namespace App\Services;

use PhpMcp\Server\Attributes\{McpTool, McpResource, McpResourceTemplate, McpPrompt};

class UserService
{
/
Create a new user account.
/
#[McpTool(name: 'create_user')]
public function createUser(string $email, string $password, string $role = 'user'): array
{
// Create user logic
return [
'id' => 123,
'email' => $email,
'role' => $role,
'created_at' => now()->toISOString(),
];
}

/
Get application configuration.
/
#[McpResource(
uri: 'config://app/settings',
mimeType: 'application/json'
)]
public function getAppSettings(): array
{
return [
'theme' => config('app.theme', 'light'),
'timezone' => config('app.timezone'),
'features' => config('app.features', []),
];
}

/
Get user profile by ID.
/
#[McpResourceTemplate(
uriTemplate: 'user://{userId}/profile',
mimeType: 'application/json'
)]
public function getUserProfile(string $userId): array
{
return [
'id' => $userId,
'name' => 'John Doe',
'email' => '[email protected]',
'profile' => [
'bio' => 'Software developer',
'location' => 'New York',
],
];
}

/
Generate a welcome message prompt.
*/
#[McpPrompt(name: 'welcome_user')]
public function generateWelcome(string $username, string $role = 'user'): array
{
return [
[
'role' => 'user',
'content' => "Create a personalized welcome message for {$username} with role {$role}. Be warm and professional."
]
];
}
}

Discovery Process:

Elements marked with attributes are automatically discovered when:
- auto_discover is enabled in configuration (default: true)
- You run php artisan mcp:discover manually

```bash

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.

Videos about PHP MCP Server for Laravel

Relevant YouTube tutorials, setups, and demos