HealthLedger MCP
🩺 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.
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 |
🧑🤝🧑 Multi-person | Every tool takes an optional |
🌐 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. |
🚀 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-mcpPrefer 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 serverThat'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.jsonCursor →
.cursor/mcp.json· Zed →context_servers· Cline / Continue / LibreChat → their MCP settingsAny other MCP client → the same
command/argsshape
Want it to hold more than one person? Pass a
userlabel on any tool call (defaults tome, fromHEALTH_MCP_DEFAULT_USER).
🗄️ Storage
SQLite at
~/.healthledger/health.db— mode0600, WAL journaling. Override withHEALTH_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_recordscatch-all.~/.healthledger/audit.logrecords every tool call (override withHEALTH_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 |
| 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 |
| 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 |
| Pearson & Spearman between two signals aligned on a common time grid, with paired sample size, a two-sided p-value, and significance caveats |
| before/after descriptive stats around a discrete event (med start, procedure) plus the difference in means and a Welch t-test |
| 2+ signals resampled onto one shared day/week/month grid — one row per bucket, one column per signal (inner or outer join) |
| 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 |
| 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 |
| 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 |
| fetch one exact row by |
| analysis tools now return |
| compact cross-domain digest of the record |
| 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 |
| stored upcoming tasks, refills, follow-ups, immunizations, reproductive due dates |
| missing/stale stored data and unresolved follow-ups — without clinical screening claims |
| paginated & capped; use |
Wearables, on purpose
Wearable imports are kept separate from ordinary metrics:
wearable_sourcesidentify the device / app / feed.wearable_samplesstore high-volume typed samples — steps, HRV, resting HR, workouts, sleep, SpO₂, calories, temperature, and similar.Use
import_wearable_samplesfor bulk. Per call: up toHEALTH_MCP_MAX_WEARABLE_IMPORT_ROWS=500samples andHEALTH_MCP_MAX_BULK_JSON_CHARS=200000bytes of JSON.
⚙️ Configuration
Everything is environment variables. Defaults shown; the local-mode defaults need no setup.
Variable | Default | Purpose |
|
|
|
|
| SQLite database path |
|
| audit log path |
|
| default |
|
| max rows returned by a list query |
|
| max rows per export page |
|
| max chars per free-text field |
|
| max wearable samples per import call |
|
| max JSON payload size for bulk import |
|
| calls allowed per window |
|
| 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.logBinds
127.0.0.1only; 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_LOGINSmay connect — everyone else gets401.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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Cole-Will-I-Am/HealthLedger-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server