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
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 inferidodescription(string $description): Establece una descripción personalizada
Para Herramientas:
annotations(ToolAnnotations $annotations): Añade anotaciones de herramientas MCPinputSchema(array $schema): Define un esquema JSON personalizado para parámetros
Para Recursos:
mimeType(string $mimeType): Especifica el tipo de contenidosize(int $size): Establece el tamaño del contenido en bytesannotations(Annotations $annotations): Añade anotaciones MCP
Para Plantillas de Recursos:
mimeType(string $mimeType): Especifica el tipo de contenidoannotations(Annotations $annotations): Añade anotaciones MCP
Formatos de Manejador:
[ClassName::class, 'methodName']- Método de claseInvokableClass::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_discoverestá habilitado en la configuración (por defecto:true)- Ejecutas
php artisan mcp:discovermanualmente
# 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
STDOUTen tus manejadores (usa el registrador de Laravel oSTDERRpara depuración).STDOUTestá 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 (stdioohttp)--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:
mcpen lugar demcp/* - 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/serverpara 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