PHP MCP Server for Laravel

Un envoltorio de Laravel para la librería php-mcp/server que expone aplicaciones Laravel como servidores MCP.

Documentación

Laravel MCP Server SDK

Latest Version on Packagist Total Downloads License

Un SDK integral de Laravel para construir servidores Model Context Protocol (MCP) con características de nivel empresarial e integraciones nativas de Laravel.

Este SDK proporciona un envoltorio optimizado para Laravel de la potente librería php-mcp/server, permitiéndote exponer la funcionalidad de tu aplicación Laravel como Herramientas, Recursos, Prompts y Plantillas de Recursos MCP estandarizados para asistentes de IA como Anthropic's Claude, Cursor IDE, OpenAI's ChatGPT y otros.

Características Clave

  • Integración Nativa de Laravel: Integración profunda con el contenedor de servicios, configuración, caché, registro, sesiones y consola Artisan de Laravel
  • Definición Fluida de Elementos: Define elementos MCP con una API elegante y estilo Laravel usando la fachada Mcp
  • Descubrimiento Basado en Atributos: Usa atributos de PHP 8 (#[McpTool], #[McpResource], etc.) con descubrimiento automático y caché
  • Gestión Avanzada de Sesiones: Manejadores de sesión nativos de Laravel (archivo, base de datos, caché, redis) con recolección de basura automática
  • Opciones de Transporte Flexibles:
    • HTTP Integrado: Sirve a través de rutas de Laravel con soporte de middleware
    • Servidor HTTP Dedicado: Servidor ReactPHP independiente de alto rendimiento
    • STDIO: Interfaz de línea de comandos para integración directa con clientes
  • Transporte Transmisible: Transporte HTTP mejorado con reanudabilidad y event sourcing
  • Comandos Artisan: Comandos para servir, descubrir y gestionar elementos
  • Cobertura Completa de Pruebas: Suite de pruebas integral que garantiza la fiabilidad

Este paquete soporta la versión 2025-03-26 del Model Context Protocol.

Requisitos

  • PHP >= 8.1
  • Laravel >= 10.0
  • Extensiones: json, mbstring, pcre (normalmente habilitadas por defecto)

Instalación

Instala el paquete vía Composer:

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

Publica el archivo de configuración:

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

Para el almacenamiento de sesiones en base de datos, publica la migración:

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

Configuración

Todos los ajustes del servidor MCP se gestionan a través de config/mcp.php, que contiene documentación completa para cada opción. La configuración cubre identidad del servidor, capacidades, ajustes de descubrimiento, gestión de sesiones, opciones de transporte, caché y registro. Todos los ajustes soportan variables de entorno para facilitar la gestión del despliegue.

Las áreas clave de configuración incluyen:

  • Información del Servidor: Nombre, versión e identidad básica
  • Capacidades: Controla qué características MCP están habilitadas (herramientas, recursos, prompts, etc.)
  • Descubrimiento: Cómo se encuentran y cachean los elementos de tu código
  • Gestión de Sesiones: Múltiples backends de almacenamiento (archivo, base de datos, caché, redis) con recolección de basura automática
  • Transportes: Opciones de STDIO, HTTP integrado y servidor HTTP dedicado
  • Rendimiento: Estrategias de caché y límites de paginación

Revisa el archivo config/mcp.php publicado para documentación detallada de todas las opciones disponibles y sus anulaciones de variables de entorno.

Definiendo Elementos MCP

Laravel MCP proporciona dos enfoques potentes para definir elementos MCP: Registro Manual (usando la fachada fluida Mcp) y Descubrimiento Basado en Atributos (usando atributos de PHP 8). Ambos se pueden combinar, con los registros manuales teniendo prioridad.

Tipos de Elementos

  • Herramientas: Funciones/acciones ejecutables (p. ej., calculate, send_email, query_database)
  • Recursos: Contenido/datos estáticos accesibles vía URI (p. ej., config://settings, file://readme.txt)
  • Plantillas de Recursos: Recursos dinámicos con patrones de URI (p. ej., user://{id}/profile)
  • Prompts: Iniciadores/plantillas de conversación (p. ej., summarize, translate)

1. Registro Manual

Define tus elementos MCP usando la elegante fachada Mcp en 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');

Métodos Fluidos Disponibles:

Para Todos los Elementos:

  • name(string $name): Anula el nombre inferido
  • description(string $description): Establece una descripción personalizada

Para Herramientas:

  • annotations(ToolAnnotations $annotations): Añade anotaciones de herramientas MCP
  • inputSchema(array $schema): Define un esquema JSON personalizado para parámetros

Para Recursos:

  • mimeType(string $mimeType): Especifica el tipo de contenido
  • size(int $size): Establece el tamaño del contenido en bytes
  • annotations(Annotations $annotations): Añade anotaciones MCP

Para Plantillas de Recursos:

  • mimeType(string $mimeType): Especifica el tipo de contenido
  • annotations(Annotations $annotations): Añade anotaciones MCP

Formatos de Manejador:

  • [ClassName::class, 'methodName'] - Método de clase
  • InvokableClass::class - Clase invocable con método __invoke()
  • function(...) { ... } - Callables (v3.2+)

2. Descubrimiento Basado en Atributos

Alternativamente, puedes usar atributos de PHP 8 para marcar tus métodos o clases como elementos MCP, en cuyo caso no tienes que registrarlos en 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' => 'john@example.com',
            '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."
            ]
        ];
    }
}

Proceso de Descubrimiento:

Los elementos marcados con atributos se descubren automáticamente cuando:

  • auto_discover está habilitado en la configuración (por defecto: true)
  • Ejecutas php artisan mcp:discover manualmente
# Discover and cache MCP elements
php artisan mcp:discover

# Force re-discovery (ignores cache)
php artisan mcp:discover --force

# Discover without saving to cache
php artisan mcp:discover --no-cache

Precedencia de Elementos

  • Los registros manuales siempre anulan los elementos descubiertos con el mismo identificador
  • Los elementos descubiertos se cachean por rendimiento
  • La caché se invalida automáticamente en ejecuciones de descubrimiento frescas

Ejecutando el Servidor MCP

Laravel MCP ofrece tres opciones de transporte, cada una optimizada para diferentes escenarios de despliegue:

1. Transporte STDIO

Mejor para: Ejecución directa del cliente, Cursor IDE, herramientas de línea de comandos

php artisan mcp:serve --transport=stdio

Configuración del Cliente (Cursor IDE):

{
    "mcpServers": {
        "my-laravel-app": {
            "command": "php",
            "args": [
                "/absolute/path/to/your/laravel/project/artisan",
                "mcp:serve",
                "--transport=stdio"
            ]
        }
    }
}

⚠️ Importante: Cuando uses el transporte STDIO, nunca escribas en STDOUT en tus manejadores (usa el registrador de Laravel o STDERR para depuración). STDOUT está reservado para la comunicación JSON-RPC.

2. Transporte HTTP Integrado

Mejor para: Desarrollo, aplicaciones con servidores web existentes, configuración rápida

El transporte integrado sirve MCP a través de las rutas de tu aplicación Laravel:

// Routes are automatically registered at:
// GET  /mcp       - Streamable connection endpoint
// POST /mcp       - Message sending endpoint  
// DELETE /mcp     - Session termination endpoint

// Legacy mode (if enabled):
// GET  /mcp/sse   - Server-Sent Events endpoint
// POST /mcp/message - Message sending endpoint

Configuración de Protección CSRF:

Añade las rutas MCP a tus exclusiones CSRF:

Laravel 11+:

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'mcp',           // For streamable transport (default)
        'mcp/*',   // For legacy transport (if enabled)
    ]);
})

Laravel 10 y anteriores:

// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    'mcp',           // For streamable transport (default)
    'mcp/*',   // For legacy transport (if enabled)
];

Opciones de Configuración:

'http_integrated' => [
    'enabled' => true,
    'route_prefix' => 'mcp',           // URL prefix
    'middleware' => ['api'],           // Applied middleware
    'domain' => 'api.example.com',     // Optional domain
    'legacy' => false,                 // Use legacy SSE transport instead
],

Configuración del Cliente:

{
    "mcpServers": {
        "my-laravel-app": {
            "url": "https://your-app.test/mcp"
        }
    }
}

Consideraciones del Entorno del Servidor:

Los servidores síncronos estándar tienen dificultades con las conexiones SSE persistentes, ya que cada conexión activa ocupa un proceso de trabajo. Esto afecta tanto a los entornos de desarrollo como a los de producción.

Para Desarrollo:

  • El servidor integrado de PHP (php artisan serve) no funcionará - el flujo SSE bloquea el proceso único
  • Laravel Herd (recomendado para desarrollo local)
  • Nginx configurado correctamente con múltiples trabajadores PHP-FPM
  • Laravel Octane con Swoole/RoadRunner para manejo asíncrono
  • Servidor HTTP dedicado (php artisan mcp:serve --transport=http)

Para Producción:

  • Servidor HTTP dedicado (fuertemente recomendado)
  • Laravel Octane con Swoole/RoadRunner
  • Nginx configurado correctamente con suficientes trabajadores PHP-FPM

3. Servidor HTTP Dedicado (Recomendado para Producción)

Mejor para: Entornos de producción, aplicaciones de alto tráfico, múltiples clientes concurrentes

Lanza un servidor HTTP independiente basado en ReactPHP:

# Start dedicated server
php artisan mcp:serve --transport=http

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

Opciones de Configuración:

'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
],

Modos de Transporte:

  • Modo Transmisible (legacy: false): Transporte mejorado con reanudabilidad y event sourcing
  • Modo Legado (legacy: true): Transporte HTTP+SSE obsoleto.

Modo de Respuesta JSON:

'enable_json_response' => true,  // Returns immediate JSON responses
'enable_json_response' => false, // Uses SSE streaming (default)
  • Modo JSON: Devuelve respuestas inmediatas, mejor para herramientas de ejecución rápida
  • Modo SSE: Transmite respuestas, ideal para operaciones de larga duración

Despliegue en Producción:

Esto crea un proceso de larga duración que debe gestionarse con:

  • Supervisor (recomendado)
  • systemd
  • Contenedores Docker
  • Gestores de procesos

Ejemplo de configuración de Supervisor:

[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

Para guías completas de despliegue en producción, consulta la documentación de php-mcp/server.

Comandos Artisan

Laravel MCP incluye varios comandos Artisan para gestionar tu servidor MCP:

Comando de Descubrimiento

Descubre y cachea elementos MCP de tu código:

# Discover elements and update cache
php artisan mcp:discover

# Force re-discovery (ignore existing cache)
php artisan mcp:discover --force

# Discover without updating cache
php artisan mcp:discover --no-cache

Ejemplo de Salida:

Starting MCP element discovery...
Discovery complete.

┌─────────────────────┬───────┐
│ Element Type        │ Count │
├─────────────────────┼───────┤
│ Tools               │ 5     │
│ Resources           │ 3     │
│ Resource Templates  │ 2     │
│ Prompts             │ 1     │
└─────────────────────┴───────┘

MCP element definitions updated and cached.

Comando de Lista

Ver los elementos MCP registrados:

# List all elements
php artisan mcp:list

# List specific type
php artisan mcp:list tools
php artisan mcp:list resources
php artisan mcp:list prompts
php artisan mcp:list templates

# JSON output
php artisan mcp:list --json

Ejemplo de Salida:

Tools:
┌─────────────────┬──────────────────────────────────────────────┐
│ Name            │ Description                                  │
├─────────────────┼──────────────────────────────────────────────┤
│ add_numbers     │ Add two numbers together                     │
│ send_email      │ Send email to specified recipient            │
│ create_user     │ Create a new user account with validation    │
└─────────────────┴──────────────────────────────────────────────┘

Resources:
┌─────────────────────────┬───────────────────┬─────────────────────┐
│ URI                     │ Name              │ MIME                │
├─────────────────────────┼───────────────────┼─────────────────────┤
│ config://app/settings   │ app_settings      │ application/json    │
│ file://readme.txt       │ readme_file       │ text/plain          │
└─────────────────────────┴───────────────────┴─────────────────────┘

Comando de Servir

Inicia el servidor MCP con varias opciones de transporte:

# Interactive mode (prompts for transport selection)
php artisan mcp:serve

# STDIO transport
php artisan mcp:serve --transport=stdio

# HTTP transport with defaults
php artisan mcp:serve --transport=http

# HTTP transport with custom settings
php artisan mcp:serve --transport=http \
    --host=0.0.0.0 \
    --port=8091 \
    --path-prefix=api/mcp

Opciones del Comando:

  • --transport: Elige el tipo de transporte (stdio o http)
  • --host: Dirección del host para transporte HTTP
  • --port: Número de puerto para transporte HTTP
  • --path-prefix: Prefijo de ruta URL para transporte HTTP

Actualizaciones Dinámicas y Eventos

Laravel MCP se integra con el sistema de eventos de Laravel para proporcionar actualizaciones en tiempo real a los clientes conectados:

Eventos de Cambio de Lista

Notifica a los clientes cuando tus elementos disponibles cambian:

use PhpMcp\Laravel\Events\{ToolsListChanged, ResourcesListChanged, PromptsListChanged};

// Notify clients that available tools have changed
ToolsListChanged::dispatch();

// Notify about resource list changes
ResourcesListChanged::dispatch();

// Notify about prompt list changes  
PromptsListChanged::dispatch();

Eventos de Actualización de Recursos

Notifica a los clientes cuando el contenido de un recurso específico cambia:

use PhpMcp\Laravel\Events\ResourceUpdated;

// Update a file and notify subscribers
file_put_contents('/path/to/config.json', json_encode($newConfig));
ResourceUpdated::dispatch('file:///path/to/config.json');

// Update database content and notify
User::find(123)->update(['status' => 'active']);
ResourceUpdated::dispatch('user://123/profile');

Características Avanzadas

Validación de Esquemas

El servidor genera automáticamente esquemas JSON para los parámetros de las herramientas a partir de las sugerencias de tipo y docblocks de PHP. Puedes mejorar esto con el atributo #[Schema] para validación avanzada:

use PhpMcp\Server\Attributes\Schema;

class PostService
{
    public function createPost(
        #[Schema(minLength: 5, maxLength: 200)]
        string $title,
        
        #[Schema(minLength: 10)]
        string $content,
        
        #[Schema(enum: ['draft', 'published', 'archived'])]
        string $status = 'draft',
        
        #[Schema(type: 'array', items: ['type' => 'string'])]
        array $tags = []
    ): array {
        return Post::create([
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'tags' => $tags,
        ])->toArray();
    }
}

Características del Esquema:

  • Inferencia automática a partir de sugerencias de tipo y docblocks de PHP
  • Validación a nivel de parámetro usando atributos #[Schema]
  • Soporte para restricciones de cadena, rangos numéricos, enums, arrays y objetos
  • Funciona con registro manual y descubrimiento basado en atributos

Para documentación completa del esquema y características avanzadas, consulta la documentación de esquema de php-mcp/server.

Proveedores de Completado

Proporciona sugerencias de autocompletado para variables de plantillas de recursos y argumentos de prompts para ayudar a los usuarios a descubrir opciones disponibles:

use PhpMcp\Server\Contracts\CompletionProviderInterface;
use PhpMcp\Server\Contracts\SessionInterface;
use PhpMcp\Server\Attributes\CompletionProvider;

class UserIdCompletionProvider implements CompletionProviderInterface
{
    public function getCompletions(string $currentValue, SessionInterface $session): array
    {
        return User::where('username', 'like', $currentValue . '%')
            ->limit(10)
            ->pluck('username')
            ->toArray();
    }
}

class UserService
{
    public function getUserData(
        #[CompletionProvider(UserIdCompletionProvider::class)]
        string $userId
    ): array {
        return User::where('username', $userId)->first()->toArray();
    }
}

Características de Completado:

  • Autocompletado para variables de plantillas de recursos y argumentos de prompts
  • Integración con Laravel - usa modelos Eloquent, colecciones, etc.
  • Consciente de la sesión - los completados pueden variar según la sesión del usuario
  • Filtrado en tiempo real basado en la entrada del usuario

Para documentación detallada del proveedor de completado, consulta la documentación de completado de php-mcp/server.

Inyección de Dependencias

Tus manejadores MCP se benefician automáticamente del contenedor de servicios de Laravel:

class OrderService
{
    public function __construct(
        private PaymentGateway $gateway,
        private NotificationService $notifications,
        private LoggerInterface $logger
    ) {}

    #[McpTool(name: 'process_order')]
    public function processOrder(array $orderData): array
    {
        $this->logger->info('Processing order', $orderData);
        
        $payment = $this->gateway->charge($orderData['amount']);
        
        if ($payment->successful()) {
            $this->notifications->sendOrderConfirmation($orderData['email']);
            return ['status' => 'success', 'order_id' => $payment->id];
        }
        
        throw new \Exception('Payment failed: ' . $payment->error);
    }
}

Manejo de Excepciones

Los manejadores de herramientas pueden lanzar excepciones que se convierten automáticamente en respuestas de error JSON-RPC adecuadas:

#[McpTool(name: 'get_user')]
public function getUser(int $userId): array
{
    $user = User::find($userId);
    
    if (!$user) {
        throw new \InvalidArgumentException("User with ID {$userId} not found");
    }
    
    if (!$user->isActive()) {
        throw new \RuntimeException("User account is deactivated");
    }
    
    return $user->toArray();
}

Registro y Depuración

Configura un registro completo para tu servidor MCP:

// config/mcp.php
'logging' => [
    'channel' => 'mcp',  // Use dedicated log channel
    'level' => 'debug',  // Set appropriate log level
],

Crea un canal de registro dedicado en config/logging.php:

'channels' => [
    'mcp' => [
        'driver' => 'daily',
        'path' => storage_path('logs/mcp.log'),
        'level' => env('MCP_LOG_LEVEL', 'info'),
        'days' => 14,
    ],
],

Guía de Migración

De v3.0 a v3.1

Nuevos Tipos de Manejador:

Laravel MCP v3.1 introduce soporte para manejadores de cierre, expandiendo más allá de solo métodos de clase y clases invocables:

// v3.0 and earlier - Class-based handlers only
Mcp::tool([CalculatorService::class, 'add'])
    ->name('add_numbers');

Mcp::tool(EmailService::class)  // Invokable class
    ->name('send_email');

// v3.1+ - Now supports closures
Mcp::tool(function(float $x, float $y): float {
    return $x * $y;
})
    ->name('multiply')
    ->description('Multiply two numbers');

Mcp::resource('system://time', function(): string {
    return now()->toISOString();
})
    ->name('current_time');

Soporte de Esquema de Entrada:

Las herramientas ahora pueden definir esquemas JSON personalizados para la validación de parámetros:

// v3.1+ - Custom input schema
Mcp::tool([CalculatorService::class, 'calculate'])
    ->inputSchema([
        'type' => 'object',
        'properties' => [
            'operation' => [
                'type' => 'string',
                'enum' => ['add', 'subtract', 'multiply', 'divide']
            ],
            'numbers' => [
                'type' => 'array',
                'items' => ['type' => 'number'],
                'minItems' => 2
            ]
        ],
        'required' => ['operation', 'numbers']
    ]);

Métodos de Blueprint Mejorados:

Nuevos métodos fluidos disponibles en blueprints:

->inputSchema(array $schema)  // Define custom parameter schema

Sin Cambios Rupturistas:

Todo el código existente de v3.0 continúa funcionando sin modificación. Las nuevas características son mejoras aditivas.

De v2.x a v3.x

Cambios de Configuración:

// Old structure
'capabilities' => [
    'tools' => ['enabled' => true, 'listChanged' => true],
    'resources' => ['enabled' => true, 'subscribe' => true],
],

// New structure  
'capabilities' => [
    'tools' => true,
    'toolsListChanged' => true,
    'resources' => true,
    'resourcesSubscribe' => true,
],

Configuración de Sesión:

// Old: Basic configuration
'session' => [
    'driver' => 'cache',
    'ttl' => 3600,
],

// New: Enhanced configuration
'session' => [
    'driver' => 'cache',
    'ttl' => 3600,
    'store' => config('cache.default'),
    'lottery' => [2, 100],
],

Actualizaciones de Transporte:

  • El transporte por defecto cambió de sse a streamable
  • Nuevo patrón de exclusión CSRF: mcp en lugar de mcp/*
  • Gestión de sesiones mejorada con recolección de basura automática

Cambios Rupturistas:

  • Se eliminaron métodos obsoletos en favor de la nueva API de registro
  • Se actualizó el registro de elementos para usar el nuevo formato de esquema
  • Se cambió la estructura de configuración para una mejor organización

Ejemplos y Casos de Uso

Integración de Comercio Electrónico

class EcommerceService
{
    #[McpTool(name: 'get_product_info')]
    public function getProductInfo(int $productId): array
    {
        return Product::with(['category', 'reviews'])
            ->findOrFail($productId)
            ->toArray();
    }

    #[McpTool(name: 'search_products')]
    public function searchProducts(
        string $query,
        ?string $category = null,
        int $limit = 10
    ): array {
        return Product::search($query)
            ->when($category, fn($q) => $q->where('category', $category))
            ->limit($limit)
            ->get()
            ->toArray();
    }

    #[McpResource(uri: 'config://store/settings', mimeType: 'application/json')]
    public function getStoreSettings(): array
    {
        return [
            'currency' => config('store.currency'),
            'tax_rate' => config('store.tax_rate'),
            'shipping_zones' => config('store.shipping_zones'),
        ];
    }
}

Gestión de Contenido

class ContentService
{
    #[McpResourceTemplate(uriTemplate: 'post://{slug}', mimeType: 'text/markdown')]
    public function getPostContent(string $slug): string
    {
        return Post::where('slug', $slug)
            ->firstOrFail()
            ->markdown_content;
    }

    #[McpPrompt(name: 'content_summary')]
    public function generateContentSummary(string $postSlug, int $maxWords = 50): array
    {
        $post = Post::where('slug', $postSlug)->firstOrFail();
        
        return [
            [
                'role' => 'user',
                'content' => "Summarize this blog post in {$maxWords} words or less:\n\n{$post->content}"
            ]
        ];
    }
}

Integración de API

class ApiService
{
    #[McpTool(name: 'send_notification')]
    public function sendNotification(
        #[Schema(format: 'email')]
        string $email,
        
        string $subject,
        string $message
    ): array {
        $response = Http::post('https://api.emailservice.com/send', [
            'to' => $email,
            'subject' => $subject,
            'body' => $message,
        ]);

        if ($response->failed()) {
            throw new \RuntimeException('Failed to send notification: ' . $response->body());
        }

        return $response->json();
    }
}

Contribuyendo

¡Damos la bienvenida a contribuciones! Consulta CONTRIBUTING.md para las pautas.

Configuración de desarrollo

# Clone the repository
git clone https://github.com/php-mcp/laravel.git
cd laravel

# Install dependencies
composer install

# Run tests
./vendor/bin/pest

# Check code style
./vendor/bin/pint

Licencia

La Licencia MIT (MIT). Consulta LICENSE para más detalles.

Agradecimientos

  • Construido sobre la especificación Model Context Protocol
  • Impulsado por php-mcp/server para la funcionalidad principal de MCP
  • Aprovecha las características del framework Laravel para una integración perfecta
  • Utiliza ReactPHP para operaciones asíncronas de alto rendimiento