Skip to content

🤖 Servidor MCP multiusuario Laravel 11 + OpenAI + Sanctum + Queue. Procesa archivos Excel con IA y expone API REST para chatbots (SendPulse). Compatible cPanel.

License

Notifications You must be signed in to change notification settings

jonasvelasquez01/laravel-mcp-server-multiusuario

Repository files navigation

Servidor MCP (Model Context Protocol) Multiusuario - Laravel 11

Laravel PHP OpenAI License GitHub Stars

🤖 Sistema SaaS que permite a clientes subir archivos Excel, procesarlos con OpenAI y exponer los datos mediante una API REST para chatbots (SendPulse, etc.).

🚀 Características principales

  • Autenticación multiusuario con Laravel Sanctum
  • Procesamiento asíncrono de archivos Excel/CSV con Jobs/Queue
  • Integración con OpenAI para limpiar y estructurar datos automáticamente
  • API REST pública con tokens únicos por cliente
  • Compatible con hosting compartido (cPanel)
  • Tests automatizados con PHPUnit
  • Manejo robusto de errores con logs detallados

📋 Requisitos

  • PHP 8.1+
  • Composer
  • MySQL 5.7+ / MariaDB 10.3+
  • Laravel 11
  • Cuenta de OpenAI con API Key

🛠️ Instalación

1. Clonar el proyecto

git clone https://github.com/jonasvelasquez01/laravel-mcp-server-multiusuario.git
cd laravel-mcp-server-multiusuario

2. Instalar dependencias

composer install

Si no tienes las dependencias instaladas, ejecuta:

composer require laravel/sanctum
composer require phpoffice/phpspreadsheet
composer require openai-php/client

3. Configurar variables de entorno

Copia .env.example a .env:

cp .env.example .env

Edita .env y configura:

APP_NAME="MCP Server"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mcp_server
DB_USERNAME=root
DB_PASSWORD=

# Clave de OpenAI (OBLIGATORIA)
OPENAI_API_KEY=sk-tu-api-key-aqui

# Queue (database por defecto, cambiar a redis en producción)
QUEUE_CONNECTION=database

# CORS para SendPulse
CORS_ALLOWED_ORIGINS=*

4. Generar APP_KEY

php artisan key:generate

5. Crear base de datos

Crea la base de datos mcp_server en MySQL:

CREATE DATABASE mcp_server CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

6. Publicar Sanctum y ejecutar migraciones

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Esto creará las tablas:

  • clientes → usuarios del sistema
  • products → productos procesados por cliente
  • consultas → log de consultas desde SendPulse
  • personal_access_tokens → tokens de Sanctum
  • jobs → cola de trabajos (queue)

7. Configurar queue worker

Para procesamiento asíncrono de archivos Excel, ejecuta el worker:

php artisan queue:work --tries=3 --timeout=120

En producción (cPanel): configura un cron job cada minuto:

* * * * * cd /ruta/a/tu/proyecto && php artisan schedule:run >> /dev/null 2>&1

Y añade en app/Console/Kernel.php:

protected function schedule(Schedule $schedule)
{
    $schedule->command('queue:work --stop-when-empty')->everyMinute();
}

8. Servir la aplicación (desarrollo)

php artisan serve

La aplicación estará en http://localhost:8000


🧪 Ejecutar tests

php artisan test

Los tests cubren:

  • ✅ Registro y login de clientes
  • ✅ Validación de datos de entrada
  • ✅ Subida de archivos Excel
  • ✅ Endpoint MCP público con validación de tokens
  • ✅ Búsqueda de productos

📡 Endpoints de la API

1. Registro de cliente

POST /api/register

Body (JSON):

{
  "nombre": "Juan Pérez",
  "email": "juan@example.com",
  "password": "password123",
  "password_confirmation": "password123"
}

Respuesta (201):

{
  "cliente": {
    "id": 1,
    "nombre": "Juan Pérez",
    "email": "juan@example.com"
  },
  "sanctum_token": "1|abc123...",
  "api_token": "xyz789..."
}
  • sanctum_token → usar en header Authorization: Bearer {token} para endpoints protegidos
  • api_token → usar en la URL del endpoint MCP público

2. Login

POST /api/login

Body (JSON):

{
  "email": "juan@example.com",
  "password": "password123"
}

Respuesta (200):

{
  "cliente": {...},
  "sanctum_token": "1|abc123...",
  "api_token": "xyz789..."
}

3. Subir archivo Excel (autenticado)

POST /api/upload

Headers:

Authorization: Bearer {sanctum_token}
Content-Type: multipart/form-data

Body (Form Data):

  • file → archivo Excel (.xlsx, .xls, .csv) - máx. 10MB

Respuesta (202):

{
  "message": "Archivo recibido. Procesando en segundo plano...",
  "status": "queued",
  "file": "uploads/abc123.xlsx"
}

Proceso:

  1. El archivo se sube y almacena
  2. Se despacha un Job a la cola
  3. El Job lee el Excel con PhpSpreadsheet
  4. Envía los datos a OpenAI para estructurarlos
  5. Guarda los productos en la base de datos

Nota: El procesamiento puede tardar 10-60 segundos dependiendo del tamaño del archivo.


4. Endpoint MCP público (para SendPulse)

POST /api/mcp/{api_token}/consulta

Headers:

Content-Type: application/json

Body (JSON):

{
  "pregunta": "precio del aceite 20w50"
}

Respuesta (200):

{
  "respuesta": "El Aceite Motor 20W50 Premium cuesta $12.50 según la lista actualizada del cliente."
}

Si no se encuentra:

{
  "respuesta": "No se encontró información relevante."
}

Notas:

  • No requiere Authorization header, usa api_token en la URL
  • Guarda cada consulta en la tabla consultas
  • Busca productos por coincidencia parcial en nombre, categoría y descripción

🔧 Configuración de SendPulse

En tu chatbot de SendPulse, configura una acción HTTP:

URL: https://tu-dominio.com/api/mcp/TU_API_TOKEN_AQUI/consulta

Método: POST

Headers:

Content-Type: application/json

Body:

{
  "pregunta": "{{user_message}}"
}

Respuesta: Extrae respuesta del JSON y envíala al usuario.


📂 Estructura de base de datos

Tabla clientes

Campo Tipo Descripción
id bigint ID único
nombre varchar(255) Nombre del cliente
email varchar(255) Email único
password varchar(255) Contraseña hasheada
api_token varchar(80) Token único para endpoint MCP

Tabla products

Campo Tipo Descripción
id bigint ID único
cliente_id bigint FK a clientes
producto varchar(255) Nombre del producto
precio decimal(12,2) Precio
descripcion text Descripción
categoria varchar(255) Categoría
ultima_actualizacion timestamp Fecha de última actualización

Tabla consultas

Campo Tipo Descripción
id bigint ID único
cliente_id bigint FK a clientes
texto_consulta text Pregunta recibida
respuesta text Respuesta generada
fecha timestamp Fecha de la consulta

🎯 Ejemplo de flujo completo

1. Registro del cliente

curl -X POST http://localhost:8000/api/register \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "Tienda AutoParts",
    "email": "autoparts@example.com",
    "password": "seguro123",
    "password_confirmation": "seguro123"
  }'

Respuesta:

{
  "cliente": {...},
  "sanctum_token": "2|abcdefg12345",
  "api_token": "xyz789token"
}

2. Subir archivo Excel

curl -X POST http://localhost:8000/api/upload \
  -H "Authorization: Bearer 2|abcdefg12345" \
  -F "file=@productos.xlsx"

Respuesta:

{
  "message": "Archivo recibido. Procesando en segundo plano...",
  "status": "queued"
}

3. Consultar desde SendPulse

curl -X POST http://localhost:8000/api/mcp/xyz789token/consulta \
  -H "Content-Type: application/json" \
  -d '{"pregunta": "precio del filtro de aceite"}'

Respuesta:

{
  "respuesta": "El Filtro de Aceite Premium cuesta $5.99 según la lista actualizada del cliente."
}

🔐 Seguridad

  • ✅ Contraseñas hasheadas con bcrypt
  • ✅ Tokens únicos por cliente (60 caracteres aleatorios)
  • ✅ Validación de MIME types en uploads
  • ✅ Límite de 10MB por archivo
  • ✅ Middleware de validación de tokens
  • ✅ Rate limiting (configurable en RouteServiceProvider)

Recomendaciones:

  • En producción, usa HTTPS
  • Configura QUEUE_CONNECTION=redis para mejor rendimiento
  • Añade rate limiting al endpoint MCP
  • Implementa soft deletes para auditoría

🐛 Debugging y logs

Los logs se guardan en storage/logs/laravel.log. Eventos clave:

  • Subida de archivos
  • Procesamiento de Excel (inicio y fin)
  • Consultas MCP
  • Errores de OpenAI
  • Fallos de Jobs

Ver logs en tiempo real:

tail -f storage/logs/laravel.log

Ver estado de la cola:

php artisan queue:failed

Reintentar jobs fallidos:

php artisan queue:retry all

🚀 Deployment en cPanel

1. Subir archivos

Sube todos los archivos excepto vendor y node_modules.

2. Instalar dependencias vía SSH

cd public_html/mcp
composer install --optimize-autoloader --no-dev

3. Configurar .env

Edita .env con los datos de tu hosting:

APP_ENV=production
APP_DEBUG=false
DB_HOST=localhost
DB_DATABASE=usuario_mcp_server
DB_USERNAME=usuario_mysql
DB_PASSWORD=tu_password
OPENAI_API_KEY=sk-...

4. Configurar DocumentRoot

En cPanel, apunta el dominio a /public_html/mcp/public

5. Ejecutar migraciones

php artisan migrate --force

6. Configurar cron para queue

En cPanel → Cron Jobs:

* * * * * cd /home/usuario/public_html/mcp && php artisan queue:work --stop-when-empty >/dev/null 2>&1

7. Optimizar Laravel

php artisan config:cache
php artisan route:cache
php artisan view:cache

📝 Personalización

Mejorar búsqueda de productos

En ConsultaController@handle, puedes:

  • Usar búsqueda full-text de MySQL
  • Implementar embeddings con OpenAI para búsqueda semántica
  • Añadir sinónimos y stemming

Cambiar modelo de OpenAI

En OpenAIProcessor.php, línea 32:

'model' => 'gpt-4', // cambiar a gpt-4 para mejor calidad

Añadir webhooks

Crear un endpoint para notificar al cliente cuando termine el procesamiento:

// app/Jobs/ProcessExcelJob.php
public function handle() {
    // ... procesamiento
    Http::post($cliente->webhook_url, [
        'status' => 'completed',
        'products' => $updated
    ]);
}

🤝 Contribuir

  1. Fork el proyecto
  2. Crea una rama (git checkout -b feature/mejora)
  3. Commit tus cambios (git commit -am 'Añade nueva funcionalidad')
  4. Push a la rama (git push origin feature/mejora)
  5. Abre un Pull Request

📄 Licencia

Este proyecto es de código abierto bajo licencia MIT.


💬 Soporte

Para reportar bugs o solicitar features, abre un issue en GitHub.


✅ Checklist de deployment

  • Configurar .env con datos de producción
  • Ejecutar composer install --no-dev --optimize-autoloader
  • Ejecutar php artisan migrate --force
  • Configurar cron para queue worker
  • Apuntar DocumentRoot a /public
  • Ejecutar php artisan config:cache
  • Probar registro de cliente
  • Probar subida de Excel
  • Probar endpoint MCP desde SendPulse
  • Configurar HTTPS con certificado SSL
  • Configurar backups automáticos de BD

¡Listo! 🎉 Tu servidor MCP está funcionando.

About

🤖 Servidor MCP multiusuario Laravel 11 + OpenAI + Sanctum + Queue. Procesa archivos Excel con IA y expone API REST para chatbots (SendPulse). Compatible cPanel.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published