Skip to main content
Glama
MayankKapgate

fitness-tracker-mcp

🏋️ Fitness Tracker — MCP Server

完全オフラインの Model Context Protocol (MCP) サーバーで、Claude Code、Claude Desktop、Cursor などの MCP 互換 AI クライアントが、ワークアウトの記録、食事マクロの追跡、日次ヘルスサマリーの取得 を、ネットワーク依存ゼロのローカル SQLite データベースを基盤として実現できます。


📖 目次


Related MCP server: Nutrition MCP

💡 このプロジェクトの目的は?

大規模言語モデル(LLM)は会話には優れていますが、セッションをまたいでユーザーデータを永続化することは本来できません。Model Context Protocol は、LLM が外部ツールを呼び出せるようにすることでこのギャップを埋め、ユーザーに代わって構造化データの読み取り、書き込み、クエリを実行できる真のアシスタントへと AI を変えます。

このプロジェクトは、実用的な MCP 統合のデモです。AI アシスタントがハンズフリーで操作できるフィットネストラッカーです。AI に 「30分のランニングで300カロリーを消費した」と記録して と伝えると、データを検証し、SQLite に保存し、確認まで行います。スプレッドシートを開く必要は一切ありません。


✨ 主な機能

機能

説明

ワークアウトの記録

種目、時間、消費カロリーを含む運動セッションを記録

マクロの追跡

1食ごとまたは1日ごとのタンパク質、炭水化物、脂質の摂取量を記録

日次サマリー

カロリー計算を含むワークアウトと栄養の集計ビュー

完全オフライン

stdio トランスポート — ネットワーク呼び出しなし、API キー不要、クラウド依存なし

厳格な検証

Pydantic v2 スキーマが不正な LLM 出力を DB に到達する前に検出

SQL インジェクション対策

すべてのクエリでパラメータ化を採用 — ユーザー入力が生の SQL に触れることはありません

包括的なテスト

スキーマ検証、DB ロジック、エッジケースをカバーする 22 件の Pytest テスト


🧱 技術スタック

レイヤー

技術

目的

MCP フレームワーク

FastMCP

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 アクセスの前にすべての入力フィールドを解析・検証

ビジネスロジック

コア関数

挿入、集計、カロリー計算を実行

ストレージ

sqlite3 経由の SQLite

単一の fitness_tracker.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)は初回実行時に自動生成され、2つのテーブルを含みます:

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

ファイル内訳

ファイル

行数

説明

server.py

~322

完全な MCP サーバー:DB 初期化、Pydantic モデル、CRUD 操作、FastMCP ツール定義、stdio エントリポイント

test_server.py

~265

6 クラスにわたる 22 テスト — スキーマ検証(有効・無効な入力)、DB 挿入、日次集計、日付の分離、SQL インジェクション安全性

requirements.txt

3

fastmcp、pydantic、pytest


🚀 はじめに

前提条件

  • Python 3.10+ がインストールされていること

  • pip パッケージマネージャー

1. リポジトリのクローン

git clone https://github.com/MayankKapgate/fitness-tracker-mcp.git
cd MCP_Project

2. 仮想環境の作成と有効化(推奨)

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

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

3. 依存関係のインストール

pip install -r requirements.txt

4. テストスイートの実行

pytest test_server.py -v

22 件のテストがパスする はずです ✅

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

単一のワークアウトセッションを記録します。

パラメータ

型

制約

例

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

type

string

1〜100 文字

"running"

duration

float

> 0(分)

30.0

calories

float

≥ 0(kcal)

300.0

戻り値:

{
  "status": "success",
  "workout": {
    "id": 1,
    "date": "2026-08-04",
    "type": "running",
    "duration": 30.0,
    "calories": 300.0
  }
}

2. log_macros

1食または1日分のマクロ栄養素を記録します。

パラメータ

型

制約

例

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

protein

float

≥ 0(グラム)

150.0

carbs

float

≥ 0(グラム)

200.0

fat

float

≥ 0(グラム)

60.0

戻り値:

{
  "status": "success",
  "macros": {
    "id": 1,
    "date": "2026-08-04",
    "protein": 150.0,
    "carbs": 200.0,
    "fat": 60.0
  }
}

3. get_daily_summary

指定された日付のワークアウトと栄養を組み合わせたサマリーを取得します。

パラメータ

型

制約

例

date

string

ISO 8601 (YYYY-MM-DD)

"2026-08-04"

戻り値:

{
  "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カロリーを消費した」

log_workout

今日の日付でワークアウトを保存

「昼食を記録して:タンパク質40g、炭水化物60g、脂質15g」

log_macros

マクロエントリを1件記録

「今日はどうだった?」

get_daily_summary

現在の日付の集計合計を返す

「8月4日のワークアウトは何だった?」

get_daily_summary

2026-08-04 のデータを取得


🧪 テスト

テストスイート(test_server.py)には 6 つのテストクラス にわたる 22 件のテスト が含まれており、テストごとに分離された一時 SQLite データベースを使用します:

テストクラス

テスト数

カバー内容

TestWorkoutSchema

10

有効なワークアウト、不正な日付、負/ゼロの時間、負のカロリー、空/長すぎる種目、フィールド欠落、誤った型

TestMacrosSchema

6

有効なマクロ、不正な日付、負のタンパク質/炭水化物/脂質、フィールド欠落

TestDailySummarySchema

2

有効なリクエスト、不正な日付

TestWorkoutDB

3

挿入と取得、複数挿入、SQL インジェクション安全性

TestMacrosDB

2

挿入と取得、日付フィールド経由の SQL インジェクション

TestDailySummary

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 インジェクション

すべてのデータベースクエリはパラメータ化された ? プレースホルダーを使用します — ユーザー入力

Related MCP Connectors

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