Skip to main content
Glama

🩺 HealthLedger MCP

Your health record, on your machine. Let any AI read and reason over it — on your terms.

A local-first, model-agnostic Model Context Protocol server that stores your personal health data in a local SQLite file and hands back analysis-ready views, so any MCP client — and any LLM behind it — can log, retrieve, and reason over that record on demand.

Python MCP Tools Local-first Model-agnostic Storage

WARNING

Not a medical device. HealthLedger stores and summarizes what you record. Its analysis tools return descriptive statistics, trends, and associations — not diagnosis. For any clinical decision, consult a licensed professional.


✨ What it does

HealthLedger is a personal health ledger you run yourself. Install it wherever you want, point your AI client at it, and start adding your data. By default it runs as a local stdio server — nothing binds to the network and the record never leaves your machine.

🏠 Local-first

Runs as a stdio subprocess of your MCP client. No server to host, no account, no network — your data lives in a local SQLite file.

🤖 Model-agnostic

It's a plain MCP server. Works with any MCP-capable client (Claude Desktop, Cline, Cursor, Zed, Continue, LibreChat, custom agents…) and any model behind it.

🧱 Structured clinical schema

20+ dedicated tables (conditions, meds, labs, biomarkers, oncology, imaging, wearables, …) rather than a bag of notes.

📈 Analysis-ready

Trend tools compute count / min / max / mean / median plus a slope with uncertainty over dated numeric values.

🔗 Cross-signal reasoning

Correlate two signals, estimate before/after change around an event, align many signals onto one time grid, and reconcile units & reference ranges.

📐 Trend intelligence

Slopes with a confidence interval and p-value (real trend vs noise), robust outlier flags, latest-vs-baseline framing, non-linear/cyclical warnings, and change-point detection.

🔎 Retrieval & grounding

Ranked full-text search over all free text (local FTS5, no embeddings), an explicit "what's present / absent / stale" coverage view, and source_ids + get_record so every computed claim traces to a specific row.

🧑‍🤝‍🧑 Multi-person

Every tool takes an optional user label, so one instance can hold a whole household.

🌐 Optional remote mode

If you want a shared instance, it can run as an OAuth-protected HTTP server behind a tunnel. Entirely opt-in — see Remote mode.


Related MCP server: personal-health-mcp

🚀 Quick start

You need Python 3.11+. The fastest path uses uv (uvx runs it with zero install):

# Try it directly from the repo — no clone, no install:
uvx --from git+https://github.com/Cole-Will-I-Am/HealthLedger-MCP healthledger-mcp

Prefer a persistent install?

pipx install git+https://github.com/Cole-Will-I-Am/HealthLedger-MCP
# or, from a clone:
git clone https://github.com/Cole-Will-I-Am/HealthLedger-MCP && cd HealthLedger-MCP
pip install .
healthledger-mcp        # starts a local stdio server

That's it — no OAuth, no tunnel, no account. Your data is written to ~/.healthledger/health.db (override with HEALTH_MCP_DB).


🔌 Use it with any client / any model

HealthLedger speaks stdio MCP, so it drops into the standard mcpServers config that virtually every MCP client uses. Point your client at it and you're done — the model on the other side can be Claude, a local Llama, GPT-something, whatever your client runs.

Zero-install (uvx):

{
  "mcpServers": {
    "healthledger": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/Cole-Will-I-Am/HealthLedger-MCP", "healthledger-mcp"]
    }
  }
}

After pipx/pip install:

{
  "mcpServers": {
    "healthledger": { "command": "healthledger-mcp" }
  }
}
  • Claude Desktop → claude_desktop_config.json

  • Cursor → .cursor/mcp.json · Zed → context_servers · Cline / Continue / LibreChat → their MCP settings

  • Any other MCP client → the same command/args shape

Want it to hold more than one person? Pass a user label on any tool call (defaults to me, from HEALTH_MCP_DEFAULT_USER).


🗄️ Storage

  • SQLite at ~/.healthledger/health.db — mode 0600, WAL journaling. Override with HEALTH_MCP_DB.

  • Schema v4 covers quantitative metrics, events, notes, profile facts, conditions, allergies, medications & dose logs, lab reports/results, biomarkers, tumor/cancer records, encounters/physicals, procedures, imaging, immunizations, care tasks, documents, enriched family history, genomic/PGx records, reproductive-health records, substance-use logs, wearable/app sources, wearable samples, and a generic health_records catch-all.

  • ~/.healthledger/audit.log records every tool call (override with HEALTH_MCP_AUDIT_LOG).

  • It's just a SQLite file — back it up, sync it, or delete it like any other file.

Profile keys (stable facts only)

Recommended keys for clients: birth_date, sex, gender, height_cm, blood_type, emergency_contact, primary_care_provider, preferred_pharmacy, insurance, advance_directive_on_file, plus stable preferences/goals.

⏳ Time-varying data belongs in the dedicated tables, not in profile keys.


🧰 Tool catalog

79 tools, grouped by purpose. Every tool accepts an optional user label (default me, from HEALTH_MCP_DEFAULT_USER).

log_metric · get_metrics · list_metrics · analyze_metric · log_event · get_events · log_note · get_notes · set_profile · get_profile · delete_profile

add_condition · list_conditions · add_allergy · list_allergies · add_medication · list_medications · log_medication_taken · list_medication_schedule · list_medication_logs · add_encounter · list_encounters · add_procedure · list_procedures · add_imaging_report · list_imaging_reports · add_immunization · list_immunizations

add_lab_report · list_lab_reports · add_lab_result · list_lab_results · analyze_lab_trend · add_biomarker · list_biomarkers · analyze_biomarker_trend · add_tumor_record · list_tumor_records · add_document · list_documents · add_family_history · list_family_history · add_health_record · list_health_records

add_reproductive_record · list_reproductive_records · analyze_reproductive_trend · add_substance_use_log · list_substance_use_logs · analyze_substance_trend · add_wearable_source · list_wearable_sources · add_wearable_sample · import_wearable_samples · list_wearable_samples · analyze_wearable_trend

add_genomic_record · list_genomic_records

correlate_metrics · analyze_event_impact · align_series · normalize_series · analyze_trend

semantic_search · get_record · data_coverage

get_reasoning_guide returns the packaged reasoning guide; clients with MCP resource support can also read healthledger://skill/reasoning. Analysis tools guarantee top-level value, reference_range, recency, and source_ids keys; source_ids are table/id citations suitable for get_record. Analysis, summary, care-gap, and clinician-packet tools advertise statementType: descriptive.

add_care_task · complete_care_task · list_care_tasks · list_due_tasks · health_agenda · care_gap_report · summarize_health · build_clinician_packet · search_records · delete_record · export_data · health_status

How the "smart" tools behave

Tool

What it returns

analyze_*_trend / analyze_metric

count · min · max · mean · median · least-squares slope over dated numeric values — the slope now carries a standard error, 95% CI, p-value, and R² so a trend can be told from noise

analyze_trend

full trend intelligence for one signal: slope with uncertainty (SE, 95% CI, p-value, "distinguishable from flat / treat as noise") · robust median/MAD outlier flags · baseline framing (latest vs your own median & Q1–Q3) · rate-of-change (recent vs earlier slope) · shape check warning when a straight line is the wrong model for a bounded/cyclical signal · single change-point detection

correlate_metrics

Pearson & Spearman between two signals aligned on a common time grid, with paired sample size, a two-sided p-value, and significance caveats

analyze_event_impact

before/after descriptive stats around a discrete event (med start, procedure) plus the difference in means and a Welch t-test

align_series

2+ signals resampled onto one shared day/week/month grid — one row per bucket, one column per signal (inner or outer join)

normalize_series

one signal's readings converted to a common unit (incl. mg/dL↔mmol/L via analyte molar mass) with reference ranges reconciled and a unitless in-range position

semantic_search

relevance-ranked (BM25) full-text over all free text — notes, event details, encounter reasons/plans, lab flags, imaging findings, document text, … — stemmed, best-first; each hit carries source_table + record_id + a highlighted snippet. Local FTS5, no embeddings/network.

data_coverage

what's present / absent / stale, as data: per-domain counts with latest date & staleness, an explicit list of empty domains, and a per-signal inventory — so the model checks before asserting instead of confabulating

get_record

fetch one exact row by table + id — resolves a source_ids citation to the underlying data

analyze_* (grounding)

analysis tools now return source_ids as {"table", "id"} citations (the rows behind the numbers) and the latest value's days_stale, so every claim is traceable and recency is explicit

summarize_health

compact cross-domain digest of the record

build_clinician_packet

source-cited visit-prep packet with current snapshot, changed signals, stored follow-ups, genomic/PGx records, reason-for-visit matches, Markdown output, and no clinical recommendations

health_agenda

stored upcoming tasks, refills, follow-ups, immunizations, reproductive due dates

care_gap_report

missing/stale stored data and unresolved follow-ups — without clinical screening claims

export_data

paginated & capped; use table, limit, offset (table=all → one capped page per table)

Wearables, on purpose

Wearable imports are kept separate from ordinary metrics:

  • wearable_sources identify the device / app / feed.

  • wearable_samples store high-volume typed samples — steps, HRV, resting HR, workouts, sleep, SpO₂, calories, temperature, and similar.

  • Use import_wearable_samples for bulk. Per call: up to HEALTH_MCP_MAX_WEARABLE_IMPORT_ROWS=500 samples and HEALTH_MCP_MAX_BULK_JSON_CHARS=200000 bytes of JSON.


⚙️ Configuration

Everything is environment variables. Defaults shown; the local-mode defaults need no setup.

Variable

Default

Purpose

HEALTH_MCP_TRANSPORT

stdio

stdio (local) or http (remote, opt-in)

HEALTH_MCP_DB

~/.healthledger/health.db

SQLite database path

HEALTH_MCP_AUDIT_LOG

~/.healthledger/audit.log

audit log path

HEALTH_MCP_DEFAULT_USER

me

default user label when none is passed

HEALTH_MCP_MAX_ROWS

1000

max rows returned by a list query

HEALTH_MCP_MAX_EXPORT_ROWS

500

max rows per export page

HEALTH_MCP_MAX_TEXT_CHARS

20000

max chars per free-text field

HEALTH_MCP_MAX_WEARABLE_IMPORT_ROWS

500

max wearable samples per import call

HEALTH_MCP_MAX_BULK_JSON_CHARS

200000

max JSON payload size for bulk import

HEALTH_MCP_RATE_LIMIT_CALLS

240

calls allowed per window

HEALTH_MCP_RATE_LIMIT_WINDOW_SECONDS

60

rate-limit window length

Remote-mode-only (HEALTH_MCP_TRANSPORT=http): HEALTH_MCP_GITHUB_CLIENT_ID, HEALTH_MCP_GITHUB_CLIENT_SECRET, HEALTH_MCP_ALLOWED_LOGINS, HEALTH_MCP_PUBLIC_URL, HEALTH_MCP_HOST (127.0.0.1), HEALTH_MCP_PORT (8800), HEALTH_MCP_PATH (/mcp).


✅ Offline tests

From a clone (these touch neither your real database nor real GitHub credentials — they use a temp DB and dummy config):

python test_tools.py     # exercises the tools end-to-end
python test_wiring.py    # exercises the optional remote (OAuth) wiring

🌐 Remote mode (optional)

You don't need any of this to use HealthLedger — it's for people who want to reach one instance from a networked client (e.g. a web-based assistant) instead of running it locally. Set HEALTH_MCP_TRANSPORT=http and it becomes an OAuth-protected HTTP server:

client ──HTTPS──► reverse proxy / tunnel ──► 127.0.0.1:8800  (HealthLedger, http mode)
                        │                            │
                  GitHub OAuth                SQLite 0600 / WAL
                 (allow-list only)             + audit.log
  • Binds 127.0.0.1 only; expose it via your own reverse proxy or a Cloudflare Tunnel.

  • Auth: OAuth 2.1 via FastMCP's GitHub OAuth proxy. Only the GitHub logins in HEALTH_MCP_ALLOWED_LOGINS may connect — everyone else gets 401.

  • Fail-closed: in http mode the process refuses to start without client id/secret and at least one allow-listed login. There is no open networked mode.

  • Health check: an unauthenticated request returns 401 (up and guarded).

Live demo: a single-tenant instance runs at https://health-mcp.manticthink.com/mcp (allow-listed to the maintainer). It's there to show the remote path working — to actually use HealthLedger, run your own local copy per Quick start.


Available Tools

79 tools
add_allergyAdd an allergyC

Store a structured allergy or intolerance record.

Inputs: allergen (required), user, notes, status, +3 more. Returns: object

add_biomarkerAdd a biomarkerC

Store a biomarker observation, including oncology/genetic/inflammatory markers.

Inputs: value (required), biomarker (required), flag, unit, +9 more. Returns: object

add_care_taskAdd care taskB

Store an actionable health task: appointment, refill, lab, screening, follow-up, upload, call, etc.

Inputs: title (required), user, notes, status, +6 more. Returns: object

add_conditionAdd a conditionC

Store a structured problem-list condition. Descriptive record only.

Inputs: name (required), user, notes, status, +4 more. Returns: object

add_documentAdd documentB

Store document/report metadata and extracted text. Binary files are not stored here.

Inputs: title (required), document_type (required), tags, user, +7 more. Returns: object

add_encounterAdd encounterC

Store a visit/encounter such as annual physical, specialist visit, ER visit, therapy, dental, or vision.

Inputs: encounter_type (required), plan, user, notes, +7 more. Returns: object

add_family_historyAdd family historyC

Store family history facts by relation.

Inputs: relation (required), condition_name (required), user, notes, +5 more. Returns: object

add_genomic_recordAdd genomic/PGx recordC

Store one structured genomic/PGx record as lab-reported data.

Inputs: record_type (required), gene, rsid, user, +22 more. Returns: object

add_health_recordAdd generic health recordB

Store any health datum that does not fit a dedicated table yet.

Inputs: title (required), record_type (required), body, tags, +4 more. Returns: object

add_imaging_reportAdd imaging reportC

Store imaging/radiology report metadata and text findings.

Inputs: modality (required), user, notes, facility, +7 more. Returns: object

add_immunizationAdd immunizationC

Store an immunization/vaccine record and optional next due date.

Inputs: vaccine (required), lot, dose, user, +5 more. Returns: object

add_lab_reportAdd a lab reportB

Store metadata for a lab/bloodwork report. Add individual results separately.

Inputs: title (required), user, notes, source, +6 more. Returns: object

add_lab_resultAdd a lab resultC

Store one lab/bloodwork result. Numeric values can later be trended.

Inputs: value (required), analyte (required), flag, unit, +9 more. Returns: object

add_medicationAdd a medicationC

Store a structured medication with schedule/refill metadata.

Inputs: name (required), dose, user, notes, +11 more. Returns: object

add_procedureAdd procedureB

Store a procedure/surgery/test record and any follow-up date.

Inputs: name (required), user, notes, outcome, +5 more. Returns: object

add_reproductive_recordAdd reproductive health recordC

Store menstrual cycle, pregnancy, contraception, fertility sign, or related reproductive record.

Inputs: record_type (required), user, notes, method, +14 more. Returns: object

add_substance_use_logAdd substance use logC

Store time-varying substance exposure such as alcohol, nicotine, caffeine, cannabis, or other.

Inputs: substance (required), unit, user, notes, +5 more. Returns: object

add_tumor_recordAdd a tumor recordC

Store tumor/cancer-related structured information as user-provided data.

Inputs: tumor_name (required), user, grade, notes, +10 more. Returns: object

add_wearable_sampleAdd wearable sampleA

Store one wearable sample. Use import_wearable_samples for batches.

Inputs: value (required), sample_type (required), unit, user, +8 more. Returns: object

add_wearable_sourceAdd wearable sourceC

Store a wearable/app/data-source identity such as Apple Health, Garmin, Oura, Fitbit, CGM, or scale.

Inputs: name (required), user, model, notes, +5 more. Returns: object

align_seriesAlign multiple signalsA
Read-onlyIdempotent

Resample 2+ signals onto one shared time grid for side-by-side comparison.

Takes a JSON array of signal specs and returns a single aligned table — one row per time bucket, one column per signal — so signals can be compared without hand-matching timestamps.

Inputs: series_json (required), agg, join, user, +4 more. Returns: object

analyze_biomarker_trendAnalyze biomarker trendB
Read-onlyIdempotent

Return descriptive trend stats for numeric biomarker observations.

Inputs: biomarker (required), user, since, until. Returns: object

analyze_event_impactAnalyze event impactA
Read-onlyIdempotent

Estimate a signal's before/after change around a discrete event.

Splits one signal at an anchor date (e.g. a medication start, procedure, or regimen change) into 'before' and 'after' groups, reports descriptive stats for each, and adds the difference in means plus a Welch t-test.

Inputs: name (required), event_date (required), user, source, +3 more. Returns: object

analyze_lab_trendAnalyze lab trendB
Read-onlyIdempotent

Return descriptive trend stats for numeric lab results for one analyte.

Inputs: analyte (required), user, since, until. Returns: object

analyze_metricAnalyze a metricA
Read-onlyIdempotent

Compute analysis-ready statistics and a trend for one metric over a window.

Returns count, first/last/latest, min/max, mean, median, standard deviation, and a least-squares linear trend (slope per day, projected next value, direction). These are descriptive statistics for interpretation — not a diagnosis.

Inputs: metric (required), user, since, until. Returns: object

analyze_reproductive_trendAnalyze reproductive trendA
Read-onlyIdempotent

Return descriptive cycle length/duration stats from stored cycle records only.

Inputs: user, limit. Returns: object

analyze_substance_trendAnalyze substance trendB
Read-onlyIdempotent

Return descriptive daily-total stats for one substance when numeric amounts exist.

Inputs: substance (required), user, since, until. Returns: object

analyze_trendAnalyze trend (advanced)A
Read-onlyIdempotent

Trend intelligence for one signal — beyond a single straight line.

Pulls a signal's dated numeric readings and returns, in one call:

  • trend — least-squares slope with a standard error, 95% CI, p-value, and an honest 'distinguishable from flat / treat as noise' verdict;

  • baseline — the latest reading framed against your own recent median and typical range (Q1-Q3), the way a clinician reads a value;

  • rate_of_change — recent vs earlier slope, exposing acceleration;

  • outliers — points flagged by a robust median/MAD z-score, not silently averaged into the mean;

  • shape — whether a straight line is the right model at all (weak fit, residual runs, or a better-fitting quadratic) and whether linear extrapolation is advisable for bounded or cyclical signals;

  • change_point — the single most likely regime shift, if any.

Inputs: name (required), user, since, until, +3 more. Returns: object

analyze_wearable_trendAnalyze wearable trendC
Read-onlyIdempotent

Return descriptive stats/trend for one wearable sample type.

Inputs: sample_type (required), user, since, until, +1 more. Returns: object

build_clinician_packetBuild clinician packetA
Read-onlyIdempotent

Build a source-cited, descriptive visit-prep packet for a clinician or specialist.

The packet is deterministic and local: current medications/conditions/allergies, recent changed numeric signals with uncertainty, relevant stored records, follow-up/completeness items, lab-reported genomic/PGx records, and a Markdown rendering. It does not diagnose, rank clinical urgency, or suggest treatment.

Inputs: user, limit, since, until, +2 more. Returns: object

care_gap_reportCare gap reportA
Read-onlyIdempotent

Report missing/stale data and unresolved stored follow-ups. This is organizational, not clinical guidance.

Inputs: user. Returns: object

complete_care_taskComplete care taskC
Idempotent

Mark a care task completed.

Inputs: task_id (required), user, notes. Returns: object

correlate_metricsCorrelate two signalsA
Read-onlyIdempotent

Correlate two health signals aligned onto a common time grid.

Resamples each signal to one value per resample bucket (day/week/month) with agg, inner-joins the buckets they share, then computes Pearson and/or Spearman correlation with a two-sided p-value and the paired sample size. Either signal may come from any source: metric, wearable, lab, biomarker, substance.

Inputs: name_a (required), name_b (required), source_a (required), source_b (required), +7 more. Returns: object

data_coverageData coverage / what's missingA
Read-onlyIdempotent

Expose what data actually exists — and what's absent or stale — as data.

Purpose: let the model check the record before asserting, instead of confabulating around missing values. Two modes:

  • source + name given → coverage for that one signal: present?, count, first/last date, and days since the last reading.

  • otherwise → a whole-record inventory: per-domain counts with latest date and staleness, an explicit list of EMPTY domains, and a per-signal inventory (which metrics / analytes / biomarkers / wearable types / substances are tracked, each with count + last date + staleness).

Inputs: name, user, source. Returns: object

delete_profileDelete a profile fieldA
DestructiveIdempotent

Delete one durable profile fact by key. Use for corrections/removals.

Inputs: key (required), user. Returns: object

delete_recordDelete a recordB
DestructiveIdempotent

Delete one record by id (for corrections). DESTRUCTIVE.

Inputs: table (required), record_id (required), user. Returns: object

export_dataExport data pageA
Read-onlyIdempotent

Export a bounded page of a user's record as structured JSON.

Inputs: user, limit, table, offset, +1 more. Returns: object

get_eventsGet event historyA
Read-onlyIdempotent

Return recorded events (symptoms/medications/meals/activities), newest first.

Inputs: user, limit, since, until, +1 more. Returns: object

get_metricsGet metric historyA
Read-onlyIdempotent

Return raw metric readings, newest first, optionally filtered by metric/date.

Inputs: user, limit, since, until, +1 more. Returns: object

get_notesGet notesA
Read-onlyIdempotent

Return journal notes, newest first, optionally filtered by date or tag substring.

Inputs: tag, user, limit, since, +1 more. Returns: object

get_profileGet profileA
Read-onlyIdempotent

Return all durable profile facts for a user as a key/value map.

Inputs: user. Returns: object

get_reasoning_guideGet reasoning guideA
Read-onlyIdempotent

Return HealthLedger's packaged guidance on interpreting this schema: order of operations, when to defer to a clinician, and how to phrase uncertainty. Call this once per session before doing cross-signal reasoning.

Inputs: no named parameters. Returns: object

get_recordGet a record by idA
Read-onlyIdempotent

Fetch one exact stored row by table + id — the citation primitive.

Search and analysis tools return source_table / source_ids; this resolves one of those to the full row, so a statement can be grounded in the actual data.

Inputs: table (required), record_id (required), user. Returns: object

health_agendaHealth agendaA
Read-onlyIdempotent

Return a deterministic agenda: due tasks, refills, follow-ups, immunizations, and medication schedule.

Inputs: days, user. Returns: object

health_statusHealth MCP statusA
Read-onlyIdempotent

Return non-secret operational status and per-user record counts.

Inputs: user. Returns: object

import_wearable_samplesImport wearable samplesB

Bulk import wearable samples from a JSON array of objects. Capped per call.

Inputs: samples_json (required), user. Returns: object

list_allergiesList allergiesA
Read-onlyIdempotent

List stored allergies/intolerances, optionally filtered by status.

Inputs: user, limit, status. Returns: object

list_biomarkersList biomarkersB
Read-onlyIdempotent

List biomarker observations, optionally filtered by marker/category/date.

Inputs: user, limit, since, until, +2 more. Returns: object

list_care_tasksList care tasksB
Read-onlyIdempotent

List care tasks, optionally filtered by status or task type.

Inputs: user, limit, status, task_type. Returns: object

list_conditionsList conditionsB
Read-onlyIdempotent

List stored conditions, optionally filtered by status.

Inputs: user, limit, status. Returns: object

list_documentsList documentsB
Read-onlyIdempotent

List stored health documents/reports and extracted text metadata.

Inputs: user, limit, since, until, +1 more. Returns: object

list_due_tasksList due tasksA
Read-onlyIdempotent

List open care tasks due within N days, optionally including overdue tasks.

Inputs: days, user, limit, include_overdue. Returns: object

list_encountersList encountersC
Read-onlyIdempotent

List visits/encounters, optionally filtered by type.

Inputs: user, limit, encounter_type. Returns: object

list_family_historyList family historyB
Read-onlyIdempotent

List family history records, optionally filtered by relation.

Inputs: user, limit, relation. Returns: object

list_genomic_recordsList genomic/PGx recordsA
Read-onlyIdempotent

List genomic/PGx records, optionally filtered by type or gene.

Inputs: gene, user, limit, record_type. Returns: object

list_health_recordsList generic health recordsA
Read-onlyIdempotent

List generic/catch-all health records, optionally filtered by type/date.

Inputs: user, limit, since, until, +1 more. Returns: object

list_imaging_reportsList imaging reportsA
Read-onlyIdempotent

List imaging/radiology reports, optionally filtered by modality/date.

Inputs: user, limit, since, until, +1 more. Returns: object

list_immunizationsList immunizationsA
Read-onlyIdempotent

List immunizations, optionally limited to vaccines due within N days.

Inputs: user, limit, due_within_days. Returns: object

list_lab_reportsList lab reportsB
Read-onlyIdempotent

List lab/bloodwork report containers, newest first.

Inputs: user, limit, since, until. Returns: object

list_lab_resultsList lab resultsB
Read-onlyIdempotent

List lab results, optionally filtered by analyte and date range.

Inputs: user, limit, since, until, +1 more. Returns: object

list_medication_logsList medication logsA
Read-onlyIdempotent

List medication adherence/dose logs, optionally filtered by medication/date.

Inputs: user, limit, since, until, +1 more. Returns: object

list_medicationsList medicationsB
Read-onlyIdempotent

List medications, defaulting to active/current medications.

Inputs: user, limit, status. Returns: object

list_medication_scheduleList medication scheduleB
Read-onlyIdempotent

Return active medication schedules and refill dates.

Inputs: user. Returns: object

list_metricsList tracked metricsB
Read-onlyIdempotent

List which metrics have data for a user, with counts and the latest value of each.

Inputs: user. Returns: object

list_proceduresList proceduresC
Read-onlyIdempotent

List procedures, surgeries, and tests with outcomes/follow-up dates.

Inputs: user, limit, since, until. Returns: object

list_reproductive_recordsList reproductive health recordsC
Read-onlyIdempotent

List reproductive health records, optionally filtered by type/date.

Inputs: user, limit, since, until, +1 more. Returns: object

list_substance_use_logsList substance use logsB
Read-onlyIdempotent

List substance-use logs, optionally filtered by substance/date.

Inputs: user, limit, since, until, +1 more. Returns: object

list_tumor_recordsList tumor recordsB
Read-onlyIdempotent

List tumor/cancer-related records. Descriptive storage only.

Inputs: user, limit, status. Returns: object

list_wearable_samplesList wearable samplesB
Read-onlyIdempotent

List wearable samples, optionally filtered by type/source/date.

Inputs: user, limit, since, until, +2 more. Returns: object

list_wearable_sourcesList wearable sourcesC
Read-onlyIdempotent

List wearable/app data sources.

Inputs: user, limit. Returns: object

log_eventLog a health eventA

Record a discrete event: a symptom, a medication dose, a meal, or an activity.

Inputs: name (required), category (required), user, detail, +2 more. Returns: object

log_medication_takenLog medication takenC

Log an adherence event: taken, missed, skipped, delayed, or other status.

Inputs: medication_name (required), note, user, status, +4 more. Returns: object

log_metricLog a health metricA

Record one quantitative reading (a point in a time series).

Inputs: value (required), metric (required), note, unit, +2 more. Returns: object

log_noteLog a free-form noteC

Record a free-form health journal entry.

Inputs: body (required), tags, user, title, +1 more. Returns: object

normalize_seriesNormalize units & rangesA
Read-onlyIdempotent

Reconcile mixed units and reference ranges within one signal.

Pulls a signal's readings, converts every value (and its reference range, for labs/biomarkers) to a single common unit, and adds a unitless 'reference position' so readings taken with different units or reference ranges become directly comparable.

Inputs: name (required), user, limit, since, +4 more. Returns: object

search_recordsSearch recordsA
Read-onlyIdempotent

Full-text-ish search across stored health domains (case-insensitive substring).

Inputs: query (required), user, limit. Returns: object

set_profileSet a profile fieldB
Idempotent

Set (upsert) a durable profile fact for a user.

Inputs: key (required), value (required), user. Returns: object

summarize_healthSummarize health recordA
Read-onlyIdempotent

Produce a compact, analysis-ready digest of a user's whole record over a window: profile, per-metric statistics + trend, recent events grouped by category, and recent notes. This is the primary tool for an LLM to reason over someone's health; it returns computed descriptive data only, never a diagnosis.

Inputs: user, since, until. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 79 tools

    Disambiguation3/5

    Most tools are scoped to distinct domains, but there is meaningful overlap among the many trend-analysis tools (analyze_trend, analyze_metric, analyze_lab_trend, analyze_wearable_trend, etc.) and between generic catch-all records and domain-specific records. The detailed descriptions help, but with 79 tools the risk of misselection is elevated.

    Naming Consistency4/5

    The overwhelming majority of tools follow a clear verb_noun pattern like list_medications, add_condition, and delete_record. Minor deviations exist with noun-phrase names such as health_agenda, data_coverage, and semantic_search, and the mix of get_ vs list_ for retrieval actions creates slight inconsistency without breaking the overall pattern.

    Tool Count1/5

    79 tools is far beyond the practical range for an MCP server and will heavily burden tool selection and context windows. The count is driven by repetitive add/list pairs across many domains plus multiple overlapping analysis tools, making the surface feel bloated rather than curated.

    Completeness4/5

    The server covers an impressively broad health-record surface: profiles, metrics, events, notes, medications, labs, imaging, genomics, procedures, care tasks, documents, family history, and more. The main gap is the lack of a generic update/edit path beyond delete-plus-re-add, though delete_record and set_profile partially mitigate this for corrections.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      A
      maintenance
      A local-first MCP server that enables AI agents to read user-authorized Google Health API v4 data from Fitbit, Pixel Watch, and partners via OAuth, with tokens never leaving the machine.
      26
      850 npm
      81
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Self-hosted MCP server that aggregates personal health data from Google Health, Oura, and Withings into a single, provider-attributed interface with configurable source of truth preferences.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      A local-first MCP server for querying multi-omic personal health data (genome, labs, wearables) with an honesty contract and progressive disclosure skills.
      1
      AGPL 3.0