health-mcp
This server exposes a personal health data hub over MCP, letting an AI agent sync, log, and query one person's training, nutrition, steps, and Apple Health data in a single SQLite-backed interface.
Search and manage a food catalog:
find_productto look up products by name/brand (or list all),add_productto add items with per-100g macros and source (verified/estimated).Log food intake:
log_foodrecords grams eaten either against a catalog product or as a one-off with model-supplied macros (stored as estimated);delete_food_entryremoves entries.Sync workouts from Hevy:
sync_workoutspulls new lifting data (workouts, exercise templates, body measurements) — delta by default, full re-sync withfull=True.Sync cardio activities from Strava (built but not yet connected):
sync_activitiespulls runs/rides; requires priorstrava-auth.Import Apple Health data:
import_stepsingests step-count CSV exports (deduplicated by per-source daily max);import_workoutsimports Apple Watch workout CSVs, excluding Hevy-sourced rows to avoid double counting.Query the entire schema with SQL:
queryruns read-only SELECT/WITH statements across products, food_log, workouts, exercise templates, sets, body measurements, and sync state — enabling cross‑source analysis like comparing intake vs. training volume.Manage synchronization state: internal sync_state tracks last runs; CLI commands (
sync,normalize,strava-auth) support maintenance.
Syncs workout data from Hevy, including workouts, exercise templates, and body measurements.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@health-mcp sync my latest Hevy workouts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
health-mcp
A single agent-facing surface over one person's health data, so an AI can cross-reference sources that usually sit in separate apps — training and nutrition today ("did intake track with volume?"), with room to bring in sleep or other metrics later — in service of actually optimizing toward that person's health goals, not just logging numbers.
It's an MCP server, speaking stdio, backed by one SQLite file. Training data is synced in from external sources — Hevy for lifting, Strava for cardio (runs, rides). Daily step counts and Apple Watch-native workout sessions are imported by hand from Apple Health CSV exports — no API for those, just files dropped into chat. Food is logged directly through the agent against a small hand-curated Catalog of Products.
Tools
find_product(query?)— search the Catalog by name/brand; list it all ifqueryis omitted. Always call this beforelog_foodagainst a Catalog item.add_product(...)— add a Product to the Catalog. Macros are per 100g;sourceisverified(off a package label) orestimated.log_food(grams, product_id? | name + macros, at?)— log that a quantity was eaten, either against a Catalog Product or as a one-off (always recorded as estimated).delete_food_entry(id)— remove a Food Log Entry.sync_workouts(full?)— pull new workouts, exercise templates, and body measurements from Hevy. Delta by default;full=Truere-fetches everything and reconciles deletions.sync_activities(full?)— pull new cardio activities (runs, rides) from Strava. Delta by default, but only sees activities whose start date is after the last sync — an edited or back-dated activity needsfull=Trueto be picked up (see PLAN.md "Strava sync"). Requires having runstrava-authonce (below).import_steps(path)— import an Apple Health step-count CSV export from wherever it landed (e.g. attached to a chat message). No API, no cursor — always reprocesses the whole file and upserts by day, so a repeated or overlapping export is harmless. A day with samples from more than one source (phone + watch) is deduplicated by taking the larger source total, not summing them — see PLAN.md "Step import" and ADR-0010.import_workouts(paths)— import Apple Health workout CSV export(s) (one file per workout type — Running, Cycling, Walking, ... — so this is usually several paths at once). Rows sourced from Hevy are dropped, not stored: that training already exists viasync_workouts, and keeping both would double-count it — see PLAN.md "Apple workout import" and ADR-0011.query(sql)— read-only SQL (SELECT/WITHonly) against the whole schema. There are deliberately no narrow read tools (list_workouts,daily_nutrition, etc.) — see ADR-0006.
The domain vocabulary these tools use (Product, Food Log Entry, Macros, Catalog, Verified/Estimated, Day, Workout, Activity, Daily Steps, Apple Workout, Volume) is defined in CONTEXT.md.
Related MCP server: Apple Health AI Bridge MCP Server
Setup
Requires Python 3.13+ and uv.
uv syncConfigure via a .env file in the repo root (or HEALTH_MCP_* env vars):
HEALTH_MCP_DB_PATH=/path/to/health.db # defaults to ./data/health.db (repo-relative, gitignored)
HEALTH_MCP_HEVY_API_KEY=... # required for sync_workouts / `sync`
HEALTH_MCP_STRAVA_CLIENT_ID=... # from strava.com/settings/api
HEALTH_MCP_STRAVA_CLIENT_SECRET=... # required for sync_activities / `strava-auth`Strava additionally needs a one-time interactive strava-auth (below) before
sync_activities / sync-strava will work — the resulting token pair is stored
separately, not in .env (see ADR-0009).
Strava is built but not yet connected in this deployment — as of 2026-06-01 Strava requires an active paid subscription ($11.99/mo) to register and use an API app, which is why this is paused rather than done. See PLAN.md "Strava setup (when ready)" for the exact steps to pick it back up once that's worth it.
Migrations run automatically on every CLI invocation.
Running
As an MCP server (what Claude Code / Claude Desktop launch):
uv run health-mcp serveThis repo is already registered as a project-scoped MCP server in .mcp.json, so any
Claude Code session opened here loads it automatically.
Other CLI commands:
uv run health-mcp sync # pull new workouts from Hevy (delta)
uv run health-mcp sync --full # re-fetch everything, reconcile deletions
uv run health-mcp normalize # re-parse stored raw workout payloads, no network
uv run health-mcp strava-auth # one-time: connect a Strava account (ADR-0008)
uv run health-mcp sync-strava # pull new activities from Strava (delta)
uv run health-mcp sync-strava --full # re-fetch everything, reconcile deletions
uv run health-mcp import-steps <path> # import an Apple Health step-count CSV export
uv run health-mcp import-workouts <path> [...] # import Apple Health workout CSV export(s)Tests
uv run pytestRoadmap
Hevy (lifting) syncs into the database today, and daily step counts plus Apple
Watch-native workout sessions import from Apple Health CSV exports on request. Strava
(cardio) is fully built alongside them but paused before its first real connection — see
"Setup" above and PLAN.md "Strava setup (when ready)". query can already answer
questions across Hevy, steps, and Apple workouts; Strava joins once connected. See
"Future ideas" in PLAN.md for what's next after that — an Albert Heijn / NEVO
product lookup, a scheduled digest, and a couple of other candidates, in rough order of
likely value.
Design notes
Key decisions and their rationale live in docs/adr/:
Available Tools
6 toolsadd_productA
Add a Product to the Catalog. Macros are per 100g. source is "verified"
(transcribed from a package label) or "estimated" (general knowledge) — verified is
the standard for anything worth trusting. Returns the new product id.
Inputs: name (required), fat_100g (required), kcal_100g (required), carbs_100g (required), +8 more. Returns: result
delete_food_entryB
Delete a Food Log Entry by id.
Inputs: id (required). Returns: result
find_productA
Search the Catalog by name or brand (substring match). Omit query to list the
whole Catalog. Call this before log_food against a Catalog Product — the result's
id is the product_id log_food expects.
Inputs: query. Returns: result
log_foodA
Log that grams of a food were eaten. Pass exactly one of: product_id (from
find_product, for a Catalog item) or name + macros (per 100g, model-supplied,
for a one-off — always recorded as estimated). at defaults to now; the stored
date is derived via the 04:00 Europe/Amsterdam day rule, not a calendar date.
Returns the new food_log id.
Inputs: grams (required), at, name, macros, +2 more. Returns: result
queryA
Read-only SQL against the health database. Must be a single SELECT or WITH statement.
Schema: products(id, name, brand, source, kcal_100g, protein_100g, carbs_100g, fat_100g, fibre_100g, sugar_100g, sat_fat_100g, salt_100g, note, created_at) food_log(id, logged_at, date, product_id, name, source, grams, entered_as, kcal, protein, carbs, fat, note) workouts(id, title, start_time, end_time, date, updated_at, raw) exercise_templates(id, title, primary_muscle_group, secondary_muscle_groups, equipment) workout_exercises(id, workout_id, idx, exercise_template_id, title) workout_sets(id, workout_exercise_id, idx, type, weight_kg, reps, rpe, duration_s, distance_m) body_measurements(date, weight_kg, fat_percent) sync_state(source, cursor, last_run_at, last_status, last_error)
date columns are always the 04:00 Europe/Amsterdam day, computed at write time —
group by date, not by a calendar date derived from a timestamp.
Inputs: sql (required). Returns: result
sync_workoutsA
Pull new training data from Hevy into the database. Call this before answering a
question about recent training — a workout finished after the last sync isn't in the
database until you do. Delta by default and cheap to call. full=True re-fetches
everything and reconciles deletions; use it only if the data looks wrong, not
routinely. Also refreshes exercise templates and body measurements.
Inputs: full.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 6 tools
Each tool targets a distinct resource and action: catalog management (add/find product), food logging (log/delete entries), workout synchronization, and generic SQL query. There is no overlap or ambiguity between tool purposes.
All tool names follow a consistent verb_noun pattern with lowercase and underscores (delete_food_entry, add_product, find_product, log_food, sync_workouts, query). The naming is predictable and uniform.
The server has 6 tools, which is well-scoped for a health data management domain. Each tool serves a clear purpose without unnecessary redundancy or overwhelming count.
Core workflows are covered: product catalog creation and search, food logging and deletion, workout sync, and read-only query access. Minor gaps exist (e.g., no update or delete for products, no update for food entries), but these can be worked around via delete/re-log or are not essential for the server's purpose.
Maintenance
Related MCP Connectors
Fitness MCP for coaches and gyms: build workouts and read clients' training from live Superset data.
Agent-first strength-training platform across iOS, Web & MCP: read & write workouts, PRs & plans.
Your Garmin, Oura, WHOOP, Hevy and 35 more fitness apps, queryable from your own AI.
Manage your Health Partner account, log food, water, workouts, body using agent
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects AI clients to the Hevy workout tracking app, allowing users to manage routines and exercises. It enables reading workout history and logging new fitness sessions through simple natural language commands.-
- AlicenseAqualityAmaintenanceRead-only MCP server that exposes Apple Health data (steps, workouts, sleep, etc.) from a local SQLite store, allowing AI agents to query health metrics without sending data to hosted services.930Apache 2.0
- AlicenseNot gradedqualityCmaintenanceAn MCP server that securely syncs and queries your health data from Apple Health, storing it in your own Supabase Postgres database and exposing tools for AI assistants to retrieve weight, calories, macros, and more.14 npmMIT
- AlicenseNot gradedqualityBmaintenanceSelf-hosted fitness tracking MCP server that gives AI assistants access to your nutrition, training, weight, sleep, and accomplishment data via 77 tools and 5 resources. Enables natural-language logging and querying of personal health metrics through Claude or ChatGPT.62 npm1BSD 2-Clause "Simplified"