Skip to main content
Glama
cbotworks
by cbotworks
README.md
# @cdorneles/hevy-mcp-pro

A production-ready [Model Context Protocol](https://modelcontextprotocol.io) server for the [Hevy](https://www.hevyapp.com) fitness API. Exposes 27 tools for reading, writing, and analyzing your workout data — designed for "personal trainer via LLM" workflows in Claude Desktop, Claude Code, and Cursor.

[![CI](https://github.com/cbotworks/mcp-hevy-pro/actions/workflows/ci.yml/badge.svg)](https://github.com/cbotworks/mcp-hevy-pro/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/@cdorneles/hevy-mcp-pro.svg)](https://www.npmjs.com/package/@cdorneles/hevy-mcp-pro)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

## What sets this apart

Compared to the existing community Hevy MCP server, `hevy-mcp-pro` adds:

- **Local analytics**: progression series, personal records (Epley 1RM), volume summaries, frequency stats, and stagnation detection — computed locally from your data, not via the Hevy API.
- **Smart fetching**: single-exercise analytics use Hevy's `/exercise_history` endpoint (one call, full history) instead of paginating all workouts.
- **Robust HTTP client**: token-bucket throttling, exponential backoff with jitter on 429/5xx, honors `Retry-After`, and never logs your API key.
- **Strict request validation**: Zod schemas reject malformed payloads before they hit the Hevy API.
- **Convenience tools**: `duplicate_workout`, `routine_from_workout`, `compare_workouts`.

## Requirements

- Node.js 20+
- A [Hevy PRO subscription](https://www.hevyapp.com/pro) (required to obtain an API key)
- Your Hevy API key from [hevy.com/settings?p=developer](https://www.hevy.com/settings?p=developer)

## Quick start

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "hevy": {
      "command": "npx",
      "args": ["-y", "@cdorneles/hevy-mcp-pro"],
      "env": {
        "HEVY_API_KEY": "your-key-here"
      }
    }
  }
}
```

Restart Claude Desktop and you should see "hevy" in the MCP tool picker.

### Cursor

Add to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "hevy": {
      "command": "npx",
      "args": ["-y", "@cdorneles/hevy-mcp-pro"],
      "env": { "HEVY_API_KEY": "your-key-here" }
    }
  }
}
```

### Claude Code

```bash
claude mcp add hevy npx -- -y @cdorneles/hevy-mcp-pro
# then set HEVY_API_KEY in the resulting config
```

## Tools

### Reading

| Tool | Purpose |
|---|---|
| `list_workouts` | Paginate workouts (max pageSize 10 — Hevy API limit) |
| `get_workout` | Fetch a single workout with all sets |
| `get_workout_count` | Total workout count for the account |
| `get_workout_events` | Sync incremental updates/deletes since a timestamp |
| `list_routines` | Paginate routines |
| `get_routine` | Fetch a single routine |
| `list_exercise_templates` | Paginate exercise templates |
| `get_exercise_template` | Fetch one template |
| `search_exercise_templates` | Local fuzzy search across all templates (cached) |
| `get_exercise_history` | Flat history of every set for one exercise |
| `list_routine_folders` | Paginate folders |
| `get_routine_folder` | Fetch one folder |
| `get_user_info` | Authenticated user profile |

### Writing

| Tool | Purpose |
|---|---|
| `create_workout` | Log a new workout |
| `update_workout` | Modify an existing workout |
| `create_routine` | Create a routine template |
| `update_routine` | Modify an existing routine |
| `create_routine_folder` | Create a new folder |
| `create_exercise_template` | Create a custom exercise |

### Analytics

| Tool | Purpose |
|---|---|
| `get_exercise_progression` | Time series of best set per session for one exercise |
| `get_personal_records` | PRs (heaviest weight, best set, top estimated 1RM) |
| `get_volume_summary` | Volume grouped by exercise / muscle group / week |
| `get_workout_frequency` | Workouts/week, current streak, longest gap |
| `detect_stagnation` | Exercises whose 1RM has plateaued in the last N weeks |

### Convenience

| Tool | Purpose |
|---|---|
| `duplicate_workout` | Re-log a past workout starting now (or at a given time) |
| `routine_from_workout` | Convert a logged workout into a reusable routine |
| `compare_workouts` | Side-by-side diff of two workouts |

## Configuration

All configuration is via environment variables.

| Variable | Required | Default | Description |
|---|---|---|---|
| `HEVY_API_KEY` | yes | — | Your Hevy API key |
| `LOG_LEVEL` | no | `info` | `error` \| `warn` \| `info` \| `debug` |
| `HEVY_RATE_LIMIT_CAPACITY` | no | `10` | Token bucket capacity (max burst) |
| `HEVY_RATE_LIMIT_REFILL_PER_SEC` | no | `10` | Token refill rate (requests/sec) |
| `HEVY_ANALYTICS_MAX_PAGES` | no | `50` | Soft cap for analytics pagination (50 pages = 500 workouts) |
| `HEVY_CACHE_TTL_MS` | no | `3600000` | Exercise template cache TTL (default 1h) |

## Example prompts

Once installed, you can ask your LLM things like:

> "Show me my bench press progression over the last 3 months."

> "What are my current personal records on squats, deadlifts, and bench?"

> "Detect any exercises where I've stagnated in the last 8 weeks."

> "Duplicate yesterday's workout and start it now."

> "Compare my last two leg days."

> "How many times did I train chest in March?"

## Troubleshooting

### `Invalid API key or Hevy PRO subscription required`

Confirm you have a Hevy PRO subscription and that the key from [hevy.com/settings?p=developer](https://www.hevy.com/settings?p=developer) is correctly set in `HEVY_API_KEY`. The key never appears in logs, so a typo is the most common cause.

### `Rate limited by Hevy API (retries exhausted)`

The default client-side throttle is 10 req/s. If you're running heavy analytics queries against a long workout history, lower `HEVY_RATE_LIMIT_REFILL_PER_SEC` to e.g. `5` to slow down further.

### `Analysis limited to first 500 workouts`

Analytics tools paginate workouts with a soft cap. Raise `HEVY_ANALYTICS_MAX_PAGES` if you need to analyze deeper history. Each page is up to 10 workouts.

### Logs

This server writes structured JSON logs to **stderr** (stdout is reserved for the MCP protocol). To debug, set `LOG_LEVEL=debug` and check your MCP client's server log view.

## Development

```bash
git clone https://github.com/cbotworks/mcp-hevy-pro.git
cd hevy-mcp-pro
pnpm install
pnpm test       # 41+ unit tests, no network
pnpm typecheck
pnpm lint
pnpm build      # produces dist/ (ESM + CJS + .d.ts)
```

To regenerate the vendored OpenAPI snapshot:

```bash
pnpm fetch-openapi
```

## Architecture

```
src/
├── client/         HTTP layer (rate limiter, retry, error mapping, paginator)
├── schemas/        Zod schemas for API requests + responses
├── tools/          Tool implementations grouped by domain
│   └── analytics/  Pure analyzers (progression, PRs, volume, frequency, stagnation)
├── utils/          Logger, errors, TTL cache
├── server.ts       MCP server: registers tools, wires stdio transport
└── index.ts        CLI entry: parses env, fails fast on missing API key
```

The HTTP client owns all network I/O. Tools never call `fetch` directly. Analytics tools are pure functions over data fetched via the client, which makes them trivially fixture-testable.

## Contributing

Issues and PRs welcome. Please run `pnpm typecheck && pnpm lint && pnpm test` before submitting.

## License

MIT — see [LICENSE](LICENSE).

## Acknowledgements

The Hevy team for the public API. The community [chrisdoc/hevy-mcp](https://github.com/chrisdoc/hevy-mcp) server informed early API exploration but no code was reused.

TDQS

B3.4/5.0

Scored across 27 tools

Disambiguation5/5

Each tool targets a distinct entity and action, with clear separation between list/get/create/update and analytical operations. Even similar tools like search_exercise_templates and list_exercise_templates have clearly differentiated purposes described in their summaries.

Naming Consistency4/5

The vast majority of tools follow a consistent verb_noun snake_case pattern (e.g., list_workouts, create_workout, get_exercise_history). The single exception is 'routine_from_workout', which deviates from the pattern but remains readable and clear.

Tool Count3/5

With 27 tools, the server is heavier than the ideal 3-15 range, but the breadth covers multiple entities (workouts, routines, templates, folders) plus analytics. The count feels justified for a feature-rich API, though it is borderline excessive.

Completeness2/5

The server lacks delete operations for all entities (workouts, routines, exercise templates, routine folders), preventing full lifecycle management. While CRUD for create/get/update exists, the inability to delete creates dead ends and forces workarounds.

Maintenance

ActivityInactive
ResponsivenessNo issues