Skip to main content
Glama

Elite MCP

An MCP (Model Context Protocol) server that gives an AI agent direct, real-time read/write access to a self-hosted Elite instance — a personal fitness tracker for workouts, food, cardio, and body weight.

If you are an agent reading this to decide how to use this server: read the whole file before calling any tool. It covers what each tool does, what its arguments mean, what units/formats are expected, and where the sharp edges are (mainly: writes are immediate and real, there is no undo). The "Data model notes" and "Safety notes" sections below matter as much as the tool list itself.

What this is, and what it is not

Elite (the app) stores everything in its own SQLite database behind a plain REST API — no local cache, no offline queue, one source of truth. This MCP server is a thin protocol adapter over that API: every tool call here is one (or two) HTTP requests to a specific, already-running Elite instance that you point it at. It holds no state of its own and does no caching — call get_workout_history twice in a row and you'll get two fresh reads.

It is not a general fitness API, it does not talk to any other app, and it does not do food-database lookups (no OpenFoodFacts/USDA search) — that lookup logic lives client-side in the Elite web app itself and isn't exposed over HTTP. If you need to log a food that isn't already in this user's data, use log_food with macros you already know or the user gives you; there's no "search for a food by name" tool here.

Requirements

  • A running Elite instance you have the URL for (e.g. http://192.168.1.50:8080, or wherever it's self-hosted). See the Elite repo if you need to stand one up.

  • Node.js 18+.

  • If that Elite instance was started with API_TOKEN set, you'll need that same token.

Setup

git clone https://github.com/natyavidhan/elite-mcp.git
cd elite-mcp
npm install
cp .env.example .env   # then fill in ELITE_BASE_URL (and ELITE_API_TOKEN if the server needs one)

This is a standard stdio MCP server — it's meant to be spawned by an MCP client's own config, not run standalone and left open. Point your agent/client at node /path/to/elite-mcp/index.js with ELITE_BASE_URL (and optionally ELITE_API_TOKEN) as environment variables. For a client that reads a JSON config (Claude Desktop, Claude Code, and most others follow this shape):

{
  "mcpServers": {
    "elite": {
      "command": "node",
      "args": ["/path/to/elite-mcp/index.js"],
      "env": {
        "ELITE_BASE_URL": "http://192.168.1.50:8080",
        "ELITE_API_TOKEN": ""
      }
    }
  }
}

For an agent runtime without a JSON-config MCP client (a custom orchestrator, for instance), the same two env vars plus spawning node index.js over stdio is the whole contract — see index.js and src/client.js, both short.

If ELITE_BASE_URL isn't set, the process logs an error to stderr and exits immediately rather than starting in a broken state.

Tools

20 tools total: 1 connection check, 11 read-only analytics tools, 1 lookup tool, and 7 write tools. Every tool returns its result as a JSON text block; a failure (Elite unreachable, bad token, 404, validation error) comes back as a normal tool result with isError: true and a {"error": "..."} body — it does not crash the MCP connection, so check for that rather than assuming success.

Connection

  • check_connection — no arguments. Hits Elite's /api/health. Call this first if anything else is failing; it tells you whether the server is reachable at all and whether its AI Coach is enabled (irrelevant to this MCP server, but a useful signal that you're talking to the right instance).

Analytics (read-only)

These mirror exactly what Elite's own built-in AI Coach calls internally — same functions, same math, so numbers here will always match what the user sees in the app.

  • get_workout_history({ days? }) — sessions over the last N days (default 30): date, exercises, sets, total volume.

  • get_exercise_trend({ exerciseName, limit? }) — best weight per session for one exercise over time, plus its all-time PR. exerciseName is matched fuzzily (exact id, exact name, or substring) — you don't need list_exercises first just to read a trend.

  • get_personal_records({ limit? }) — best weight and best single-set volume per exercise, heaviest first.

  • get_muscle_volume({ date }) — muscle-by-muscle volume for one specific day (primary muscles full credit, secondary half credit).

  • get_weekly_muscle_summary({ days? }) — total volume per muscle over the last N days (default 7), ranked — use this to find what's undertrained.

  • get_muscle_exercise_split({ muscle, days? }) — which exercises make up one muscle's volume and what share each is (e.g. "what's my tricep split"). muscle must be one of the enum values listed below.

  • get_food_log({ date }) — every entry logged on one date, with macros, plus the day's totals.

  • get_nutrition_trend({ days? }) — daily calorie/macro totals over the last N days (default 7) plus the user's configured daily goals.

  • get_cardio_summary({ days? }) — cardio sessions over the last N days (default 30) plus personal bests.

  • get_body_weight_trend({ days? }) — entries over the last N days (default 90) plus current/starting/change/7-day-average.

  • get_consistency({ days? }) — per-day whether the user logged a workout, food, cardio, and body weight, over the last N days (default 14).

Lookup

  • list_exercises({ query? }) — the full exercise catalog (built-in + this instance's custom exercises), optionally filtered by a case-insensitive substring match on id or name. Call this before log_workout_set if you don't already know the exact exerciseId — the catalog uses specific ids like barbell_bench_press, not free text, and log_workout_set will reject anything that isn't a real id.

Writes

Every write here takes effect immediately on the live Elite instance — see Safety notes below before using these on someone's real data.

  • log_workout_set({ date, exerciseId, reps, weightKg, rpe? }) — logs one set. Creates that day's workout session automatically if it doesn't exist yet. Returns the created set and isPR: true/false. rpe (rate of perceived exertion, 1–10) is optional.

  • delete_workout_set({ setId }) — deletes one logged set.

  • delete_workout_session({ sessionId }) — deletes an entire session and every set under it. There is no confirmation step — this tool does exactly what it says.

  • log_food({ date, mealType, name, quantityG, calories, protein?, carbs?, fat? }) — logs a food entry. Macros are the totals for quantityG, not per-100g (this tool does that conversion for you). Creates a manual-source food item behind the scenes.

  • delete_food_log({ logId }) — deletes one logged food entry.

  • log_cardio_session({ date, activityType, durationSeconds, distanceKm?, avgHeartRate?, caloriesBurned?, notes? }) — logs a cardio session.

  • log_body_weight({ date, weightKg, bodyFatPct?, notes? })upserts by date: logging again for a date that already has an entry overwrites it rather than creating a duplicate. This is intentional (it's how the Elite app itself behaves), not a bug.

Data model notes

  • Dates are always YYYY-MM-DD strings, no time component, no timezone. There is no "today" helper on this server — if a user says "log this for today," resolve today's date yourself before calling a tool.

  • IDs (sessionId, setId, logId, exerciseId, etc.) are opaque strings minted by the Elite server (or, for exercises, defined in its catalog) — never construct or guess one. Get them from a prior tool's result (a log_workout_set response gives you a real set.id and sessionId) or from list_exercises.

  • muscle enum (for get_muscle_exercise_split): chest, triceps, shoulder, lats, bicep, forearm, traps, quads, hamstrings, glutes, calves, abs.

  • mealType: breakfast, lunch, dinner, snack.

  • activityType: run, walk, cycle, swim, other.

  • Weights are kilograms, distances are kilometers, durations are seconds — always, regardless of what unit system the user has Elite's UI set to display in.

Safety notes

  • There is no undo. delete_workout_set, delete_workout_session, and delete_food_log are real, immediate deletes against the user's actual training/nutrition history. Don't call a delete tool speculatively or "just to check what happens" — confirm with the user first unless they've explicitly asked for the deletion.

  • log_body_weight silently overwrites an existing entry for that date rather than erroring or asking — if you're not sure whether the user already logged today's weight, get_body_weight_trend first.

  • This server does no authorization beyond the single shared ELITE_API_TOKEN (if the target instance uses one) — it has exactly as much access as that token grants, which by default is everything. Treat it accordingly.

Repo layout

index.js         entry point — starts the stdio MCP server
src/client.js     fetch wrapper around the target Elite instance's REST API
src/tools.js      every tool's schema + implementation
  • natyavidhan/elite — the tracker itself. Its README documents the full REST API this server is built on (/api/data/*, /api/workout/*, /api/analytics/*, etc.) if you need something this MCP server doesn't already expose as a tool.

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Create Hevy routines and analyze your training from chat. Unofficial; BYO Hevy PRO API key.

  • Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/natyavidhan/elite-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server