Skip to content
Get Started

Getting Started

Self-Host Mirobody

Run the Mirobody engine on your own infrastructure: what you get, the three stages, how the data flows, and how to extend it.

Run Mirobody on your own machine, server, or cloud instance. The engine is open source under Apache 2.0 — a Python package (3.12+) usable as a library, plus an HTTP server, a background worker, PostgreSQL with pgvector, and Redis when you want the full capability. The source is at thetahealth/mirobody.

For what Mirobody is and the problem it solves, start at Introduction to Mirobody. This page is about running it yourself.

The code layout, the contribution areas and this documentation all follow the same three stages — C · S · A, where the A is both Answers and the agent that produces them.

StageWhat it meansWhere in the package
CollectTake data in from device providers, uploaded documents and on-device batchesmirobody/pulse/
StandardizeResolve readings to canonical codes (LOINC · SNOMED CT · RxNorm), normalize units, land against FHIR-recognized code systemsmirobody/indicator/
AnswersAn agent reads the original documents through a virtual filesystem and answers with charts and citations. The same standardized series also drives the derived uses: a drafted report, or the insights and alerts you build on topmirobody/agent/

The same measurement is written differently by every source that produces it, with its own units and reference ranges — differences that are enough to stop one person’s own history from being compared against itself. That is the layer Mirobody occupies: an indicator name is resolved before the reading is stored, rather than kept as the string it arrived as. 血红蛋白, ヘモグロビン and hemoglobin all resolve to LOINC 718-7; LDL-C and 低密度脂蛋白胆固醇 both resolve to LOINC 13457-7. Units are normalized to UCUM in the same pass, so 毫摩尔每升 and mmol/L are recorded as one unit. The result is that reports from different devices, laboratories and languages can be placed on a single time series.

Resolution runs locally against vocabularies shipped inside the package — no key, no configuration, and no network connection:

Terminal window
pip install mirobody
mirobody resolve "LDL cholesterol" "血红蛋白" "ヘモグロビン"
from mirobody.engine import resolve
resolve("血红蛋白").loinc # -> '718-7'

Standardization is installable on its own, so this stage can be adopted without running the rest of the services. The resolution rules and the shipped vocabularies are described in Health Indicators; the library API is in The Engine as a Library.

Providers and on-device batches converge on StandardPulseData before anything is written; file extraction writes straight to the store, keeping the report’s own indicator names for semantic search to reconcile. Both routes land in the same indicator table, which is why the agent queries indicators rather than one shape per vendor. The write path, the two tables behind it and the aggregation that follows are described in Data Flow.

There is an agent for each, and the difference is who runs the tool loop.

DeepAgent — you run the engineBaseAgent — an external model calls in
Tool loop runshere, in your deploymentin the LLM provider, against /mcp over HTTP
Forrunning the whole engine yourselfClaude Desktop · Cursor · ChatGPT Apps · any MCP client
Extrasvirtual filesystem, QuickJS, Agent Skills, chartswhatever the MCP tool surface exposes

The engine mints a per-user MCP URL on request — POST /personal/mcp — so one person’s MCP client reaches only their own data. The bundled web client offers it under Settings; your own client can call the endpoint directly. See Agent Types and MCP Integration.

Five configuration keys each point at a set of directories, which the engine scans at startup. Extending it requires no compile step and no entry in any registry.

KeyDefaultWhat goes there
MCP_TOOL_DIRSmirobody/agent/toolsTool modules: a function or a *Service class becomes an MCP tool
MCP_RESOURCE_DIRSmirobody/agent/resourcesMCP UI resources
AGENT_DIRSmirobody/agentAgent implementations
PROVIDER_DIRSmirobody/pulse/providersData providers, one mirobody_<slug>/ package per source
SKILL_DIRSmirobody/agent/skillsAgent Skills: a directory holding one SKILL.md

Add your own directory in config.{env}.yaml and place it first in the list to take precedence over the packaged one. See Adding Custom Tools, Agent Skills and Building a Provider.

Self-hosting is one of two ways to run Mirobody, and each comes with finished surfaces, not only an API:

SurfaceAddressWhat it is
Your own deploymentlocalhost:18060git clone./deploy.sh → sign in. Your data stays on your machine, and the bundled web client is a full app: /data for documents and readings, /ask for the agent, plus Care Circle sharing: a member can let family — or a clinician — ask the AI using their records.
Your MCP endpointlocalhost:18060/mcpFor Claude Desktop / Cursor. Set MCP_PUBLIC_URL for HTTPS and remote clients.
Hosted chatchat.mirobody.aiThe client we operate.
Mirobody Cloudplatform.mirobody.aiKeys, usage, and the health-data API for building on top; see the Cloud tab.
WeChat miniprogramsearch mirobody in WeChatChina only, Chinese interface. Same backend, same records and indicators as the hosted chat client.

Sign-in needs no mail server. The config.yaml template ships one predefined account, caregiver@mirobody.ai with code 111111 — named for the role it plays: you sign in as the caregiver and the shared record you read belongs to someone else — and every start path uses it, because deploy.sh adds no accounts of its own. The server prints the accounts it accepted at startup. A deployment cloned to try out has no Mandrill or SMTP, so the sign-in page opens on password and keeps the email code as a third tab; POST /password/register creates an account with a password of eight characters or more.

The Docker path also arrives with data, because SEED_DEMO_DATA defaults to on: one synthetic person, Demo (synthetic), is already in your care circle with 244 indicators across two years and five documents the agent can read — and your own account holds a thin record of its own (a few weeks of vitals, one checkup, one document), so owned and shared data are distinguishable from the first screen. Her next lab panel is deliberately held out of the seed and shipped as mirobody/demo/lab_report_2025-10-15.pdf, so uploading it is not a no-op — ① Collect and ② Standardize run on a real file, the LDL series gains a point, and the same question gets a different answer. Every value is synthetic; set SEED_DEMO_DATA=false for a deployment that will hold real data. The walkthrough is in the Quickstart.

Run it

Follow the Quickstart: clone, ./deploy.sh, sign in.

Configure it

Add one LLM key in config.{env}.yaml; chat, vision and embeddings all follow it, so the same key also unlocks free-text indicator search and tidied display names. See Configuration.

Understand it

Read The Engine as a Library for the install layers, then the Architecture Overview.

Extend it

Add a tool with Adding Custom Tools, or a data source with Building a Provider.

Contributions are organized around the same three stages. The lowest-barrier kind is making an unresolved indicator name resolve: check it with mirobody resolve "<term>", add a mapping to resolver_overrides.tsv, and add a case to test_engine_coverage.py.