fitness-tracker-mcp
🏋️ Fitness Tracker — MCP Server
Un servidor totalmente offline basado en el Model Context Protocol (MCP) que permite a cualquier cliente de IA compatible con MCP (como Claude Code, Claude Desktop o Cursor) registrar entrenamientos, realizar un seguimiento de los macros dietéticos y obtener resúmenes diarios de salud, todo ello respaldado por una base de datos SQLite local con cero dependencias de red.
📖 Tabla de contenidos
Related MCP server: Nutrition MCP
💡 ¿Por qué este proyecto?
Los grandes modelos de lenguaje son excelentes en la conversación, pero no pueden persistir datos de usuario de forma nativa entre sesiones. El Model Context Protocol salva esa distancia al permitir que los LLM llamen a herramientas externas, convirtiendo a la IA en un asistente de verdad que puede leer, escribir y consultar datos estructurados en nombre del usuario.
Este proyecto demuestra una integración MCP práctica: un rastreador de fitness que un asistente de IA puede manejar sin intervención manual. Dile a tu IA «Registra una carrera de 30 minutos que quemó 300 calorías» y validará los datos, los almacenará en SQLite y te lo confirmará, todo sin que tengas que abrir una hoja de cálculo.
✨ Características principales
Característica | Descripción |
Registro de entrenamientos | Registra sesiones de ejercicio con tipo, duración y calorías quemadas |
Seguimiento de macros | Registra la ingesta diaria de proteínas, carbohidratos y grasas por comida o por día |
Resúmenes diarios | Vista agregada de entrenamientos + nutrición con cálculo de calorías |
Totalmente offline | Transporte stdio: sin llamadas de red, sin claves de API, sin dependencia de la nube |
Validación estricta | Los esquemas Pydantic v2 detectan salidas malformadas del LLM antes de que lleguen a la BD |
A prueba de inyección SQL | Consultas parametrizadas en todo momento: la entrada del usuario nunca toca SQL sin procesar |
Pruebas exhaustivas | 22 casos de Pytest que cubren validación de esquemas, lógica de BD y casos límite |
🧱 Stack tecnológico
Capa | Tecnología | Propósito |
Framework MCP | Expone funciones de Python como herramientas MCP sobre stdio | |
Base de datos | SQLite 3 | Persistencia local ligera y sin configuración |
Validación | Pydantic v2 | Aplicación de esquemas y coerción de tipos para entradas del LLM |
Pruebas | Pytest | Bases de datos en memoria aisladas por prueba |
Lenguaje | Python 3.10+ | Runtime principal |
🏗️ Descripción general de la arquitectura
El sistema sigue una arquitectura por capas con una clara separación de responsabilidades:
graph TB
subgraph Client Layer
A["🤖 MCP Client<br/>(Claude Code / Claude Desktop / Cursor)"]
end
subgraph Transport Layer
B["📡 stdio<br/>(JSON-RPC over stdin/stdout)"]
end
subgraph MCP Server ["MCP Server (server.py)"]
direction TB
C["🔧 FastMCP Tool Router<br/>Routes tool calls to handlers"]
D["📋 Pydantic Schemas<br/>WorkoutInput · MacrosInput · DailySummaryRequest"]
E["⚙️ Core Business Logic<br/>insert_workout · insert_macros · fetch_daily_summary"]
F["🗄️ Database Layer<br/>get_connection · init_db"]
end
subgraph Storage
G[("💾 SQLite<br/>fitness_tracker.db")]
end
A <-->|"JSON-RPC"| B
B <-->|"Tool calls & responses"| C
C --> D
D -->|"Validated data"| E
E <--> F
F <--> G
style A fill:#4A90D9,stroke:#2C5F8A,color:#fff
style B fill:#F5A623,stroke:#C77E1A,color:#fff
style C fill:#7B68EE,stroke:#5A4DB2,color:#fff
style D fill:#50C878,stroke:#3A9458,color:#fff
style E fill:#FF6B6B,stroke:#CC5555,color:#fff
style F fill:#DDA0DD,stroke:#AA70AA,color:#fff
style G fill:#87CEEB,stroke:#5F9EAF,color:#000Responsabilidades de las capas
Capa | Componente | Responsabilidad |
Cliente | Claude Code / Desktop | Envía lenguaje natural → llamadas de herramientas MCP |
Transporte | stdio (JSON-RPC) | Serializa llamadas de herramientas a través de stdin/stdout: sin HTTP, sin puertos |
Enrutador | FastMCP | Hace coincidir los nombres de herramientas entrantes con las funciones de Python |
Validación | Esquemas Pydantic | Analiza y valida cada campo de entrada antes de acceder a la BD |
Lógica de negocio | Funciones principales | Ejecuta inserciones, agregaciones y cálculos de calorías |
Almacenamiento | SQLite mediante | Persiste datos en un único archivo |
🔄 Flujo de datos
Trazado paso a paso de lo que ocurre cuando un usuario dice «Registra una carrera de 30 minutos»:
sequenceDiagram
participant User
participant Client as MCP Client (Claude)
participant Transport as stdio (JSON-RPC)
participant Router as FastMCP Router
participant Schema as Pydantic Validator
participant Logic as Business Logic
participant DB as SQLite DB
User->>Client: "Log a 30-minute run that burned 300 calories"
Client->>Transport: tool_call: log_workout(date, type, duration, calories)
Transport->>Router: Deserialize JSON-RPC request
Router->>Schema: WorkoutInput(date, type, duration, calories)
alt Validation Fails
Schema-->>Router: ❌ ValidationError (clear message)
Router-->>Transport: Error response
Transport-->>Client: Display error to user
end
Schema-->>Router: ✅ Validated WorkoutInput object
Router->>Logic: insert_workout(validated_data)
Logic->>DB: INSERT INTO workouts (date, type, duration, calories) VALUES (?, ?, ?, ?)
DB-->>Logic: Row ID
Logic-->>Router: {status: success, workout: {...}}
Router-->>Transport: JSON-RPC response
Transport-->>Client: "Logged: 30 min running — 300 kcal burned ✅"
Client-->>User: Confirmation message🗃️ Esquema de la base de datos
La base de datos SQLite (fitness_tracker.db) se crea automáticamente en la primera ejecución y contiene dos tablas:
erDiagram
WORKOUTS {
INTEGER id PK "Auto-increment"
TEXT date "YYYY-MM-DD (NOT NULL)"
TEXT type "e.g. running, cycling (NOT NULL)"
REAL duration "Minutes, > 0 (NOT NULL)"
REAL calories "kcal burned, >= 0 (NOT NULL)"
}
MACROS {
INTEGER id PK "Auto-increment"
TEXT date "YYYY-MM-DD (NOT NULL)"
REAL protein "Grams, >= 0 (NOT NULL)"
REAL carbs "Grams, >= 0 (NOT NULL)"
REAL fat "Grams, >= 0 (NOT NULL)"
}Cálculo de calorías
El resumen diario calcula las calorías estimadas consumidas a partir de los macros utilizando los factores estándar de Atwater:
$$\text{Calories} = (\text{Protein} \times 4) + (\text{Carbs} \times 4) + (\text{Fat} \times 9) ;\text{kcal}$$
📂 Estructura del proyecto
MCP_Project/
├── server.py # MCP server — tools, schemas, DB helpers, entrypoint
├── test_server.py # Pytest suite (22 tests across 6 test classes)
├── requirements.txt # Python dependencies (fastmcp, pydantic, pytest)
├── fitness_tracker.db # SQLite database (auto-created on first run)
├── .gitignore # Ignores venv, __pycache__, .env
├── .env # Environment variables (git-ignored)
└── README.md # This fileDesglose de archivos
Archivo | Líneas | Descripción |
| ~322 | Servidor MCP completo: inicialización de BD, modelos Pydantic, operaciones CRUD, definiciones de herramientas FastMCP y punto de entrada stdio |
| ~265 | 22 pruebas en 6 clases: validación de esquemas (entradas válidas e inválidas), inserciones en BD, agregación diaria, aislamiento de fechas y seguridad frente a inyección SQL |
| 3 |
|
🚀 Primeros pasos
Requisitos previos
Python 3.10+ instalado
Gestor de paquetes pip
1. Clonar el repositorio
git clone https://github.com/MayankKapgate/fitness-tracker-mcp.git
cd MCP_Project2. Crear y activar un entorno virtual (recomendado)
# Windows
python -m venv myvenv
myvenv\Scripts\activate
# macOS / Linux
python3 -m venv myvenv
source myvenv/bin/activate3. Instalar las dependencias
pip install -r requirements.txt4. Ejecutar la suite de pruebas
pytest test_server.py -vDeberías ver 22 pruebas superadas ✅
5. Iniciar el servidor (de forma independiente)
python server.pyNota: El servidor utiliza transporte stdio: lee JSON‑RPC desde
stdiny escribe enstdout. No verás un prompt de shell; esto es así por diseño para el consumo por parte de clientes MCP.
🔌 Conexión con clientes MCP
Claude Code
Registra el servidor una vez desde tu terminal:
claude mcp add fitness-tracker --transport stdio -- python server.pyConsejo: Si Claude Code no se lanza desde el directorio del proyecto, usa la ruta completa:
claude mcp add fitness-tracker --transport stdio -- python "C:\Users\Mayan\OneDrive\Documents\MCP_Project\server.py"
Claude Desktop
Añade lo siguiente a tu claude_desktop_config.json:
{
"mcpServers": {
"fitness-tracker": {
"command": "python",
"args": ["C:\\Users\\Mayan\\OneDrive\\Documents\\MCP_Project\\server.py"],
"transport": "stdio"
}
}
}Otros clientes MCP
Cualquier cliente compatible con MCP puede conectarse usando:
Transporte:
stdioComando:
python server.py(o la ruta completa aserver.py)
🛠️ Referencia de herramientas (API)
El servidor expone 3 herramientas MCP:
1. log_workout
Registra una sola sesión de entrenamiento.
Parámetro | Tipo | Restricciones | Ejemplo |
|
| ISO 8601 ( |
|
|
| de 1 a 100 caracteres |
|
|
| > 0 (minutos) |
|
|
| ≥ 0 (kcal) |
|
Devuelve:
{
"status": "success",
"workout": {
"id": 1,
"date": "2026-08-04",
"type": "running",
"duration": 30.0,
"calories": 300.0
}
}2. log_macros
Registra los macronutrientes dietéticos de una comida o de un día completo.
Parámetro | Tipo | Restricciones | Ejemplo |
|
| ISO 8601 ( |
|
|
| ≥ 0 (gramos) |
|
|
| ≥ 0 (gramos) |
|
|
| ≥ 0 (gramos) |
|
Devuelve:
{
"status": "success",
"macros": {
"id": 1,
"date": "2026-08-04",
"protein": 150.0,
"carbs": 200.0,
"fat": 60.0
}
}3. get_daily_summary
Recupera un resumen combinado de entrenamiento y nutrición para una fecha determinada.
Parámetro | Tipo | Restricciones | Ejemplo |
|
| ISO 8601 ( |
|
Devuelve:
{
"date": "2026-08-04",
"workouts": {
"count": 2,
"entries": [
{"id": 1, "date": "2026-08-04", "type": "running", "duration": 30.0, "calories": 300.0},
{"id": 2, "date": "2026-08-04", "type": "weights", "duration": 45.0, "calories": 250.0}
],
"total_duration_min": 75.0,
"total_calories_burned": 550.0
},
"macros": {
"count": 1,
"entries": [
{"id": 1, "date": "2026-08-04", "protein": 150.0, "carbs": 200.0, "fat": 60.0}
],
"total_protein_g": 150.0,
"total_carbs_g": 200.0,
"total_fat_g": 60.0,
"total_calories_consumed": 1940.0
}
}💬 Ejemplo de uso
Una vez conectado, simplemente habla con tu asistente de IA de forma natural:
Tú dices | Herramienta llamada | Qué ocurre |
«Hice una carrera de 30 minutos y quemé 300 calorías» |
| Almacena el entrenamiento para la fecha de hoy |
«Registra mi almuerzo: 40 g de proteína, 60 g de carbohidratos, 15 g de grasa» |
| Registra una entrada de macros |
«¿Cómo me ha ido hoy?» |
| Devuelve los totales agregados para la fecha actual |
«¿Cuál fue mi entrenamiento el 4 de agosto?» |
| Obtiene los datos para |
🧪 Pruebas
La suite de pruebas (test_server.py) contiene 22 pruebas repartidas en 6 clases de prueba, que usan bases de datos SQLite temporales y aisladas por prueba:
Clase de prueba | Pruebas | Qué cubre |
| 10 | Entrenamiento válido, fechas incorrectas, duración negativa/cero, calorías negativas, tipo vacío/demasiado largo, campos faltantes, tipos incorrectos |
| 6 | Macros válidos, fecha inválida, proteínas/carbohidratos/grasas negativas, campos faltantes |
| 2 | Solicitud válida, fecha basura |
| 3 | Insertar y recuperar, múltiples inserciones, seguridad frente a inyección SQL |
| 2 | Insertar y recuperar, inyección SQL a través del campo de fecha |
| 3 | Día vacío, día poblado con agregación, aislamiento entre fechas |
Ejecutar las pruebas
# Run all tests with verbose output
pytest test_server.py -v
# Run a specific test class
pytest test_server.py::TestWorkoutSchema -v
# Run with coverage (requires pytest-cov)
pip install pytest-cov
pytest test_server.py --cov=server --cov-report=term-missing🔒 Seguridad y protección
Preocupación | Mitigación |
Inyección SQL | Todas las consultas a la base de datos usan marcadores |
Salida malformada del LLM | Cada entrada de herramienta pasa por un esquema Pydantic v2 con validadores de campo estrictos antes de llegar a la base de datos |
Validación de fechas | Un |
Coerción de tipos | El modo estricto de Pydantic detecta tipos realmente incompatibles (p. ej., |
Exposición de red | Transporte stdio: cero tráfico de red, sin puertos abiertos, sin claves de API necesarias |
Privacidad de datos | Todos los datos permanecen en un archivo |
📝 Licencia
MIT — úsalo libremente.
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
- FlicenseBqualityDmaintenanceA personal fitness tracking server that enables logging and querying workouts, nutrition, and body metrics through a local SQLite database. Integrates with OpenNutrition MCP for food logging and supports exercise history tracking for workout progression.17
- AlicenseNot gradedqualityBmaintenanceA filesystem-based MCP server that turns any MCP-capable AI agent into a conversational calorie and protein tracker with natural-language estimates, confidence-aware logging, daily/weekly progress, food-history search, and export, working offline with local fallback data.20MIT
- FlicenseNot gradedqualityBmaintenanceLocal-first nutrition tracker MCP server for Hermes, enabling food, alias, recipe, and meal log management with SQLite persistence.
- FlicenseAqualityBmaintenancePersonal workout coach MCP server that logs exercises in natural language, tracks progress with SQLite, and provides coaching signals like estimated 1RM and volume trends.6
Related MCP Connectors
MCP server for Withings health data — sleep, activity, heart, and body metrics.
GibsonAI MCP server: manage your databases with natural language
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
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/MayankKapgate/fitness-tracker-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server