# Tally Workout MCP server > This host is the API for Tally, a free iPhone strength tracker. It exposes one > remote MCP server. An AI assistant connects to it to read the user's training > history and write planned workouts into the app. The marketing site is > https://tallyworkout.app — it does not host the API. ## Connect - MCP endpoint: https://mcp.tallyworkout.app/api/mcp - Transport: Streamable HTTP (JSON-RPC over POST). There is no separate SSE endpoint. - Auth, option 1 (clients that support OAuth): OAuth 2.1, authorization code + PKCE (S256), public client, dynamic client registration (RFC 7591). Scope: workouts. - Auth, option 2 (clients without OAuth, for example Hark, Perplexity, Codex, scripts): an API key. The user creates it in the Tally app under Settings → API keys and gives it to the client. Send it on every request as `Authorization: Bearer tally_ct_…`. A key is Read only, Read and plan, or Full access. A Read only key lists only the read tools, and every write tool returns an error that tells the user to create a Read and plan key. A Read and plan key does not list the tools that change finished workouts; they return an error that tells the user to create a Full access key. OAuth connections can use every tool. Keys do not expire; the user revokes them in Settings → API keys. - Authorization server metadata: https://mcp.tallyworkout.app/.well-known/oauth-authorization-server - Protected resource metadata: https://mcp.tallyworkout.app/.well-known/oauth-protected-resource - Discovery manifest: https://mcp.tallyworkout.app/.well-known/mcp-server - Register a client: POST https://mcp.tallyworkout.app/api/oauth/register with {"redirect_uris":[...],"client_name":"..."}. Redirect URIs must be https, or loopback (127.0.0.1, [::1] or localhost; http is allowed for loopback only). - Meta Muse only: its "Add custom connector" sheet requires a Client ID — use the public client ID `tally-muse` (public client, PKCE S256; its callback is fixed to https://agent.meta.ai/api/hatch/oauth/callback, so it works for Muse and nothing else). Every other client registers its own client dynamically. - The user signs in on the consent page with their Tally account (email, Google or Apple). Access tokens last 1 hour; refresh tokens rotate and last 30 days. - Unauthenticated GET https://mcp.tallyworkout.app/api/mcp returns 401 with a WWW-Authenticate header that points at the protected-resource metadata. ## Tools (21) - get_training_context — read the timezone-aware future plan, with each day's skipped flag (read-only) - get_planned_workout — read one planned day in the exact shape plan_workout_day accepts (read-only) - get_workout_history — completed workouts, newest first, paginated; each session has a stable id (read-only) - get_exercise_progress — per-exercise progress from the last 365 days: recent sessions, top sets, estimated 1RM and bests, in the user's weight unit when Tally knows it (read-only) - search_exercises — resolve exercise names against the user's recent exercises and the library; up to 30 queries per call (read-only) - plan_workout_day — create or overwrite one MCP-authored planned day - plan_workout_range — plan several days in one call; each date reports written or skipped - delete_planned_workout — remove one planned day - skip_planned_workout — mark one planned day as skipped, or restore it; only the status changes - update_planned_workout — edit part of one planned day (add, remove, replace or modify single exercises); other exercises stay as stored - move_planned_workout — move one planned day to an empty date, in one transaction - get_workout — one completed workout by its stable id, in the get_workout_history session format (read-only) - get_training_summary — weekly totals for the current week and up to 11 weeks before it: workouts, completed sets, volume, duration, sets per primary muscle, missed and skipped planned days, and the top exercises; volume is in the user's weight unit when Tally knows it (read-only) - get_saved_workouts — the user's saved and favorite workout templates as last synced from the app, most recently used first, paginated; each exercise has suggestedSets and suggestedReps as stored (read-only) - get_exercise — one exercise by its id: library detail (muscles, equipment, instructions) or a custom exercise from the user's own workouts; library_unavailable is an error result, not a miss (read-only) - send_feedback — send a message from the user to the Tally team (a bug, something Tally cannot do yet, or other feedback); stored with the user's account; at most 5 per account in 24 hours - log_workout — log a finished workout to the user's history (Full access) - update_workout — change one finished workout at its current version: fields, exercises or sets; the earlier content stays restorable for 7 days (Full access) - delete_workout — delete one finished workout at its current version; restorable for 7 days (Full access) - restore_workout — make an earlier version of a finished workout current again, within 7 days, also after a delete (Full access) - get_workout_versions — list the restorable versions of one finished workout, also a deleted one (read-only) Finished workouts change only through log_workout, update_workout, delete_workout and restore_workout. update_workout and delete_workout need the workout's version from get_workout as expectedVersion; a stale version changes nothing. Each change keeps the earlier content for 7 days: get_workout_versions lists the revisions and restore_workout brings one back. These tools need a phone of the user on the current Tally app, except restore_workout. The Tally app shows one finished workout per date: when log_workout, update_workout or restore_workout returns sameDate, tell the user that the app shows only one of the workouts on that date, and offer to merge them with update_workout or to move one to another date. plan_workout_day and delete_planned_workout skip a day the user authored or modified in the app unless overrideUserModified is true; plan_workout_range always skips such days (it has no override). plan_workout_day and plan_workout_range skip dates in the past unless allowPast is true (each result says which dates were skipped). delete_planned_workout has no date guard: it can delete any day it is allowed to touch, past or future. skip_planned_workout changes only a day's status, so it works on any planned day, including days the user authored. plan_workout_range leaves days the user skipped alone. plan_workout_day overwrites a date that already has exercises (planned or skipped) only with replace: true or after reading it (expectedUpdatedAt or expectedVersion from get_planned_workout); otherwise the date is skipped with code exists. Such a write over a skipped day clears the skip. expectedVersion makes a write skip with code version_conflict when the day changed, or was deleted or re-created, after that read. suggestedWeight is in the user's weight unit; a call that passes weightUnit is converted to the user's unit when Tally knows it (weightUnitSource settings or history) and stored as given when it does not. update_planned_workout and move_planned_workout skip a day the user authored or modified unless overrideUserModified is true; update_planned_workout keeps a day's skip status; move_planned_workout never replaces a day already on the target date and skips a past target date unless allowPast is true. Custom exercises are allowed. ## Prompts (1) - weekly-review — Weekly review: Review the last 7 days of training, then plan next week in Tally. A prompt is a starter message the user picks (Claude Code lists them as slash commands). It returns text only; the tools above do every read and write. ## Docs - Setup guide for people: https://tallyworkout.app/connect - Privacy policy: https://mcp.tallyworkout.app/privacy - Support: support@tallyworkout.app