FitCoach MCP
FitCoach MCP
Un servidor MCP remoto que convierte Claude Desktop o ChatGPT en un entrenador con memoria: objetivos persistentes, registro conversacional de entrenamientos, ajuste de parámetros por usuario y un ritual semanal de "plan my sessions" que produce un plan de entrenamiento versionado y explicado.
La división del trabajo: el LLM captura la conversación y narra; el motor determinista en src/engine/ toma todas las decisiones de programación (progresión, volumen, descargas, sustitución de ejercicios, ritmo de carrera, autorregulación). Mismas entradas, mismo plan, siempre.
La verdad vive en un solo lugar
docs/CURRENT-STATE.md es la fuente de verdad para recuentos, constantes, identidad de despliegue y qué está y no está construido. Este README deliberadamente repite lo menos posible de ello, porque una auditoría de agosto de 2026 encontró que este archivo, RUNBOOK y SUBMISSION-PACK reclamaban de forma independiente 11 herramientas cuando había 22. Si un número aquí discrepa de CURRENT-STATE, CURRENT-STATE gana y este archivo está obsoleto. Si CURRENT-STATE discrepa del código, arregla CURRENT-STATE primero.
Related MCP server: WorkoutGuide MCP
Mecánica del producto
El registro bruto es de solo anexión. Las sesiones, series, comentarios, carreras y métricas de recuperación nunca se editan: everything intelligent is derived state in
user_params(e1RMs, tendencias, detección de estancamiento, puntuación de recuperación, hitos de volumen, aptitud de carrera), recalculo en cada llamada de planificación.Los planes están versionados. Cada
plan_my_weeksustituye a la revisión anterior and records a parent pointer + una justificación legible por humanos — "git, sin git."La prueba es un bloque de entrenamiento, no un reloj.
TRIAL_DAYS = 35(un mesociclo de 28 días + 7 días de gracia), comienza en el primerlog_workout,plan_my_weekolog_run. El proceso de onboarding yimport_historydeliberadamente no lo inician. Las herramientas de lectura nunca están bloqueadas ydelete_my_accountnunca está limitado: tus datos siguen siendo tuyos.La actualización ocurre en la conversación. Una herramienta de escritura bloqueada devuelve un mensaje cálido de actualización como contenido de la herramienta (no un error) para que el modelo lo transmita en el momento de la intención.
EARLY_ACCESSestá actualmente ACTIVADO, así que nada está restringido ahora mismo y el reloj de prueba nunca arranca. La barrera está completamente construida y probada; el flag solo la mantiene abierta. Ver CURRENT-STATE → Entitlements.Pantalla de seguridad.
src/server/safety.tsejecuta un comparador determinista de indicadores de riesgo sobre las 9 superficies de texto libre del usuario, enumeradas en un solo lugar (freeTextSources()ensrc/server/tools.ts). Una coincidencia de nivel de emergencia elimina todo lo demás de la respuesta, incluido el pie de página de actualización — y también se activa en la ruta con permisos bloqueados, así que un usuario fuera del acceso que reporta dolor en el pecho recibe la escalada, no un discurso de ventas.
Inicio rápido (local)
npm install
npm test # full suite; see CURRENT-STATE for the current count
AUTH_MODE=dev npm run dev # Streamable HTTP MCP server on :3000AUTH_MODE es obligatorio y explícito — el servidor se niega a abrirse si no está definido o es cualquier cosa distinta de dev / supabase:
Fatal startup error: Error: Unknown or missing AUTH_MODE null. Set AUTH_MODE=dev or AUTH_MODE=supabaseNada en este repositorio carga un archivo .env — no hay dependencia dotenv ni flag --env-file en el script dev. .env.example documenta las variables, pero copiarlo a .env no tiene efecto: pasa las variables en línea (como antes), exportalas o añade tú mismo --env-file=.env.
Una vez en marcha hay dos sondas, y la diferencia importa:
curl localhost:3000/healthz devuelve {"ok":true} sin tocar la base de datos (liveness — es lo que Fly sondea cada 30 s, así que un fallo de base de datos no debe provocar su error), y curl localhost:3000/readyz hace una consulta real y devuelve {"ok":true,"db":"up","durationMs":N} o un 503 db:down. /readyz es el que vigila la monitorización externa.
En modo dev cualquier token bearer dev-<nombre> autentica como usuario <nombre>; se rechaza directamente cuando NODE_ENV=production.
Conéctate desde Claude (conector personalizado) o MCP Inspector con la URL
http://localhost:3000/mcp y la cabecera Authorization: Bearer dev-henry, y luego
prueba: configura un perfil, define un objetivo, registra un entrenamiento y plan my week.
Otros scripts: npm run build (tsc + copia las migraciones a dist/),
npm start (ejecuta el build), npm run test:watch, npm run provision
(Supabase), npm run seed-demo, npm run metrics, npm run deploy (ver
Despliegue).
Almacenamiento
Una función decide el backend: createStorage() in
src/storage/select.ts, llamada una vez desde
src/server/index.ts.
| Backend | Uso |
definida |
| producción |
no definida, dev/test |
| dev y tests |
no definida, tipo producción | lanza una excepción al inicio | — |
"Entorno como producción" significa NODE_ENV=production o AUTH_MODE=supabase, y negarse es deliberado. DATA_DIR no está definido en fly.toml, así que el antiguo fallback PGlite era en memoria: el servidor arrancaba limpio, /healthz seguía en verde, las herramientas funcionaban y cada usuario recibía una cuenta vacía que se vaciaba de nuevo en el siguiente reinicio. Un secreto caído parecía exactamente un despliegue sano. Ahora falla con un error claro en su lugar (tests/storage-select.test.ts).
Ambos son implementaciones completas de la misma interfaz Storage y ejecutan las mismas migraciones (src/storage/migrations/, 0001_init … 0015_rls_v7, con políticas RLS en los archivos _rls_ emparejados). PGlite no es un simulacro y Postgres no es trabajo futuro: PostgresStorage es una implementación completa y listo para entornos de producción, and is what the live deployment runs. La única consulta donde los dos backends no deben divergir, el agregado de afge-tuning, se comparte literalmente desde src/storage/tuning-shared.ts.
PostgresStorage.init() aplica todas las migraciones en orden al inicio. Los archivos portables son aditivos e idempotentes, así que volver a ejecutarlos sobre una base de datos real es seguro; los archivos _rls_ referencian el auth.uid() de Supabase y se aplican automáticamente solo cuando la base de datos conectada lo expone — Postgres sin más en el dev local y CI los omite.
Ten en cuenta que 71 pruebas se saltan a menos que haya un DATABASE_URL real. Ejecuta la suite contra Postgres antes de un release, no solo PGlite.
Despliegue
La aplicación Fly se llama fitcoach-hs — no el
nombre del paquete. Tanto fly.toml como scripts/deploy-fly.sh la nombran, así que un despliegue básico (bare deploy) es correcto:
FLY_API_TOKEN=... npm run deploy(Hasta 0.7.1 ambos eran por defecto fitcoach-mcp, así que un despliegue básico crearía esa aplicación, desplegaría allí y comprobaría la salud de su URL — una ejecución verde contra algo que nadie usa. Si una aplicación huérfana fitcoach-mcp sigue en la cuenta de Fly desde entonces, ejecuta flyctl apps destroy fitcoach-mcp; un señuelo que responde a /healthz es peor que no tener ninguna.)
fly.toml declara un volumen [[mounts]] y eso es deliberado — coincide con la máquina, que mantiene los despliegues sin indicaciones. El volumen no se usa (los datos de producción están en Postgres externo) pero fija la aplicación a una sola máquina, de la que depende el limitador de tasa del proceso. Detalles en
docs/DEPLOY-NOTES.md.
Arquitectura
src/
types.ts # binding contracts: domain, Storage, Engine, TOOL_NAMES
storage/
migrations/ # 0001..0015; portable DDL + paired Supabase RLS policies
select.ts # createStorage(): DATABASE_URL ? Postgres : PGlite
postgres.ts # production Storage impl (Supabase Postgres)
pglite.ts # dev/test Storage impl (embedded Postgres)
tuning-shared.ts # the aggregates-only tuning evidence SQL, shared by both
seed-exercises.ts # exercise catalog: substitutes, movement pattern, fatigue cost
engine/ # deterministic; see docs/INTELLIGENCE-DESIGN.md
e1rm.ts # Epley + RPE→RIR adjustment
fitting.ts # fitParams: e1RM smoothing, trends, stalls, freshness, landmarks
planner.ts # planWeek: splits, progression, deloads, hybrid day layout
running.ts # run fitness, program-mode arbitration, run-week construction
adjust.ts # same-day autoregulation (short on time / beat up)
alignment.ts # goal-vs-behaviour drift detection, proactive check-ins
experiments.ts # 2-week n-of-1 plateau tests
recap.ts # weekly recap + PR detection
tuning.ts # bounded population tuning from aggregate evidence
server/
index.ts # express + stateless StreamableHTTP, per-request server factory
auth.ts # dev tokens / Supabase JWT (JWKS) + RFC 9728 metadata
consent.ts # OAuth 2.1 consent UI (Supabase as authorization server)
entitlements.ts # mesocycle trial gate + EARLY_ACCESS
metering.ts # idempotent usage events
safety.ts # deterministic red-flag screen (emergency / injury)
temporal.ts # server-side, timezone-aware natural-language dates
rate-limit.ts # in-process burst + sustained limits
tools.ts, tools-*.ts, tools/*.ts # the tool surface (see CURRENT-STATE)
pages/, site.ts, share.ts, ui/ # landing, /connect, /docs, share links
billing/provider.ts # BillingProvider interface + StubBillingProviderNo hay ningún proveedor de pago conectado. StubBillingProvider es lo que se ejecuta y CHECKOUT_BASE_URL está sin definir, por lo que los enlaces de pago caen en la sección /#pricing en vivo. Stripe es la Fase 4 del runbook.
Documentación
Documento | Contenido |
Fuente de verdad — recuentos, identidad, qué está y no está construido | |
El motor: cada algoritmo, constante y salvaguarda | |
Manual de operación — variables de entorno, despliegues, | |
Está caído (o parece caído): pruebas de triaje y playbooks de causas | |
Este producto almacena notas de lesiones y texto de bienestar — trata como sensible | |
Detalles específicos de Fly | |
Ingesta de métricas portátiles | |
Material de envío para presentación |
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes Whoop fitness data (recovery, sleep, strain, workouts) to Claude for use as a daily training coach, enabling natural language queries about your health metrics and training readiness.MIT
- FlicenseNot gradedqualityCmaintenanceEnables workout tracking and coaching within Claude conversations, managing exercise configs, logs, streaks, and health metrics via an MCP server with PostgreSQL.
- AlicenseNot gradedqualityBmaintenanceEnables Claude to act as a personal health coach by connecting to Garmin wearable data and Notion workspace for automated calorie tracking, photo food logging, and coaching insights.MIT
- AlicenseNot gradedqualityAmaintenanceEnables Claude to analyze training data from spreadsheets and Amazfit watches, providing insights on strength progression, running metrics, recovery status, and readiness, with tools for weekly reviews, exercise progression, and health reporting.1MIT
Related MCP Connectors
Create Hevy routines and analyze your training from chat. Unofficial; BYO Hevy PRO API key.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/henryhf/fitcoach-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server