Laravel Loop

Un servidor MCP para aplicaciones Laravel que se conecta con asistentes de IA utilizando el protocolo MCP.

Documentación

Laravel Loop

Laravel Supported Versions MIT Licensed Latest Version on Packagist

Laravel Loop es un potente servidor de Model Context Protocol (MCP) diseñado específicamente para aplicaciones Laravel. Conecta tu aplicación Laravel con asistentes de IA utilizando el protocolo MCP.

Laravel Loop utiliza Prism internamente para construir las herramientas.

[!IMPORTANT] Laravel Loop y sus herramientas preconstruidas aún están en desarrollo y esta es una versión beta.

Qué Hace

Laravel Loop te permite:

  • Crear y exponer tus propias herramientas directamente integradas con tu aplicación Laravel
  • Conectarte con clientes MCP como Claude Code, Cursor, Windsurf y más

Herramientas preconstruidas:

  • Servidor MCP de Filament.
  • Herramientas de Modelos Laravel (Interactúa con los datos de tus modelos): Kirschbaum\Loop\Toolkits\LaravelModelToolkit (Operaciones de escritura próximamente)
  • Herramientas de Factories Laravel (Crea datos de prueba desde tu cliente MCP): Kirschbaum\Loop\Toolkits\LaravelFactoriesToolkit
  • Herramienta Stripe (Interactúa con la API de Stripe): Kirschbaum\Loop\Tools\StripeTool

Instalación

Puedes instalar el paquete mediante composer:

composer require kirschbaum-development/laravel-loop

Publica el archivo de configuración:

php artisan vendor:publish --tag="loop-config"

Uso

Primero, debes registrar tus herramientas (Si no sabes dónde colocarlas, ponlas en app/Providers/AppServiceProvider).

use Illuminate\Support\ServiceProvider;
use Kirschbaum\Loop\Facades\Loop;
use Kirschbaum\Loop\Toolkits;
use Kirschbaum\Loop\Tools;

Loop::toolkit(Kirschbaum\Loop\Filament\FilamentToolkit::make());

Herramientas Personalizadas

Para construir tus propias herramientas, puedes usar el método Loop::tool.

use Kirschbaum\Loop\Facades\Loop;
use Kirschbaum\Loop\Tools\CustomTool;

Loop::tool(
    CustomTool::make(
        name: 'custom_tool',
        description: 'This is a custom tool',
    )
        ->withStringParameter(name: 'name', description: 'The name of the user', required: true)
        ->withNumberParameter(name: 'age', description: 'The age of the user')
        ->using(function (string $name, ?int $age = null) {
            return sprintf('Hello, %s! You are %d years old.', $name, $age ?? 'unknown');
        }),
    );
);

Los tipos de parámetros disponibles se pueden encontrar en la Documentación de Herramientas de Prism.

Objetos de Herramientas Personalizadas

También puedes construir tus propias clases de herramientas. Cada herramienta debe implementar el contrato Tool y devolver una instancia de Prism\Prism\Tool en el método build.

use Kirschbaum\Loop\Contracts\Tool;

class HelloTool implements Tool
{
    use \Kirschbaum\Loop\Concerns\Makeable;

    public function build(): \Prism\Prism\Tool
    {
        return app(\Prism\Prism\Tool::class)
            ->as($this->getName())
            ->for('Says hello to the user')
            ->withStringParameter('name', 'The name of the user to say hello to.', required: true)
            ->using(fn (string $name) => "Hello, $name!");
    }

    public function getName(): string
    {
        return 'hello';
    }
}

Si deseas proporcionar múltiples herramientas similares, puedes construir un toolkit que devuelva una colección de herramientas.

use Kirschbaum\Loop\Collections\ToolCollection;
use Kirschbaum\Loop\Contracts\Toolkit;

class LaravelFactoriesToolkit implements Toolkit
{
    use \Kirschbaum\Loop\Concerns\Makeable;

    public function getTools(): ToolCollection
    {
        return new ToolCollection([
            HelloTool::make(),
            GoodbyeTool::make(),
        ]);
    }
}

Conexión al servidor MCP

Para que esto sea realmente útil, necesitas conectar tu cliente MCP (Claude Code, Claude Desktop, Cursor, Windsurf, etc.) al servidor Laravel LoopMCP.

El protocolo MCP tiene dos transportes principales para conectarse: STDIO y Streamable HTTP, y el transporte HTTP+SSE obsoleto. Laravel Loop soporta todos ellos.

La forma más fácil de configurar tu cliente MCP es usar el comando php artisan loop:mcp:config. Esto te guiará a través del proceso de configuración de tu cliente MCP.

php artisan loop:mcp:generate-config

STDIO

Para ejecutar el servidor MCP usando STDIO, proporcionamos el siguiente comando artisan:

php artisan loop:mcp:start [--user-id=1 [--user-model=] [--auth-guard=] [--debug]

Para conectar el servidor MCP de Laravel Loop a Claude Code, por ejemplo, puedes usar el siguiente comando:

claude mcp add laravel-loop-mcp php /your/full/path/to/laravel/artisan loop:mcp:start

# with an authenticated user
claude mcp add laravel-loop-mcp php /your/full/path/to/laravel/artisan loop:mcp:start --user-id=1 --user-model=App\Models\User

# with debug mode
claude mcp add laravel-loop-mcp php /your/full/path/to/laravel/artisan loop:mcp:start --debug

Para configurar Laravel Loop en Cursor, Claude o cualquier cliente MCP con un archivo de configuración JSON:

{
  "mcpServers": {
    "laravel-loop-mcp": {
      "command": "php",
      "args": [
        "/your/full/path/to/laravel/artisan",
        "loop:mcp:start",
        "--user-id=1"
      ]
    }
  }
}

Streamable HTTP y SSE

Tener que ejecutar PHP o Node para ejecutar el servidor MCP puede ser molesto. Para evitar esto, puedes usar el transporte Streamable HTTP o SSE, que conecta el cliente MCP directamente a tu aplicación mediante HTTP.

Laravel Loop también soporta el transporte Streamable HTTP y el obsoleto transporte HTTP+SSE.

[!IMPORTANT] NOTA: El transporte Streamable HTTP es nuevo y aún no es soportado por todos los clientes MCP, mientras que SSE (soportado por la mayoría de los clientes MCP) está obsoleto.

La siguiente documentación es para ambos transportes. Ten en cuenta que solo necesitas habilitar uno de ellos.

1. Habilitar y configurar el transporte

Para habilitar el transporte Streamable HTTP, actualiza tu archivo .env:

# streamable http
LOOP_STREAMABLE_HTTP_ENABLED=true

# sse
LOOP_SSE_ENABLED=true

Nota: Al usar SSE, el driver predeterminado es file, que es el más simple y conveniente para el desarrollo local. Sin embargo, para producción, recomendamos usar redis para evitar problemas con el bloqueo de archivos. Puedes cambiar el driver y opciones adicionales en el archivo config/loop.php.

Esto expondrá dos endpoints MCP:

  • /mcp que soporta el nuevo transporte Streamable HTTP.
  • /mcp/sse que soporta el obsoleto transporte HTTP+SSE.

Nota: Si estás ejecutando tu aplicación localmente con https, la mayoría de los clientes fallarán debido a los certificados autofirmados. Para evitar esto, usa el transporte STDIO o usa el protocolo http localmente.

2. Configurar la autenticación (opcional)

Ten en cuenta que si expones tu endpoint públicamente, estás exponiendo tus datos al mundo. Para asegurar que tus endpoints MCP sean seguros, asegúrate de configurar las opciones de configuración streamable_http.middleware o sse.middleware. Recomendamos usar algo como Sanctum (configurado por defecto) para proteger el endpoint.

[
    'streamable_http' => [
        'middleware' => ['auth:sanctum'],
    ],
    
    'sse' => [
        'middleware' => ['auth:sanctum'],
    ],
]

3. Añadir el servidor MCP a tu cliente

Luego, solo necesitas configurar el endpoint del servidor MCP en tu cliente:

Claude Code

claude mcp add laravel-loop-mcp http://your-url.test/mcp/sse -t sse

Desde archivo de configuración JSON

{
  "mcpServers": {
    "laravel-loop-mcp": {
      "url": "http://your-url.test/mcp/sse",
    }
  }
}

Ten en cuenta que no todos los clientes soportan conexiones SSE directas. Para esas situaciones, puedes usar un proxy a través del paquete mcp-remote. Esto requiere que tengas Node.js (> 20) instalado. A continuación, un ejemplo usando el paquete mcp-remote.

{
  "mcpServers": {
    "laravel-loop-mcp": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://your-remote-url.com/mcp",
        "--header",
        "Authorization: Bearer ${AUTH_TOKEN}"
      ]
    }
  }
}

Solución de Problemas

Error de conexión: MCP error -32000: Connection closed

Si obtienes este error, probablemente significa que hay algún error ocurriendo en tu aplicación. Revisa los registros de tu aplicación para más detalles.

Error: spawn php ENOENT

Esto puede ocurrir cuando tu binario "php" no está en el PATH. Esto se puede resolver de varias maneras:

  • Añade la ruta a tu archivo .bashrc o .zshrc. A veces solo puede estar en el archivo .zshrc, pero aplicaciones como Claude usan .bashrc.
  • Usa la ruta completa del binario de PHP. Puedes obtenerla ejecutando which php en tu terminal.
    • Esta puede ser una buena opción para asegurarte de usar siempre la versión adecuada de PHP para un proyecto dado. Si usas Herd, por ejemplo, tu php cambiará dependiendo de la versión seleccionada.

Llamar herramientas manualmente y verificar la salida

A veces, al construir herramientas, puedes obtener resultados inesperados y depurar desde el cliente MCP puede ser difícil. Puedes llamar herramientas manualmente y verificar la salida ejecutando el siguiente comando:

php artisan loop:mcp:call

Asegúrate de revisar los registros de tu aplicación

Si obtienes un error desconocido, revisa los registros de tu aplicación para más detalles.


Hoja de Ruta

  • Añadir un componente de chat al paquete, para que puedas usar las herramientas dentro de la aplicación sin un cliente MCP.
  • Refinar las herramientas existentes
  • Añadir capacidades de escritura a las herramientas existentes

Seguridad

Si descubres algún problema relacionado con la seguridad, por favor envía un correo a security@kirschbaumdevelopment.com en lugar de usar el rastreador de problemas.

Patrocinio

El desarrollo de este paquete está patrocinado por Kirschbaum Development Group, una empresa impulsada por desarrolladores enfocada en la resolución de problemas, la formación de equipos y la comunidad. Aprende más sobre nosotros o únete a nosotros!

Licencia

La Licencia MIT (MIT). Consulta el Archivo de Licencia para más información.