Skip to main content
Mirobody

Mirobody

Turn scattered health data into answers you can trace.

A self-hosted AI health data engine for lab reports, wearables and genetic files.
Start with Docker and one model key, or run every model on your own machine.

English · 中文

PyPI License: Apache-2.0 GitHub stars

▶ Live demo · 🐳 Start with Docker · 📚 Documentation

Asking how cholesterol has changed: the agent finds three files that name the test differently, charts one trend and names the file behind every number

Three reports, three names for the same test. One trend, with the file behind every number.

Start with Docker

Docker with Compose is all the stack needs: no Python, Node.js or GPU. On Windows, run these in a WSL 2 terminal.

git clone --depth 1 https://github.com/thetahealth/mirobody.git && cd mirobody
./deploy.sh

Open the setup link the script prints and paste one model key: OpenRouter, OpenAI, Gemini, Anthropic, DeepSeek, DashScope, or any OpenAI-compatible gateway. The key is kept only after one real request through it works. Postgres, the server, the worker and a synthetic demo record start together.

  1. Sign in as you@mirobody.ai, code 111111, on the Email code tab. The demo holds 2,019 readings across two records: yours, and mom@mirobody.ai's, which she shares with you view-only.
  2. Ask "How has my cholesterol changed?" The answer charts the trend and names the file behind each number.
  3. Upload a sample from demo/upload/ on the Data page, or switch to mom's record and ask again.
Prefer every model on your own machine? No model key needed.

From the cloned folder, start the stack with llama.cpp's CPU image beside it:

COMPOSE_PROFILES=local-cpu ./deploy.sh

The script points Mirobody at llama.cpp, which serves a small answering model and a document reader; the setup page has nothing to ask. Allow 16 GB of memory, at least 8 GB of it for Docker, and a one-time download of about 3.7 GB. With no GPU a first answer takes minutes: 2–3 on an M1 Pro's cores, up to about 15 on a 4-vCPU x86 server. On a Mac, running llama-server natively uses the GPU: about 30 s per answer on a 16 GB M1 Pro.

The first-run page: a model name edited beside an OpenRouter key, then 100% on this machine: the page finds the llama.cpp server, lists the models it serves, and both models are ready

Mac, NVIDIA and Windows setup · Which model to choose

→ Self-host guide · Walkthrough · Deploy on a server

What you can do

  • Compare reports across labs. PDFs, phone photos and spreadsheets, 23 file types in all, land in one history. Every reading links to the page it was read from.
  • Bring in everyday data. Import an Apple Health export, or connect Garmin, Oura and Whoop.
  • Look after your family. Invite someone who shares their own record, or keep one for a parent who never signs in.
  • Write a health journal. headache since last night, BP 150/95, no fever becomes a coded complaint and two coded readings; "no fever" is not logged as a fever.
  • Explore genetic data. Upload a 23andMe, AncestryDNA or WeGene export, or a VCF, and ask by rsID, gene or region. Drug questions get CPIC coverage, never a change of medication.
  • Use your own agent. Connect Claude Code, Codex or Cursor over MCP, or embed the offline engine in Python.

Collect · Translate · Agent

Collect reports, device data and genetics; translate names and units so sources compare; ask across your history and trace each answer to its source

Stage What it does Where
① Collect Files, devices and journal entries come in; the source is kept, so every reading points back to it. collect/
② Translate A1c, HbA1c and Glycated Hemoglobin resolve to one code, units to one standard, offline. A name it cannot place stays unresolved. engine/ · translate/
③ Agent Ask over the coded record: trends, comparisons across labs and devices, a chart, and the file behind every number. agent/

The model reads documents and reasons; the codes and units come from vocabularies bundled with the package, never from the model. How a reading moves through the pipeline.

Care for your family

Invite a family member; they choose whether you may view or edit their own record; ask about the record they share. A family member who does not sign in can be managed by you until they take over and choose your access

Joining a care circle shares nothing by itself. Each member decides whether others may view or edit their own record. A parent who never signs in can be managed by you until they claim the record and choose what you keep. See it in the walkthrough.

What stays on your machine

Your record lives in a Postgres you run, and nothing here reports usage anywhere. What leaves depends on who reads it:

With a model key 100% on this machine
Your documents and questions sent to that model vendor, under its terms stay here
A name to a code, a unit to UCUM (② Translate) here, from the bundled vocabulary, with no network the same
Model weights none downloaded once from Hugging Face

Device vendors see data only after you link one. Before this reaches a network you do not control, read SECURITY.md: it lists every address the server can call.

Build on Mirobody

You want Start here
Your record in Claude Code, Codex, Cursor or Gemini CLI Settings → MCP link, then one line per client
Names and units resolved in your own code pip install mirobody: offline, no key, numpy the only dependency (library guide)
Your coding agent taught the workflow npx skills add thetahealth/mirobody --skill translate-health-data (skills)
A new device provider or tool Drop a file into mirobody/collect/providers/ or mirobody/agent/tools/ (CONTRIBUTING)
A hosted API instead Mirobody Cloud

Over MCP the stack serves seven tools, each scoped to the signed-in person: four read your record (readings, medications, genotypes, pharmacogenomics) and three resolve names and units.

Try the vocabulary with no key, no network and, with uvx, no install:

uvx --python 3.12 mirobody resolve "LDL cholesterol" 血红蛋白 ヘモグロビン 血脂
from mirobody.engine import resolve, resolve_reading

resolve("血红蛋白").loinc                                     # '718-7'   any language, one code
resolve_reading("total cholesterol", "5.0", "mmol/L").loinc  # '14647-2' the unit picks the code...
resolve_reading("total cholesterol", "193", "mg/dL").loinc   # '2093-3'  ...mass, not moles
resolve("中性粒细胞百分比").loinc                               # '26511-6' Neutrophils/Leukocytes
resolve("血脂").resolved                                     # False    a category, not one test

Numbers you can check

Claim Check it
317/317 on the tests an ordinary checkup prints, in English, Chinese, Japanese, Russian and Estonian test_engine_coverage.py prints the score
330 UCUM units with dimensional analysis, and 316 standard device indicators Standardization · Device crosswalk
The package names its vocabulary: mirobody.BUNDLE_VERSION is loinc-2.83+2026.09.17-aacb2c715b56 python -c "import mirobody; print(mirobody.BUNDLE_VERSION)"
Public health-agent benchmarks: ESL-Bench, MedHall-Bench, MedHarm-Bench mirobody-eval · benchmarks/

Mirobody is the engine under Theta Wellness, a live consumer health app.

Contributing

The most useful contribution is a term the resolver gets wrong. Run mirobody resolve "<term>"; if the answer is wrong or empty, report it or send a fix with a test case. CONTRIBUTING.md has the setup and the checks.

Built on HL7 FHIR, LOINC from the Regenstrief Institute, UCUM, ICPC-3 (WONCA), CPIC, llama.cpp and deepagents, with thanks. Terminology licences: LICENSE-3RD-PARTY.

If Mirobody helped you make sense of a report, a star helps the next person find it.

Documentation · Roadmap · Changelog · Security · AGENTS.md

Apache 2.0 · © 2026 Theta Health

Metadata

Release files for mirobody 1.5.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mirobody 1.5.4
File Size Uploaded
mirobody-1.5.4.tar.gz 15.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for mirobody 1.5.4
File Interpreter ABI Platform
mirobody-1.5.4-py3-none-any.whl Python 3 none any Details

Total release size: 30.5 MB

Release files / mirobody-1.5.4.tar.gz

Download URL mirobody-1.5.4.tar.gz
Size 15.2 MB
Tags Source
SHA-256 checksum
How to use checksums
4fc22b7f6f55e4db5ba8010ff8c9f942fd595377b244cae23512a90107aa4925
BLAKE2b-256 checksum
How to use checksums
867c224ec96f98a9f2700798ba04c6915c4d2d521e41ef3b7c8bc24a11f8c690
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / mirobody-1.5.4-py3-none-any.whl

Download URL mirobody-1.5.4-py3-none-any.whl
Size 15.3 MB
Tags Python 3
SHA-256 checksum
How to use checksums
aa4efdc41050d12d3a045a46a1009c43d74abc0817912815f968848b823843de
BLAKE2b-256 checksum
How to use checksums
a9ceb4e6eefc782deb9652d98b4b0f21fa49a33a5e61f29a7a6133c440df9583
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

This release

1.5.4 This release

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.0.62

2 release files

1.0.51

2 release files

1.0.50

2 release files

1.0.4

2 release files

1.0.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page