================================================================================
LUMEN RESTO MCP - README
================================================================================
PURPOSE
-------
MCP server para crear reservas y consultar horarios de restaurantes usando
Supabase de forma segura y multi-tenant.
Diseñado para agentes de WhatsApp y llamadas telefónicas que necesitan:
- Verificar horarios de apertura y cierre
- Crear reservas con asignación automática de mesas
- Manejar múltiples restaurantes desde un solo servidor
TOOLS
-----
1. check_restaurant_schedule
Consulta horarios de un restaurante para una fecha y hora específica.
Parámetros:
- restaurant_id (requerido): UUID del restaurante
- date (requerido): Fecha en formato YYYY-MM-DD
- time (opcional): Hora en formato HH:MM
- service_type (opcional): "almuerzo" o "cena" (se infiere de time si omitido)
- channel (opcional): Canal de origen (whatsapp, phone, etc.)
Ejemplo:
{
"restaurant_id": "123e4567-e89b-12d3-a456-426614174000",
"date": "2025-12-25",
"time": "20:00",
"service_type": "cena",
"channel": "whatsapp"
}
Respuesta típica:
🕒 Abierto
📅 Miércoles 2025-12-25, cena
⏰ Horario: 19:00-23:00
🌍 Timezone: America/Argentina/Buenos_Aires
✅ Abierto
2. create_reservation
Crea una nueva reserva con asignación automática de mesa.
Parámetros:
- restaurant_id (requerido): UUID del restaurante
- phone (requerido): Teléfono del cliente (se normaliza a E.164)
- full_name (opcional): Nombre completo del cliente
- language (opcional): Idioma preferido del cliente
- date (requerido): Fecha en formato YYYY-MM-DD
- time (requerido): Hora en formato HH:MM
- party_size (requerido): Número de personas (>0)
- service_type (opcional): "almuerzo" o "cena" (se infiere de time si omitido)
- duration_minutes (opcional): Duración en minutos (usa default del restaurante si omitido)
- notes (opcional): Notas adicionales
- occasion (opcional): Ocasión especial (cumpleaños, aniversario, etc.)
- special_needs (opcional): Necesidades especiales (silla de ruedas, alergias, etc.)
- channel (opcional): Canal de origen
- idempotency_hint (opcional): Hint para deduplicación
Ejemplo:
{
"restaurant_id": "123e4567-e89b-12d3-a456-426614174000",
"phone": "+5491123456789",
"full_name": "Juan Pérez",
"date": "2025-12-25",
"time": "20:00",
"party_size": "4",
"service_type": "cena",
"occasion": "cumpleaños",
"channel": "whatsapp"
}
Respuesta típica (éxito):
✅ Reserva confirmada
🍽️ ID: 789e4567-e89b-12d3-a456-426614174999
📅 2025-12-25 a las 20:00
👥 4 personas
📍 Mesa: A5
⏱️ Duración: 90 min
🌍 Timezone: America/Argentina/Buenos_Aires
📱 Canal: whatsapp
Respuesta típica (sin disponibilidad):
❌ Sin disponibilidad: no hay mesas para 4 personas.
📅 2025-12-25 a las 20:00
🍽️ cena
💡 Horarios disponibles: 19:30, 20:30
ENVIRONMENT VARIABLES
---------------------
Requeridas:
- SUPABASE_URL: URL del proyecto Supabase
Ejemplo: https://vgydyxbtqjzuxloqnvuy.supabase.co
- SUPABASE_SERVICE_ROLE_KEY: Service role key de Supabase
(secret - nunca logueado)
SECURITY MODEL
--------------
1. Multi-tenant
- Cada herramienta requiere restaurant_id explícito
- Las consultas siempre filtran por restaurant_id
- No hay cross-tenant data leakage
2. Table whitelist
- Solo 8 tablas permitidas (hardcoded)
- No se permiten DELETE operations
- No se permite SQL arbitrario
- No se permiten nombres de tabla dinámicos
3. Input validation
- Todos los UUIDs validados con regex
- Todas las fechas parseadas estrictamente (YYYY-MM-DD)
- Todas las horas parseadas estrictamente (HH:MM)
- Todos los enteros validados con bounds
4. Secrets protection
- Service role key nunca se loguea
- Teléfonos enmascarados en logs (***1234)
- Authorization headers nunca en logs
5. Network safety
- Timeouts: connect 5s, read 10s
- HTTP client compartido (connection pooling)
- Retry no implementado (fail fast)
6. Error handling
- Errores amigables en español
- No se exponen stack traces al usuario
- Logs técnicos a stderr
BUSINESS RULES
--------------
Horarios (check_restaurant_schedule):
- Precedencia: event closes > special_dates > regular_closed_days > schedules
- day_of_week: 0=Domingo, 6=Sábado
- service_type: almuerzo (< 17:00), cena (>= 17:00)
- Timezone: siempre del restaurante (restaurants.timezone)
Reservas (create_reservation):
- SIEMPRE asigna mesa (table_id nunca NULL)
- Status inicial: "confirmed"
- Duración: restaurants.default_reservation_duration o 90 min
- Best-fit table: menor capacidad >= party_size
- Anti-overbooking: chequea reservas activas (pending, confirmed, seated)
- Anti-duplicados: mismo client + date + start_time devuelve existente
- Cliente: upsert por (restaurant_id, phone)
- Teléfono: normalizado a E.164 si posible
Disponibilidad:
- Rechaza si restaurante cerrado
- Rechaza si todas las mesas ocupadas o bloqueadas
- Sugiere hasta 2 alternativas (±30min, ±60min)
- Alternativas verificadas (horario abierto + mesa disponible)
TROUBLESHOOTING
---------------
Error: "Missing SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY"
Solución: Verificar variables de entorno están seteadas.
Error: "❌ Configuración: credenciales Supabase inválidas."
Solución: Verificar SUPABASE_SERVICE_ROLE_KEY es correcto y no expiró.
Error: "❌ Conexión: timeout consultando Supabase."
Solución: Verificar conectividad de red, Supabase status.
Error: "❌ Error: restaurante {id} no encontrado."
Solución: Verificar restaurant_id existe en tabla restaurants.
Error: "❌ Cerrado: el restaurante no atiende en ese horario."
Solución: Normal - restaurante cerrado. Chequear restaurant_schedules,
special_dates, regular_closed_days.
Error: "❌ Sin disponibilidad: no hay mesas para X personas."
Solución: Normal - todas las mesas ocupadas. Usar horarios sugeridos o
verificar tables.capacity y tables.is_active.
DOCKER USAGE
------------
Build:
docker build -t lumen-resto-mcp .
Run:
docker run -i --rm \
-e SUPABASE_URL="https://vgydyxbtqjzuxloqnvuy.supabase.co" \
-e SUPABASE_SERVICE_ROLE_KEY="your-service-role-key" \
lumen-resto-mcp
Test tools/list:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | docker run -i --rm \
-e SUPABASE_URL="https://vgydyxbtqjzuxloqnvuy.supabase.co" \
-e SUPABASE_SERVICE_ROLE_KEY="your-service-role-key" \
lumen-resto-mcp
TESTING
-------
Verificar herramientas disponibles:
tools/list debe devolver:
- check_restaurant_schedule
- create_reservation
Test schedule check (ajustar restaurant_id y date):
tools/call check_restaurant_schedule {
"restaurant_id": "your-restaurant-uuid",
"date": "2025-12-25",
"time": "20:00",
"service_type": "cena"
}
Test reservation (ajustar restaurant_id, phone, date):
tools/call create_reservation {
"restaurant_id": "your-restaurant-uuid",
"phone": "+5491123456789",
"full_name": "Test User",
"date": "2025-12-25",
"time": "20:00",
"party_size": "2",
"channel": "test"
}
LOGS
----
Todos los logs van a stderr.
Formato: TIMESTAMP [LEVEL] mensaje
Ejemplos:
2025-12-22 10:30:45 [INFO] Starting Lumen Resto MCP server
2025-12-22 10:31:12 [INFO] Checking schedule for restaurant abc-123...
2025-12-22 10:31:15 [INFO] Creating reservation for restaurant abc-123, phone ***6789
2025-12-22 10:31:18 [INFO] Reservation created: def-456, table A5
2025-12-22 10:32:00 [ERROR] Supabase 401 on restaurants
ARCHITECTURE
------------
Ver CLAUDE.md para detalles técnicos y guía de extensión.
SUPPORT
-------
Para bugs o feature requests, contactar al equipo de desarrollo.
================================================================================