Skip to main content
Glama

mi-health-mcp

Project Introduction

mi-health-mcp provides the sleep, heart rate, and step data of the currently logged-in Xiaomi account and authorized family members to MCP clients such as Hermes via the MCP protocol. The service runs on Cloudflare Workers. This project originates from wusaki0723/mi-health-mcp, retains the GPL-3.0 license, and references the interface implementations of Misty02600/mi-fitness-python and shkyyy18/mi_fitness_data_bridge.

Related MCP server: boyuan-health-bridge

Deployment

Requires Node.js 20 or later and a Cloudflare account.

git clone https://github.com/<your-github-account>/mi-health-mcp.git
cd mi-health-mcp
npm install
npx wrangler login
npx wrangler kv namespace create MI_HEALTH_KV

Write the namespace ID output by the command into kv_namespaces[0].id in wrangler.toml. The KV namespace ID is a Cloudflare resource identifier, not an access credential; public repositories must commit wrangler.toml so that Workers Builds can identify the Worker entry point and binding. After forking, you must replace it with the namespace ID from your own account before deploying.

Then set the access token and deploy:

npx wrangler secret put AUTH_TOKEN
npx wrangler deploy

Use a long random string you generate yourself for the value of AUTH_TOKEN; do not write it into source code, wrangler.toml, or Git.

passToken login

It is recommended to set userId, passToken, and deviceId from the Xiaomi Account browser Cookie as Cloudflare Secrets. deviceId usually starts with wb_. The Worker uses them to exchange for a short-lived health API session with sid=miothealth; the raw passToken is never written to KV, logs, or MCP responses.

npx wrangler secret put XIAOMI_USER_ID
npx wrangler secret put XIAOMI_PASS_TOKEN
npx wrangler secret put XIAOMI_DEVICE_ID

You can also add Secrets with the same names in the Worker's "Settings > Variables and Secrets" in the Cloudflare Dashboard. XIAOMI_USER_ID and XIAOMI_PASS_TOKEN must be set together; XIAOMI_DEVICE_ID is optional, and when set, use the deviceId from the same browser session in which that passToken was obtained.

The KV binding name must remain MI_HEALTH_KV. AUTH_TOKEN, XIAOMI_USER_ID, and XIAOMI_PASS_TOKEN must be set as Cloudflare Secrets; do not write them into source code, configuration files, or Git.

Hermes configuration

mcp_servers:
  mi_health:
    url: "https://<worker-name>.<account-subdomain>.workers.dev/mcp"
    headers:
      Authorization: "Bearer ${MI_HEALTH_AUTH_TOKEN}"

Replace the URL with the address of your own deployed Worker. The value of MI_HEALTH_AUTH_TOKEN must match the AUTH_TOKEN Secret of that Worker. The example does not contain real credentials.

Hermes skill

The skills/mi-health/SKILL.md in the repository routes "me/myself" and "family/friends" requests to the correct tools and explains the field meanings of compact results. Once the repository is public, it can be installed from the raw file URL:

hermes skills install https://raw.githubusercontent.com/<your-github-account>/mi-health-mcp/main/skills/mi-health/SKILL.md
hermes skills list

The skill does not automatically create scheduled tasks. To connect it to an existing task, first check the task and its recent execution records, then add it by task ID:

hermes cron status
hermes cron list
hermes cron runs <job-id>
hermes cron edit <job-id> --add-skill mi-health

Scheduled tasks run in an independent session; the prompt must clearly specify the query target, number of days, timezone, delivery location, and how to handle failures. Do not put any credentials in the prompt; periodic tasks should pin the provider and model to avoid behavior changes when global defaults change.

Usage

  1. After configuring XIAOMI_USER_ID and XIAOMI_PASS_TOKEN, call health_login_refresh; XIAOMI_DEVICE_ID is an optional Secret used to specify the browser session in which that passToken was obtained when needed. The Worker exchanges and caches a miothealth session; on failure, the current cached session is not deleted.

  2. Use health_me to confirm the current account; call health_latest, health_sleep, health_heart, or health_steps to query individual raw summaries, and prefer health_analyze with the user's current IANA timezone when trend analysis is needed.

  3. When querying family members, first call health_relatives, then pass target: "relative" and the returned relative_uid.

health_login_start and health_login_poll are kept only for compatibility. This QR code flow is rejected by Xiaomi on some accounts with 70036, and the 小米运动健康 App may also report that the QR code is unsupported; this project does not describe it as a verified login method.

Health queries default to target: "self", using the personal data endpoint and not sending relative_uid; family queries must provide a valid relative_uid and will not automatically select the first item in the family list.

MCP tools

  • health_me: Returns the current login status and user_id; does not return credentials.

  • health_login_status: Returns whether the current health API session is available and the login method; does not return credentials.

  • health_login_refresh: Forces a session refresh using the Xiaomi account Secrets; keeps the existing cached session on failure.

  • health_relatives: Lists the relative_uid and notes of queryable family members.

  • health_latest: Queries the latest sleep, heart rate, and step summaries.

  • health_analyze: Queries 30 days by default, building a personal baseline from the most recent 7 complete days and earlier records; separates unfinished same-day activity, reports missing dates, sync delay, sleep stage completeness, and heart rate sampling quality, and outputs non-diagnostic robust statistics.

  • health_sleep: Queries daily sleep summaries for the last 1 to 30 days, at most one per day.

  • health_heart: Queries daily heart rate statistics for the last 1 to 30 days; does not return all sample points.

  • health_steps: Queries daily step summaries for the last 1 to 30 days, at most one per day.

When querying yourself, omit target or explicitly pass {"target":"self"}. When querying family members, you must pass:

{
  "target": "relative",
  "relative_uid": "...",
  "days": 7
}

Trend analysis example:

{
  "target": "self",
  "days": 30,
  "recent_days": 7,
  "timezone": "Europe/Berlin"
}

health_analyze does not recompute dates already returned by the health API; timezone is only used to identify the current calendar day, marking the current day's steps and daily heart rate as partial and excluding them from the complete-day baseline. Sleep is treated as a completed record based on the wake-up date. When duplicate summaries exist for the same date, the analyzer deterministically selects one by valid measurements, sampling or sleep stage completeness, record time, and stable key. recent_days represents the most recent calendar-day window; dates that are missing or excluded due to insufficient quality are not backfilled by earlier records. The results first return data_quality: missing_dates means the record for that day is missing, and missing_measurements means the record exists but the target value is empty, non-numeric, or negative; both are treated as unknown rather than as 0. The results also report the latest data sync delay, sleep stage completeness, and heart rate sampling quality. Dates with fewer than 50% of the median complete-day sample count are listed in low_sample_dates, and dates lacking a valid sample count are listed in unknown_sample_dates; neither enters the heart rate trend. Trend comparisons use unrounded median, MAD, IQR, and robust z-score, rounding only at output; when samples are insufficient, insufficient_data is returned without forcing a trend conclusion. All comparisons are personal historical summaries and cannot be used for disease diagnosis or medication advice.

Usage boundaries

Only for logging into your own Xiaomi account and querying data of family members you are authorized to access. Do not use it for any purpose that infringes on others' privacy or violates the Xiaomi User Agreement.

Personal data uses POST /app/v1/data/get_fitness_data_by_time. For the China region, the query window is extended by 18 hours on both ends, and records are assigned to dates by their zone_offset; when zone_offset is missing, it falls back to UTC+8. Personal steps records are aggregated per day according to the endpoint's incremental semantics; personal heart sample points are converted to daily statistics; for sleep, on the same day, records that are not naps, have longer duration, and have a newer update time are preferred. Family data uses the daily_report of /app/v1/relatives/*; records on the same day are not summed repeatedly.

MCP responses use a field whitelist and do not return AUTH_TOKEN, passToken, cUserId, serviceToken, ssecurity, or Cookies. Do not commit .dev.vars, .env, wrangler.toml, or .wrangler/.

License

This project is licensed under the GNU General Public License v3.0 (GPL-3.0), consistent with the license of the upstream Misty02600/mi-fitness-python.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    B
    maintenance
    Enables reading and syncing Xiaomi Mi Fitness health data (steps, heart rate, sleep, workouts) from the Chinese cloud region to a local SQLite database via MCP tools.
    10
    7
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables users to query Polar health data (activity, sleep, recovery, training sessions, heart rate) through MCP with secure authentication, redacted personal info, and bounded responses.

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/Zhou-Ruichen/mi-health-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server