Restaurant MCP Server
Un servidor Model Context Protocol (MCP) para gestión de restaurantes construido con Spring Boot y Spring AI.
Descripción General
Este servidor MCP expone funcionalidades de gestión de restaurantes como herramientas que pueden ser llamadas por clientes de IA (como Claude). Proporciona operaciones CRUD completas para:
- Menus - Gestión de menús del restaurante
- Dishes - Gestión del catálogo de platos
- Dish-Menu Relationships - Asociar platos con menús (con precio y fecha)
- Sales - Registros de transacciones de ventas
- Sale-Menu Relationships - Rastrear qué menús fueron vendidos (con cantidad)
Arquitectura
Stack Tecnológico
- Spring Boot 3.5.6 - Framework de aplicación
- Spring AI 1.0.3 - Implementación del servidor MCP (
spring-ai-starter-mcp-server-webmvc) - Java 17 - Lenguaje de programación
- Gradle 8.14.3 - Herramienta de construcción
- Jackson - Serialización JSON
Modelo de Entidades
Basado en el diagrama ER:
MENUS (Menús)
menu_id(PK) - Identificador del menúDescripcion- Descripción del menú
PLATOS (Dishes)
plato_id(PK) - Identificador del platotipo- Tipo de platonombre- Nombre del platodescripcion- Descripción del plato
PLATOS_MENU (Dish-Menu)
menu_id(PK, FK) - Referencia al menúplato_id(PK, FK) - Referencia al platoprecio- Precio del plato en este menúfecha- Fecha en que se agregó al menú
VENTAS (Sales)
venta_id(PK) - Identificador de ventafecha- Fecha de venta
VENTAS_MENU (Sale-Menu)
menu_id(PK, FK) - Referencia al menúventa_id(PK, FK) - Referencia a la ventacantidad- Cantidad vendida
Herramientas MCP Disponibles
Herramientas de Menús (MenuService)
getAllMenus()- Obtener todos los menús del restaurantegetMenuById(Long menuId)- Obtener un menú específico por su IDcreateMenu(String description)- Crear un nuevo menú con una descripciónupdateMenu(Long menuId, String description)- Actualizar la descripción de un menú existentedeleteMenu(Long menuId)- Eliminar un menú por su ID
Herramientas de Platos (DishService)
getAllDishes()- Obtener todos los platos del restaurantegetDishById(Long dishId)- Obtener un plato específico por su IDcreateDish(String type, String name, String description)- Crear un nuevo platoupdateDish(Long dishId, String type, String name, String description)- Actualizar un platodeleteDish(Long dishId)- Eliminar un plato por su ID
Herramientas de Platos-Menús (DishMenuService)
getAllDishMenus()- Obtener todas las relaciones plato-menúgetDishesByMenuId(Long menuId)- Obtener todos los platos de un menú específicogetDishMenu(Long menuId, Long dishId)- Obtener una relación plato-menú específicaaddDishToMenu(Long menuId, Long dishId, Double price, String date)- Agregar un plato a un menúupdateDishMenu(Long menuId, Long dishId, Double price, String date)- Actualizar relación plato-menúremoveDishFromMenu(Long menuId, Long dishId)- Remover un plato de un menú
Herramientas de Ventas (SaleService)
getAllSales()- Obtener todas las ventas del restaurantegetSaleById(Long saleId)- Obtener una venta específica por su IDcreateSale(String date)- Crear un nuevo registro de ventaupdateSale(Long saleId, String date)- Actualizar la fecha de una ventadeleteSale(Long saleId)- Eliminar una venta por su ID
Herramientas de Ventas-Menús (SaleMenuService)
getAllSaleMenus()- Obtener todas las relaciones venta-menúgetMenusBySaleId(Long saleId)- Obtener todos los menús de una venta específicagetSaleMenu(Long menuId, Long saleId)- Obtener una relación venta-menú específicaaddMenuToSale(Long menuId, Long saleId, Integer quantity)- Agregar un menú a una ventaupdateSaleMenu(Long menuId, Long saleId, Integer quantity)- Actualizar cantidad de menú en ventaremoveMenuFromSale(Long menuId, Long saleId)- Remover un menú de una venta
Configuración
application.properties
# Banner and Logging (disabled for STDIO)
spring.main.banner-mode=off
logging.level.root=OFF
logging.level.org.springframework=OFF
logging.level.com.uptc.frw=OFF
# MCP Server - STDIO Transport
spring.ai.mcp.server.name=mcprestaurant
spring.ai.mcp.server.version=0.0.1
spring.ai.mcp.server.stdio=true
spring.main.web-application-type=none
# Change Notifications
spring.ai.mcp.server.resource-change-notification=true
spring.ai.mcp.server.tool-change-notification=true
spring.ai.mcp.server.prompt-change-notification=true
# External Restaurant API
restaurant.api.base-url=http://localhost:8080/api
restaurant.api.username=admin
restaurant.api.password=passwordVariables de Entorno
Configura mediante la sección env de Claude Desktop o variables de entorno del sistema:
Opción 1: Configuración de Claude Desktop
{
"mcpServers": {
"restaurant": {
"command": "/usr/bin/java",
"args": ["-jar", "/path/to/MCPRestaurant/build/libs/mcprestaurant-0.0.1-SNAPSHOT.jar"],
"env": {
"RESTAURANT_API_BASE_URL": "http://localhost:8080/api",
"RESTAURANT_API_USERNAME": "admin",
"RESTAURANT_API_PASSWORD": "password"
}
}
}
}Opción 2: Variables de Entorno del Sistema
export RESTAURANT_API_BASE_URL=https://your-api.com/api
export RESTAURANT_API_USERNAME=your_username
export RESTAURANT_API_PASSWORD=your_passwordConstrucción y Ejecución
Construir el Proyecto
./gradlew clean buildEjecutar el Servidor
./gradlew bootRunO ejecutar el JAR:
java -jar build/libs/mcprestaurant-0.0.1-SNAPSHOT.jarRequisitos de la API Externa
El servidor MCP espera que tu API externa de restaurante exponga los siguientes endpoints:
Menus
GET /api/menus- Listar todos los menúsGET /api/menus/{id}- Obtener un menú por IDPOST /api/menus- Crear un menú (body:{"description": "...")PUT /api/menus- Actualizar un menú (body:{"idMenu": ..., "description": "...")DELETE /api/menus?id={id}- Eliminar un menú (parámetro de consulta)
Dishes
GET /api/dishes- Listar todos los platosGET /api/dishes/{id}- Obtener un plato por IDPOST /api/dishes- Crear un plato (body:{"dishType": "...", "name": "...", "description": "...")PUT /api/dishes- Actualizar un plato (body:{"id": ..., "dishType": "...", "name": "...", "description": "...")DELETE /api/dishes?id={id}- Eliminar un plato (parámetro de consulta)
Dish-Menus
GET /api/dish-menus- Listar todas las relacionesGET /api/dish-menus/{menuId}/{dishId}- Obtener relación específicaPOST /api/dish-menus- Crear relación (body:{"idMenu": ..., "idDish": ..., "price": ..., "date": "...")PUT /api/dish-menus- Actualizar relación (body:{"idMenu": ..., "idDish": ..., "price": ..., "date": "...")DELETE /api/dish-menus?idmenu={id}&iddish={id}- Eliminar relación (parámetros de consulta)
Sales
GET /api/sales- Listar todas las ventasGET /api/sales/{id}- Obtener una venta por IDPOST /api/sales- Crear una venta (body:{"date": "...")PUT /api/sales- Actualizar una venta (body:{"id": ..., "date": "...")DELETE /api/sales?id={id}- Eliminar una venta (parámetro de consulta)
Sale-Menus
GET /api/SalesMenu- Listar todas las relacionesGET /api/SalesMenu/sale/{saleId}- Obtener menús de una ventaGET /api/SalesMenu/{menuId}/{saleId}- Obtener relación específicaPOST /api/SalesMenu- Crear relación (body:{"menuId": ..., "saleId": ..., "quantity": ...})PUT /api/SalesMenu- Actualizar relación (body:{"idMenu": ..., "idSale": ..., "quantity": ...})DELETE /api/SalesMenu?idmenu={id}&idsale={id}- Eliminar relación (parámetros de consulta)
Patrones Clave
Crear (POST): Todos los datos en el body JSON Actualizar (PUT): Todos los datos incluyendo IDs en el body JSON (sin parámetros de ruta) Eliminar (DELETE): IDs como parámetros de consulta (ej., ?id={id} o ?idmenu={id}&iddish={id}) Obtener por ID (GET): ID en la ruta (ej., /menus/{id}) Obtener relaciones (GET): Parámetros de ruta o consulta según sea necesario
Conexión a Claude Desktop
Este servidor utiliza transporte STDIO - Claude Desktop lanza el JAR directamente y se comunica mediante flujos de entrada/salida estándar.
Configuración Rápida
- Construir el servidor:
./gradlew clean build- Configurar Claude Desktop - Edita
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"restaurant": {
"command": "/usr/bin/java",
"args": [
"-jar",
"/path/to/MCPRestaurant/build/libs/mcprestaurant-0.0.1-SNAPSHOT.jar"
],
"env": {
"RESTAURANT_API_BASE_URL": "http://localhost:8080/api",
"RESTAURANT_API_USERNAME": "admin",
"RESTAURANT_API_PASSWORD": "password"
}
}
}
}- Reiniciar Claude Desktop - El servidor se lanzará automáticamente cuando sea necesario.
Notas de Arquitectura
- Transporte: STDIO (flujos de entrada/salida estándar)
- Tipo de Aplicación: No-web (
spring.main.web-application-type=none) - Logging: Completamente deshabilitado para prevenir corrupción del protocolo JSON-RPC
- Ciclo de Vida: Gestionado por Claude Desktop (inicio/parada automática)
Para configuración detallada, solución de problemas y formatos de endpoints de API, ver MCP_CONNECTION_GUIDE.md.
Estructura del Proyecto
src/main/java/com/uptc/frw/mcprestaurant/
├── model/
│ ├── Menu.java # Entidad Menu
│ ├── Dish.java # Entidad Dish
│ ├── DishMenu.java # Relación Dish-Menu
│ ├── Sale.java # Entidad Sale
│ └── SaleMenu.java # Relación Sale-Menu
├── service/
│ ├── MenuService.java # Herramientas de Menu (métodos @Tool)
│ ├── DishService.java # Herramientas de Dish (métodos @Tool)
│ ├── DishMenuService.java # Herramientas de Dish-Menu (métodos @Tool)
│ ├── SaleService.java # Herramientas de Sale (métodos @Tool)
│ └── SaleMenuService.java # Herramientas de Sale-Menu (métodos @Tool)
└── McprestaurantApplication.java # Aplicación principal con ToolCallbackProvidersCómo Funciona
- Anotación @Tool: Cada método de servicio está anotado con
@Tooly una descripción - ToolCallbackProvider: La aplicación principal registra cada servicio como un
MethodToolCallbackProvider - Protocolo MCP: Spring AI MCP Server automáticamente expone estas herramientas mediante el protocolo MCP
- Integración con IA: Los clientes de IA (como Claude) pueden descubrir e invocar estas herramientas
- API Externa: Cada método de herramienta llama a la API externa del restaurante usando RestClient con Basic Auth
Ejemplo de Uso
Una vez conectado a Claude, puedes preguntar:
- "Muéstrame todos los menús del restaurante"
- "Crea un nuevo plato llamado 'Pasta Carbonara' de tipo 'Main Course'"
- "Agrega el plato con ID 5 al menú con ID 2 con un precio de 15.99"
- "¿Qué platos hay en el menú 1?"
- "Crea una nueva venta para hoy"
- "Agrega el menú 2 con cantidad 3 a la venta 10"
Claude automáticamente llamará las herramientas MCP apropiadas para cumplir estas solicitudes.
Referencias
Licencia
Este proyecto es para fines educativos.
