feat: servidor MCP local y remoto con 13 tools para operar TravelMap con LLM#75
feat: servidor MCP local y remoto con 13 tools para operar TravelMap con LLM#75tucho235 wants to merge 19 commits intofabiomb:mainfrom
Conversation
- Nuevo servidor MCP en mcp/ (PHP, sin Composer, JSON-RPC 2.0 NDJSON) - 12 tools: list/search/get/create trips, list/create routes (BRouter CSV), list/search/create POIs (auto-fill EXIF GPS+fecha, suggested_place Nominatim), import_photos_batch (hasta 50 fotos con interpolación GPS), get_stats - Extracción de helpers reutilizables: BRouterParser, ExifExtractor, Geocoder - FileHelper: nuevo saveImageFromBase64 con validación MIME+GD probe+realpath - Trip::search y Point::search con LIKE escapado y filtros opcionales - admin/import_brouter.php refactorizado para delegar en BRouterParser Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tools de edición - bootstrap.php: cargar Link.php en lugar del eliminado PoiLink.php - PoiTools: corregir new PoiLink() → new Link() en create_poi - create_route: soporta ahora el campo links (igual que create_poi) - Nuevas tools: update_trip, update_route, update_poi — patch parcial de cualquier campo excepto geometría/foto; links/tags se reemplazan completos cuando se incluyen en la llamada Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…API key auth y LocationTools - Reemplaza StatsTools por LocationTools (search_location via Nominatim) - Agrega transporte HTTP (mcp/http.php) además del stdio existente - Implementa autenticación por API key: migración DB, modelo User, admin UI y endpoint api/mcp_apikey.php - Agrega BRouterClient helper para cálculo de rutas via HTTP - Refactoriza TripTools, RouteTools y PoiTools (lógica simplificada, nuevos params) - Agrega .mcp.json para integración con Claude Code - Documenta el servidor en docs/MCP.md y docs/RFC_MCP.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Faltaba el require_once y el register de LocationTools en http.php; solo estaba en server.php (stdio), por eso el cliente remoto no veía search_location. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
ah bueno... On fire Mr. Tucho. 👏 |
|
Tucho, no lo pude testear todavía para el merge porque estuve enfermo estos días, cero programación, pero a partir de mañana espero estar mejor y ya sin fiebre 🥵 |
See no problem, no hay apuro. Capaz alguien tiene alguna nueva idea, sugerencia, o corrección. De hecho hoy mandé 1 push mas con 1 fix para que las rutas de vuelos no intente usar BRouter, sino que arme solamente con los 2 puntos de los aeropuertos. |
…compara contra $tempDir . '/' (slash forward). La verificación siempre falla en Windows.
|
le pude dar un poco de cariño y testear @tucho235 |
|
Otro tema, la url que genera es medio falopa ¿Puerto 32080? Eso dónde lo configura? mi webserver entrega sólo en el puerto 80, y esto lo maneja Apache, así que la url que genera es cualquiera |
|
Nunca te hice ACK de esto. Sí, tengo que fixear estas cosas, cuando tenga un rato le dedico. |
Reemplaza la URL hardcodeada (192.168.3.195:32080) por BASE_URL configurado en cada instalación, para que los snippets sean correctos en cualquier entorno. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
voy con el fix de la url 👍 |
Tool descriptions, parameter descriptions, error messages, hints and comments were all in Spanish — now fully in English to reduce LLM token cost. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
los prompt 👍 |
Tool descriptions, parameter descriptions, error messages, hints and comments translated from Spanish to reduce LLM token cost. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
mañana reviso una vez más todo y le doy merge suicida |
There was a problem hiding this comment.
Pull request overview
Este PR incorpora un servidor MCP (Model Context Protocol) para operar TravelMap con LLMs mediante 2 transportes (stdio y HTTP), sumando 13 tools para gestionar viajes, rutas, POIs y geocodificación, además de soporte de API Key por usuario para acceso remoto.
Changes:
- Nuevo servidor MCP en
mcp/(dispatcher, JSON-RPC NDJSON, validador de schema, logging y endpoints stdio/HTTP) + 13 tools. - Nuevos helpers reutilizables (BRouter, EXIF, Geocoder) y extensiones a modelos para soportar búsquedas y MCP API keys.
- UI + API para generar API key y migración/DDL para persistirla.
Reviewed changes
Copilot reviewed 33 out of 37 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| src/models/User.php | Agrega getters/setters y lookup por mcp_api_key + generación de API key. |
| src/models/Trip.php | Incluye show_routes_in_timeline en listados y agrega Trip::search() para búsquedas. |
| src/models/Point.php | Agrega Point::search() y amplía formatos aceptados para visit_date. |
| src/helpers/Geocoder.php | Nuevo helper para geocodificación directa/inversa con cache y rate limit. |
| src/helpers/FileHelper.php | Refactoriza post-proceso de imágenes y agrega guardado desde base64 con validaciones. |
| src/helpers/ExifExtractor.php | Nuevo helper para leer EXIF GPS/fecha e interpolar GPS faltante. |
| src/helpers/BRouterParser.php | Nuevo helper para parsear CSV de BRouter y emitir GeoJSON + métricas. |
| src/helpers/BRouterClient.php | Nuevo cliente HTTP para calcular rutas vía API de BRouter y normalizar respuesta. |
| mcp/tools/TripTools.php | Tools MCP para listar/buscar/obtener/crear/actualizar viajes. |
| mcp/tools/RouteTools.php | Tools MCP para planificar/commit/crear/actualizar rutas (incl. BRouter y temporales). |
| mcp/tools/PoiTools.php | Tools MCP para buscar/crear/actualizar POIs (incl. foto base64 + EXIF + geocoder). |
| mcp/tools/LocationTools.php | Tool MCP para búsqueda de coordenadas por nombre (Nominatim). |
| mcp/tests/run_tests.sh | Smoke tests de integración del servidor MCP + casos básicos de seguridad. |
| mcp/tests/fixtures/tiny.jpg.b64 | Fixture base64 para test de subida de imagen. |
| mcp/tests/fixtures/sample.brouter.csv | Fixture CSV para test de importación BRouter. |
| mcp/server.php | Entry point MCP stdio (NDJSON) con routing JSON-RPC y manejo de errores. |
| mcp/Schema.php | Validador minimal de JSON Schema para inputs de tools. |
| mcp/README.md | Guía rápida de configuración y lista de tools. |
| mcp/Logger.php | Logger MCP con sanitización de payloads grandes/binarios. |
| mcp/JsonRpc.php | Framing NDJSON y helpers JSON-RPC para stdio. |
| mcp/http.php | Endpoint MCP HTTP con auth Bearer/cookie y routing JSON-RPC. |
| mcp/Dispatcher.php | Registro/routing de tools + validación de schema y empaquetado de respuestas. |
| mcp/bootstrap.php | Bootstrap compartido de config/DB/helpers/modelos para servidor MCP. |
| mcp/.htaccess | Restricciones de acceso web dentro de mcp/. |
| install/migrations/024_mcp_api_key.php | Migración para agregar users.mcp_api_key + índice único. |
| includes/auth.php | Agrega utilidades CSRF (csrf_token, csrf_verify). |
| docs/RFC_MCP.md | Documento de arquitectura/decisiones para el servidor MCP. |
| docs/MCP.md | Documentación de instalación/uso del MCP server y tools. |
| database.sql | Actualiza schema base para incluir mcp_api_key e índice único. |
| backups/.htaccess | Bloquea acceso web directo a backups. |
| backups/.gitkeep | Mantiene el directorio backups/ en git. |
| backups/.gitignore | Ignora archivos zip en backups. |
| assets/js/admin_mcp_apikey.js | UI para ver/copiar/generar API key desde el admin con CSRF. |
| api/mcp_apikey.php | API para leer/generar API key asociada a la sesión del usuario. |
| admin/user_form.php | Añade sección “Acceso MCP” en el formulario de usuario + scripts de UI. |
| admin/import_brouter.php | Simplifica import delegando parseo a BRouterParser. |
| .gitignore | Ajustes de ignore (incl. logs/, .mcp.json, .claude/, etc.). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if ($passing === 0) { | ||
| $errors[$path ?: 'root'] = 'Debe cumplir exactamente una de las condiciones oneOf'; | ||
| } | ||
| // No retornamos aquí: seguimos validando el resto del schema |
| } | ||
| break; | ||
| case 'integer': | ||
| if (!is_int($data) && !(is_numeric($data) && floor((float)$data) == (float)$data)) { |
| // Capa B: sesión web (cookie PHPSESSID) | ||
| if (!$authOk && !empty($_COOKIE['PHPSESSID'])) { | ||
| session_name('PHPSESSID'); | ||
| session_start(); | ||
| if (!empty($_SESSION['logged_in']) && !empty($_SESSION['user_id'])) { | ||
| $authOk = true; | ||
| } | ||
| } |
| <FilesMatch "^(?!http\.php$).*\.php$"> | ||
| Require all denied | ||
| </FilesMatch> |
| $tempDir = ROOT_PATH . '/uploads/mcp_temp'; | ||
| if (!is_dir($tempDir)) { | ||
| mkdir($tempDir, 0750, true); | ||
| } | ||
| $tempFilename = 'route_' . uniqid('', true) . '.geojson'; |
| // 7. MIME check vía finfo | ||
| $finfo = finfo_open(FILEINFO_MIME_TYPE); | ||
| $mimeReal = finfo_file($finfo, $tmpFile); | ||
| finfo_close($finfo); |
| if ($body === false) { | ||
| return [ | ||
| 'success' => false, | ||
| 'error' => 'No se pudo conectar con BRouter (' . self::DEFAULT_API_URL . '). Verificá la conexión a internet.', |
| * GET → devuelve la API key actual del usuario (null si no tiene). | ||
| * POST → genera y guarda una nueva API key. Requiere token CSRF en el | ||
| * header X-CSRF-Token o en el body JSON { "csrf_token": "..." }. | ||
| * Solo accesible para usuarios con sesión activa (admin). |
| private static function isIndexed(array $arr): bool | ||
| { | ||
| if (empty($arr)) return true; | ||
| return array_keys($arr) === range(0, count($arr) - 1); | ||
| } |
| foreach ($images as $idx => &$img) { | ||
| if ($img['has_gps']) { | ||
| $withGps[$idx] = $img; | ||
| } elseif ($img['has_date'] && $img['timestamp'] !== null) { | ||
| $needsEstimate[$idx] = $img; | ||
| } | ||
| } |
|
bueno, el review de Copilot generó como 30 cositas, pequeñas, pero así de perfeccionista es 😁 no me mates |
Resumen
Implementación completa de un servidor MCP (Model Context Protocol) que permite operar TravelMap en lenguaje natural desde Claude Desktop, Claude Code, Cursor u otros clientes LLM compatibles.
Cambios principales
Servidor MCP (
mcp/)Infraestructura nueva desde cero con dos transportes:
mcp/server.phpmcp/http.php*El stdio local me dio muchos problemas para que funcione correctamente, muchas veces intentó utilizar los modelos para hacer las operaciones, recomiendo el
http.Componentes internos:
Dispatcher.php(registro y routing de tools),JsonRpc.php(framing NDJSON),Schema.php(validador JSON Schema),Logger.php(logs enlogs/mcp.log),bootstrap.php(carga compartida de config, DB, helpers y modelos).13 Tools en 4 módulos
Viajes —
TripTools.phplist_trips— lista con filtros de estado, orden y límitesearch_trips— búsqueda por texto libre, tag o rango de fechasget_trip— viaje completo con rutas, POIs, tags y linkscreate_trip— crea un viaje nuevoupdate_trip— actualiza campos, tags y links (reemplazo completo)Rutas —
RouteTools.phpplan_route— calcula ruta terrestre via BRouter; guarda GeoJSON temporalcommit_route— persiste en BD la ruta calculada porplan_routecreate_route— crea ruta desde GeoJSON o CSV BRouter externoupdate_route— actualiza metadatos (sin cambiar geometría)POIs —
PoiTools.phpsearch_pois— busca por texto, viaje o tipocreate_poi— crea POI; auto-rellena coords y fecha desde EXIF si se adjunta fotoupdate_poi— actualiza datos de un POILocalización —
LocationTools.phpsearch_location— geocodifica un lugar por nombre via Nominatim (OSM)Nuevos helpers extraídos
BRouterParser.php— parseo de CSV y GeoJSON de BRouterBRouterClient.php— cliente HTTP para calcular rutas contra la API BRouterExifExtractor.php— extracción de coordenadas y fecha desde EXIF de fotosGeocoder.php— geocodificación inversa y directa via Nominatimadmin/import_brouter.phpfue simplificado al delegar enBRouterParser.Autenticación por API Key para acceso remoto
Migración
024_mcp_api_key.php: añade columnamcp_api_keyausersapi/mcp_apikey.php: endpoint para generar y revocar la claveadmin/user_form.php: nueva sección "Acceso MCP" en el formulario de usuarioincludes/auth.php: validación de Bearer tokentmk_<64hex>src/models/User.php: métodofindByMcpApiKey()El transporte HTTP acepta también la cookie de sesión web como fallback.
Configuración y documentación
.mcp.json— configuración lista para Claude Code (stdio local)docs/MCP.md— documentación completa de instalación y usodocs/RFC_MCP.md— diseño y decisiones de arquitecturamcp/README.md— guía de configuración rápidamcp/tests/run_tests.sh— suite de tests de integración con fixtures realesCómo probar