Join our live, hands-on workshop about agentic AI on May 22 & June 13, 2026. Learn more! πŸ‘‰
← AI Guides

Health Coach

Heads up: This guide is a step more technical than most on this site. You will edit a config file and connect MCP servers (Model Context Protocol) so Claude can read your Strava and Oura data. If that sounds fine, keep going. If not, start with How to Setup Claude and come back when you are ready.

You do not need to pay a personal trainer hundreds of dollars to get a workout plan that respects how you actually feel on a given day. If you already track runs in Strava and recovery in Oura (or Apple Health), Claude can read that data and help you train smarter.

I built a Health Dashboard as a Claude Cowork Live Artifact. It pulls fresh data from my wearables and Strava each time I open it: readiness, sleep, HRV, cycle phase, training load, and a week-by-week plan with nutrition notes. No spreadsheet. No copy-paste from three apps.

Key insight: The dashboard only works because Claude can call your real health data through MCP connectors. Set up the data pipes first, then ask Cowork to build the artifact.

What you need before you start

  • Claude Desktop on Mac or Windows (for MCP setup)
  • A paid Claude plan with Cowork and Live Artifacts enabled
  • At least one data source: Strava (runs/activities), Oura (sleep/recovery), or Apple Health (beta on Claude mobile)

Connect your data sources

1. Connect Strava with MCP

We use the open-source Strava MCP server so Claude can read your activities, stats, and workout details.

Add Strava to Claude Desktop

Open your Claude Desktop configuration file:

  • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add this block (merge with any existing mcpServers you already have):

{
  "mcpServers": {
    "strava": {
      "command": "npx",
      "args": ["-y", "@r-huijts/strava-mcp-server"]
    }
  }
}

Restart Claude Desktop

Close and fully quit Claude Desktop, then reopen it so the new MCP server loads.

Connect your Strava account

In Claude, say:

Connect my Strava account

A browser window opens. Enter your Strava API credentials, authorize the app, and you are done. Claude will confirm when the connection is live.

First-time setup (what happens)

  1. Browser opens to the MCP setup page
  2. You enter Client ID and Client Secret
  3. Click Continue to Strava and authorize on Strava's site
  4. You see a success message and can close the browser
  5. Claude confirms you are connected

Credentials are saved locally at ~/.config/strava-mcp/config.json and persist across sessions.

Get your Strava API credentials (one-time)

  1. Go to strava.com/settings/api
  2. Click Create an App (or open an existing app)
  3. Fill in the form:
    • Application Name: anything (e.g. "My Claude Assistant")
    • Category: any
    • Website: can be http://localhost
    • Authorization Callback Domain: must be localhost
  4. Copy your Client ID and Client Secret

You only do this once.

Manage the connection

  • Check status: "Am I connected to Strava?"
  • Reconnect: "Connect my Strava account" (use force: true to reconnect)
  • Disconnect: "Disconnect my Strava account"

After Strava is connected, you can ask Claude about recent runs, pace, weekly volume, and athlete stats.

2. Connect Oura with MCP

For sleep, readiness, HRV, and cycle tags, use the Oura Ring MCP.

Get a Personal Access Token

  1. Go to cloud.ouraring.com/personal-access-tokens
  2. Create a new token (e.g. note it "Claude MCP")
  3. Copy it (you will paste it into Claude Desktop config)

Oura Developer portal New Personal Access Token formCreate a personal access token in Oura Cloud.

Install

npm install -g oura-ring-mcp

Terminal running npm install -g oura-ring-mcpInstall the Oura Ring MCP package globally.

Or skip install and run via npx each time (Claude Desktop does this for you in the config below).

Add Oura to Claude Desktop

Open ~/Library/Application Support/Claude/claude_desktop_config.json on Mac (or %APPDATA%\Claude\claude_desktop_config.json on Windows). Add an mcpServers block at the root level, next to preferences:

claude_desktop_config.json with mcpServers section for OuraAdd mcpServers alongside preferences in your Claude Desktop config.

Merge this into your file (keep any other MCP servers you already have, like Strava):

{
  "mcpServers": {
    "oura": {
      "command": "npx",
      "args": ["oura-ring-mcp"],
      "env": {
        "OURA_ACCESS_TOKEN": "your_token_here"
      }
    }
  }
}

Replace your_token_here with the token you copied. Restart Claude Desktop again.

3. Connect Apple Health (beta)

On iPhone, open the Claude iOS app β†’ Settings β†’ Beta Features β†’ turn on Apple Health and approve the categories you want (steps, sleep, heart rate, and so on).

On Android, use Health Connect the same way in the Claude Android app.

Apple Health in Claude is still beta and syncs through the phone, not Desktop MCP. My workaround: I send Apple Health data to Strava, then let Claude read it through the Strava MCP. That keeps everything in one Cowork session on desktop.

Build your Health Dashboard (Live Artifact)

Once Strava and/or Oura are connected in Claude Desktop, switch to Cowork and open the Live artifacts tab. Click New artifact β†’ Chat with Claude, then paste a build prompt like the one below.

The artifact should be one self-contained HTML page that:

  • Calls Oura and Strava tools on each load via window.cowork.callMcpTool
  • Uses Chart.js v4 for charts
  • Uses window.cowork.askClaude for the weekly plan and nutrition copy

MCP tools to require in the artifact

  • Oura: get_readiness, get_sleep, get_daily_sleep, analyze_hrv_trend, get_cardiovascular_age, get_resilience, get_enhanced_tags
  • Strava: get-recent-activities, get-athlete-stats, get-activity-details

Two gotchas that trip people up

  1. MCP responses are objects, not plain strings. Shape looks like { content: [{ text: "..." }] }. Normalize with a small wrapper before you parse anything.
  2. Oura often returns formatted markdown, not JSON. Parse with regex against known templates. Entries split on ---+. Examples: \*\*Score:\*\* (\d+) \(([^)]+)\), Total Sleep:\*\* (\d+)h (\d+)m, Avg HRV: ([0-9.]+).

Personalize the prompt

Before you paste the build prompt, tell Claude your chronological age and primary sport. If you track your cycle in Oura, say so. If not, ask Claude to skip cycle-related sections.

Cowork build prompt (copy and adapt)

# Build: Personal training/recovery dashboard (Cowork Live Artifact)

Build one self-contained HTML artifact that pulls fresh data from Oura + Strava MCPs each load. Use Chart.js v4 only. Call MCPs via `window.cowork.callMcpTool`, generate AI content via `window.cowork.askClaude`.

## MCP tools (all required in artifact's `mcp_tools`)

**Oura:** `get_readiness` `get_sleep` `get_daily_sleep` `analyze_hrv_trend` `get_cardiovascular_age` `get_resilience` `get_enhanced_tags`
**Strava:** `get-recent-activities` `get-athlete-stats` `get-activity-details`

## Two critical gotchas

1. **MCP responses are objects, not strings**: `{ content: [{ text: "..." }] }`. Normalize with a wrapper before every parse.
2. **Oura returns formatted markdown, not JSON.** Parse with regex against known templates. Entries split on `---+`. Examples: `\*\*Score:\*\* (\d+) \(([^)]+)\)`, `Total Sleep:\*\* (\d+)h (\d+)m`, `Avg HRV: ([0-9.]+)`.

## Cycle algorithm β€” derive from Oura, don't ask the user

1. `get_enhanced_tags` for last 120 days
2. Extract dates of all "Generic Period" entries
3. Group consecutive tagged days; gap >7 days = new cycle start
4. Avg gaps between starts β†’ personal cycle length (don't assume 28)
5. Day in cycle = days since last start + 1
6. Phases: 1–5 menstrual, 6–13 follicular, 14–17 ovulatory, 18+ luteal

## Activity intensity (Strava often has no HR data)

Classify by type + pace:
- Yoga / walk β†’ easy
- Hike / swim / strength / moderate ride β†’ moderate
- Ride >25 km/h β†’ hard
- Run by pace: β‰₯7:00/km easy, 6:30–7:00 moderate, <6:30 hard

## ACWR (training load)

Acute = last 7d km. Chronic = last 28d km / 4. Ratio = acute/chronic.
Zones: 0.8–1.3 sweet spot Β· 1.3–1.5 caution Β· >1.5 injury risk Β· <0.8 detraining.

## "Today's call" engine

Base from readiness: β‰₯85 hard Β· β‰₯75 moderate Β· β‰₯65 easy Β· <65 rest.

Downgrade one level if ANY of: HRV β‰€βˆ’7% baseline Β· ACWR >1.5 (force to easy) Β· sleep <6h last night Β· menstrual phase Β· late luteal (≀3 days to period).

## Warnings (surface only when actionable)

- **Recovery debt** β€” HRV β‰€βˆ’7% AND last 3d readiness <80
- **Injury risk** β€” ACWR >1.5 (warn at 1.3–1.5)
- **Period incoming** β€” late luteal, ≀3 days
- **Sleep debt** β€” 2 of last 3 nights <7h

## Sections, top to bottom

1. **Daily glance** (4-col grid)
   - Readiness card (span 2): big score + Optimal/Good/Fair/Pay badge + 6 contributors with mini bars
   - Today's call (span 2): title + body + workout window line
   - Sleep / HRV / RHR / Cycle (1 col each)

2. **Weekly view**
   - 8-week volume bar chart, current week highlighted, dashed 4-week-avg line
   - ACWR gauge (3 colored zones, marker for current ratio)
   - This week's activities β€” type badges header (πŸƒ 5 Run, 🧘 1 Yoga …) + row per activity with emoji, name, distance, pace/duration
   - Easy/hard distribution donut bar (target ~80% easy)
   - HRV trend line: 30d β†’ 14d β†’ 7d β†’ last night, with baseline line
   - Sleep regularity line over 30 days

3. **Weekly plan (Sunβ†’Sat)** β€” `askClaude` returning JSON `{plan: [{weekday, type, intensity, duration, reason}], summary}`. Pass: current phase, each day's phase across the week, recent 10 activities, ACWR, today's readiness, HRV%. Constraints in prompt: hard on follicular/ovulatory, easy/rest on menstrual + late luteal, β‰₯2 non-running days (yoga/strength), hold volume if ACWR >1.3. Color each card by intensity.

4. **Nutrition** β€” `askClaude` prompt: ~140 words in 4 sections (daily anchors, pre/post fueling, one meal to make, one grocery item). Phase + training-aware.

5. **Long-term** (4-col stat grid): YTD distance Β· all-time count Β· vascular age vs chronological Β· resilience "Exceptional" streak count.

## Info tooltips on every metric

Small β“˜ icon next to each metric label. Click β†’ popover with **(a) what it is** (2 sentences) **(b) how to read it** (concrete thresholds). Cover: readiness, HRV, RHR, sleep, cycle, ACWR/training-load, weekly volume, easy/hard distribution, vascular age, resilience, workout window, recovery debt, weekly plan. Generate the copy yourself β€” keep it tight.

## Style

Light mode. Off-white background, white cards, soft shadows, generous whitespace. Status colors: sage (good), amber (caution), muted red (danger), dusty rose (cycle), cool blue (HRV). Big numbers, small labels.

## Before building

1. Call `get-athlete-profile` once β†’ hardcode the athlete ID
2. Probe each Oura and Strava tool with one real call β†’ inspect actual response shape
3. Then build

## Personalize this prompt

Tell the LLM your chronological age, primary sport, and whether you track your cycle in Oura.

Claude will probe your MCP tools, then generate the HTML artifact. Expect a few rounds of "fix the HRV parser" or "highlight this week on the volume chart." Live Artifacts keep version history, so you can roll back if an edit breaks something.

What mine looks like

Here is the dashboard running on my real Strava + Oura data.

Daily glance: readiness score, today's training call, sleep, HRV, resting heart rate, and cycle phase (derived from Oura period tags, not a generic 28-day guess).

Health dashboard daily glance with readiness, today's call, sleep, HRV, and cycleDaily glance: readiness, workout recommendation, sleep, HRV, and cycle phase.

Weekly view: 8-week running volume, acute-to-chronic workload ratio (ACWR), this week's Strava activities, easy vs hard distribution, HRV trend, and sleep regularity.

Health dashboard weekly view with volume chart, ACWR gauge, activities, and trendsWeekly training load, recent activities, and recovery trends.

Weekly plan and nutrition: Sun–Sat sessions with reasons tied to cycle phase and recovery, plus phase-aware nutrition anchors.

Health dashboard weekly plan and nutrition sectionAI-generated weekly plan and nutrition notes based on your phase and load.

The β“˜ icons on each metric open short tooltips so you are not guessing what "ACWR 1.19" or "follicular" means for today's workout.

Tips after your first build

  • Refresh before a run. Open the artifact and hit reload so readiness and HRV reflect last night.
  • Iterate in plain English. "Make hard days terracotta" or "Add a warning when sleep is under 6 hours two nights in a row" works better than editing HTML yourself.
  • Start with one data source. Strava-only still gives you volume and pace; add Oura when you want readiness and cycle logic.

Additional Reading

Here are some related guides to check out:

  1. Intro to Claude Live Artifacts
  2. How to Setup Claude (10 Minute Setup Guide)
  3. 5 AI Tools That Save Me 10+ Hours a Week
  4. How to Give Claude Memory
  5. How to Create Your Own Custom Skill