mirobody
thetahealth · thetahealth/mirobody
This self-hosted AI health data engine consolidates and standardizes lab reports, wearables, and genetic files, allowing an agent to answer questions with cited sources.
Self-hosted health data engine: lab reports, wearables and genetic files in one record, and an agent that cites its sources.
Preview
What you can do with it
- Query your personal health records to track trends of specific markers over time.
- Consolidate health data from different providers and formats into a single, standardized record.
- Ask an AI agent questions about your genetic data or wearable device readings with source traceability.
Safety check
Usable, but read the notes first.
- ●Contains instructions that try to override the agent or hide actions from you.
skills/mirobody/SKILL.md
Automated scan of the repo files. Always review code you run.
From the README
Mirobody
Self-hosted AI health data engine: lab reports, wearables and genetic files in one record, and an agent that cites its sources.
English · 中文
▶ Live demo, no sign-up · 📚 Documentation · 🐳 Docker Hub · ☁ Cloud API
Last year's checkup wrote A1c, this year's panel HbA1c, the new clinic Glycated Hemoglobin. One test, three names, nothing to compare. Mirobody reads any source, any format, any language, settles every value onto one standard, and answers questions over that record with each number traced to its file. It runs on your machine, on a model key you choose.
Three files, three names for the same test, one code. The agent finds all three, charts the trend, and names the file every number came from.
Run it in two commands
git clone --depth 1 https://github.com/thetahealth/mirobody.git && cd mirobody
OPENROUTER_API_KEY=sk-or-... ./deploy.sh # Postgres, server and worker → http://localhost:18060
Docker is the only requirement: no Python, Node.js, GPU or Git LFS, and not even Git (curl -L https://github.com/thetahealth/mirobody/archive/refs/heads/main.tar.gz | tar xz && cd mirobody-main is the same checkout). deploy.sh writes the secrets and your key into .env and pulls the prebuilt image, building it from the checkout when the pull fails. It stops and names the fix when a port is taken or another Mirobody stack already runs under this folder's name. The image runs beside its own Postgres, so docker run alone is not a way in. A key added later goes in .env, then docker compose up -d: a restart does not read .env again.
- Sign in. The sign-in page offers the demo account,
you@mirobody.aiwith code111111on the Email code tab.SEED_DEMO_DATAis on by default, so two accounts already hold 2,019 readings: you, andmom@mirobody.ai, who shares her record with you view-only. - Drop a file on the Data page.
demo/upload/holds four files the seed leaves out. The lab PDF and the other lab's CSV are yours; the report photo and the spreadsheet are mom's, so drop those signed in as her. Each analyte comes out with a value, a unit and a code, linked to the page it was read from. - Ask. "How has my cholesterol moved?" finds every file that carries it, whatever the lab called it, charts the trend, and names the file behind each number. The same question on the shared record answers from data you can only view.
- Say how you feel. Type
headache since last night, BP 150/95, no fever, metformin 500 mg morning and eveningunder Data › Records. One sentence becomes a coded complaint, two coded readings and a medication on your list, and "no fever" is kept out of the record rather than logged as a fever.
Which key. Any one of these runs every surface: OpenRouter (OPENROUTER_API_KEY), OpenAI (OPENAI_API_KEY), Gemini (GOOGLE_API_KEY), Anthropic (ANTHROPIC_API_KEY), DeepSeek, DashScope, or any OpenAI-compatible gateway through _BASE_URL. config.llm.yaml names the variable (api_key: OPENROUTER_API_KEY), never the secret; mirobody doctor prints what each surface selected.
→ Self-host guide · Configuration · Deploy on a server
What you get
- Every source, one record. Garmin, Oura and Whoop connect directly; anything a band, ring or scale writes into Apple Health comes with it; PDFs, phone photos, spreadsheets and exports, 23 file types in all, are read by kind.
- One record for the whole family. Invite a partner or a parent, or add a child who never signs in. Sharing is a care circle: invite-only, off by default, and one function,
resolve_subject, is the only way an account reaches a record that is not its own. - Say how you feel, in your own words. Type
headache since last night, BP 150/95, no fever, metformin 500 mg morning and eveninginto the journal. Your model splits the sentence and types each part; the codes come from the vocabulary, never from the model. - No invented codes. Every reading lands in one settled system, or the engine says it could not place it and keeps your words. Built and tested against real reports in English, Chinese, Japanese and Russian.
- Genotypes as facts, not verdicts. Upload a 23andMe, AncestryDNA, MyHeritage, FTDNA or WeGene export, or a VCF, and ask by rsID, gene or region. A drug question gets CPIC coverage, never a phenotype or a change of medication. How genetics works.
- The agent reasons only over coded data, and it need not be ours. Trends from minutes to months, drawn as a chart; comparisons across labs, files and devices, because one code sits under all of them. Every tool is also served at
/mcp, gated per user.
→ The four-minute walkthrough · Device setup for Garmin, Oura and Whoop
Collect · Translate · Agent
| Stage | What it does | Where |
|---|---|---|
| ① Collect | Lab reports, wearables, phone photos, genetic files, a sentence in the journal, all pulled in. The source is kept as it was, so every reading points back to the page it was read from. | collect/ |
| ② Translate | One name to one code, one unit to UCUM, offline and deterministic. A1c, HbA1c and Glycated Hemoglobin become the same test here (LOINC), and 头疼 and headache the same complaint (ICPC-3). | engine/ · [translate/](mirobody/trans |