Skip to main content
Glama
MayankKapgate

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

FastMCP

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:#000

Responsabilidades 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 sqlite3

Persiste datos en un único archivo fitness_tracker.db


🔄 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 file

Desglose de archivos

Archivo

Líneas

Descripción

server.py

~322

Servidor MCP completo: inicialización de BD, modelos Pydantic, operaciones CRUD, definiciones de herramientas FastMCP y punto de entrada stdio

test_server.py

~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

requirements.txt

3

fastmcp, pydantic, pytest


🚀 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_Project

2. Crear y activar un entorno virtual (recomendado)

# Windows
python -m venv myvenv
myvenv\Scripts\activate

# macOS / Linux
python3 -m venv myvenv
source myvenv/bin/activate

3. Instalar las dependencias

pip install -r requirements.txt

4. Ejecutar la suite de pruebas

pytest test_server.py -v

Deberías ver 22 pruebas superadas

5. Iniciar el servidor (de forma independiente)

python server.py

Nota: El servidor utiliza transporte stdio: lee JSON‑RPC desde stdin y escribe en stdout. 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.py

Consejo: 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: stdio

  • Comando: python server.py (o la ruta completa a server.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

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

type

string

de 1 a 100 caracteres

"running"

duration

float

> 0 (minutos)

30.0

calories

float

≥ 0 (kcal)

300.0

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

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

protein

float

≥ 0 (gramos)

150.0

carbs

float

≥ 0 (gramos)

200.0

fat

float

≥ 0 (gramos)

60.0

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

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

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»

log_workout

Almacena el entrenamiento para la fecha de hoy

«Registra mi almuerzo: 40 g de proteína, 60 g de carbohidratos, 15 g de grasa»

log_macros

Registra una entrada de macros

«¿Cómo me ha ido hoy?»

get_daily_summary

Devuelve los totales agregados para la fecha actual

«¿Cuál fue mi entrenamiento el 4 de agosto?»

get_daily_summary

Obtiene los datos para 2026-08-04


🧪 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

TestWorkoutSchema

10

Entrenamiento válido, fechas incorrectas, duración negativa/cero, calorías negativas, tipo vacío/demasiado largo, campos faltantes, tipos incorrectos

TestMacrosSchema

6

Macros válidos, fecha inválida, proteínas/carbohidratos/grasas negativas, campos faltantes

TestDailySummarySchema

2

Solicitud válida, fecha basura

TestWorkoutDB

3

Insertar y recuperar, múltiples inserciones, seguridad frente a inyección SQL

TestMacrosDB

2

Insertar y recuperar, inyección SQL a través del campo de fecha

TestDailySummary

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 ? parametrizados: la entrada del usuario nunca se interpola en cadenas SQL

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 @field_validator personalizado garantiza el cumplimiento de ISO 8601; se rechazan cadenas basura como "yesterday" o "'; DROP TABLE"

Coerción de tipos

El modo estricto de Pydantic detecta tipos realmente incompatibles (p. ej., "slow" para un campo float)

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 fitness_tracker.db local en tu máquina: nada sale de tu sistema


📝 Licencia

MIT — úsalo libremente.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    B
    quality
    D
    maintenance
    A 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
  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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.
    20
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Local-first nutrition tracker MCP server for Hermes, enabling food, alias, recipe, and meal log management with SQLite persistence.
  • F
    license
    A
    quality
    B
    maintenance
    Personal 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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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