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 noWWW-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, otherwise403 PLAN_LIMIT_REACHEDwithlimit: "mcp"). Each MCP HTTP request counts towards the monthly API request quota.
Connecting a client
Claude Code
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):
{
"mcpServers": {
"latido": {
"url": "https://api.getlatido.com/mcp",
"headers": { "Authorization": "Bearer lat_test_…" }
}
}
}Any client
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_workoutrefuses a Strava or Oura workout;get_trendsleaves their data out of the aggregates and reports it inmeta.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.