# MCP tool reference

The server exposes **16 tools**, all read-only. Every tool carries `annotations.readOnlyHint: true`, so a client may run any of them without asking for confirmation.

This page is generated from the running tool catalog. It is the same list `tools/list` returns.

| Tool | Catalog | Purpose |
| --- | --- | --- |
| [`get_streak`](#get-streak) | Curated | Get current and historical streak data for any tracked habit or metric. |
| [`get_metric_data`](#get-metric-data) | Curated | Retrieve historical data for any metric with statistics. |
| [`get_day_details`](#get-day-details) | Curated | Get all tracked data for a specific date. |
| [`list_columns`](#list-columns) | Curated | Get list of all tracked metrics/columns for this user with their descriptions. |
| [`get_recovery_context`](#get-recovery-context) | Curated | Get WHOOP recovery metrics with context and trends. |
| [`analyze_strain_balance`](#analyze-strain-balance) | Curated | Analyze strain-to-recovery balance over time. |
| [`get_correlations`](#get-correlations) | Curated | THE single tool for any 'what affects X', 'why is X changing', 'what's connected to X', or pattern/correlation question - across EVERY data source (WHOOP recovery/HRV/sleep/strain, nutrition, habits, weight, custom metrics, bloodwork labs, AND methylation genetics). |
| [`analyze_relationship`](#analyze-relationship) | Curated | Compute a rigorous correlation between ANY TWO metrics ON DEMAND, for pairs the nightly engine didn't precompute (get_correlations only has a fixed catalog). |
| [`get_lab_data`](#get-lab-data) | Curated | Get the user's bloodwork lab results (biomarkers like testosterone, vitamin D, ApoB, triglycerides, TSH, ferritin, hs-CRP, cholesterol). |
| [`get_methylation_data`](#get-methylation-data) | Curated | Get the user's methylation genetic test results (a one-time, STABLE genetic profile: genes like MTHFR, COMT, MTR, MTRR, AHCY and their variants). |
| [`get_daily_features`](#get-daily-features) | Warehouse | Retrieve the raw daily feature matrix: each metric in this user's retrieval catalog (call list_metrics for the exact set - it includes their custom columns) as a normalized numeric series plus its z-score against a trailing 30-day baseline. |
| [`list_metrics`](#list-metrics) | Warehouse | List this user's retrieval catalog - every metric get_daily_features can return: ids, labels, units, domains, and whether each is a behavior or an outcome. |
| [`get_correlation_edges`](#get-correlation-edges) | Warehouse | Query the correlation graph directly as structured edges, with the statistics attached (r, partial r, lag, p-value, sample size, tier, and provenance). |
| [`get_user_facts`](#get-user-facts) | Warehouse | All-time aggregates per metric: first and last recorded day, min, max, total, current and best streak, and 30/90-day rolling averages. |
| [`get_insights`](#get-insights) | Warehouse | Precomputed statistical models the nightly engine maintains: readiness scoring, lead-lag relationships, goal ETA with Monte Carlo confidence bands, streak survival curves, training load, HRV baseline, momentum, dose-response curves, changepoint detection and behavioral archetypes. |
| [`get_summaries`](#get-summaries) | Warehouse | Narrative rollups written by the summarization pipeline: period reviews, lab and methylation interpretations, mission analysis, personal records and the cross-module correlation narrative. |

## Curated tools

These are the same tools the in-app coach uses. They return a conclusion the analysis pipeline already reached, which makes them cheap to call and easy to reason about.

### get_streak

Get current and historical streak data for any tracked habit or metric. Use when user asks about streaks, consecutive days, or 'how many days in a row' for ANY metric - especially custom columns like No Zyn, No Weed, No Alcohol, GMAD, etc. ALWAYS use this for custom/non-standard habits. Supports fuzzy matching: 'no alcohol' finds 'No Alch', 'nicotine' finds 'No Zyn', etc.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metric` | `string` | Yes | The metric to check. Supports: (1) Standard habits: 'vitamins', 'wake7am', 'reading', 'exercise', (2) Custom columns by ID, label, or description keywords: 'noZyn', 'No Weed', 'alcohol', 'nicotine', 'gmad'. Fuzzy matching handles abbreviations and synonyms. |
| `include_history` | `boolean` | No | If true, include when streak started and previous streak segments. Default: false |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_streak",
    "arguments": {
      "metric": "<metric>"
    }
  }
}
```

### get_metric_data

Retrieve historical data for any metric with statistics. Use when user asks about specific values, trends, averages, totals, or comparisons over time. Supports all standard and custom columns.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metric` | `string` | Yes | The metric to retrieve: 'weight', 'pushUps', 'sitUps', 'healthyEating', 'workoutSession', or any custom column ID/label |
| `time_range` | `today` \| `yesterday` \| `week` \| `month` \| `quarter` \| `year` \| `all` | No | Time period to retrieve. Default: 'month' |
| `include_stats` | `boolean` | No | Include computed statistics (avg, min, max, trend). Default: true |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_metric_data",
    "arguments": {
      "metric": "<metric>"
    }
  }
}
```

### get_day_details

Get all tracked data for a specific date. Use when user asks about a particular day, what they did on a date, or needs to verify what was logged.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `date` | `string` | Yes | Date in YYYY-MM-DD format, or relative: 'today', 'yesterday' |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_day_details",
    "arguments": {
      "date": "<date>"
    }
  }
}
```

### list_columns

Get list of all tracked metrics/columns for this user with their descriptions. Use when unsure what columns exist, need to find the correct column ID, or user asks what they can track. Custom columns include descriptions explaining what they mean (e.g., 'No Alch' description: 'No alcohol consumption').

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `include_stats` | `boolean` | No | Include basic stats per column (days tracked, last value). Default: false |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_columns",
    "arguments": {}
  }
}
```

### get_recovery_context

Get WHOOP recovery metrics with context and trends. Use when user asks about their recovery readiness, HRV, sleep quality, strain, or whether they're recovered enough to work out. Provides recovery zone (green/yellow/red), recent trends, and training recommendations.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `days_back` | `number` | No | Number of days to analyze for trends. Default: 7 |
| `include_recommendations` | `boolean` | No | Include training recommendations based on recovery state. Default: true |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_recovery_context",
    "arguments": {}
  }
}
```

### analyze_strain_balance

Analyze strain-to-recovery balance over time. Use when user asks about overtraining, training load, whether they're pushing too hard, or optimal training intensity. Shows strain vs recovery relationship and identifies imbalances.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `time_range` | `week` \| `month` \| `quarter` | No | Time period to analyze. Default: 'week' |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "analyze_strain_balance",
    "arguments": {}
  }
}
```

### get_correlations

THE single tool for any 'what affects X', 'why is X changing', 'what's connected to X', or pattern/correlation question - across EVERY data source (WHOOP recovery/HRV/sleep/strain, nutrition, habits, weight, custom metrics, bloodwork labs, AND methylation genetics). Returns known physiology tested on THEIR data (confirmed/contradicted/confounded), discovered patterns, behavior->lab links, and genetics-informed expectations - all with partial-correlation controls and multiple-testing correction, so the numbers are authoritative (don't recompute from raw rows). Use it for WHOOP-specific pattern questions too. When a metric is given, also returns a GRAPH view: the direct edges touching that metric and (depth 2) one-hop mechanistic chains (e.g. sleep -> recovery -> next-day strain capacity).

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metric` | `string` | No | Optional: filter findings to those involving this metric (fuzzy matched), e.g. 'recovery', 'triglycerides', 'meal quality', 'No Alcohol'. Omit for the full cross-module picture. |
| `status_filter` | `all` \| `confirmed` \| `contradicted` \| `robust` | No | Optional: 'confirmed' for validated physiology, 'contradicted' for surprising deviations or confounded links worth investigating, 'robust' for only the highest-confidence patterns (survived confounder controls + multiple-testing correction). Default: 'all' |
| `depth` | `1` \| `2` | No | Graph traversal depth when a metric is provided. 1 = direct edges touching the metric (default). 2 = also return one-hop chains (metric -> intermediate -> downstream) for mechanistic storytelling. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_correlations",
    "arguments": {}
  }
}
```

### analyze_relationship

Compute a rigorous correlation between ANY TWO metrics ON DEMAND, for pairs the nightly engine didn't precompute (get_correlations only has a fixed catalog). Use when the user asks whether two specific things relate that aren't already in get_correlations - e.g. 'does my sauna use affect my HRV?', 'is there a link between my late dinners and deep sleep?', 'does creatine correlate with my push-up count?'. Works for daily metric x daily metric (habits, WHOOP, fitness, nutrition, custom columns) and daily behavior x lab marker. Applies the SAME statistical guards as the nightly engine (partial correlation controlling for time trend + sleep, autocorrelation-adjusted significance) so it never just eyeballs raw data. Results on a single fished pair are hypotheses, never 'robust'.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metric_a` | `string` | Yes | First metric (the behavior/driver), fuzzy matched. E.g. 'sauna', 'late dinner', 'creatine', 'sleep hours', 'meal quality', 'vitamins'. |
| `metric_b` | `string` | Yes | Second metric (the outcome), fuzzy matched. Can be a daily metric ('HRV', 'recovery', 'push-ups', 'deep sleep') OR a bloodwork marker ('triglycerides', 'vitamin d', 'testosterone'). |
| `lag` | `0` \| `1` | No | Optional day lag for daily x daily: 0 = same day (default search tries both 0 and 1 and reports the stronger). Ignored for lab-marker outcomes. |
| `window` | `integer` | No | Optional lookback window in days (e.g. 90). Omit to use up to a year of data. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "analyze_relationship",
    "arguments": {
      "metric_a": "<metric_a>",
      "metric_b": "<metric_b>"
    }
  }
}
```

### get_lab_data

Get the user's bloodwork lab results (biomarkers like testosterone, vitamin D, ApoB, triglycerides, TSH, ferritin, hs-CRP, cholesterol). Use when the user asks about their labs, bloodwork, a specific biomarker's value or trend, or hormone/metabolic/cardiovascular health backed by blood tests. Supports fuzzy matching: 'vit d' finds Vitamin D, 'testosterone' finds Total/Free Testosterone. Without a marker, returns a panel overview with precomputed insights.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `marker` | `string` | No | Biomarker to look up by name or key, e.g. 'vitamin d', 'apob', 'triglycerides', 'free testosterone'. Omit for a full panel overview. |
| `include_history` | `boolean` | No | Include every historical reading (date + value), not just latest and stats. Default: true when a marker is specified. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_lab_data",
    "arguments": {}
  }
}
```

### get_methylation_data

Get the user's methylation genetic test results (a one-time, STABLE genetic profile: genes like MTHFR, COMT, MTR, MTRR, AHCY and their variants). Use when the user asks about their genetics, methylation, a specific gene, why they respond a certain way to caffeine/stress/supplements/B-vitamins, or which bloodwork their genes suggest watching. Genetics is a MODERATOR, not a daily metric - it explains mechanisms and predicts which labs/behaviors matter, and generates hypotheses that get tested in get_correlations. Without a gene, returns the full pathway overview plus genetically-predicted watch-markers (cross-linked to their labs) and genetic priors.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `gene` | `string` | No | Optional gene symbol to look up, e.g. 'MTHFR', 'COMT', 'MTR'. Omit for the full pathway overview. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_methylation_data",
    "arguments": {}
  }
}
```

## Warehouse tools

These exist only over MCP. They return the underlying evidence rather than a verdict, so a client can test a hypothesis the nightly engine never considered. Results are larger; narrow the window or the metric list when you can.

### get_daily_features

Retrieve the raw daily feature matrix: each metric in this user's retrieval catalog (call list_metrics for the exact set - it includes their custom columns) as a normalized numeric series plus its z-score against a trailing 30-day baseline. This is the analysis primitive - use it to test your OWN hypotheses (custom lag windows, three-way interactions, subgroup splits, regime changes) rather than reading conclusions someone else drew. Returns columnar data: a date axis plus one array per metric, aligned by index, with null for days that have no value. For a precomputed verdict on whether a relationship is statistically real, use get_correlations instead.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | `string` | No | Start date YYYY-MM-DD (inclusive). Defaults to 90 days before `to`. |
| `to` | `string` | No | End date YYYY-MM-DD (inclusive). Defaults to today. |
| `metrics` | `string[]` | No | Metric ids to return, from list_metrics. Omit for all metrics, which is only allowed for windows of 180 days or less. |
| `include_z` | `boolean` | No | Include z-scores alongside raw values. Default: true. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_daily_features",
    "arguments": {}
  }
}
```

### list_metrics

List this user's retrieval catalog - every metric get_daily_features can return: ids, labels, units, domains, and whether each is a behavior or an outcome. Includes their own custom columns under domain 'custom', so the set differs per user. Call this before get_daily_features or analyze_relationship to learn the exact ids. Distinct from list_columns, which describes the user-facing tracking table; this describes the analytical schema and includes derived metrics such as _exercise and _sleepHours that have no column of their own. Note that the nightly correlation scan runs over a deliberately narrower curated subset, so a metric listed here may have no precomputed findings in get_correlations.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `domain` | `string` | No | Filter by domain. The catalog defines exactly these: 'custom', 'fitness', 'habits', 'nutrition', 'whoop'. |
| `role` | `behavior` \| `outcome` | No | Filter by whether the metric is something the user does or something that happens to them. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_metrics",
    "arguments": {}
  }
}
```

### get_correlation_edges

Query the correlation graph directly as structured edges, with the statistics attached (r, partial r, lag, p-value, sample size, tier, and provenance). Use this when you want to filter, sort or traverse relationships yourself - for example every edge above a given effect size, or the mechanistic chain connecting two metrics. get_correlations returns the same underlying analysis as prose aimed at a person; this returns rows aimed at a program.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metric` | `string` | No | Focus the graph on one metric (fuzzy matched on id and label). Omit to return all edges. |
| `depth` | `1` \| `2` | No | With `metric`: 1 returns direct edges, 2 also returns one-hop chains through an intermediate metric. Default: 1. |
| `min_abs_r` | `number` | No | Drop edges whose absolute correlation is below this, 0-1. |
| `tier` | `string` | No | Keep only edges of this confidence tier, e.g. 'confirmed', 'probable', 'hypothesis'. |
| `limit` | `number` | No | Maximum edges to return, strongest first. Default: 100. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_correlation_edges",
    "arguments": {}
  }
}
```

### get_user_facts

All-time aggregates per metric: first and last recorded day, min, max, total, current and best streak, and 30/90-day rolling averages. Use this to ground a claim about a personal record or a lifetime trend without pulling the full history. Much cheaper than get_daily_features when the question is about extremes or streaks rather than day-to-day shape.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `metrics` | `string[]` | No | Restrict to these metric ids. Omit for all. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_user_facts",
    "arguments": {}
  }
}
```

### get_insights

Precomputed statistical models the nightly engine maintains: readiness scoring, lead-lag relationships, goal ETA with Monte Carlo confidence bands, streak survival curves, training load, HRV baseline, momentum, dose-response curves, changepoint detection and behavioral archetypes. Ask for specific sections rather than the whole document - it is large.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `sections` | `string[]` | No | Sections to return, e.g. ['goalEta','changepoints']. Omit to receive the list of available sections plus a size estimate for each, which is the cheapest way to decide what to ask for. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_insights",
    "arguments": {}
  }
}
```

### get_summaries

Narrative rollups written by the summarization pipeline: period reviews, lab and methylation interpretations, mission analysis, personal records and the cross-module correlation narrative. Useful for recovering what was happening in a period, or the qualitative context around a numeric change you found in the feature matrix.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | `string` | No | Summary type, e.g. 'weekly_summary', 'monthly_summary', 'unified_correlations', 'lab_insights'. Call without this argument first to get the exact types that exist for this user, with counts. |
| `from` | `string` | No | Earliest period key to include, e.g. 2026-W03 or 2026-01. |
| `to` | `string` | No | Latest period key to include. |
| `limit` | `number` | No | Maximum summaries to return, most recent first. Default: 12. |

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_summaries",
    "arguments": {}
  }
}
```
