fitness-tracker-mcp
ποΈ Fitness Tracker β MCP Server
μμ ν μ€νλΌμΈμΌλ‘ λμνλ Model Context Protocol (MCP) μλ²λ‘, Claude Code, Claude Desktop, Cursor λ± MCP νΈν AI ν΄λΌμ΄μΈνΈκ° μ΄λ κΈ°λ‘, μλ¨ λ§€ν¬λ‘ μΆμ , μΌμΌ κ±΄κ° μμ½ μ‘°νλ₯Ό ν μ μκ² ν΄μ€λλ€. λͺ¨λ λ°μ΄ν°λ λ‘컬 SQLite λ°μ΄ν°λ² μ΄μ€μ μ μ₯λλ©° λ€νΈμν¬ μμ‘΄μ±μ΄ μ ν μμ΅λλ€.
π λͺ©μ°¨
Related MCP server: Nutrition MCP
π‘ μ μ΄ νλ‘μ νΈμΈκ°?
λκ·λͺ¨ μΈμ΄ λͺ¨λΈμ λνμλ λ°μ΄λμ§λ§, μΈμ μ λμ΄ μ¬μ©μ λ°μ΄ν°λ₯Ό κΈ°λ³Έμ μΌλ‘ μμνν μλ μμ΅λλ€. Model Context Protocolμ LLMμ΄ μΈλΆ λꡬλ₯Ό νΈμΆν μ μκ² ν¨μΌλ‘μ¨ μ΄ κ²©μ°¨λ₯Ό λ©μλλ€. μ¦, AIκ° μ¬μ©μλ₯Ό λμ ν΄ κ΅¬μ‘°νλ λ°μ΄ν°λ₯Ό μ½κ³ , μ°κ³ , μ‘°νν μ μλ μ§μ ν μ΄μμ€ν΄νΈκ° λλ κ²μ λλ€.
μ΄ νλ‘μ νΈλ μ€μ©μ μΈ MCP ν΅ν©μ 보μ¬μ€λλ€. AI μ΄μμ€ν΄νΈκ° μ§μ μ‘°μν μ μλ νΌνΈλμ€ νΈλ컀μ λλ€. AIμκ² *"300μΉΌλ‘리λ₯Ό μλͺ¨ν 30λΆ λ¬λμ κΈ°λ‘ν΄μ€"*λΌκ³ λ§νλ©΄, AIκ° λ°μ΄ν°λ₯Ό κ²μ¦νκ³ SQLiteμ μ μ₯ν λ€ νμΈν΄ μ€λλ€. μ€νλ λμνΈλ₯Ό μ΄μ΄λ³Ό νμκ° μ ν μμ΅λλ€.
β¨ μ£Όμ κΈ°λ₯
κΈ°λ₯ | μ€λͺ |
μ΄λ κΈ°λ‘ | μ΄λ μ ν, μκ°, μλͺ¨ μΉΌλ‘리λ₯Ό ν¬ν¨ν μ΄λ μΈμ κΈ°λ‘ |
λ§€ν¬λ‘ μΆμ | μμ¬λ³ λλ ν루 λ¨μλ‘ λ¨λ°±μ§, νμνλ¬Ό, μ§λ°© μμ·¨λ κΈ°λ‘ |
μΌμΌ μμ½ | μΉΌλ‘리 κ³μ°μ ν¬ν¨ν μ΄λ + μμ μ§κ³ 보기 |
μμ μ€νλΌμΈ | Stdio μ μ‘ β λ€νΈμν¬ νΈμΆ μμ, API ν€ μμ, ν΄λΌμ°λ μμ‘΄μ± μμ |
μ격ν κ²μ¦ | Pydantic v2 μ€ν€λ§κ° μλͺ»λ LLM μΆλ ₯μ DBμ λλ¬νκΈ° μ μ μ°¨λ¨ |
SQL μΈμ μ μμ | λͺ¨λ κ³³μμ λ§€κ°λ³μνλ 쿼리 μ¬μ© β μ¬μ©μ μ λ ₯μ΄ μμ SQLμ λΏμ§ μμ |
ν¬κ΄μ μΈ ν μ€νΈ | μ€ν€λ§ κ²μ¦, DB λ‘μ§, μ£μ§ μΌμ΄μ€λ₯Ό λ€λ£¨λ 22κ°μ Pytest μΌμ΄μ€ |
π§± κΈ°μ μ€ν
κ³μΈ΅ | κΈ°μ | μ©λ |
MCP νλ μμν¬ | Python ν¨μλ₯Ό stdioλ₯Ό ν΅ν΄ MCP λκ΅¬λ‘ λ ΈμΆ | |
λ°μ΄ν°λ² μ΄μ€ | SQLite 3 | κ°λ³κ³ μ€μ μ΄ νμ μλ λ‘컬 μμν |
κ²μ¦ | Pydantic v2 | LLM μ λ ₯μ λν μ€ν€λ§ κ°μ λ° νμ λ³ν |
ν μ€νΈ | Pytest | ν μ€νΈλ³λ‘ 격리λ μΈλ©λͺ¨λ¦¬ λ°μ΄ν°λ² μ΄μ€ |
μΈμ΄ | Python 3.10+ | ν΅μ¬ λ°νμ |
ποΈ μν€ν μ² κ°μ
μ΄ μμ€ν μ κ΄μ¬μ¬κ° λͺ νν λΆλ¦¬λ κ³μΈ΅ν μν€ν μ²λ₯Ό λ°λ¦ λλ€:
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κ³μΈ΅λ³ μ± μ
κ³μΈ΅ | κ΅¬μ± μμ | μ± μ |
ν΄λΌμ΄μΈνΈ | Claude Code / Desktop | μμ°μ΄λ₯Ό MCP λꡬ νΈμΆλ‘ μ μ‘ |
μ μ‘ | stdio (JSON-RPC) | stdin/stdoutμ ν΅ν΄ λꡬ νΈμΆ μ§λ ¬ν β HTTP μμ, ν¬νΈ μμ |
λΌμ°ν° | FastMCP | λ€μ΄μ€λ λꡬ μ΄λ¦μ Python νΈλ€λ¬ ν¨μμ λ§€μΉ |
κ²μ¦ | Pydantic μ€ν€λ§ | DB μ κ·Ό μ μ λͺ¨λ μ λ ₯ νλλ₯Ό νμ± λ° κ²μ¦ |
λΉμ¦λμ€ λ‘μ§ | ν΅μ¬ ν¨μ | μ½μ , μ§κ³, μΉΌλ‘리 κ³μ° μ€ν |
μ μ₯μ |
| λ¨μΌ |
π λ°μ΄ν° νλ¦
μ¬μ©μκ° *"30λΆ λ¬λμ κΈ°λ‘ν΄μ€"*λΌκ³ λ§νμ λ μΌμ΄λλ μΌμ λ¨κ³λ³λ‘ μΆμ ν©λλ€:
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ποΈ λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§
SQLite λ°μ΄ν°λ² μ΄μ€(fitness_tracker.db)λ 첫 μ€ν μ μλμΌλ‘ μμ±λλ©° λ κ°μ ν
μ΄λΈμ ν¬ν¨ν©λλ€:
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)"
}μΉΌλ‘리 κ³μ°
μΌμΌ μμ½μ νμ€ Atwater κ³μλ₯Ό μ¬μ©νμ¬ λ§€ν¬λ‘μμ μΆμ μλͺ¨ μΉΌλ‘리λ₯Ό κ³μ°ν©λλ€:
$$\text{Calories} = (\text{Protein} \times 4) + (\text{Carbs} \times 4) + (\text{Fat} \times 9) ;\text{kcal}$$
π νλ‘μ νΈ κ΅¬μ‘°
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νμΌ κ΅¬μ±
νμΌ | μ€ μ | μ€λͺ |
| ~322 | μμ ν MCP μλ²: DB μ΄κΈ°ν, Pydantic λͺ¨λΈ, CRUD μ°μ°, FastMCP λꡬ μ μ, stdio μ§μ μ |
| ~265 | 6κ° ν΄λμ€μ 22κ° ν μ€νΈ β μ€ν€λ§ κ²μ¦(μ ν¨ + λ¬΄ν¨ μ λ ₯), DB μ½μ , μΌμΌ μ§κ³, λ μ§ κ²©λ¦¬, SQL μΈμ μ μμ μ± |
| 3 |
|
π μμνκΈ°
μ¬μ μꡬ μ¬ν
Python 3.10+ μ€μΉ
pip ν¨ν€μ§ λ§€λμ
1. μ μ₯μ ν΄λ‘
git clone https://github.com/MayankKapgate/fitness-tracker-mcp.git
cd MCP_Project2. κ°μ νκ²½ μμ± λ° νμ±ν (κΆμ₯)
# Windows
python -m venv myvenv
myvenv\Scripts\activate
# macOS / Linux
python3 -m venv myvenv
source myvenv/bin/activate3. μμ‘΄μ± μ€μΉ
pip install -r requirements.txt4. ν μ€νΈ μ€μνΈ μ€ν
pytest test_server.py -v22κ°μ ν μ€νΈκ° ν΅κ³Όνλ κ²μ νμΈν μ μμ΅λλ€ β
5. μλ² μμ (λ 립 μ€ν)
python server.pyμ°Έκ³ : μλ²λ stdio μ μ‘μ μ¬μ©ν©λλ€ β
stdinμμ JSONβRPCλ₯Ό μ½κ³stdoutμΌλ‘ μλλ€. μ Έ ν둬ννΈκ° νμλμ§ μμ΅λλ€. μ΄λ MCP ν΄λΌμ΄μΈνΈκ° μ¬μ©νλλ‘ μ€κ³λ λμμ λλ€.
π MCP ν΄λΌμ΄μΈνΈ μ°κ²°
Claude Code
ν°λ―Έλμμ μλ²λ₯Ό ν λ² λ±λ‘νμΈμ:
claude mcp add fitness-tracker --transport stdio -- python server.pyν: Claude Codeκ° νλ‘μ νΈ λλ ν°λ¦¬μμ μ€νλμ§ μλ κ²½μ° μ 체 κ²½λ‘λ₯Ό μ¬μ©νμΈμ:
claude mcp add fitness-tracker --transport stdio -- python "C:\Users\Mayan\OneDrive\Documents\MCP_Project\server.py"
Claude Desktop
claude_desktop_config.jsonμ λ€μμ μΆκ°νμΈμ:
{
"mcpServers": {
"fitness-tracker": {
"command": "python",
"args": ["C:\\Users\\Mayan\\OneDrive\\Documents\\MCP_Project\\server.py"],
"transport": "stdio"
}
}
}κΈ°ν MCP ν΄λΌμ΄μΈνΈ
MCP νΈν ν΄λΌμ΄μΈνΈλ λ€μμ μ¬μ©νμ¬ μ°κ²°ν μ μμ΅λλ€:
μ μ‘:
stdioλͺ λ Ή:
python server.py(λλserver.pyμ μ 체 κ²½λ‘)
π οΈ λꡬ μ°Έμ‘° (API)
μλ²λ 3κ°μ MCP λꡬλ₯Ό μ 곡ν©λλ€:
1. log_workout
λ¨μΌ μ΄λ μΈμ μ κΈ°λ‘ν©λλ€.
λ§€κ°λ³μ | νμ | μ μ½ μ‘°κ±΄ | μμ |
|
| ISO 8601 ( |
|
|
| 1β100μ |
|
|
| > 0 (λΆ) |
|
|
| β₯ 0 (kcal) |
|
λ°νκ°:
{
"status": "success",
"workout": {
"id": 1,
"date": "2026-08-04",
"type": "running",
"duration": 30.0,
"calories": 300.0
}
}2. log_macros
μμ¬ λλ ν루 μ 체μ μμ΄ λ§€ν¬λ‘μμμλ₯Ό κΈ°λ‘ν©λλ€.
λ§€κ°λ³μ | νμ | μ μ½ μ‘°κ±΄ | μμ |
|
| ISO 8601 ( |
|
|
| β₯ 0 (κ·Έλ¨) |
|
|
| β₯ 0 (κ·Έλ¨) |
|
|
| β₯ 0 (κ·Έλ¨) |
|
λ°νκ°:
{
"status": "success",
"macros": {
"id": 1,
"date": "2026-08-04",
"protein": 150.0,
"carbs": 200.0,
"fat": 60.0
}
}3. get_daily_summary
νΉμ λ μ§μ μ΄λ λ° μμ ν΅ν© μμ½μ μ‘°νν©λλ€.
λ§€κ°λ³μ | νμ | μ μ½ μ‘°κ±΄ | μμ |
|
| ISO 8601 ( |
|
λ°νκ°:
{
"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
}
}π¬ μ¬μ© μμ
μ°κ²°μ΄ μλ£λλ©΄ AI μ΄μμ€ν΄νΈμ μμ°μ€λ½κ² λννκΈ°λ§ νλ©΄ λ©λλ€:
μ¬μ©μ λ§ | νΈμΆλλ λꡬ | κ²°κ³Ό |
"30λΆ λ¬λμ νκ³ 300μΉΌλ‘리λ₯Ό μλͺ¨νμ΄" |
| μ€λ λ μ§λ‘ μ΄λ μ μ₯ |
"μ μ¬ κΈ°λ‘ν΄μ€: λ¨λ°±μ§ 40g, νμνλ¬Ό 60g, μ§λ°© 15g" |
| λ§€ν¬λ‘ νλͺ© νλ κΈ°λ‘ |
"μ€λ λλ μ΄λ μ΄?" |
| νμ¬ λ μ§μ μ§κ³ ν©κ³ λ°ν |
"8μ 4μΌ μ΄λμ λμμ§?" |
|
|
π§ͺ ν μ€νΈ
ν
μ€νΈ μ€μνΈ(test_server.py)λ 6κ°μ ν
μ€νΈ ν΄λμ€μ κ±ΈμΉ 22κ°μ ν
μ€νΈλ₯Ό ν¬ν¨νλ©°, ν
μ€νΈλ§λ€ 격리λ μμ SQLite λ°μ΄ν°λ² μ΄μ€λ₯Ό μ¬μ©ν©λλ€:
ν μ€νΈ ν΄λμ€ | ν μ€νΈ μ | λ€λ£¨λ λ΄μ© |
| 10 | μ ν¨ν μ΄λ, μλͺ»λ λ μ§, μμ/0 μ§μ μκ°, μμ μΉΌλ‘리, λΉ/λ무 κΈ΄ μ ν, λλ½λ νλ, μλͺ»λ νμ |
| 6 | μ ν¨ν λ§€ν¬λ‘, μλͺ»λ λ μ§, μμ λ¨λ°±μ§/νμνλ¬Ό/μ§λ°©, λλ½λ νλ |
| 2 | μ ν¨ν μμ², μλͺ»λ λ μ§ |
| 3 | μ½μ λ° μ‘°ν, λ€μ€ μ½μ , SQL μΈμ μ μμ μ± |
| 2 | μ½μ λ° μ‘°ν, λ μ§ νλλ₯Ό ν΅ν SQL μΈμ μ |
| 3 | λΉ λ μ§, μ§κ³κ° ν¬ν¨λ λ°μ΄ν°κ° μλ λ μ§, λ μ§ κ° κ²©λ¦¬ |
ν μ€νΈ μ€ν
# 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π 보μ λ° μμ
μ°λ € μ¬ν | μν λ°©λ² |
SQL μΈμ μ | λͺ¨λ λ°μ΄ν°λ² μ΄μ€ 쿼리λ λ§€κ°λ³μνλ |
μλͺ»λ LLM μΆλ ₯ | λͺ¨λ λꡬ μ λ ₯μ λ°μ΄ν°λ² μ΄μ€μ λλ¬νκΈ° μ μ μ격ν νλ κ²μ¦κΈ°κ° μλ Pydantic v2 μ€ν€λ§λ₯Ό ν΅κ³Ό |
λ μ§ κ²μ¦ | μ¬μ©μ μ μ |
νμ λ³ν | Pydanticμ μ격 λͺ¨λκ° μ€μ λ‘ νΈνλμ§ μλ νμ
(μ: |
λ€νΈμν¬ λ ΈμΆ | stdio μ μ‘ β λ€νΈμν¬ νΈλν½ 0, μ΄λ¦° ν¬νΈ μμ, API ν€ λΆνμ |
λ°μ΄ν° νλΌμ΄λ²μ | λͺ¨λ λ°μ΄ν°λ μ¬μ©μ λ¨Έμ μ λ‘컬 |
π λΌμ΄μ μ€
MIT β μμ λ‘κ² μ¬μ©νμΈμ.
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