Skip to main content
Glama
hevy-mcp-server

hevy-mcp-server

by tomtorggler

Hevy MCP Server

A remote Model Context Protocol server for the Hevy fitness tracking API, running on Cloudflare Workers. Connect it to Claude (or any MCP client) to browse and log workouts, manage routines and track progress by chatting.

Ask DeepWiki

  • Multi-user: sign in with GitHub, add your own Hevy API key, done. One deployment serves many people.

  • Standards-based auth: OAuth 2.1 with PKCE, protected resource metadata (RFC 9728), Client ID Metadata Documents and Dynamic Client Registration. Works out of the box as a custom connector in Claude.

  • Stateless Streamable HTTP at /mcp, built on MCP SDK v2 (protocol 2026-07-28, with 2025-era clients served transparently). No sessions, no Durable Objects.

  • Tools with titles, descriptions and annotations covering the Hevy public API.

šŸ‹ļø Tools

Area

Tools

Workouts

get_workouts, get_workout, create_workout, update_workout, get_workouts_count, get_workout_events

Routines

get_routines, get_routine, create_routine, update_routine

Exercises

get_exercise_templates, search_exercise_templates, get_exercise_template, create_exercise_template, get_exercise_history

Folders

get_routine_folders, get_routine_folder, create_routine_folder

Body & profile

get_user_info, get_body_measurements, get_body_measurement, log_body_measurement, update_body_measurement

Read tools are marked readOnlyHint; update_* tools replace the whole record and are marked destructive so clients can ask before running them.

Related MCP server: hevy-mcp

šŸ”Œ Using a hosted instance

  1. Open the server's home page and click Connect your Hevy account. Sign in with GitHub and paste your API key from Hevy Settings → Developer (requires Hevy Pro).

  2. Add the server to your client using its /mcp URL:

    • Claude (web/desktop): Settings → Connectors → Add custom connector → paste the URL. No client ID or credentials are needed.

    • Claude Code: claude mcp add --transport http hevy https://<your-host>/mcp, then /mcp to sign in.

    • Other clients: anything that speaks Streamable HTTP with OAuth. stdio-only clients can bridge with npx mcp-remote https://<your-host>/mcp.

  3. Approve the connection in the browser window your client opens.

šŸš€ Deploying your own

Prerequisites

  • A Cloudflare account and npx wrangler login

  • A GitHub OAuth App (Settings → Developer settings → OAuth Apps) with the callback URL https://<your-host>/callback

Steps

git clone https://github.com/tomtorggler/hevy-mcp-server.git
cd hevy-mcp-server
npm install

# Create the KV namespace and put its id into wrangler.jsonc (kv_namespaces → OAUTH_KV)
npx wrangler kv namespace create OAUTH_KV

# Secrets
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
openssl rand -hex 32 | npx wrangler secret put COOKIE_ENCRYPTION_KEY   # encrypts stored Hevy keys

npm run deploy

Adjust the routes entry in wrangler.jsonc to your own domain (or remove it to use the *.workers.dev URL).

Local development

cp .dev.vars.example .dev.vars   # fill in a dev GitHub OAuth App + encryption key
npm start                         # http://localhost:8787

Useful checks:

curl http://localhost:8787/health
curl http://localhost:8787/.well-known/oauth-protected-resource/mcp
npx @modelcontextprotocol/inspector http://localhost:8787/mcp

šŸ“– Usage examples

"Show me my last 5 workouts"

"Log a workout from today 10:00 to 11:00: bench press 3Ɨ10 at 100 kg, squats 4Ɨ8 at 120 kg"

"How has my deadlift progressed this year?"

"Create a Push Day routine with bench press 4 sets of 8–12 at 100 kg and overhead press 3Ɨ10 at 60 kg"

The assistant looks up exercise IDs with search_exercise_templates or get_exercise_templates, then calls the matching write tool. The server publishes instructions so clients know that update_* tools replace the whole record and that exercise IDs must never be guessed.

šŸ”§ Data shapes

All parameters are snake_case. Times are ISO 8601 with timezone (2024-10-15T10:00:00Z), weights in kilograms, distances in meters, durations in seconds.

Workout (create_workout, update_workout): title, start_time, end_time, optional description, routine_id, is_private, and exercises[] with title, exercise_template_id, optional superset_id, notes, and sets[] of type (warmup | normal | failure | dropset), weight_kg, reps, distance_meters, duration_seconds, custom_metric, rpe (6–10 in half steps). Exercise and set index fields are generated from array order.

Routine (create_routine, update_routine): title, optional folder_id, notes, and exercises[] with exercise_template_id, optional superset_id, rest_seconds, notes, and sets[] that may use rep_range: { start, end } instead of reps. Routines do not take title on exercises or rpe on sets.

Custom exercise (create_exercise_template): title, exercise_type, equipment_category, muscle_group, optional other_muscles[].

šŸ” How auth works

MCP client ── 401 + WWW-Authenticate(resource_metadata) ──▶ /.well-known/oauth-protected-resource/mcp
           ── discovers ──▶ /.well-known/oauth-authorization-server
           ── CIMD or POST /register ──▶ client_id
           ── GET /authorize (PKCE S256) ──▶ GitHub sign-in ──▶ consent ──▶ code (+ iss)
           ── POST /token (code_verifier) ──▶ 30-day bearer token
           ── POST /mcp (Bearer) ──▶ fresh McpServer per request ──▶ Hevy API (user's key)

The legacy /sse endpoint returns 410 Gone; clients that still use the HTTP+SSE transport must switch to /mcp.

  • Redirect URIs are validated against the client's registration or metadata document before any code is issued.

  • Hevy API keys are AES-GCM encrypted in KV with COOKIE_ENCRYPTION_KEY and never returned to clients.

  • Each MCP client receives its own token; signing out of the web UI does not revoke connected clients, and removing your API key disables all of them.

šŸ› ļø Development

src/
ā”œā”€ā”€ index.ts             # Worker entry: the Hono app
ā”œā”€ā”€ app.ts               # CORS (incl. Mcp-* headers), error handling, route mounting
ā”œā”€ā”€ github-handler.ts    # OAuth 2.1 AS (authorize/token/register), discovery metadata, setup pages
ā”œā”€ā”€ mcp-handler.ts       # Stateless MCP endpoint: createMcpHandler per request, per-user Hevy client
ā”œā”€ā”€ tools.ts             # The 17 MCP tools on an SDK v2 McpServer
ā”œā”€ā”€ tool-catalog.ts      # Single list of tools (home page + tests derive from it)
ā”œā”€ā”€ version.ts           # Version read from package.json
ā”œā”€ā”€ middleware/auth.ts   # Bearer token middleware with RFC 9728 challenge
ā”œā”€ā”€ routes/              # /mcp, /sse (410), /health, /stats, /
ā”œā”€ā”€ ui/                  # Home, setup and consent pages (shared layout, dark mode)
└── lib/                 # Hevy client, schemas, validation, errors, key storage, OAuth clients, PKCE
test/                    # Vitest suite, incl. in-memory MCP client tests
api.json                 # Hevy OpenAPI spec (snapshot of https://api.hevyapp.com/docs)
npm test             # run the suite
npm run type-check   # tsc
npm run format       # biome

Adding a tool

  1. Add the API call to src/lib/client.ts.

  2. Register the tool in src/tools.ts with a title, description, Zod input schema and annotations:

    tool("get_thing", {
        title: "Get thing",
        description: "What it does and when to use it.",
        inputSchema: { thing_id: z.string().describe("...") },
        annotations: READ_ONLY,
    }, async ({ thing_id }, client) => ({ content: [text(JSON.stringify(await client.getThing(thing_id)))] }));

    Errors thrown inside the handler are formatted by handleError.

  3. Add it to the matching group in src/tool-catalog.ts; the home page renders from it and test/tools.test.ts checks that exactly those tools are registered.

šŸ“š Resources

šŸ“ License

Unlicense - see LICENSE.

This project is not affiliated with Hevy. Hevy is a trademark of Hevy Studios Inc.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables interaction with the Hevy fitness tracking platform through their API. Supports managing workouts, routines, exercise templates, and webhook subscriptions for comprehensive fitness data management.
      20 npm
      ISC
    • A
      license
      Not graded
      quality
      D
      maintenance
      Exposes the Hevy workout API to Claude, enabling users to manage workouts, routines, exercise templates, body measurements, and user info via natural language.
      2,615 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with the Hevy fitness tracking API, allowing users to log workouts, manage routines, browse exercises, and track fitness progress through natural language.
      15 npm
      MIT