Browse the docs

API reference

MCP: health data for AI agents

Latido runs an MCP server at https://api.getlatido.com/mcp, so an agent (Claude Code, Claude Desktop, Cursor, your own) can read a project's members and their data and act on them — with the same rules, limits and events as the REST API.

  • Transport: streamable HTTP, stateless (no Mcp-Session-Id), plain JSON responses (no SSE stream). Every request is authenticated on its own.
  • Auth: Authorization: Bearer <credential>. A project API key (lat_test_… / lat_live_…) gets the data tools below, scoped to its project and mode. A personal MCP token (lat_mcp_…, dashboard → Settings → Agents (MCP)) gets only the user tools (get_me, list_users). The 401 carries no WWW-Authenticate, so clients do not start an OAuth discovery.
  • Plan: MCP must be included in the account's plan (mcp; every current plan includes it, otherwise 403 PLAN_LIMIT_REACHED with limit: "mcp"). Each MCP HTTP request counts towards the monthly API request quota.

Connecting a client

Claude Code

bash
claude mcp add --transport http latido https://api.getlatido.com/mcp \
  --header "Authorization: Bearer lat_test_…"

Add --scope project to share it through .mcp.json (keep the key in an environment variable rather than in the repo).

Cursor

.cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

json
{
  "mcpServers": {
    "latido": {
      "url": "https://api.getlatido.com/mcp",
      "headers": { "Authorization": "Bearer lat_test_…" }
    }
  }
}

Any client

bash
curl -s https://api.getlatido.com/mcp \
  -H "Authorization: Bearer $LATIDO_API_KEY" \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The client snippets follow each client's documented configuration format.

Tools (project API key)

Reads default to the last 30 days, newest first, 25 per page (max 100); pass meta.nextCursor back as cursor.

Tool Input What it does
list_providers — The providers of this key's mode (test: only the demo provider) and whether members can connect each now (available). allowsAiProcessing: false marks providers whose data agents never see.
list_members externalUserId? (exact), search? (prefix), limit?, cursor? The project's members, newest first.
get_member memberId (mem_…) One member with connections and record counts. Counts include AI-restricted records.
create_connect_link externalUserId, redirectUrl, providers?, metadata? A hosted connect link (1 hour). Creates the member if new. redirectUrl's origin must be allowed (test keys also accept localhost).
list_workouts memberId, from?, to?, sport?, limit?, cursor? Workouts. Units: meters, seconds, m/s, bpm, watts, kcal; ISO 8601 UTC with utcOffsetMinutes.
get_workout recordId (rec_…) One workout in full: laps, heart-rate zones, power, cadence, polyline. Refused for Strava and Oura workouts.
list_sleep_sessions memberId, from?, to?, limit?, cursor? Sleep; date is the wake-up day; stage durations in seconds, HRV in ms (RMSSD), score 0-100.
list_daily_summaries same Steps, meters, kcal, active seconds, resting HR, HRV, stress 0-100, readiness/recovery 0-100, SpO2 %.
list_body_measurements same Weigh-ins and body measurements: kg, %, meters, mmHg, °C.
get_trends memberId, weeks? (1-26, default 8) Weekly aggregates, oldest first, ISO weeks starting Monday UTC: workouts (count, distance, duration, by sport), sleep (nights, average asleep), average resting HR and HRV.
push_planned_workout memberId, provider, workout Sends a structured workout to the member's device through a provider that accepts them (Garmin, Suunto, COROS, Wahoo, demo) and that the member connected. Asynchronous: answers queued; the result arrives as planned_workout.pushed / .failed. Needs a plan with planned workouts.

There is no MCP tool for heart-rate series or glucose yet; use the REST API for those.

With a lat_mcp_ token the server lists only get_me and list_users (the dashboard user and their team).

The Strava / Oura AI exclusion

Strava's and Oura's 2026 API agreements forbid sending their data to AI models. Latido enforces it on the MCP surface (catalog flag allowsAiProcessing: false):

  • Their records are never returned by any MCP tool. List tools leave them out and say so in meta.withheld:

    json
    "withheld": {
      "count": 12,
      "providers": ["strava", "oura"],
      "reason": "These providers' terms forbid sending their data to AI models; ask the member to view them in your app instead"
    }
  • get_workout refuses a Strava or Oura workout; get_trends leaves their data out of the aggregates and reports it in meta.withheld.

  • Members can still connect Strava and Oura, and the REST API (/v1) returns their data as usual — it is your application, not an AI model, that reads it there. If you forward REST data to an LLM yourself, the same terms apply to you.

  • Raw provider payloads never leave through MCP.

Same rules as the API

Tools dispatch through the same command and query buses as the HTTP routes: plan limits, validation, entity locks and webhook events behave identically (an MCP create_connect_link creates the same member, push_planned_workout fires the same webhooks). Errors come back as MCP tool errors carrying the API's error code and message.