Mi Fitness MCP
# Mi Fitness MCP
[](https://github.com/kubulashvili/mi-fitness-mcp/actions/workflows/ci.yml)
[](https://github.com/kubulashvili/mi-fitness-mcp/releases)
[](https://github.com/kubulashvili/mi-fitness-mcp/blob/main/LICENSE)
MCP server for Mi Fitness data.
This project provides a local SQLite-backed MCP server for Mi Fitness cloud data.
## Current data coverage
Confirmed with the current cloud flow:
- daily activity
- steps
- distance
- active calories
- heart rate
- body measurements
- weight
- BMI
- fat, water, bone, and muscle metrics
- visceral fat
- basal metabolism
- official Xiaomi workout sessions
- sport/category, duration, distance, calories, pace, cadence, speed, elevation
- heart-rate zones, training effect/load, recovery time, VO2 max when supplied
Not yet supported:
- sleep. The available endpoint and payload contract have not been confirmed, so sleep is
intentionally not advertised or synchronized yet.
## Install
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
```
## Setup
You need:
- `userId`
- `passToken`
Typical flow:
1. Open `https://account.xiaomi.com`
2. Sign in to your Xiaomi account
3. Open browser DevTools
4. Inspect cookies for `account.xiaomi.com`
5. Copy `userId` and `passToken`
Configure the server. The interactive prompt hides `passToken` and stores credentials in the
system keyring:
```bash
mi-fitness-mcp setup --mode mi_fitness_cloud --user-id "<userId>" --region ru
mi-fitness-mcp doctor
```
For automation, prefer `--pass-token-stdin` or `MI_FITNESS_PASS_TOKEN`. The legacy
`--pass-token` argument remains available for backward compatibility but is deprecated because
command-line arguments may be visible in shell history and process listings.
Xiaomi accounts may be hosted in regional Mi Fitness backends. `ru` remains the default for
compatibility, while the adapter can discover and persist another accepted global/EU region such
as `de`, `i2`, `sg`, or `us`. This does not change the Xiaomi `userId + passToken` login flow.
For local endpoint exploration there is also a probe script:
```bash
uv run python probe_mifitness.py --user-id "<userId>"
```
The probe prompts for `passToken` without echo. For automation, provide
`MI_FITNESS_USER_ID` and `MI_FITNESS_PASS_TOKEN`, or use `--pass-token-stdin` with a
protected input source. Secret command-line arguments are intentionally unsupported.
## Use
```bash
mi-fitness-mcp sync --start-date 2025-04-01 --end-date 2025-05-31
mi-fitness-mcp serve
```
## MCP client config
Example `Claude Desktop` config:
```json
{
"mcpServers": {
"mi-fitness": {
"command": "mi-fitness-mcp",
"args": ["serve"]
}
}
}
```
## Example prompts
- `Show my daily activity for the last 14 days`
- `How has my resting heart rate changed this month?`
- `Summarize my latest body measurements`
- `Show my running workouts from the last 30 days`
- `Summarize workout volume by sport or ISO week`
- `Compare this month's workout totals with last month`
- `What were my longest-distance and fastest-pace workout records?`
- `Sync my latest Mi Fitness data`
## MCP tools
- `get_connection_status`
- `sync_data`
- `get_profile`
- `get_daily_summary`
- `query_metric_series`
- `query_heart_rate`
- `query_body_measurements`
- `query_workouts`
- `summarize_workouts`
- `get_workout_records`
- `compare_workout_periods`
- `get_data_coverage`
Existing tool names, argument semantics, and `status: ok|error` response envelopes remain
backward compatible. Sync reports successful and failed data types separately; a partial sync
returns `ok`, while a sync where every requested type fails returns `error`.
## Commands
```bash
mi-fitness-mcp --help
mi-fitness-mcp setup --help
mi-fitness-mcp doctor
mi-fitness-mcp sync --help
mi-fitness-mcp serve
```
## Development
```bash
uv run ruff check .
uv run pytest -q
uv run python -m build
```
The current test suite contains 89 tests and reports 78% statement coverage. CI runs on Python
3.11, 3.12, and 3.13, keeps HTTP tests offline with `respx`, and installs the built wheel in a
clean environment before checking `mi-fitness-mcp --help`.
## Configuration compatibility
- SQLite schema changes use the existing versioned migration runner; existing tables and data are
preserved.
- `busy_timeout` configures SQLite lock waiting in milliseconds and defaults to `5000`.
- `auto_sync_on_start`, `stale_after_minutes`, `store_raw_payloads`, `default_lookback_days`, and
`logs_path` are retained for config-file compatibility but are deprecated no-ops.
## Troubleshooting
- `Connection: failed`
- verify `userId` and `passToken`
- verify the configured region; global/EU accounts may resolve to another backend
- `Credentials not found`
- run `setup` again
- `sync` returns no data
- try another date range
- verify that the data actually exists in Mi Fitness cloud
## Security
- `passToken` is stored via the system keyring
- `userId` is masked in CLI and MCP diagnostics; `passToken` is never printed
- do not commit `.env`, local config files, or real credentials
- rotate tokens if they were pasted into chats or shell history
## Disclaimer
This is an unofficial project and is not affiliated with Xiaomi.
TDQS
Scored across 12 tools
Most tools are clearly distinct, but `get_workout_records` vs `query_workouts` could be confused (personal vs official workouts). Also `query_metric_series` is somewhat generic and may overlap with `query_heart_rate` and `query_body_measurements`.
All tool names follow a verb_noun structure, but there is a mix of `get_` and `query_` prefixes (both meaning retrieval). This is a minor deviation from a perfectly uniform pattern.
12 tools is well within the ideal 3-15 range and each tool serves a distinct purpose for a fitness data server, covering connection, sync, profile, summaries, metrics, workouts, and data coverage.
The toolset offers broad coverage for retrieving and analyzing fitness data, including raw series, summaries, workouts, and comparisons. Minor gaps could include sleep tracking or goal management, but they are not obviously required for the stated purpose.