fitness-tracker-mcp
🏋️ Fitness Tracker — MCP Server
一个完全离线的 Model Context Protocol (MCP) 服务器,使任何兼容 MCP 的 AI 客户端(如 Claude Code、Claude Desktop 或 Cursor)都能记录锻炼、追踪饮食宏量营养素,并获取每日健康摘要,全部由本地 SQLite 数据库支持,零网络依赖。
📖 目录
Related MCP server: Nutrition MCP
💡 为什么选择这个项目?
大型语言模型擅长对话,但它们无法原生地跨会话持久化用户数据。Model Context Protocol 通过让 LLM 调用外部工具来弥合这一差距——将 AI 转变为真正能代表用户读取、写入和查询结构化数据的助手。
本项目展示了一个实用的 MCP 集成:一个 AI 助手可以免手动操作的健身追踪器。对你的 AI 说 "记录一次燃烧了 300 卡路里的 30 分钟跑步",它就会验证数据、将其存入 SQLite,并确认——全程无需你打开电子表格。
✨ 主要特性
Feature | Description |
锻炼记录 | 记录运动会话的类型、时长和消耗的卡路里 |
宏量营养素追踪 | 按餐或按天记录每日蛋白质、碳水化合物和脂肪摄入量 |
每日摘要 | 锻炼 + 营养的聚合视图,包含卡路里计算 |
完全离线 | stdio 传输——无网络调用、无 API 密钥、无云依赖 |
严格验证 | Pydantic v2 模式在数据到达数据库之前捕获格式错误的 LLM 输出 |
SQL 注入安全 | 全程使用参数化查询——用户输入永远不会触及原始 SQL |
全面测试 | 22 个 Pytest 用例,涵盖模式验证、数据库逻辑和边界情况 |
🧱 技术栈
Layer | Technology | Purpose |
MCP 框架 | 通过 stdio 将 Python 函数暴露为 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各层职责
Layer | Component | Responsibility |
客户端 | Claude Code / Desktop | 将自然语言 → MCP 工具调用 |
传输 | stdio (JSON-RPC) | 通过 stdin/stdout 序列化工具调用——无 HTTP、无端口 |
路由器 | FastMCP | 将传入的工具名称匹配到 Python 处理函数 |
验证 | Pydantic 模式 | 在访问数据库之前解析并验证每个输入字段 |
业务逻辑 | 核心函数 | 执行插入、聚合和卡路里计算 |
存储 | 通过 | 将数据持久化到单个 |
🔄 数据流
当用户说 "记录一次 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文件说明
File | Lines | Description |
| ~322 | 完整的 MCP 服务器:数据库初始化、Pydantic 模型、CRUD 操作、FastMCP 工具定义和 stdio 入口点 |
| ~265 | 6 个类中的 22 个测试——模式验证(有效和无效输入)、数据库插入、每日聚合、日期隔离和 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 -v你应该会看到 22 个测试通过 ✅
5. 启动服务器(独立运行)
python server.py注意: 服务器使用 stdio 传输——它从
stdin读取 JSON‑RPC 并写入stdout。你不会看到 shell 提示符;这是有意为之,供 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
记录一次单独的锻炼会话。
Parameter | Type | Constraints | Example |
|
| ISO 8601 ( |
|
|
| 1–100 个字符 |
|
|
| > 0(分钟) |
|
|
| ≥ 0(千卡) |
|
返回:
{
"status": "success",
"workout": {
"id": 1,
"date": "2026-08-04",
"type": "running",
"duration": 30.0,
"calories": 300.0
}
}2. log_macros
记录一餐或一整天的饮食宏量营养素。
Parameter | Type | Constraints | Example |
|
| 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
检索指定日期的锻炼和营养综合摘要。
Parameter | Type | Constraints | Example |
|
| 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 助手聊天:
You Say | Tool Called | What Happens |
"我跑了 30 分钟,消耗了 300 卡路里" |
| 存储今天的锻炼记录 |
"记录我的午餐:40 克蛋白质、60 克碳水化合物、15 克脂肪" |
| 记录一条宏量营养素条目 |
"我今天表现如何?" |
| 返回当前日期的聚合总计 |
"我 8 月 4 日的锻炼是什么?" |
| 获取 |
🧪 测试
测试套件(test_server.py)包含 22 个测试,分布在 6 个测试类中,每个测试使用隔离的临时 SQLite 数据库:
Test Class | Tests | What It Covers |
| 10 | 有效锻炼、错误日期、负/零时长、负卡路里、空/过长类型、缺失字段、错误类型 |
| 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🔒 安全与保障
Concern | Mitigation |
SQL 注入 | 所有数据库查询都使用参数化的 |
格式错误的 LLM 输出 | 每个工具输入在到达数据库之前都会通过带有严格字段验证器的 Pydantic v2 模式 |
日期验证 | 自定义 |
类型转换 | Pydantic 的严格模式会捕获真正不兼容的类型(例如, |
网络暴露 | stdio 传输——零网络流量、无开放端口、无需 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