The OpenClaw community keeps asking how to wire their wearables into the agent and get something more useful than the default vendor dashboards. This post is the long-form answer. We’ll walk through end-to-end OpenClaw health and fitness tracking with wearable integrations: pulling metrics from Apple Health, Fitbit, Oura Ring, and Garmin; normalising them; creating a daily briefing; generating workout suggestions based on recovery data; and finishing with the experimental biomarker optimisation agent that’s been making the rounds on Discord.
Why bother with OpenClaw instead of the vendor apps?
The OEM dashboards are fine when you only own one device. The moment you carry an Apple Watch, sleep with an Oura ring, and ride with a Garmin Edge, you’re in data silos. OpenClaw solves three pain points:
- Unified memory. The daemon stores metrics in the same persistent layer that drives every other task. No export-import ritual.
- Cross-tool actions. The same agent that fetches HRV can nudge you on Slack when your readiness score tanks, or open a GitHub issue when you broke your sleep streak.
- Programmability. If the metric exists, it’s just another JSON payload the agent can transform, schedule, and reason about in natural language.
Trade-off: you own the plumbing. OAuth keys expire, APIs rate-limit. If “just works” is your priority, stay with the stock apps. If you want freedom, keep reading.
Collecting data from wearables
OpenClaw delegates the heavy lifting to Composio integrations where possible. Where the marketplace is missing an adapter (looking at you, Garmin), we fall back to plain HTTP requests and a tiny glue script.
Apple Health via HealthKit bridge
Apple still doesn’t expose a public cloud API for HealthKit, so we piggy-back on health-export 1.7.4. The tool runs on device and posts a nightly JSON dump to an S3 bucket. From there, a Claw task ingests the latest file.
# .claw/workflows/apple-health.yaml
on:
schedule: "0 3 * * *" # 3 AM local phone time
jobs:
import-healthkit:
steps:
- uses: composio/s3@v0
with:
bucket: personal-health
filePattern: health-export-*.json
- run: node scripts/parseHealthkit.js ${{ steps.s3.outputs.file }}
The parseHealthkit.js just normalises units (mg/dL vs mmol/L, kcal vs kJ) and writes into claw.memory().
Fitbit official API
Fitbit’s cloud API is well-documented but still stuck on OAuth 1.0a. Use oauth-1.0a@2.2.7 and store the consumer secret in Claw secrets.
# scripts/fetchFitbit.js
import OAuth from 'oauth-1.0a'
import crypto from 'crypto'
import fetch from 'node-fetch'
...
const url = `https://api.fitbit.com/1/user/-/activities/date/${date}.json`
const authHeader = oauth.toHeader(oauth.authorize({ url, method: 'GET' }, token))
const res = await fetch(url, { headers: { ...authHeader } })
claw.memory().put('fitbit', date, await res.json())
Rate limit is 150 requests per hour. Cache aggressively.
Oura Cloud API
Oura moved to OAuth 2 in v2 of their API (March 2023). Composio ships an adapter composio/oura@v2 so the workflow is trivial.
# .claw/workflows/oura.yaml
on:
schedule: "0 */6 * * *" # every 6 hours
jobs:
oura-import:
steps:
- uses: composio/oura@v2
with:
endpoint: "sleep"
since: "yesterday"
The step’s output lands under oura.sleep in memory.
Garmin Health API (DIY)
Garmin hides the API behind a partner program, but you can self-host garmin-connect-iq-proxy. It scrapes your user session and emits fit-files. Then:
# scripts/garmin.js
import FitParser from 'fit-file-parser'
...
const fit = new FitParser({ force: true })
fit.parse(fitBuffer, (error, data) => {
if (error) throw error
claw.memory().put('garmin', data.session.start_time, data)
})
It’s brittle—Garmin changes HTML often—so pin the proxy to commit ad3f91b which still works as of Node 22.2.
Normalising metrics in OpenClaw memory
Different vendors name the same concept differently (readiness vs body_battery). To avoid if-elseif hell, build a mapper:
// scripts/normalise.js
const map = {
hrv: ["apple/HRV", "oura/hrv", "garmin/heart_rate_variability"],
readiness: ["oura/readiness_score", "garmin/body_battery"],
rhr: ["fitbit/restingHeartRate", "oura/resting_heart_rate"],
}
export function normalise(metric, vendorPayload) {
... // return { metric, ts, value }
}
Store the canonical form under metrics.[metric].[isoDate]. Keeping timelines dense but small (1-day buckets) avoids DynamoDB hot-partition when you later query trends.
Building the daily health briefing agent
OpenClaw excels at turning structured data into natural language. The briefing agent lives in the gateway’s UI so you can ask ad-hoc questions, but it also sends a scheduled digest over your chat app of choice.
# .claw/agents/briefing.yaml
name: "Daily Health Briefing"
prompts:
system: |
You are a quantified-self analyst. Use the user's wearable metrics to create a concise morning report (max 5 bullets).
user: |
Metrics since midnight are available via `memory.get("metrics.*.today")`.
actions:
- type: memory.query
- type: compose.slack.send
with:
channel: "#health"
message: "${agent.response}"
triggers:
- cron: "0 7 * * *" # 07:00 local time
Because the agent has shell access, you can extend it to fetch missing data on the fly, but be mindful that long-running scrapes may time out in the hosted gateway (60 s limit).
Trend analysis and recovery-based workout suggestions
The next level is making the agent proactive. Not just “here’s the data” but “do this today.” The community pattern is:
- Query 7-day rolling averages for HRV, resting HR, sleep debt.
- Compare today’s metrics vs the baseline.
- Classify recovery:
green,yellow,red. - Choose a workout template (intervals, zone 2, rest).
All logic is in TypeScript to avoid hallucinations about numbers.
// scripts/recovery.ts
import { getMetric } from './metrics'
export function recoveryStatus() {
const today = getMetric('readiness', 0)
const avg = avgLast('readiness', 7)
const delta = today - avg
if (delta > 5) return 'green'
if (delta > -5) return 'yellow'
return 'red'
}
The workout agent then references that helper:
# .claw/agents/workout.yaml
name: "Workout Suggester"
prompts:
system: |
You are a certified coach. Recovery is ${recoveryStatus()}. Suggest one workout.
triggers:
- cron: "0 8 * * *"
actions:
- type: compose.telegram.message
with:
chatId: 123456
text: "${agent.response}"
Users report 15-20 % fewer hard-bonk days after following this schedule. Small sample size, but promising.
Advanced biomarker optimisation workflow
This is the experimental bit floated in GitHub issue #4821. Idea: factor supplements and diet logs into a genetic algorithm that tunes for a target biomarker (e.g., lower fasting glucose).
Required data:
- Continuous glucose monitor (CGM) readings via Abbott Libre BLE → Raspberry Pi collector → MQTT.
- Food intake from Cronometer CSV export.
- Supplements tracked in Notion database (Composio adapter exists).
Workflow sketch:
# .claw/workflows/biomarker-ga.yaml
on:
schedule: "0 */12 * * *"
jobs:
evolve-protocol:
steps:
- run: node scripts/collectCgm.js
- run: node scripts/collectDiet.js
- run: node scripts/geneticAlgorithm.js
geneticAlgorithm.js:
import GA from 'geneticalgorithm'
...
const population = initPopulationFromMemory()
const ga = GA(population, fitnessFn)
for (let i = 0; i < 50; i++) ga.evolve()
const best = ga.best()
claw.memory().put('biomarkerProtocol', Date.now(), best)
The agent later turns the protocol into a human-readable checklist and pushes it to your phone at 06:00. Early testers saw a 6 mg/dL average drop in fasting glucose over four weeks. Caveat: n=7, and everyone also started exercising more because they were paying attention. Correlation, not causation.
Security, rate limits, and other trade-offs
Health data is sensitive. Storing it in OpenClaw means you become your own privacy officer.
- Encryption: The hosted ClawCloud encrypts memory at rest (AES-256) and in transit (TLS 1.3). Self-hosters must toggle
storage.encrypted: trueindaemon.yaml. - OAuth tokens: Rotate them. Apple sources expire every 90 days, Fitbit every 30. Use the
claw secrets rotatescheduler. - API costs: Oura caps at 10k calls/day per user—fine. Garmin proxy scrapes unlimited but will get your account banned if you hammer it.
- Compliance: If you’re in EU and share the agent output with a team Slack, welcome to GDPR. Don’t store raw medical identifiers in messages.
The bottom line: fun side project = fine. Enterprise setting = talk to legal.
Shipping your agent to ClawCloud in 60 seconds
npm i -g openclaw@latest(Node 22 required).claw login --cloudclaw deploy— the CLI zips.claw/, uploads, and provisions a gateway instance.- Name your agent, pick the Personal Productivity template, and it boots new containers with your workflows.
- Open the gateway URL, confirm the OAuth consent screens, and metrics start flowing.
Note: The free tier allows 1k workflow invocations/month. My setup (four vendors, two agents, GA job) hovers around 600. Heavy CGM polling will push you over.
Practical takeaway
The stack outlined above turns OpenClaw into a personal health analyst: raw data in, actionable instructions out, all under your control. Start with one vendor—Fitbit is the easiest—get the daily briefing stable, then layer in trend analysis. Only tackle the biomarker GA once the basic pipes are boring. When something breaks (and it will), jump into #wearables-integration on Discord—most of the code linked here started life in that channel.