Futureweb Intervals MCP

Servidor MCP de Intervals.icu autoalojado para ChatGPT y Claude: análisis de entrenamiento (plan vs ejecución, carga, intensidad, recuperación, alimentación, durabilidad), todos los campos personalizados y flujos de datos, datos de Garmin. Solo lectura por defecto, OAuth integrado, GPL-3.0.

Documentación

Futureweb Intervals MCP icon

Futureweb Intervals MCP

Servidor MCP avanzado de Intervals.icu para ChatGPT, Claude y cualquier cliente MCP: métricas enriquecidas con Garmin, todos los campos y flujos personalizados, información de recuperación y análisis de rendimiento de resistencia.

CI License: GPL-3.0 Python 3.12+ Status: public beta Garmin Intervals Bridge

Un servidor de Model Context Protocol que permite a los asistentes de IA leer y analizar tus datos de entrenamiento de Intervals.icu como lo haría un entrenador: actividades con todos los campos y flujos personalizados, intervalos, bienestar frente a líneas base personales, umbrales y zonas, entrenamientos planificados frente a ejecutados, ascensos, medidores de potencia duales, mejores esfuerzos, eficiencia y resistencia a la fatiga, nutrición y peso, resúmenes de entrenamiento y el calendario. Se ejecuta donde tú lo ejecutes, solo habla con la API de Intervals.icu y no expone nada que escriba a menos que lo habilites.

Continuación de mvilanova/intervals-mcp-server. El proyecto original ya no se desarrolla activamente (último commit el 2 de agosto de 2026, 29 pull requests abiertas). Este fork mantenido por la comunidad lo continúa: las pull requests abiertas útiles fueron revisadas y fusionadas con crédito a sus autores, los errores corregidos y el servidor reconstruido en torno al análisis de entrenamiento, datos de Garmin y acceso remoto seguro. No está afiliado a Intervals.icu ni a Garmin.

Proyecto complementario: el Garmin Intervals Bridge restaura las métricas que Garmin elimina de los archivos que envía a Intervals.icu (resistencia, efecto de entrenamiento, tiempo de recuperación, VO₂max, dinámica de carrera, detalles de sueño y HRV…). Este MCP está diseñado para leer todo eso, pero funciona igualmente bien sin el bridge.

Contenido

Aspectos destacados

  • Cada elemento personalizado, resuelto dinámicamente. Los campos personalizados de actividades, campos de intervalos, flujos y campos de bienestar se leen de tus propias definiciones y se informan con nombre, código, valor y unidades. Nada específico del dispositivo está codificado; null, NaN, cero y ausente permanecen distintos, los campos que no pertenecen al deporte se mantienen separados y las cargas del dispositivo nunca se mezclan con la carga de Intervals.icu.
  • Flujos a resolución completa. Cualquier flujo como resumen, CSV o JSON, segmentado por índice o tiempo, reducido de muestreo y paginado, además de estadísticas por intervalo de cualquier flujo (por ejemplo, la caída de resistencia de cada intervalo).
  • Análisis de entrenamiento en lugar de volcados brutos. Informe de actividad en una sola llamada, planificado frente a ejecutado por paso (también para eventos eliminados y recorridos extendidos más allá del plan), ascensos y descensos, verificación del segundo medidor de potencia, mejores esfuerzos, intervalos similares, entrenamientos repetidos a lo largo del tiempo, eficiencia potencia-frecuencia cardíaca, resistencia a la fatiga, carga de entrenamiento (relación agudo:crónico, monotonía, tensión), distribución de intensidad en tres zonas con índice de polarización, durabilidad aeróbica, proyección de carga sobre el plan, instantánea de recuperación con líneas base de 42 días, tendencias y correlaciones de bienestar, tendencias de nutrición y peso, resúmenes semanales y mensuales. Estadísticas con sus tamaños de muestra; la interpretación queda para el entrenador.
  • Eficiente en tokens. detail_level (compact, standard, full) y output_format="json" en las herramientas pesadas, nueve indicaciones de entrenamiento listas y dos recursos MCP.
  • Acceso remoto seguro. Servidor OAuth 2.1 integrado con inicio de sesión "Continuar con Intervals.icu", página de consentimiento con permisos por conexión, documentos de metadatos de cliente con private_key_jwt (ChatGPT), PKCE y RFC 9207. HTTP transmisible (/mcp) y SSE desde un solo proceso.
  • Solo lectura por defecto. Las herramientas se agrupan en clases de permisos (read, write, destructive, admin) aplicadas en el servidor; solo read está activa a menos que habilites más.
  • Probado. Más de 400 pruebas con datos sintéticos, ruff, mypy, CodeQL, GitHub Actions fijadas, pruebas de compilación y smoke tests de Docker en cada pull request.

Funciona con el Garmin Intervals Bridge

Garmin device ──► Garmin Connect ──► official sync ──► Intervals.icu activity (filtered FIT)
                        │                                     ▲
                        └── Garmin Intervals Bridge ──────────┘  restores custom fields, streams, wellness
                                                              │
                                              Futureweb Intervals MCP (this project)
                                                              │
                                                 ChatGPT / Claude / any MCP client

El Garmin Intervals Bridge escribe las métricas que Garmin filtra en los campos personalizados de actividad, flujos personalizados y campos de bienestar que definiste en Intervals.icu. El MCP lee esas definiciones en tiempo de ejecución, por lo que cada valor restaurado aparece automáticamente en las herramientas:

Restaurado por el bridgeDónde lo muestra el MCP
Efecto de entrenamiento, EPOC, carga de entrenamiento de Garmin, tiempo de recuperación, VO₂max, condición de rendimiento, resistencia inicio/fin, pérdida de sudor, temperaturasget_activity_details, get_activity_report, get_training_summary, get_training_load (cargas del dispositivo separadas de la carga de Intervals.icu), get_fueling_analysis (pérdida de sudor por hora), get_activity_data_audit (qué campos aún tienen un marcador de cero o ningún valor)
Resistencia y resistencia potencial, segundo medidor de potencia, velocidad ajustada por pendiente, selección de marchas, flujos de dinámica de carreraget_activity_streams, get_activity_intervals, analyze_workout_execution, analyze_climbs, compare_power_streams
SpO₂ nocturna, respiración, frecuencia cardíaca durante el sueño, detalles de HRV, Body Battery, etapas de sueño y estrés, disposición, nutriciónget_wellness_data, get_recovery_snapshot, get_wellness_trends, get_nutrition_summary

El MCP nunca contacta con Garmin; el bridge es opcional y otros dispositivos o herramientas de sincronización que llenen elementos personalizados reciben el mismo tratamiento. Ejemplos prácticos y notas sobre cómo leer las métricas del dispositivo correctamente: docs/GARMIN_BRIDGE.md.

Herramientas

67 herramientas; 52 de ellas solo leen. Las herramientas de escritura están marcadas con ✎ (write), ✖ (destructive) o ⚙ (admin) y están ocultas a menos que su clase esté habilitada. La mayoría de las herramientas aceptan output_format="json" y detail_level (compact primero). Las herramientas nunca toman una clave de API: las credenciales provienen solo del entorno del servidor.

El catálogo se mantiene pequeño para el cliente de IA: descripciones cortas que dicen cuándo usar una herramienta, una descripción y (donde los valores son fijos) un enum para cada parámetro, y resultados de texto sin una copia estructurada duplicada. Los detalles de métodos y el formato de entrenamiento viven en recursos MCP (intervals://methods/<topic>, intervals://workout-syntax) y en get_guide(topic) para clientes que solo llaman herramientas. tools/list es de aproximadamente 22.7k tokens en MCP_PERMISSIONS=read,write (antes 42.0k; cl100k); consulta Conjuntos de herramientas para un conjunto más pequeño.

Análisis de actividad

HerramientaQué hace
get_activity_reportAnálisis completo en una llamada: resumen con combustible (carbohidratos usados/ingeridos por hora, pérdida de sudor, energía), clima (temperatura, sensación térmica, viento, proporción de viento en contra/a favor), balance de W′ (agotamiento máximo, tiempo por debajo del 75/50/25 % de W′), plan frente a ejecución o intervalos, verificación del segundo medidor de potencia, ascensos, notas de calidad de datos (fuente, tiempos de carga y análisis, paradas de grabación, marcadores de cero); include_route_history compara actividades anteriores en la misma ruta de Intervals.icu (tiempo, potencia, W/kg, FC, clima, resistencia); detail_level compacto (números centrales, una línea de contexto y hallazgos clave, aproximadamente 2-2.5k caracteres), estándar o completo
get_activity_data_auditProcedencia y calidad de datos de una actividad: fuente y archivo (sincronización de Garmin, exportación de Garmin o carga del bridge, stub de Strava), tiempos de carga y análisis, duplicados filtrados, paradas de grabación y vacíos, vueltas FIT frente a intervalos y ediciones manuales, identidad del dispositivo y sensores, flujos habituales para el deporte pero faltantes, cobertura por flujo, campos personalizados con valor / marcador de cero / ninguno y qué podría llenar el Garmin Intervals Bridge; sin una actividad, la cobertura de datos por deporte de un período
analyze_workout_executionPlanificado frente a ejecutado por paso (duración, adherencia al objetivo, tiempo en rango, respuesta de FC, caída, deriva Pw:FC con el signo de desacoplamiento de Intervals.icu, resistencia). Un paso puede abarcar cualquier número de vueltas; con auto-vueltas del dispositivo, los límites de paso dentro de las vueltas se colocan en el cambio de intensidad (las pulsaciones de vuelta se conservan), los pasos sin vuelta propia se encuentran entre sus vecinos, y una advertencia con alignment_confidence dice hasta qué punto se pueden confiar los resultados por paso. Los objetivos abiertos (zona superior) son límites inferiores, los pasos de distancia se comparan por distancia. Los pasos se limitan a su duración planificada, los intervalos más largos se dividen para el análisis, y el recorrido más allá del plan se informa por separado con su carga y esfuerzos adicionales. Tolerancias para desplazamiento de inicio, pausas y longitud de paso; planned_workout_doc para eventos eliminados; eventos coincidentes sugeridos solo lectura
analyze_climbsAscensos, descensos y pausas con potencia, NP, FC, VAM y flujos personalizados por segmento; pendiente suavizada sobre una ventana de distancia (pendiente bruta opcional), confianza de pendiente alta/media/baja por segmento (sin pendiente por debajo de la distancia horizontal mínima, bruta incluida), pausas reales frente a movimiento lento, perfiles de deporte para ciclismo, carrera y senderismo, indicadores de calidad de datos
compare_power_streamsComparación alineada por muestras de dos medidores de potencia: desfase, bandas de potencia, ventanas estables, deriva, retraso; sin activity_id (rango de fechas o activity_ids) cada recorrido con un segundo flujo de potencia se compara por sí mismo y se resume por bicicleta, interior/exterior, medidor principal y segunda fuente de potencia con n, mediana, DE entre recorridos y rango (general, por banda de potencia, ventanas estables), deriva, retraso, valores atípicos y recorridos lejos de la mediana; nunca un factor de corrección
get_best_effortsMejores esfuerzos de una actividad por duraciones o distancias, con sus ventanas de tiempo transcurrido (índice final exclusivo); las ventanas que cruzan una pausa de grabación se marcan
get_activity_histogramDistribución de tiempo de potencia, frecuencia cardíaca, ritmo o GAP

Actividades y flujos

HerramientaQué hace
get_activitiesLista con filtros de deporte, equipo y medidor de potencia, ordenación, paginación, salida compacta o JSON; sin start_date los 30 días antes de end_date (o hoy)
get_activity_detailsResumen, umbrales utilizados (FTP, eFTP, LTHR, zonas), dispositivo y medidor de potencia, dinámica de carrera, cada campo personalizado con unidades, combustible, clima, balance de W′ y fuente/frescura
get_activity_intervalsIntervalos y grupos, campos personalizados de intervalos, estadísticas por intervalo de cualquier flujo, opcionalmente el tipo de paso planificado junto al tipo de Intervals.icu
list_activity_streams, get_activity_streamsDescubrir y obtener cualquier flujo: resumen, CSV o JSON, segmentación, reducción de muestreo, paginación (2000 muestras por página por defecto)
get_activity_messages, add_activity_message ✎, update_activity ✎Notas y comentarios, RPE, sensación, nombre, descripción (dry_run muestra la solicitud exacta)

Rendimiento a lo largo del tiempo

HerramientaQué hace
compare_best_effortsMejores esfuerzos en todas las actividades (ids, rango de fechas, deporte, equipo) lado a lado; los ids se deduplican y se limitan antes de cualquier solicitud
find_similar_intervalsActividades con intervalos comparables, desde una actividad de referencia o una longitud e intensidad dadas; misma familia de deporte por defecto, clasificadas por comparabilidad, con contexto de equipo y medidor de potencia; con una referencia, los 365 días anteriores por defecto (ventana mostrada, start_date para cualquier rango)
compare_workoutsEntrenamientos repetidos a lo largo del tiempo, comparando solo intervalos de trabajo comparables (actividad de referencia, familia de deporte, longitud, intensidad, repeticiones, rango de FTP); la actividad de referencia siempre se obtiene y siempre es el patrón, con una búsqueda por nombre en los 365 días anteriores; los picos se mantienen aparte, medias ponderadas por tiempo, potencia, FC, cadencia y tendencias de RPE de toda la actividad, indicadores de equipo y medidor de potencia
get_power_hr_efficiencyVatios por latido por banda de potencia y bicicleta a lo largo del tiempo, con tamaños de muestra mínimos y filtros para equipo, interior/exterior y posición del intervalo
get_fatigue_resistanceMejor potencia en fresco vs. después de los umbrales de kJ del atleta; sin umbrales configurados, explica el ajuste y sugiere valores en lugar de mostrar pseudo-resultados
get_long_ride_fatigue_profileFC, W/lpm, cadencia y resistencia Garmin a potencia igualada en segmentos estables antes vs. después de umbrales de trabajo (por defecto 750 / 1.500 kJ, o kJ/kg), para salidas dadas o las salidas largas de un período; trabajo previo en cada umbral y subida (kJ, kJ/kg, kJ y tiempo por encima de FTP, esfuerzos por encima de FTP), subidas después de N horas con resistencia al inicio y al final, mediana y rango entre salidas, método indicado, muestras pequeñas marcadas
get_submax_test_trendsPruebas de fatiga submáximas detectadas por Intervals.icu (#SFT) con un filtro de validez (tolerancia objetivo, CV, ignoradas, detectadas dentro de un entrenamiento regular, esfuerzo duro previo, recuperación de FC opcional) y razones para cada prueba excluida; FC al final, factor de eficiencia, HRRc y tendencia del curso de FC por familia de deporte y tipo de prueba (potencia y ritmo nunca combinados) y semana ISO solo sobre las pruebas válidas
get_training_loadCarga aguda y crónica, ratio agudo:crónico, monotonía y tensión de Foster (días de descanso como 0), semanas tipo deload, por deporte con el deporte principal, tabla de semana ISO, CTL/ATL/form/rampa; cargas de dispositivos mantenidas separadas; rangos de referencia con fuentes, sin veredicto
get_intensity_distributionDistribución de tres zonas desde zonas de potencia, FC o ritmo (mapeo por número de zonas; tiempos de zona GAP donde Intervals.icu los usa), índice de polarización según Treff et al. 2019, clase, sesiones y días duros, deriva entre las mitades, por deporte y semana, cobertura de zonas, una advertencia cuando los totales mezclan zonas de potencia y FC
get_durabilityDesacoplamiento aeróbico de sesiones largas estables después de un filtro de calidad (sesiones excluidas por razón), mediana y recuento por encima del 5 %, reciente vs. ventana con banda de estabilidad, tendencia del factor de eficiencia; proporción calificada por deporte, menos de 8 sesiones marcadas, interior/exterior mixto, bicicletas o medidores de potencia señalados; filtro de calor en el sensor del dispositivo o la temperatura de clima / sensación térmica de la actividad (temperature_source), las sesiones listan ambas temperaturas
get_load_projectionCTL, ATL y forma proyectados sobre los entrenamientos planificados (modelo de 42/7 días), cargas planificadas faltantes reportadas, días de carrera, la propia proyección de Intervals.icu y una verificación del modelo para comparar; dice de manera prominente cuando no hay nada planificado. Simulación de qué pasaría si (scenario): sesiones o plantillas semanales que no están en el calendario (carga dada o estimada como horas x IF² x 100), añadidas o reemplazando el plan, comparadas con el plan del calendario; forma en un día objetivo o el próximo RACE_A y una búsqueda de cuadrícula para la carga de los últimos días que alcanza un rango de forma dado; estadísticas del plan por semana (rampa, monotonía, sesión más larga, días de descanso) con rangos comúnmente citados y fuentes. Nada se escribe
get_athlete_power_curves, get_hr_curves, get_pace_curvesCurvas de temporada y rango de fechas
get_training_summaryTotales por semana, mes, deporte o equipo con la carga de Intervals.icu (potencia, si no FC, si no ritmo por actividad) y las sumas superpuestas por método, tiempo en zonas de potencia (sweet spot aparte) y zonas de FC, CTL/ATL al final de cada semana o mes; campos personalizados agregados por unidades y significado (sumas solo donde tienen sentido, si no media, mediana, rango o cambio); un detail_level explícito también selecciona las partes JSON (sin él, el JSON está completo)
get_weekly_summary, get_plan_complianceRevisión semanal y visión general de planificado vs. hecho

Bienestar y recuperación

HerramientaQué hace
get_recovery_snapshotHoy y los días anteriores, líneas base de 42 días, carga reciente y sesiones planificadas en una sola llamada; nombra los campos habituales de bienestar que el registro de hoy aún no tiene (aún no disponibles, no normal)
get_coach_contextPrimera llamada recomendada para un análisis semanal: visión general en aproximadamente 2-2,5k caracteres con carga, forma física, distribución de intensidad (desglose por deporte cuando las bases de zonas se mezclan), HRV / FC en reposo / sueño medias de 7 días frente a los 42 días anteriores (z frente a la variación semana a semana de los 90 días previos), durabilidad, mejores sesiones, el plan de los próximos 7 días, campos de bienestar de hoy aún no disponibles y una línea de método (ventanas, ACWR acoplado, threshold_as, regla de sesión dura); un detail_level explícito también selecciona las partes JSON (sin él, el JSON está completo)
get_wellness_trendsMedias móviles, líneas base, valores atípicos, cambios semana a semana, correlaciones, eFTP por deporte; período solicitado, retroceso y ventana de línea base indicados por separado, muestras pequeñas marcadas
get_nutrition_summaryIngesta, gasto del dispositivo, balance energético en días registrados, tendencia de peso, carga de entrenamiento por día
get_fueling_analysisCombustible de una actividad o las sesiones largas de un período: carbohidratos usados (estimación de Intervals.icu) e ingeridos por hora en movimiento, proporción ingerida de lo usado, energía, ingesta de líquidos, sodio y pérdida de sudor de campos personalizados encontrados por unidades y nombre (ceros de archivos de dispositivo tratados como marcadores de posición); por familia de deporte, y dentro de ella por duración e intensidad, con tamaños de muestra, cobertura de registro y correlaciones de Spearman desde 8 sesiones; sin objetivos
get_wellness_data, update_wellness ✎Registros diarios (include_all_fields añade cada campo de bienestar personalizado; sin start_date los 30 días antes de end_date o hoy), con una línea que nombra los campos habituales que el registro de hoy aún no tiene (valores de noche/mañana, métricas diarias como VO2max o puntuación de resistencia, y totales del día aparte); puntuaciones subjetivas (dry_run muestra la solicitud exacta)

Atleta, equipo, calendario y entrenamientos

HerramientaQué hace
get_athlete_profile, get_sport_settings, get_training_zonesPerfil, umbrales por deporte, zonas con rangos absolutos
update_sport_settings ⚙Cambio validado de FTP, LTHR, FC máxima o ritmo umbral (ritmo con su unidad, p. ej. 4:30/km); dry_run muestra la solicitud con los valores actuales
get_gear_list, get_gear_detailsBicicletas, zapatillas y componentes con kilometraje y recordatorios de mantenimiento
get_events, get_event_by_id, get_training_planCalendario con el documento completo de entrenamiento; fases del plan, objetivos semanales, carreras
validate_workout, preview_workoutVerificar y renderizar un documento de entrenamiento antes de escribirlo
add_or_update_event ✎, add_or_update_note ✎, add_events_bulk ⚙, delete_event ✖, delete_events_by_date_range ✖Cambios en el calendario: los entrenamientos se validan antes de escribirse, dry_run devuelve la solicitud exacta, un nuevo evento se rechaza cuando ese día ya tiene el mismo (allow_duplicate), la respuesta lee lo que Intervals.icu almacenó y analizó (pasos analizados vs. enviados, advertencias de análisis); las eliminaciones nombran lo que se eliminó; la eliminación por rango muestra una vista previa por defecto
get_workout_library, get_library_workout, create_library_workout ✎, add_event_from_library ✎, delete_library_workout ✖Biblioteca de entrenamientos (prueba en seco, verificación de duplicados al programar, lectura de vuelta, las eliminaciones nombran lo que se eliminó)

Elementos personalizados y servidor

HerramientaQué hace
get_custom_items, get_custom_item_by_id, create_custom_item ⚙, update_custom_item ⚙, delete_custom_item ✖Definiciones de campos personalizados, flujos y gráficos (create_custom_item y update_custom_item con dry_run; actualización: el contenido después de la fusión)
get_server_statusVersión, permisos habilitados, conjunto de herramientas, herramientas ocultas, transporte y modo de inicio de sesión, verificación de API (también --doctor)
get_guideGuía de uso, sintaxis de entrenamientos y guías de método (los recursos a continuación) para clientes que solo llaman herramientas

Prompts: recovery_check, workout_deep_dive, weekly_training_review, training_load_review, performance_progression, long_ride_climbing_analysis, nutrition_weight_trend, power_meter_comparison, workout_planning_validation, race_week (taper y forma el día de la carrera, plan de combustible desde el historial, clima, logística), fueling_review, plan_health_check (proyección de carga y escenario de qué pasaría si de las semanas planificadas) y coach_handoff (resumen compacto para otro entrenador o sesión). Recursos: intervals://guide (cómo usar las herramientas), intervals://workout-syntax (el formato de entrenamiento estructurado), intervals://methods/<topic> (cómo funciona un análisis: datos de actividad, ejecución, subidas, medidores de potencia, carga, intensidad, durabilidad, resumen, comparaciones, fatiga, bienestar, combustible), intervals://custom-items (tus definiciones de elementos personalizados). El servidor también envía instrucciones breves en la respuesta de MCP initialize (comienza con get_coach_context o get_activity_report, compacto primero, los valores faltantes no son normales, escribe solo a petición después de una vista previa), y su icono y sitio web en serverInfo. Los transportes HTTP sirven el icono sin autenticación en /favicon.ico, /favicon.png, /icon.png, /icon.svg y /apple-touch-icon.png (también usado en la página de inicio de sesión).

Conjuntos de herramientas

MCP_TOOLSET=full (por defecto) registra cada herramienta de las clases de permisos habilitadas. MCP_TOOLSET=core registra un conjunto seleccionado de 23 herramientas para clientes con un presupuesto de herramientas pequeño (aproximadamente 9,4k tokens en MCP_PERMISSIONS=read,write); MCP_PERMISSIONS todavía se aplica dentro del conjunto:

PropósitoHerramientas principales
Orientaciónget_server_status, get_guide
Revisión semanal, carga y planget_coach_context, get_training_summary, get_load_projection, get_events, get_event_by_id, get_training_plan
Una actividadget_activities, get_activity_report, get_activity_details, get_activity_intervals, get_best_efforts, get_fueling_analysis
Recuperaciónget_recovery_snapshot, get_wellness_data, get_wellness_trends
Planificaciónget_sport_settings, validate_workout, preview_workout
Escrituras (clase write)add_or_update_event ✎, update_wellness ✎, update_activity ✎

get_server_status y --doctor muestran el conjunto de herramientas activo y cuántas herramientas deja fuera; las descripciones de herramientas, prompts y guías marcan las herramientas fuera del conjunto "(conjunto de herramientas completo)". Después de una actualización del servidor que cambie herramientas o conjuntos de herramientas, actualiza la lista de herramientas en el cliente (ChatGPT: la actualización del conector en la configuración de la aplicación; Claude: reconecta el conector).

Convenciones de salida: las horas de inicio se muestran locales con el nombre de la zona horaria cuando Intervals.icu almacena una, si no con el desfase UTC derivado de la hora local y UTC de inicio, más UTC; cadencia de carrera, caminata y senderismo en pasos por minuto (spm, 2 x el valor por pierna que Intervals.icu almacena, que se muestra como almacenado), cadencia de bicicleta en rpm; temperaturas en °C (un campo personalizado de temperatura sin unidades toma la unidad en la que coinciden sus campos de temperatura hermanos); los valores faltantes son n/a, nunca 0.

Inicio rápido

Requisitos: una clave de API de Intervals.icu (Configuración → Configuración de desarrollador) y tu ID de atleta (i123456); para el paquete de Python uv (o Python 3.12+ y pip), para la imagen de contenedor Docker. Cada instalación ejecuta tu propio servidor con tus propias credenciales; no hay servicio alojado. Las versiones etiquetadas se publican como el paquete PyPI futureweb-intervals-mcp, las imágenes de contenedor ghcr.io/futureweb/intervals-mcp-server y futurewebat/futureweb-intervals-mcp (Docker Hub), un paquete de Claude Desktop (.mcpb) en el release de GitHub y una entrada en el registro oficial de MCP.

Beta: 1.0.0b1 es una versión preliminar. Nombra la versión (uvx futureweb-intervals-mcp@1.0.0b1, pip install futureweb-intervals-mcp==1.0.0b1) o permite versiones preliminares (uvx --prerelease allow futureweb-intervals-mcp, pip install --pre futureweb-intervals-mcp). uv y pip eligen una versión preliminar por su cuenta solo mientras no exista una versión final; desde 1.0.0 en adelante uvx futureweb-intervals-mcp simple obtiene la última versión final.

Desde PyPI (uvx o pip)

export API_KEY=your-api-key ATHLETE_ID=i123456        # or put both into a .env file
uvx futureweb-intervals-mcp@1.0.0b1 --doctor          # checks configuration and API access
uvx futureweb-intervals-mcp@1.0.0b1                   # starts the server on stdio

Con pip, en un entorno virtual:

pip install futureweb-intervals-mcp==1.0.0b1
futureweb-intervals-mcp --doctor

Desde el código fuente

git clone https://github.com/futureweb/intervals-mcp-server.git
cd intervals-mcp-server
uv sync --locked
cp .env.example .env                       # set API_KEY and ATHLETE_ID
uv run futureweb-intervals-mcp --doctor    # checks configuration and API access
uv run futureweb-intervals-mcp             # starts the server on stdio

Sin clonar:

uvx --from git+https://github.com/futureweb/intervals-mcp-server futureweb-intervals-mcp --version

Docker

Las versiones etiquetadas publican la misma imagen multi-arquitectura (amd64, arm64) en el GitHub Container Registry y en Docker Hub (latest solo para versiones finales, etiquetas beta como 1.0.0b1 explícitamente):

docker run --rm -i -e API_KEY=... -e ATHLETE_ID=i123456 ghcr.io/futureweb/intervals-mcp-server:1.0.0b1
docker run --rm -i -e API_KEY=... -e ATHLETE_ID=i123456 futurewebat/futureweb-intervals-mcp:1.0.0b1

Con MCP_AUTH=oauth monta un volumen en /data (la imagen mantiene OAUTH_STATE_FILE allí), por ejemplo -v intervals-mcp:/data; de lo contrario, cada contenedor recreado desconecta a todos los clientes.

Paquete de Claude Desktop (.mcpb)

Cada release de GitHub incluye futureweb-intervals-mcp-<version>.mcpb. Ábrelo con Claude Desktop (doble clic, o Configuración → Extensiones → Instalar extensión…) e introduce la clave API (almacenada como secreto), el ID del atleta y, opcionalmente, los permisos (read por defecto) y el conjunto de herramientas. El paquete contiene las fuentes y el archivo de bloqueo; Claude Desktop lo inicia con uv (uv run --frozen), que instala las dependencias bloqueadas en el primer inicio. Necesita una versión de Claude Desktop que soporte el manifiesto MCPB 0.4 (uv tipo de servidor).

Registro MCP

Los releases se listan en el registro oficial de MCP como io.github.futureweb/intervals-mcp-server, con el paquete PyPI y la imagen GHCR y las variables de entorno que necesitan. Los clientes que leen el registro pueden instalar el servidor desde allí. La entrada solo lista paquetes: cada usuario ejecuta su propia instancia con sus propias credenciales de Intervals.icu.

Conectar un cliente de IA

Claude Desktop y Claude Code (local, stdio)

Además del paquete anterior, Claude Desktop puede iniciar el servidor desde PyPI con uvx (añade a claude_desktop_config.json; Claude Desktop necesita la ruta completa a uvx si no está en su PATH, por ejemplo /Users/you/.local/bin/uvx):

{
  "mcpServers": {
    "intervals-icu": {
      "command": "uvx",
      "args": ["futureweb-intervals-mcp@1.0.0b1"],
      "env": { "API_KEY": "your-api-key", "ATHLETE_ID": "i123456", "MCP_PERMISSIONS": "read" }
    }
  }
}

Con Docker en su lugar (los valores provienen de env, -e NAME los pasa al contenedor):

{
  "mcpServers": {
    "intervals-icu": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "-e", "API_KEY", "-e", "ATHLETE_ID", "-e", "MCP_PERMISSIONS",
               "ghcr.io/futureweb/intervals-mcp-server:1.0.0b1"],
      "env": { "API_KEY": "your-api-key", "ATHLETE_ID": "i123456", "MCP_PERMISSIONS": "read" }
    }
  }
}

Desde un checkout de las fuentes:

{
  "mcpServers": {
    "intervals-icu": {
      "command": "uv",
      "args": ["--directory", "/path/to/intervals-mcp-server", "run", "futureweb-intervals-mcp"],
      "env": { "API_KEY": "your-api-key", "ATHLETE_ID": "i123456", "MCP_PERMISSIONS": "read" }
    }
  }
}

Claude Code: claude mcp add intervals-icu -e API_KEY=your-api-key -e ATHLETE_ID=i123456 -- uvx futureweb-intervals-mcp@1.0.0b1, o desde un checkout claude mcp add intervals-icu -- uv --directory /path/to/intervals-mcp-server run futureweb-intervals-mcp.

ChatGPT, Claude.ai y otros clientes remotos (OAuth)

Los clientes remotos necesitan un endpoint HTTPS. Ejecuta el servidor detrás de un proxy inverso TLS con OAuth:

MCP_TRANSPORT=http+sse FASTMCP_HOST=127.0.0.1 FASTMCP_PORT=8001 \
MCP_AUTH=oauth MCP_PUBLIC_URL=https://mcp.example.com \
INTERVALS_OAUTH_CLIENT_ID=... INTERVALS_OAUTH_CLIENT_SECRET=... \
MCP_PERMISSIONS=read,write \
uv run futureweb-intervals-mcp
  1. Elige el inicio de sesión: sin más configuraciones inicias sesión con tu clave API de Intervals.icu (opcionalmente más un código de autenticador, OAUTH_TOTP_SECRET). Para Continuar con Intervals.icu crea una aplicación OAuth en https://intervals.icu/oauth/apply con la URL de redirección https://mcp.example.com/oauth/intervals/callback; una contraseña de servidor es la tercera opción.
  2. En ChatGPT (modo desarrollador) añade una conexión con la URL https://mcp.example.com/mcp y autenticación OAuth; deja el ID de cliente y el secreto vacíos. Claude.ai: Añadir conector personalizado con la misma URL.
  3. En la página de consentimiento elige los permisos para esta conexión e inicia sesión. Con Intervals.icu solo los atletas en OAUTH_ALLOWED_ATHLETES (por defecto ATHLETE_ID) pueden iniciar sesión.
  4. Después de las actualizaciones del servidor usa Actualizar en la conexión de ChatGPT para recargar las herramientas.

Todo sobre el servidor OAuth, el proxy inverso (ejemplos de Apache y nginx) y el modelo de seguridad: docs/REMOTE_ACCESS.md. Los clientes sin OAuth pueden usar una ruta de endpoint secreta en su lugar (FASTMCP_SSE_PATH=/mcp-<random>/sse).

Compartir el servidor con amigos

Por defecto el servidor es de un solo usuario (MCP_TENANCY=single): cada llamada de herramienta usa el API_KEY y ATHLETE_ID del servidor. Quien tenga permitido conectarse ve tus datos, por lo que en este modo el servidor se niega a iniciar cuando OAUTH_ALLOWED_ATHLETES nombra a alguien que no seas tú (tus otras cuentas de Intervals.icu pueden listarse en OAUTH_OWNER_ACCOUNTS).

Para permitir que algunos amigos usen la misma implementación con sus propios datos de Intervals.icu, cambia al modo multiusuario opcional:

MCP_TENANCY=single (por defecto)MCP_TENANCY=multi
Acceso a datosel API_KEY del servidor para cada conexióncada conexión con su propia credencial
Los amigos inician sesión con– (verían tus datos)"Continuar con Intervals.icu" (la única forma para no propietarios)
Su token de Intervals.icuusado para la verificación de identidad, nunca almacenadoalmacenado cifrado (AES-256-GCM) por conexión
Tus propias conexionesclave APIclave API, solo después de que tú inicies sesión (Intervals.icu como ATHLETE_ID, o contraseña / clave API más código de autenticador)
Argumentos de athlete_idcualquier atleta que la clave pueda leersolo el atleta propio de la conexión (0 = propio); cualquier otra cosa se rechaza antes de una solicitud
Cachés, presupuestos de solicitudesunopor conexión / por atleta, parte justa del límite de la aplicación

Configuración (detalles en docs/REMOTE_ACCESS.md):

# 1. While still in single-user mode: confirm once that your existing connections are yours
futureweb-intervals-mcp grants list
futureweb-intervals-mcp grants adopt-legacy --owner
# 2. A key for the stored tokens (mode 0600, owned by the service user; back it up separately)
futureweb-intervals-mcp token-key --file /etc/intervals-mcp/token.key
# 3. Settings, then restart and check
MCP_TENANCY=multi
OAUTH_TOKEN_KEY_FILE=/etc/intervals-mcp/token.key
OAUTH_LOGIN=intervals                     # you sign in with Intervals.icu as ATHLETE_ID (or add OAUTH_TOTP_SECRET for a password)
OAUTH_ALLOWED_ATHLETES=i123456,i234567,i345678   # you plus your friends
futureweb-intervals-mcp --doctor

Ejecuta los comandos grants y token-key como el usuario de servicio con el entorno del servidor (OAUTH_STATE_FILE, ATHLETE_ID), por ejemplo docker exec -u <uid> en el contenedor. Como root se niegan a cambiar un directorio de estado que pertenece a otro usuario (--allow-root anula; nunca siguen enlaces allí). Las conexiones del modo de un solo usuario que no fueron adoptadas se rechazan en el modo multiusuario, nunca se tratan como tuyas. Si vuelves a una versión anterior después de esta, vuelve a eliminar los atletas registrados: las conexiones creadas o actualizadas mientras tanto necesitan grants adopt-legacy --owner una vez más antes del siguiente cambio (hasta entonces se rechazan).

Tus amigos añaden la misma URL de conector en ChatGPT o Claude, eligen los permisos en la página de consentimiento y aprueban la aplicación de Intervals.icu. Los permisos de Intervals.icu solicitados coinciden con las clases que eligen (read solicita acceso de lectura a ACTIVITY, WELLNESS, CALENDAR, LIBRARY y SETTINGS; write y superiores añaden los alcances de escritura que las herramientas necesitan). Los comentarios de actividades necesitan el permiso CHATS de Intervals.icu, que también cubre los chats privados: nunca se solicita a menos que establezcas INTERVALS_OAUTH_OFFER_CHATS=true y el atleta marque "Comentarios de actividades" en la página de consentimiento; de lo contrario, las dos herramientas de comentarios indican que falta el permiso.

Qué se almacena. Por conexión, el archivo de estado guarda el ID del atleta, el cliente MCP, las fechas de creación y último uso, los alcances de Intervals.icu otorgados y el token de acceso de Intervals.icu del atleta, cifrado con la clave de OAUTH_TOKEN_KEY / OAUTH_TOKEN_KEY_FILE (sin la clave el token no se puede leer; mantén la clave separada de las copias de seguridad del archivo de estado). Se mantienen como máximo OAUTH_MAX_GRANTS_PER_ATHLETE conexiones (por defecto 5) por atleta; las tuyas nunca se eliminan. Los datos no se almacenan en caché en disco; las cachés en memoria caducan en minutos y están separadas por conexión.

Privacidad. Los datos de bienestar como HRV, sueño, frecuencia cardíaca en reposo o peso son datos de salud (en la UE una categoría especial según el Art. 9 GDPR), y como operador eres responsable de ellos. Invita solo a personas que acepten explícitamente, diles en una nota breve qué se almacena (arriba), quién puede verlo (tú: el archivo de estado y los registros del servidor con IDs de atletas, nombres de herramientas, rutas de solicitudes y errores, nunca tokens o cuerpos de datos), cuánto tiempo se conservan los registros (por ejemplo journalctl --vacuum-time=14d) y cómo salir. Mantén la implementación actualizada. Si la clave o el archivo de estado pueden haber sido filtrados, coloca una nueva clave primero en OAUTH_TOKEN_KEY, y pide a tus amigos que revoquen la aplicación en Intervals.icu.

Eliminación. El token almacenado de una conexión se elimina cuando el cliente MCP revoca la conexión al desconectarse (/revoke; no todos los clientes lo hacen), después de OAUTH_REFRESH_TOKEN_TTL sin uso (por defecto 30 días; OAUTH_TOKEN_RETENTION_DAYS lo hace más corto), o con el comando grants. Para eliminar a un amigo por completo:

  1. futureweb-intervals-mcp grants remove <athlete id> (un servidor en ejecución elimina las conexiones en su siguiente solicitud);
  2. elimina al atleta de OAUTH_ALLOWED_ATHLETES y reinicia;
  3. el amigo revoca la aplicación en su configuración de Intervals.icu (el servidor no puede revocar un token sin desconectar todas las conexiones del atleta; hasta entonces el token eliminado seguiría siendo válido en Intervals.icu);
  4. opcionalmente purga líneas de registro antiguas (journalctl --vacuum-time=...).

Límites. Todos los atletas comparten los límites de solicitudes de la única aplicación OAuth de Intervals.icu: cada atleta tiene un presupuesto diario suave (MCP_ATHLETE_DAILY_REQUESTS, por defecto 1000), todos juntos un presupuesto de 15 minutos (MCP_APP_REQUESTS_PER_15MIN, por defecto 2000) del cual un atleta puede usar como máximo MCP_ATHLETE_SHARE_PERCENT (por defecto 25; 0 aún permite una solicitud por ventana, 100 significa sin límite por atleta) y los demás dejan MCP_OWNER_RESERVED_PERCENT (por defecto 20; 100 bloquea a cada atleta menos a ti) para ti; los reintentos cuentan. El límite por llamada se aplica además. get_server_status muestra el modo y el atleta propio de la conexión que llama, los alcances y el presupuesto, nunca otros usuarios. Volver a single elimina las conexiones y tokens de los otros atletas en la siguiente escritura; tus propias conexiones siguen funcionando en ambos modos.

Configuración

Variables de entorno; un archivo .env en el directorio de trabajo se carga automáticamente (.env.example).

VariableValor por defectoSignificado
API_KEY–Clave de API de Intervals.icu (obligatoria)
ATHLETE_ID–ID de atleta, i123456 o 123456 (obligatorio)
MCP_PERMISSIONSreadClases de herramientas habilitadas, p. ej. read,write o all
MCP_TOOLSETfullfull (cada herramienta de las clases habilitadas) o core (conjunto seleccionado, ver Conjuntos de herramientas)
CUSTOM_UNITS_OVERRIDES–Unidades de visualización por código de elemento personalizado, p. ej. Stamina=%,RecoveryTime=h
CUSTOM_AGGREGATE_OVERRIDES–Agregación por código de campo personalizado en resúmenes (sum, device_load_sum, trend, mean, none), p. ej. TrainingLoad=device_load_sum
MCP_TRANSPORTstdiostdio, sse, http o http+sse (/mcp y /sse en un proceso)
FASTMCP_HOST / FASTMCP_PORT127.0.0.1 / 8000Dirección de enlace de los transportes HTTP
FASTMCP_SSE_PATH / FASTMCP_MESSAGE_PATH/sse / /messages/Rutas de los endpoints SSE
FASTMCP_ALLOWED_HOSTS / FASTMCP_ALLOWED_ORIGINShost de MCP_PUBLIC_URLEncabezados de Host públicos aceptados detrás de un proxy inverso (protección contra rebinding de DNS); obligatorio para un endpoint público sin OAuth
MCP_AUTHnoneoauth habilita el servidor OAuth 2.1 integrado
MCP_PUBLIC_URL–URL base pública, obligatoria con MCP_AUTH=oauth
INTERVALS_OAUTH_CLIENT_ID / INTERVALS_OAUTH_CLIENT_SECRET–Aplicación OAuth de Intervals.icu para "Continuar con Intervals.icu"
OAUTH_LOGINintervals con una aplicación, si no password si está definido, si no apikeyMétodo(s) de inicio de sesión: intervals, password, apikey
OAUTH_TOTP_SECRET–Código de autenticador como segundo factor para inicio de sesión con contraseña y clave de API (python -m intervals_mcp_server.auth totp-secret)
OAUTH_ALLOWED_ATHLETESATHLETE_IDAtletas permitidos para iniciar sesión (* solo con MCP_TENANCY=multi y OAUTH_ALLOW_ANY_ATHLETE=true)
MCP_TENANCYsinglemulti: cada conexión usa su propia credencial de Intervals.icu (Compartir el servidor con amigos)
OAUTH_TOKEN_KEY / OAUTH_TOKEN_KEY_FILE–Modo multiusuario (obligatorio): clave(s) que cifran los tokens de Intervals.icu almacenados (futureweb-intervals-mcp token-key)
MCP_ATHLETE_DAILY_REQUESTS / MCP_APP_REQUESTS_PER_15MIN1000 / 2000Modo multiusuario: presupuesto de solicitudes por atleta y día, y de todos los atletas juntos por 15 minutos (0 = desactivado)
MCP_ATHLETE_SHARE_PERCENT / MCP_OWNER_RESERVED_PERCENT25 / 20Modo multiusuario: parte del presupuesto de 15 minutos que un atleta puede usar (0 = una solicitud por ventana, no desactivado) y la parte reservada para el propietario (100 bloquea a cualquier otro atleta)
INTERVALS_OAUTH_OFFER_CHATSfalseModo multiusuario: ofrecer "Comentarios de actividad" (Intervals.icu CHATS, que también cubre chats privados) en la página de consentimiento
OAUTH_MAX_GRANTS_PER_ATHLETE5Modo multiusuario: conexiones mantenidas por atleta (las menos usadas recientemente se revocan; las del propietario están exentas)
OAUTH_OWNER_ACCOUNTS–Tus propias otras cuentas de Intervals.icu; los únicos otros atletas que el modo de usuario único acepta en la lista de permitidos
OAUTH_PASSWORD_HASH / OAUTH_USERNAME– / athleteInicio de sesión con contraseña (hash: python -m intervals_mcp_server.auth hash-password)
OAUTH_STATE_FILE./oauth_state.jsonClientes registrados y resúmenes de tokens de actualización
INTERVALS_API_BASE_URLhttps://intervals.icu/api/v1URL base de la API
ATHLETE_TIMEZONEperfil de atletaZona horaria para "hoy" y rangos de fechas predeterminados, p. ej. Europe/Vienna; server usa el reloj del servidor. Sin definir: el timezone del perfil de atleta de Intervals.icu (consultado una vez al día)
MCP_TOOL_MAX_REQUESTS / MCP_TOOL_TIMEOUT_S300 / 120Límites de una llamada de herramienta (solicitudes de Intervals.icu, segundos); una herramienta que los alcanza se detiene y dice que su resultado está incompleto
MCP_MAX_OUTPUT_CHARS100000Resultado de herramienta más grande; texto más largo se corta con una nota sobre cómo obtener el resto, en JSON las listas más grandes se cortan (truncated indica qué se conservó)

Opciones adicionales de OAuth (listas de permitidos de host de cliente y redirección, duraciones de token, límite de tasa) se enumeran en docs/REMOTE_ACCESS.md.

Permisos y seguridad

ClaseHerramientasHabilitar con
readtodo lo que solo leepredeterminado
writeadd_or_update_event, add_or_update_note, add_activity_message, update_activity, update_wellness, create_library_workout, add_event_from_libraryMCP_PERMISSIONS=read,write
destructivedelete_event, delete_events_by_date_range, delete_custom_item, delete_library_workoutMCP_PERMISSIONS=read,write,destructive
admincreate_custom_item, update_custom_item, add_events_bulk, update_sport_settingsMCP_PERMISSIONS=all

Las herramientas de una clase deshabilitada no se registran en absoluto. Con OAuth, cada conexión adicionalmente solo obtiene las clases otorgadas en la página de consentimiento (intervals:read, intervals:write, …); otras herramientas están ocultas para ella y se rechazan si se llaman.

Las herramientas de escritura que pueden reemplazar valores existentes (add_or_update_event, add_or_update_note, update_activity, update_wellness) llevan la pista MCP destructiveHint: true, para que los clientes pregunten antes de ejecutarlas; su clase permanece write. Nada se crea, empareja, renombra o elimina automáticamente: delete_events_by_date_range primero solo lista lo que coincide; elimina solo con dry_run=false y los ids confirmados de esa lista (confirm_ids), toca solo las categorías nombradas (entrenamientos planificados predeterminados), como máximo 31 días, nunca entrenamientos ya emparejados con una actividad a menos que se solicite. Los valores vacíos de un cliente nunca borran texto o entrenamientos existentes.

Cada escritura es predecible y verificable (detalles: seguridad de escritura en intervals://guide):

  • dry_run=true en cada herramienta de crear/actualizar (incluyendo create_custom_item) devuelve la solicitud exacta (método, ruta, cuerpo después de todos los valores predeterminados y fusiones, como JSON compacto) y el resultado de validación; no se envía ninguna solicitud de escritura (el servidor rechaza cada solicitud no GET durante una ejecución de prueba).

  • Crear un evento (individual, masivo o desde la biblioteca) primero lee los eventos de su fecha (una solicitud sobre el rango de fechas) y rechaza un duplicado (misma categoría y deporte con el mismo nombre, o el mismo entrenamiento o texto no trivial) a menos que allow_duplicate=true; un día de ladrillo o un par AM/PM con nombres diferentes no es un duplicado. La herramienta masiva decide por entrada, lista los rechazados y crea sesiones dobles planificadas (mismo nombre, contenido diferente).

  • Después de cada escritura de evento o entrenamiento de biblioteca, la respuesta lee de nuevo lo que Intervals.icu almacenó y analizó: fecha, nombre, categoría, deporte, duración, carga, pasos analizados vs enviados y advertencias de análisis (notas: fecha, nombre, categoría, longitud de texto).

  • delete_event, delete_library_workout y delete_custom_item leen el objeto primero y nombran lo que se eliminó; un id faltante no elimina nada.

  • Las credenciales nunca aparecen en registros o salida de herramientas; en el modo de usuario único, el token de inicio de sesión de Intervals.icu se usa solo para la verificación de identidad y nunca se almacena (en el modo multiusuario se almacena cifrado, ver arriba).

  • Nunca expongas los transportes HTTP sin OAuth o una ruta secreta, y siempre detrás de TLS.

  • En el modo de usuario único, una implementación sirve la clave de API de un atleta y la lista de permitidos de inicio de sesión decide quién puede conectarse; comparte una implementación solo en el modo multiusuario.

Detalles y cómo reportar una vulnerabilidad: SECURITY.md.

Estado del proyecto y hoja de ruta

1.0.0b1 es la primera beta pública de este fork. El desarrollo ocurre en solicitudes de extracción revisadas; main está protegido y cada cambio ejecuta el CI completo.

Hecho

  • Campos personalizados, flujos personalizados y estadísticas de intervalos para cualquier dato de dispositivo (también ofrecido upstream como mvilanova/intervals-mcp-server#153)
  • Herramientas de entrenamiento, clases de permisos, correcciones upstream y solicitudes de extracción de la comunidad fusionadas
  • Análisis de rendimiento, análisis de ejecución para entrenamientos eliminados y extendidos, niveles de detalle, informe de actividad en una llamada, prompts y recursos
  • OAuth con "Continuar con Intervals.icu", permisos por conexión, documentos de metadatos de cliente, HTTP transmisible y SSE en un proceso
  • Calidad de análisis: paseos extendidos divididos correctamente, solo intervalos comparables comparados, agregación de campos personalizados por significado, períodos de bienestar claros, tamaños de muestra mínimos para tendencias de eficiencia, resistencia a la fatiga honesta, grados de pendiente suavizados, informe compacto
  • Carga de entrenamiento e intensidad: relación agudo:crónico, monotonía y tensión, distribución de tres zonas con índice de polarización, durabilidad aeróbica, proyección de carga y contexto semanal de entrenador

Siguiente

  • Primera versión etiquetada: paquete PyPI, imágenes GHCR y Docker Hub, entrada MCP Registry y paquete Claude Desktop, todo publicado por el flujo de trabajo de versión desde una etiqueta
  • Modo multi-atleta opcional que usa el token OAuth de Intervals.icu de cada atleta
  • Migración a MCP SDK v2 una vez que sea estable para los transportes usados aquí

Documentación

DocumentoContenido
docs/REMOTE_ACCESS.mdServidor OAuth, inicio de sesión de Intervals.icu, configuración de ChatGPT y Claude, proxy inverso, operaciones
docs/GARMIN_BRIDGE.mdTrabajar con el Garmin Intervals Bridge, ejemplos trabajados, lectura de métricas de dispositivo
docs/FEATURE_COMPARISON.mdComparación con otros servidores MCP de Intervals.icu
docs/UPSTREAM_AUDIT.mdCada solicitud de extracción upstream abierta y qué pasó con ella
docs/RELEASE_CHECKLIST.mdProceso de versión y puertas
RELEASING.mdPublicar una versión (PyPI, GHCR, Docker Hub, MCP Registry, paquete Claude Desktop) y qué hacer cuando un paso falla
CHANGELOG.mdCambios por versión
SECURITY.mdPolítica de seguridad y reporte de vulnerabilidades

Desarrollo

uv sync --all-extras --locked
uv run --locked pytest                 # synthetic fixtures, no credentials needed
uv run --locked ruff check .
uv run --locked mypy src tests
uv run --locked --with pylint pylint --disable=C0301 $(git ls-files '*.py')   # advisory

CI ejecuta ruff, mypy y pytest en Python 3.12 y 3.13, construye e importa la rueda y el sdist, construye y prueba el humo de la imagen Docker y el paquete Claude Desktop, valida server.json contra el esquema MCP Registry, lint los flujos de trabajo, y CodeQL escanea el código. Todas las GitHub Actions están fijadas a SHAs de commit; Dependabot las mantiene y las dependencias actualizadas. Las versiones se construyen desde etiquetas (docs/RELEASE_CHECKLIST.md, RELEASING.md); las etiquetas beta se convierten en pre-lanzamientos de GitHub.

Las contribuciones son bienvenidas: ver CONTRIBUTING.md. Nunca pongas datos reales de atletas, claves de API o nombres de host en problemas, fixtures o registros.

Créditos y licencia

Proyecto original por Marc Vilanova y contribuyentes: mvilanova/intervals-mcp-server. Este fork integra solicitudes de extracción de la comunidad por arnold-maderthaner (#140, #142 a #147), biochaos (#131) y kokostitiahah (#149), y corrige reportados y las métricas de carga de entrenamiento e intensidad propuestas por morritter (#150); gracias. Mantenido por Futureweb, junto con el Garmin Intervals Bridge.

Licenciado bajo la Licencia Pública General GNU v3.0, ver LICENSE. Intervals.icu y Garmin son marcas comerciales de sus respectivos propietarios y se usan solo para describir compatibilidad.