OnlineFitness.app
Run the business side of online coaching from Claude, ChatGPT or any MCP client.
What it can do
- List Clients: Lists all of the coach's clients with status and last workout date.
- Get Client: Returns one client's full card by id, including compliance stats, tags and the client's AI system prompt.
- List Inactive Clients: Lists active clients with no scheduled workout in the last N days (default 7), including clients who never had one.
What data it sees
Do you need an account
No: the server works without sign-in
Run the business side of online coaching from Claude, ChatGPT or any MCP client. Other fitness servers read an athlete's data — this one writes into a coach's practice: clients, training, conversations and the funnel that fills the roster.
- Clients — onboard, tag, archive, and find who has gone quiet
- Training — build workouts and programs from the coach's own exercise library, schedule them, read results
- Conversations — see who is waiting for a reply, answer, or broadcast to everyone at once
- Lead funnels — quiz funnels and lead magnets, with leads and their attribution
- Content — plan and draft posts for the coach's channels
129 tools. Free for up to 3 clients.
Docs: https://onlinefitness.app/ai/mcp-tools · Website: https://onlinefitness.app
How to connect
How to connect OnlineFitness.app to Claude
The server address to paste into Claude settings:
https://onlinefitness--kulakowka.run.tools
- Open Claude (claude.ai or the desktop app).
- Go to Settings → Connectors.
- Click Add custom connector.
- Paste the server address copied below into Remote MCP server URL and click Add.
- In a chat, click + → Connectors and switch the new connector on.
Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.
Authorization
After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.
How to connect OnlineFitness.app to ChatGPT
The server address to paste into ChatGPT settings:
https://onlinefitness--kulakowka.run.tools
- Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
- Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
- Open Settings → Connectors and click Create.
- Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
- Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
- In a new chat open + → Apps/Connectors and enable the connector.
OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.
Authorization
On first use ChatGPT opens the service's sign-in window. Sign in and approve access.
How to connect OnlineFitness.app to Cursor
The server address to paste into Cursor settings:
https://onlinefitness--kulakowka.run.tools
Fastest: click Open in Cursor below and confirm the prompt.
Manually:
- In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
- Paste the JSON copied below into
~/.cursor/mcp.json(per project:.cursor/mcp.jsonin the repo root). - Save the file. The server appears in the MCP list; authorize it there if asked.
Authorization
If the service needs sign-in, an authorize button appears next to the server in the MCP list.
Server tool list (60)
Raw names from tools/list. Only developers need these.
| list_clients | Lists all of the coach's clients with status and last workout date. |
| get_client | Returns one client's full card by id, including compliance stats, tags and the client's AI system prompt. |
| list_inactive_clients | Lists active clients with no scheduled workout in the last N days (default 7), including clients who never had one. |
| create_client | Creates a client and SENDS an invitation email to the given address. Calling it again for the same email does not duplicate the client — it re-sends the invitation (use this to re-invite a pending client). Returns the client card plus the invitation link the coach can share directly. |
| list_client_tags | Lists all of the coach's client tags grouped into cohorts: each tag with the ids of clients labeled by it. Use it to see existing tags before set_client_tags and to resolve tag-based audiences. |
| set_client_tags | REPLACES a client's whole tag set: pass the complete desired list, not a diff (an empty list clears all tags). Tags are normalized to lowercase, trimmed, and a leading '#' is stripped; reuse existing tags from list_client_tags where possible. Returns the client's resulting tags. |
| set_client_access | Grants or extends a client's paid access until a calendar date (inclusive, end of day in the client's timezone) — a date in the past is accepted and ends access immediately, so double-check the year. Pass amount (with optional currency, default USD, and paidAtIso) to also record a payment in the coach's private ledger. Works only for active clients. On the free plan this is the only paid gate: opening access for a client who is not billable yet fails when the coach already has 3 such clients (extending an already billable client always works, and revoke_client_access is never gated). Returns the updated client card (see accessSummary; trialUntil marks access granted automatically as a trial, which does not take a plan slot). |
| revoke_client_access | Revokes a client's paid access immediately (accessSummary keeps the period as history with cancelledAt set). Reversible by granting access again via set_client_access. Not idempotent: each call re-stamps cancelledAt and logs the action — don't retry a successful call. Returns the updated client card. |
| list_client_payments | Lists a client's payments from the coach's private ledger, newest first (by paidAt). Payments are created by set_client_access when amount is passed. limit defaults to 20, max 100; offset skips newer entries (capped at 1000). |
| delete_client_payment | Deletes one payment record from the coach's private ledger (IRREVERSIBLE). Does NOT change the client's access period — adjust that via set_client_access. No-op if missing (deleted:false). |
| archive_client | Archives a client (status archivedByCoach, hides from the active list). Reversible via activate_client. Returns the updated client card. |
| activate_client | Restores an archived client to active status. Reverse of archive_client. Returns the updated client card. |
| update_client | Sets the system prompt of the client's built-in AI assistant (persona/instructions). An empty string resets it to the default. Name and email cannot be changed here. Returns the updated client card. |
| list_client_workouts | Lists a client's workouts within a date window (summaries, no exercises). Defaults to today±30 days. If more than 100 match, the most recent are returned with truncated=true — narrow from/to. |
| get_client_workout | Returns one client workout with full exercise cards (descriptions, video, completion). |
| create_client_workout | Creates a client workout as an empty shell — add exercises separately. type: workout (regular) or rest_day. Returns the created workout (lean). |
| update_client_workout | Updates a client workout. Pass only the fields to change (omitted fields keep their value). exerciseIds may only reorder/remove EXISTING exercise ids (unknown ids are rejected); to add new exercises use add_exercises_to_client_workout. Returns the updated workout (lean). |
| delete_client_workout | Deletes a client workout (IRREVERSIBLE, hard delete). Cascades: its exercises, the workout chat (comments/media) and the calendar event are deleted; the workout disappears from the client's schedule. No-op if missing (deleted:false). |
| add_exercises_to_client_workout | Adds exercises from the coach's library to a client workout, in the given order (each is copied; library video carries over). Set per-exercise instructions (e.g. '3×12, rest 60s') right away. Items are applied independently: a failed item is reported in results[] and the rest continue; exercises already in the workout are skipped as duplicates — retrying a batch is safe. Returns per-item results and the updated workout (lean). |
| create_client_workout_exercise | Creates a custom exercise directly in a client workout (not from the library). videoUrl: YouTube only. Prefer add_exercises_to_client_workout for library exercises. Returns the updated workout (lean). |
| update_client_workout_exercise | Updates an exercise inside a client workout (exerciseId from get_client_workout). Pass only the fields to change; omitted fields keep their value, including video. videoUrl: YouTube only. Returns the updated workout (lean). |
| delete_client_workout_exercise | Removes an exercise from a client workout (IRREVERSIBLE). Cascades: the exercise chat (comments/media) is deleted. exerciseId is the id inside the workout. No-op if already gone (deleted:false). Returns {deleted, workout} with the updated workout (lean). |
| list_exercises | Lists the coach's exercise library as summaries (no descriptions — use get_exercise for the full card). Filters: tag (exact match), query (case-insensitive substring of the title) and folderId (see list_exercise_folders). limit defaults to 50, max 100; truncated=true if more matched. |
| get_exercise | Returns one library exercise by id with the full description. The same id serves as sourceExerciseId for get_exercise_progress. |
| create_exercise | Creates an exercise in the coach's library. videoUrl: YouTube link only (video files cannot be uploaded via MCP). Returns the created exercise. |
| update_exercise | Updates a library exercise. Pass only the fields to change; omitted fields keep their value. Video cannot be cleared via MCP — omitting videoUrl keeps the current one. Returns the updated exercise. |
| delete_exercise | Deletes a library exercise (IRREVERSIBLE, hard delete). Workouts it was copied into are NOT affected (they hold snapshots). No-op if missing (deleted:false). |
| get_exercise_progress | Returns a client's latest results for one movement by sourceExerciseId (newest first). limit defaults to 20, max 100; offset skips newer results to reach older ones (capped at 1000). |
| list_leads | Lists funnel leads (newest first). Without from/to returns the most recent (up to 100, then truncated=true). Each lead has status (new/seen/archived) and converted (became a client). |
| get_lead | Returns one lead by id: questionnaire answers, contact, UTM attribution, conversion status. |
| mark_lead_seen | Marks a lead as seen (status new → seen). Idempotent (no-op on an already seen lead). Returns the updated lead. |
| archive_lead | Archives a lead (removes it from the active inbox). Reversible via restore_lead. Returns the updated lead. |
| restore_lead | Restores an archived lead back to the inbox (status archived → seen, not new). Returns the updated lead. |
| list_forms | Lists the coach's forms (questionnaires/check-ins) with their questions. Use a form's id with list_client_form_answers to narrow answers to that form. |
| get_form | Returns one form by id (questionnaire questions). |
| list_client_form_answers | Lists a client's form answers as question–answer pairs (newest first). formId narrows to one form. truncated=true if more than 200 matched — narrow by formId. |
| create_form | Creates a form (questionnaire/check-in) with an ordered list of question texts. Questions are shown to clients verbatim — write them in the client's language. Returns the created form. |
| update_form | Updates a form. Pass only the fields to change (omitted fields keep their value). questions REPLACES the whole list — pass the complete new list, not a diff. Returns the updated form. |
| delete_form | Deletes a form (IRREVERSIBLE, hard delete). Already submitted client answers are kept — they store question/answer snapshots. No-op if missing (deleted:false). |
| list_client_measurements | Lists a client's measurement entries (weight/circumferences), newest first. values holds the metrics; hasPhotos tells whether progress photos exist. limit defaults to 20, max 100; offset skips newer entries (capped at 1000). |
| list_client_health_records | Lists a client's health form entries, newest first. answers maps each condition (chronic_conditions, hormonal_medications, injuries_and_surgeries, pain, varicose, diastasis) to the client's answer: present tells yes/no, details holds their explanation. A condition missing from answers means the client did not answer it — that is not the same as 'no'. limit defaults to 20, max 100; offset skips newer entries (capped at 1000). |
| list_client_fitness_goals | Lists a client's fitness goal entries, newest first. Each entry is what the client wanted at that moment: desiredWeight plus their own wording for the month (monthResult, monthGoal). The newest entry is the current request; older ones show how it changed. limit defaults to 20, max 100; offset skips newer entries (capped at 1000). |
| list_client_inventory | Lists the equipment the client says they have (their own wording, e.g. 'dumbbells 5 kg', 'resistance bands'), oldest first. Read-only: the client edits it in the app. An empty list means the client has not filled it in — it does NOT mean they have no equipment. Check it before building a program so the exercises match what they actually own. |
| list_content | Lists the coach's planned social content, newest first. Summary cards (channel, format, status, pillar, hook, scheduledAt) without the post body — use get_content for the full text. limit defaults to 20, max 100; offset skips newer items (capped at 1000). |
| get_content | Returns one content item's full card by id, including the post body. |
| create_content | Creates a content item for the coach and returns its full card. channel and format are required; status defaults to draft — pass published to log an already-posted item, or scheduled together with scheduledAtIso (ISO 8601 slot time). |
| update_content | Updates a content item's fields (channel, format, pillar, hook, body). Pass only the fields to change; omitted fields keep their value. Status and slot are changed by dedicated tools. Returns the updated card. |
| schedule_content | Puts a draft or in-review content item into a calendar slot (status → scheduled). scheduledAtIso is the ISO 8601 slot time. Returns the updated card. |
| publish_content | Marks a scheduled content item as published (status → published) — use once it has been posted to the channel. Returns the updated card. |
| archive_content | Moves a content item into the archive (status → archived) — use to shelve an idea or draft you no longer plan to publish. Allowed from any non-terminal status; rejected for already-analyzed or archived items. Returns the updated card. |
| delete_content | Deletes a content item (IRREVERSIBLE, hard delete). Prefer archive_content to keep a record. No-op if missing (deleted:false). |
| promote_content | Turns an idea from the idea bank into a draft (status → draft). Allowed only from idea. Returns the updated card. |
| submit_content_for_review | Sends a draft for the coach's approval (status → review). Allowed only from draft. Returns the updated card. |
| return_content_to_draft | Returns content to draft and clears its slot (status → draft) — use to reject a review, unschedule, or replan a missed slot. Allowed from review, scheduled or missed. Returns the updated card. |
| list_client_chats | One row per client with the last message of their coach↔client chat (who sent it, when, a short preview), newest conversations first. awaitingReply=true means the client wrote last — that is the answer to "who is waiting for a reply". Read the thread with get_client_chat and answer with send_client_chat_message. Covers up to 100 clients; truncated=true means the coach has more. |
| get_client_chat | Returns the latest coach↔client chat messages in chronological order. Each message has from (coach/client), text and attachments (image/video/file/audio). The client's AI chat is not included. limit defaults to 30, max 100. |
| get_exercise_chat | Returns the comment thread of one exercise in a client workout (form-check photos/videos, notes), oldest first. clientId/workoutId/exerciseId come from get_client_workout. limit defaults to 30, max 100. |
| send_client_chat_message | Sends a text message from the coach to the client's chat. The client sees it in the app immediately and gets a push notification — write in the client's language. Text only (attachments are app-only). Do not retry a successful call: it would post a duplicate. |
| send_exercise_chat_message | Sends a text comment from the coach into one exercise's thread (form feedback). clientId/workoutId/exerciseId come from get_client_workout; the client gets a push notification — write in the client's language. Text only. Do not retry a successful call: it would post a duplicate. |
| list_broadcasts | Lists the coach's broadcasts, newest first: status (draft/scheduled/sending/sent/failed), audience, delivery counters and a content preview. Full text — get_broadcast. limit defaults to 20, max 100; offset skips newer entries (capped at 1000). |