What a Provider is
A Provider is a pluggable adapter that pulls raw data from an external source — a wearable API, a mobile health platform, a database — and normalizes it into Mirobody’sStandardPulseData schema. Each provider lives in its own directory under mirobody/pulse/ (or under providers/ for custom ones) and is auto-discovered at boot.
Providers in the health vertical fall into three groups:
- Theta platform (
mirobody/pulse/theta/) — direct OAuth/credential integrations Mirobody maintains itself: Garmin, Whoop, Oura, Renpho, Vital, PostgreSQL. - Apple (
mirobody/pulse/apple/) — iOS Health export plus CDA (Clinical Document Architecture) for medical records. - Vital (under the Theta platform) — an umbrella aggregator that fans out to 300+ wearable and EHR endpoints behind a single OAuth flow. EHR coverage spans roughly 90% of US records.
th_series_data, th_event_data), so downstream tools, agents, and MCP clients see one unified data model regardless of source.
Provider matrix
| Provider | Module | Data | Auth | Config keys | Credentials |
|---|---|---|---|---|---|
| Garmin | mirobody/pulse/theta/mirobody_garmin_connect/ | Activity, sleep, heart rate, HRV, stress, body composition, workouts | OAuth 1.0a | GARMIN_CLIENT_ID, GARMIN_CLIENT_SECRET, GARMIN_REDIRECT_URL | Garmin Developer Portal |
| Whoop | mirobody/pulse/theta/mirobody_whoop/ | Recovery, sleep, strain, workouts, cycles | OAuth 2.0 | WHOOP_CLIENT_ID, WHOOP_CLIENT_SECRET, WHOOP_REDIRECT_URL | Whoop Developer Portal |
| Oura | mirobody/pulse/theta/mirobody_oura/ | Sleep, readiness, activity, HRV | OAuth 2.0 | OURA_CLIENT_ID, OURA_CLIENT_SECRET, OURA_REDIRECT_URL | cloud.ouraring.com |
| Renpho | mirobody/pulse/theta/mirobody_renpho/ | Weight, body fat, BMI, muscle mass, water | Email + password | RENPHO_* (user-supplied per link) | Renpho mobile app account |
| Vital | mirobody/pulse/theta/mirobody_vital/ | 300+ wearables and EHR endpoints (Fitbit, Polar, Withings, Dexcom, Epic, Cerner, …) | OAuth via Vital | VITAL_API_KEY, VITAL_ENVIRONMENT, VITAL_REDIRECT_URL | tryvital.io |
| PostgreSQL | mirobody/pulse/theta/mirobody_pgsql/ | Any rows from a user-owned Postgres database | Connection string | per-link host, port, database, user, password | Your own DB |
| Apple Health | mirobody/pulse/apple/ | iOS Health export, CDA medical records | iOS app + Apple OAuth | APPLE_CLIENT_ID, APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY | Apple Developer Portal |
| Google Health | via Vital | Android Health Connect, Google Fit | OAuth via Vital | (configured under Vital) | Google Cloud Console |
How to connect a provider
Set OAuth credentials in config
Register your application with the vendor’s developer portal (link in the matrix above), then add the keys to Restart Mirobody so the encrypted values are reloaded. Full key list in Configuration.
config.{env}.yaml. For Garmin:config.localdb.yaml
Open the web UI
Sign in at localhost:18080 and open Drive → Providers. Every provider whose credentials are present in the config is listed; the rest are greyed out with a tooltip pointing back here.
Click Connect
The button opens the vendor’s OAuth consent screen in a new tab. Approve access; the vendor redirects to the callback URL configured above and Mirobody stores the refresh token (encrypted) in the user’s row.For password-based providers (Renpho) and DSN-based ones (PostgreSQL), a small form is shown instead of an OAuth redirect.
Pull cadence and sync
Once a provider is linked, a per-user pull task is scheduled bymirobody/pulse/theta/platform/pull_task.py:
- Initial backfill runs immediately. Window depends on the vendor — Garmin and Whoop default to 30 days, Oura to 90, Vital to whatever the upstream API allows.
- Incremental pulls run on a fixed cadence (hourly for most, daily for body-composition-only providers). Each pull is windowed by
last_syncand deduplicated bymsg_id. - Token refresh is automatic for OAuth 2.0 providers; OAuth 1.0a tokens (Garmin) do not expire.
- Failures are logged with the user/provider pair and retried on the next tick — they do not block other providers.
Bring your own provider
If the device or data source you need isn’t in the matrix, write your own. Drop amirobody_<slug>/ directory into the top-level providers/ folder, inherit from BaseThetaProvider, implement info, the credential validator, and (optionally) pull_from_vendor_api. Mirobody picks it up on the next boot.
Provider Integration Guide
Full walkthrough: directory layout, base class, OAuth patterns, data mapping, testing.
Next steps
Configuration
All provider config keys and where to put them
OAuth Implementation
OAuth 1.0a and 2.0 patterns used by Theta providers
Data Mapping
Vendor payload to
StandardPulseDataProvider Testing
Test link, callback, pull, and unlink end-to-end