Building on Mirobody
Development Setup
Run the Mirobody Python engine from a source checkout: venv, editable install, Postgres and Redis in Docker, and the test suites.
Mirobody is a Python service (requires-python = ">=3.12"). Developing on it means creating a virtual environment, installing the package in editable mode, starting Postgres and Redis with Compose, and running mirobody serve. There is no compile step.
Prerequisites
Section titled “Prerequisites”pyproject.toml declares requires-python = ">=3.12"
For the Postgres (pgvector/pgvector:0.8.6-pg17-trixie) and Redis (redis:8.2-alpine) containers
mirobody/res/*.bin, *.npz, *.npy and *.gz are LFS objects
Set up a working tree
Section titled “Set up a working tree”Clone the repository
git clone https://github.com/thetahealth/mirobody.gitcd mirobodyStart Postgres and Redis
compose.yaml defines four services — pg, redis, mirobody and mirobody_worker. For local development you only want the two backing stores; the application runs on your host:
docker compose up -d pg redisThey publish 18062 → Postgres and 18069 → Redis, on loopback only.
Create a virtual environment and install
python3 -m venv venvsource venv/bin/activate # Windows: venv\Scripts\activatepip install --upgrade pippip install -e .pip install -e . gets the engine — ① Collect and ② Standardize as a library, with no database driver and no HTTP server. Working on the chat server or the agents means the [agents] extra, which pulls [server] in with it:
pip install -e '.[agents,test]' # what you want for developmentpip install -e '.[cn]' # Aliyun OSS + Volcengine Arkpip install -e '.[indicator-build]' # only to regenerate the terminology bundlesThere is no Node.js dependency anywhere in the repository.
Write .env and your config override
.env carries three variables: which config file to load, the key that encrypts sensitive config values at rest, and the key that encrypts sensitive log fields.
echo "ENV=localdb" > .envecho "CONFIG_ENCRYPTION_KEY=$(openssl rand -hex 16)" >> .envecho "LOG_ENCRYPTION_KEY=$(openssl rand -hex 16)" >> .envconfig.yaml is the read-only template shipped with the repository. Your edits go into config.<ENV>.yaml — with ENV=localdb, that is config.localdb.yaml:
JWT_KEY: 'a 32-byte random string'
EMAIL_PREDEFINE_CODES: caregiver@mirobody.ai: '111111'
OPENROUTER_API_KEY: 'sk-or-...'Any key whose name contains _KEY, _PASSWORD, _PASS, _PWD, _SECRET, _SK or _TOKEN is encrypted automatically on first load, using CONFIG_ENCRYPTION_KEY. The full key list is in Configuration.
Point the app at the published ports
config.yaml ships the container-network addresses (PG_HOST: 10.108.0.2, REDIS_HOST: 10.108.0.9) because that is where the app container finds them. A process running on your host reaches the same containers through the published ports instead, so override them:
HTTP_PORT: 18060
PG_HOST: localhostPG_PORT: 18062REDIS_HOST: localhostREDIS_PORT: 18069Run
mirobody serveThe server listens on http://localhost:18060 with the override above (without HTTP_PORT, a source run falls back to 80). Log in with caregiver@mirobody.ai and the code you put in EMAIL_PREDEFINE_CODES.
Background work — the IndicatorSync and ProfileRefresh task queues — runs in a second process, not in the web server:
mirobody workerExtension directories
Section titled “Extension directories”Five config keys tell the engine where to look for your own code. Each is a list of directories shipping exactly one entry — the packaged one. Add your own and list it first, so it is scanned ahead of the built-in one:
| Key | Default |
|---|---|
MCP_TOOL_DIRS | mirobody/agent/tools |
MCP_RESOURCE_DIRS | mirobody/agent/resources |
AGENT_DIRS | mirobody/agent |
PROVIDER_DIRS | mirobody/pulse/providers |
SKILL_DIRS | mirobody/agent/skills |
Because everything is discovered at runtime, adding a tool, agent or provider means adding a file and restarting the process — there is no registry to edit and nothing to rebuild.
Running tests
Section titled “Running tests”Tests live beside the code they cover — the test for mirobody/user/care_circle.py is mirobody/user/test_care_circle.py — and testpaths is set, so the whole suite is bare pytest:
pip install -e '.[agents,test]'pytest# passes with no failures, in secondsNo database, no network, no API key. '.[test]' without [agents] is a supported smaller install: the collection step skips the packages whose extras are missing and prints a header naming what was skipped.
The published suite is deliberately the set of tests that are evidence for a public claim, so a clone runs it green in seconds. The core of it:
| Suite | Covers |
|---|---|
mirobody/test_engine.py | golden LOINC codes — pins the whole chain: alias index → commonness prior → axis table |
mirobody/test_engine_coverage.py | the published accuracy number, 211/211, with a coverage floor that fails the build if it drops |
mirobody/test_readme_numbers.py | every figure the four READMEs publish, re-derived from the artifact or code that defines it |
mirobody/test_one_key_defaults.py | the one-key promise: the shipped defaults chat, see and embed with a single OPENROUTER_API_KEY or DASHSCOPE_API_KEY |
mirobody/user/test_care_circle.py · mirobody/demo/test_member_seed.py | the care-circle isolation and demo seed the front page demonstrates |
mirobody/server/test_bootstrap_guard.py | the PRODUCTION / BOOTSTRAP_SCHEMA posture switches |
Additional checks
Section titled “Additional checks”lint-imports # the two import-linter contractslint-imports enforces the two import-linter contracts that keep langchain*, deepagents and langgraph out of everything except agent/ and server/ — see The Engine as a Library.
Provider tests
Section titled “Provider tests”A provider’s tests are ordinary pytest modules in its own package directory, asserting on format_data_v2 with recorded payloads — no server, no database, no network:
pytest mirobody/pulse/providers/mirobody_acme -vHow to structure those tests, and the live verification that complements them, is in Provider Testing.
Repository layout
Section titled “Repository layout”The annotated tree — packages, the extension directories, and the deployment files — is in Installation. It is the single copy, so this page doesn’t repeat it.
Next steps
Section titled “Next steps”Branches, style, and what a PR needs
Add a new health data source
Mapping tests and the live Pulse routes
Run the whole stack in containers