hevy-mcp 3.0.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +347 -315
- package/dist/cli.mjs +4 -4
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +2 -6
- package/dist/index.mjs +2 -2
- package/dist/{src-BBzEvkOX.mjs → src-D1O3O9f2.mjs} +2653 -2047
- package/dist/src-D1O3O9f2.mjs.map +1 -0
- package/package.json +12 -7
- package/server.json +2 -2
- package/dist/src-BBzEvkOX.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,415 +1,447 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Hevy MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
**Talk to your Hevy workout data from Claude, Cursor, Codex, and other MCP clients.**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/hevy-mcp)
|
|
8
|
+
[](https://www.npmjs.com/package/hevy-mcp)
|
|
4
9
|
[](https://github.com/chrisdoc/hevy-mcp/actions/workflows/build-and-test.yml)
|
|
5
10
|
[](https://codecov.io/gh/chrisdoc/hevy-mcp)
|
|
6
|
-
[](https://github.com/chrisdoc/hevy-mcp/stargazers)
|
|
12
|
+
[](#hosted-cloudflare-endpoint)
|
|
13
|
+
[](./LICENSE)
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
[Connect to the hosted MCP](#connect-to-the-hosted-endpoint) · [Watch the 18-second demo](https://raw.githubusercontent.com/chrisdoc/hevy-mcp/main/docs/assets/hevy-mcp-demo.mp4) · [Explore all 25 tools](#tools)
|
|
9
16
|
|
|
10
|
-
|
|
17
|
+
</div>
|
|
11
18
|
|
|
12
|
-
|
|
19
|
+
`hevy-mcp` is an open-source [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
|
|
20
|
+
server for the [Hevy](https://www.hevyapp.com/) fitness and workout tracking
|
|
21
|
+
app. It lets AI assistants read, analyze, create, and update your Hevy workouts,
|
|
22
|
+
routines, exercise templates, and body measurements through authenticated Hevy
|
|
23
|
+
API requests.
|
|
13
24
|
|
|
14
|
-
|
|
15
|
-
- [Quick Start](#quick-start)
|
|
16
|
-
- [Prerequisites](#prerequisites)
|
|
17
|
-
- [Installation](#installation)
|
|
18
|
-
- [Run with Docker](#run-with-docker)
|
|
19
|
-
- [Claude Desktop Configuration](#claude-desktop-configuration)
|
|
20
|
-
- [Cursor Configuration](#cursor-configuration)
|
|
21
|
-
- [Other MCP Clients (via add-mcp)](#other-mcp-clients-via-add-mcp)
|
|
22
|
-
- [Why hevy-mcp?](#why-hevy-mcp)
|
|
23
|
-
- [Configuration](#configuration)
|
|
24
|
-
- [Available MCP Tools](#available-mcp-tools)
|
|
25
|
-
- [Available MCP Resources](#available-mcp-resources)
|
|
26
|
-
- [Development & Contributing](#development--contributing)
|
|
25
|
+
> A Hevy API key, available with **Hevy PRO**, is required.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
## See it in action
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
[](https://raw.githubusercontent.com/chrisdoc/hevy-mcp/main/docs/assets/hevy-mcp-demo.mp4)
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
- **Routine Management**: Access and manage workout routines.
|
|
34
|
-
- **Exercise Templates**: Browse available exercise templates with in-memory caching.
|
|
35
|
-
- **Folder Organization**: Manage routine folders.
|
|
31
|
+
<p align="center"><sub>Click the preview to play the full-quality 18-second demo.</sub></p>
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
In the demo, the assistant retrieves real Hevy data and answers a multi-part
|
|
34
|
+
training question with evidence from the user's workout history.
|
|
38
35
|
|
|
39
|
-
##
|
|
36
|
+
## What can you do with it?
|
|
40
37
|
|
|
41
|
-
|
|
38
|
+
- **Analyze training progress:** summarize 1-12 weeks of workouts and body
|
|
39
|
+
measurements in one tool call.
|
|
40
|
+
- **Ask questions in plain language:** find recent sessions, frequently trained
|
|
41
|
+
exercises, consistency gaps, routine details, or exercise history.
|
|
42
|
+
- **Plan and log training:** create or update workouts, routines, routine folders,
|
|
43
|
+
custom exercises, and body measurements.
|
|
44
|
+
- **Search without huge responses:** discover routines and exercise templates with
|
|
45
|
+
compact, AI-friendly results.
|
|
46
|
+
- **Connect from your preferred MCP client:** use the hosted Streamable HTTP
|
|
47
|
+
endpoint or run locally with Codex, Claude Desktop, Cursor, and other clients.
|
|
48
|
+
- **Start without installing anything:** connect directly to the production
|
|
49
|
+
Cloudflare Worker—no Node.js, package download, or Docker container required.
|
|
50
|
+
- **Keep local control when you want it:** run the same server with `npx`, `bunx`,
|
|
51
|
+
or the official Docker image.
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
| :-------------------- | :-------------------------------------------------------------------------------------- | :------------------------- |
|
|
45
|
-
| **One-off stdio run** | `HEVY_API_KEY=your_key npx -y hevy-mcp` or `HEVY_API_KEY=your_key bunx hevy-mcp@latest` | Node.js ≥ 20, Hevy API key |
|
|
46
|
-
| **Docker stdio run** | `docker run -i --rm -e HEVY_API_KEY ghcr.io/chrisdoc/hevy-mcp:latest` | Docker, Hevy API key |
|
|
47
|
-
| **Local development** | `npm install && npm run build && npm start` | `.env` with `HEVY_API_KEY` |
|
|
53
|
+
Try asking:
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
> Analyze my training over the last six weeks. Show workouts per week, my most
|
|
56
|
+
> frequently trained exercises, any obvious gaps or inconsistencies, and cite the
|
|
57
|
+
> workout evidence you used.
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
> Find my push-day routine and show its exercises and sets.
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
- **npm**: v10 or higher.
|
|
55
|
-
- **Bun** (optional): If you want to launch with `bunx`.
|
|
56
|
-
- **Docker** (optional): If you want an isolated container-based stdio setup.
|
|
57
|
-
- **Hevy API key**: Required for all operations (available with Hevy PRO).
|
|
61
|
+
> Compare my recent body measurements with my training consistency.
|
|
58
62
|
|
|
59
|
-
|
|
63
|
+
> Create a completed workout from my saved routine. Ask me for any missing set
|
|
64
|
+
> results before writing it to Hevy.
|
|
60
65
|
|
|
61
|
-
##
|
|
66
|
+
## Quick start
|
|
62
67
|
|
|
63
|
-
###
|
|
68
|
+
### 1. Get your Hevy API key
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
Create an API key in Hevy, then keep it somewhere secure. API access currently
|
|
71
|
+
requires a Hevy PRO subscription.
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
# npm launcher
|
|
70
|
-
HEVY_API_KEY=your_hevy_api_key_here npx -y hevy-mcp
|
|
71
|
-
|
|
72
|
-
# bun launcher
|
|
73
|
-
HEVY_API_KEY=your_hevy_api_key_here bunx hevy-mcp@latest
|
|
74
|
-
```
|
|
73
|
+
### 2. Connect `hevy-mcp` to your client
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
The hosted Cloudflare endpoint is the fastest way to start. It runs remotely,
|
|
76
|
+
so your client does not need Node.js, Bun, Docker, or a local server process.
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
# Clone the repository
|
|
80
|
-
git clone https://github.com/chrisdoc/hevy-mcp.git
|
|
81
|
-
cd hevy-mcp
|
|
78
|
+
#### Connect to the hosted endpoint
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
npm install
|
|
80
|
+
Production URL:
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
# Edit .env and add your HEVY_API_KEY
|
|
82
|
+
```text
|
|
83
|
+
https://hevy.chrisdoc.dev/mcp
|
|
89
84
|
```
|
|
90
85
|
|
|
91
|
-
|
|
86
|
+
The endpoint uses Streamable HTTP. Send your Hevy API key as a bearer token on
|
|
87
|
+
every request.
|
|
88
|
+
|
|
89
|
+
##### Codex
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
Codex CLI, the Codex desktop app, and the IDE extension share the same MCP
|
|
92
|
+
configuration. Make your Hevy API key available in the environment that starts
|
|
93
|
+
Codex, then add the hosted server:
|
|
95
94
|
|
|
96
95
|
```bash
|
|
97
|
-
export HEVY_API_KEY=
|
|
98
|
-
|
|
96
|
+
export HEVY_API_KEY=your-hevy-api-key
|
|
97
|
+
codex mcp add hevy \
|
|
98
|
+
--url https://hevy.chrisdoc.dev/mcp \
|
|
99
|
+
--bearer-token-env-var HEVY_API_KEY
|
|
99
100
|
```
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
in the command arguments.
|
|
105
|
-
|
|
106
|
-
The image uses the official Node.js LTS Alpine base, runs as the non-root
|
|
107
|
-
`node` user, and ships the application and its third-party runtime dependencies
|
|
108
|
-
as a standalone bundle. It does not include an application `/app/node_modules`
|
|
109
|
-
directory; the official Node base image may still contain its own globally
|
|
110
|
-
packaged npm or Corepack files.
|
|
111
|
-
|
|
112
|
-
Use `latest` to follow the newest stable release. For reproducible deployments,
|
|
113
|
-
pin the exact version shown on the release, using a tag such as
|
|
114
|
-
`ghcr.io/chrisdoc/hevy-mcp:X.Y.Z`. Major (`:X`) and major.minor (`:X.Y`) tags
|
|
115
|
-
are also published for controlled automatic updates.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## 🔗 Integration
|
|
102
|
+
Codex stores the environment variable name, not the key itself, in its MCP
|
|
103
|
+
configuration. Restart Codex or begin a new session, then run `codex mcp list`
|
|
104
|
+
to verify the server is configured.
|
|
120
105
|
|
|
121
|
-
|
|
106
|
+
##### Other Streamable HTTP clients
|
|
122
107
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
126
|
-
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
108
|
+
Clients that accept a remote MCP URL and fixed headers commonly use this shape:
|
|
127
109
|
|
|
128
110
|
```json
|
|
129
111
|
{
|
|
130
112
|
"mcpServers": {
|
|
131
|
-
"hevy
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
|
|
135
|
-
"HEVY_API_KEY": "sk_live_your_key_here"
|
|
113
|
+
"hevy": {
|
|
114
|
+
"url": "https://hevy.chrisdoc.dev/mcp",
|
|
115
|
+
"headers": {
|
|
116
|
+
"Authorization": "Bearer your-hevy-api-key"
|
|
136
117
|
}
|
|
137
118
|
}
|
|
138
119
|
}
|
|
139
120
|
}
|
|
140
121
|
```
|
|
141
122
|
|
|
142
|
-
|
|
123
|
+
Exact configuration keys vary by client. The hosted server requires support for
|
|
124
|
+
Streamable HTTP and a fixed `Authorization` header.
|
|
143
125
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
```
|
|
126
|
+
> [!IMPORTANT]
|
|
127
|
+
> Treat the bearer value like a password. The Worker validates it with Hevy for
|
|
128
|
+
> each request, does not store it, and forwards it to Hevy only as the required
|
|
129
|
+
> `api-key` header.
|
|
150
130
|
|
|
151
|
-
|
|
152
|
-
outside the repository containing your real key:
|
|
131
|
+
#### Run locally instead
|
|
153
132
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
```
|
|
133
|
+
Choose local stdio if you prefer to run the server on your own machine or your
|
|
134
|
+
client cannot attach a fixed authorization header to remote MCP requests.
|
|
157
135
|
|
|
158
|
-
|
|
159
|
-
`chmod 600 /absolute/path/to/hevy-mcp.env`), then use its absolute path in the
|
|
160
|
-
Claude Desktop configuration:
|
|
136
|
+
##### Codex
|
|
161
137
|
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
"command": "docker",
|
|
167
|
-
"args": [
|
|
168
|
-
"run",
|
|
169
|
-
"-i",
|
|
170
|
-
"--rm",
|
|
171
|
-
"--env-file",
|
|
172
|
-
"/absolute/path/to/hevy-mcp.env",
|
|
173
|
-
"ghcr.io/chrisdoc/hevy-mcp:latest"
|
|
174
|
-
]
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
138
|
+
```bash
|
|
139
|
+
codex mcp add hevy \
|
|
140
|
+
--env HEVY_API_KEY=your-hevy-api-key \
|
|
141
|
+
-- npx -y hevy-mcp
|
|
178
142
|
```
|
|
179
143
|
|
|
180
|
-
|
|
181
|
-
not expose an HTTP port or start a detached service. Docker reads the key from
|
|
182
|
-
the environment file, so the Claude configuration does not replace an
|
|
183
|
-
inherited key with a placeholder. Replace `latest` with an exact version tag if
|
|
184
|
-
you want Claude Desktop to stay on a pinned release.
|
|
185
|
-
|
|
186
|
-
### Cursor Configuration
|
|
144
|
+
##### Claude Desktop or Cursor
|
|
187
145
|
|
|
188
|
-
Add this
|
|
146
|
+
Add this `mcpServers` entry to your client configuration:
|
|
189
147
|
|
|
190
148
|
```json
|
|
191
149
|
{
|
|
192
150
|
"mcpServers": {
|
|
193
|
-
"hevy
|
|
151
|
+
"hevy": {
|
|
194
152
|
"command": "npx",
|
|
195
153
|
"args": ["-y", "hevy-mcp"],
|
|
196
154
|
"env": {
|
|
197
|
-
"HEVY_API_KEY": "your-api-key
|
|
155
|
+
"HEVY_API_KEY": "your-hevy-api-key"
|
|
198
156
|
}
|
|
199
157
|
}
|
|
200
158
|
}
|
|
201
159
|
}
|
|
202
160
|
```
|
|
203
161
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
```json
|
|
207
|
-
{
|
|
208
|
-
"command": "bunx",
|
|
209
|
-
"args": ["hevy-mcp@latest"]
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### Other MCP Clients (via add-mcp)
|
|
214
|
-
|
|
215
|
-
For a generic setup flow across MCP clients, use [`add-mcp`](https://github.com/neon-solutions/add-mcp):
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
npx add-mcp hevy-mcp --env "HEVY_API_KEY=secret"
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
This bootstraps the `hevy-mcp` entry in your client config without manual JSON edits.
|
|
222
|
-
|
|
223
|
-
---
|
|
224
|
-
|
|
225
|
-
## ✨ Why hevy-mcp?
|
|
162
|
+
Common local configuration locations:
|
|
226
163
|
|
|
227
|
-
-
|
|
228
|
-
|
|
229
|
-
-
|
|
230
|
-
|
|
164
|
+
- **Claude Desktop on macOS:**
|
|
165
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
166
|
+
- **Claude Desktop on Windows:**
|
|
167
|
+
`%APPDATA%\Claude\claude_desktop_config.json`
|
|
168
|
+
- **Cursor:** `~/.cursor/mcp.json`
|
|
231
169
|
|
|
232
|
-
|
|
170
|
+
Restart or reconnect the client after saving the file.
|
|
233
171
|
|
|
234
|
-
|
|
172
|
+
##### Any stdio MCP client
|
|
235
173
|
|
|
236
|
-
|
|
237
|
-
|
|
174
|
+
Configure your client to launch this command with `HEVY_API_KEY` in the child
|
|
175
|
+
process environment:
|
|
238
176
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
Set `HEVY_MCP_DEBUG=1` to emit verbose, privacy-bounded diagnostics to stderr.
|
|
243
|
-
Debug records include tool invocations and sanitized Hevy API response timing
|
|
244
|
-
and status details. Other values leave diagnostics disabled, and stdout remains
|
|
245
|
-
reserved for the MCP JSON-RPC stream.
|
|
246
|
-
|
|
247
|
-
```env
|
|
248
|
-
# Example .env
|
|
249
|
-
HEVY_API_KEY=your_hevy_api_key_here
|
|
250
|
-
# Optional: customize Hevy API request timeout (milliseconds)
|
|
251
|
-
HEVY_MCP_API_TIMEOUT=30000
|
|
252
|
-
# Optional: enable verbose stderr diagnostics (only the value 1 enables it)
|
|
253
|
-
HEVY_MCP_DEBUG=1
|
|
177
|
+
```bash
|
|
178
|
+
npx -y hevy-mcp
|
|
254
179
|
```
|
|
255
180
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
`search-exercise-templates` and the `hevy://exercise-templates` resource use a
|
|
259
|
-
shared in-memory async cache for the full exercise template catalog:
|
|
260
|
-
|
|
261
|
-
- **TTL**: 5 minutes per cached catalog entry.
|
|
262
|
-
- **Memory bound**: max 1 catalog entry (LRU bounded cache).
|
|
263
|
-
- **In-flight de-duplication**: concurrent requests share the same active
|
|
264
|
-
fetch when possible.
|
|
265
|
-
- **Manual refresh**: set `refresh: true` in the tool input to invalidate the
|
|
266
|
-
cached catalog and force a re-fetch from the Hevy API.
|
|
267
|
-
|
|
268
|
-
Paginated `get-exercise-templates` requests still call the API directly to keep
|
|
269
|
-
paging behavior explicit and avoid cross-page invalidation complexity.
|
|
270
|
-
|
|
271
|
-
### 📡 Sentry Monitoring
|
|
272
|
-
|
|
273
|
-
`hevy-mcp` includes Sentry monitoring to observe errors and usage in production. It initializes `@sentry/node` with tracing enabled and PII collection disabled by default. Recent observability changes also add:
|
|
274
|
-
|
|
275
|
-
- lifecycle spans around server build, run, and stdio connect
|
|
276
|
-
- per-tool execution spans plus captured handler exceptions
|
|
277
|
-
- stdio parse diagnostics, including leading UTF-8 BOM stripping and invalid JSON context
|
|
278
|
-
- a deterministic pseudonymous Sentry user ID derived from `HEVY_API_KEY`, so the raw key is never sent to Sentry
|
|
279
|
-
|
|
280
|
-
---
|
|
181
|
+
`npx` requires Node.js 20 or newer. Restart or reconnect your client after
|
|
182
|
+
saving its configuration.
|
|
281
183
|
|
|
282
184
|
<details>
|
|
283
|
-
<summary><strong
|
|
185
|
+
<summary><strong>Use bunx instead</strong></summary>
|
|
284
186
|
|
|
285
|
-
|
|
286
|
-
Docker packaging. Docker support is now available again for the stdio server.
|
|
187
|
+
Requires [Bun](https://bun.sh/):
|
|
287
188
|
|
|
288
|
-
|
|
289
|
-
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"mcpServers": {
|
|
192
|
+
"hevy": {
|
|
193
|
+
"command": "bunx",
|
|
194
|
+
"args": ["hevy-mcp@latest"],
|
|
195
|
+
"env": {
|
|
196
|
+
"HEVY_API_KEY": "your-hevy-api-key"
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
290
202
|
|
|
291
203
|
</details>
|
|
292
204
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
## 🛠️ Available MCP Tools
|
|
205
|
+
<details>
|
|
206
|
+
<summary><strong>Use Docker instead</strong></summary>
|
|
296
207
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
| **Workouts** | `get-workouts`, `get-workout`, `create-workout`, `update-workout`, `get-workout-count`, `get-workout-events` |
|
|
300
|
-
| **Routines** | `get-routines`, `get-routine`, `create-routine`, `update-routine` |
|
|
301
|
-
| **Templates** | `get-exercise-templates`, `get-exercise-template`, `search-exercise-templates`, `create-exercise-template`, `get-exercise-history` |
|
|
302
|
-
| **Folders** | `get-routine-folders`, `get-routine-folder`, `create-routine-folder` |
|
|
303
|
-
| **Body Measurements** | `get-body-measurements`, `get-body-measurement`, `create-body-measurement`, `update-body-measurement` |
|
|
304
|
-
| **User** | `get-user-info` |
|
|
208
|
+
Official images support `linux/amd64` and `linux/arm64`. Keep stdin open with
|
|
209
|
+
`-i` because the container runs the stdio MCP server:
|
|
305
210
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
211
|
+
```bash
|
|
212
|
+
export HEVY_API_KEY=your-hevy-api-key
|
|
213
|
+
docker run -i --rm -e HEVY_API_KEY ghcr.io/chrisdoc/hevy-mcp:latest
|
|
214
|
+
```
|
|
310
215
|
|
|
311
|
-
|
|
216
|
+
For an MCP client, store the key in a protected environment file and configure
|
|
217
|
+
the client to launch Docker:
|
|
312
218
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"mcpServers": {
|
|
222
|
+
"hevy": {
|
|
223
|
+
"command": "docker",
|
|
224
|
+
"args": [
|
|
225
|
+
"run",
|
|
226
|
+
"-i",
|
|
227
|
+
"--rm",
|
|
228
|
+
"--env-file",
|
|
229
|
+
"/absolute/path/to/hevy-mcp.env",
|
|
230
|
+
"ghcr.io/chrisdoc/hevy-mcp:latest"
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
317
236
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
`arguments` object before prompt field defaults are evaluated.
|
|
237
|
+
Pin an exact image tag such as `ghcr.io/chrisdoc/hevy-mcp:X.Y.Z` when you need
|
|
238
|
+
reproducible upgrades.
|
|
321
239
|
|
|
322
|
-
|
|
240
|
+
</details>
|
|
323
241
|
|
|
324
|
-
|
|
242
|
+
You can also add the npm server to supported clients with
|
|
243
|
+
[`add-mcp`](https://github.com/neon-solutions/add-mcp):
|
|
325
244
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
| `workout-count` | `hevy://workout-count` |
|
|
330
|
-
| `exercise-templates` | `hevy://exercise-templates` |
|
|
331
|
-
| `routine-folders` | `hevy://routine-folders` |
|
|
245
|
+
```bash
|
|
246
|
+
npx add-mcp hevy-mcp --env "HEVY_API_KEY=your-hevy-api-key"
|
|
247
|
+
```
|
|
332
248
|
|
|
333
|
-
|
|
249
|
+
### 3. Ask your first question
|
|
334
250
|
|
|
335
|
-
|
|
251
|
+
Try one of these after restarting or reconnecting your MCP client:
|
|
336
252
|
|
|
337
|
-
|
|
253
|
+
- “Give me a training summary for the last four weeks.”
|
|
254
|
+
- “What routines do I have saved on Hevy?”
|
|
255
|
+
- “Show my three most recent workouts.”
|
|
256
|
+
- “Find exercise templates containing squat.”
|
|
257
|
+
- “Which Hevy account is connected?”
|
|
338
258
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
- **Type Check**: `npm run check:types`
|
|
342
|
-
- **Unit Tests**: `npm run test:unit`
|
|
343
|
-
- **Full Vitest Discovery**: `npm test` (builds first; live tests skip when
|
|
344
|
-
`HEVY_API_KEY` is absent)
|
|
345
|
-
- **Changeset Check**: `npm run check:changeset`
|
|
346
|
-
- **Tool Token Cost**: `npm run measure:tokens` ([measurement guide](./docs/token-cost-tracking.md))
|
|
259
|
+
Your assistant should ask for approval before mutation tools when the client
|
|
260
|
+
supports tool confirmations.
|
|
347
261
|
|
|
348
|
-
|
|
262
|
+
## How it works
|
|
349
263
|
|
|
350
|
-
|
|
264
|
+
```text
|
|
265
|
+
Hosted: Your AI assistant → Streamable HTTP → Cloudflare Worker → Hevy API
|
|
266
|
+
Local: Your AI assistant → MCP over stdio → local hevy-mcp → Hevy API
|
|
267
|
+
```
|
|
351
268
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
269
|
+
The hosted endpoint creates a fresh MCP server and Hevy client for each request.
|
|
270
|
+
It validates the supplied key with Hevy, keeps no shared user session, and does
|
|
271
|
+
not persist the key. The local server follows the same tool contract but runs on
|
|
272
|
+
your machine and receives the key through its child-process environment.
|
|
273
|
+
|
|
274
|
+
In either mode, read tools retrieve data; mutation tools create or replace data
|
|
275
|
+
only when your assistant calls them.
|
|
276
|
+
|
|
277
|
+
## Guided prompts
|
|
278
|
+
|
|
279
|
+
These server-provided MCP prompts coordinate common multi-step workflows:
|
|
280
|
+
|
|
281
|
+
| Prompt | Arguments | Workflow |
|
|
282
|
+
| ----------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
283
|
+
| `analyze-workout-progress` | Optional `weeks` from 1-12; default `4` | Calls `get-training-summary`, then analyzes workout activity and body-measurement trends from the returned evidence. |
|
|
284
|
+
| `create-workout-from-routine` | Required `routineId` and UTC `startTime` | Loads a routine, collects actual completed-set data and an end time, then creates a workout without inventing results. |
|
|
285
|
+
|
|
286
|
+
> [!NOTE]
|
|
287
|
+
> With MCP SDK v1.29.0, clients invoking `analyze-workout-progress` with its
|
|
288
|
+
> default value must send `arguments: {}`. Omitting the entire `arguments`
|
|
289
|
+
> object is rejected by that SDK version before the default is applied.
|
|
290
|
+
|
|
291
|
+
## Tools
|
|
292
|
+
|
|
293
|
+
`hevy-mcp` registers 25 tools. Read-only tools are safe for exploration; create
|
|
294
|
+
and update tools are exposed with MCP mutation annotations so compatible clients
|
|
295
|
+
can request confirmation.
|
|
296
|
+
|
|
297
|
+
| Category | Tool | Description |
|
|
298
|
+
| ------------------ | --------------------------- | --------------------------------------------------------------------------------- |
|
|
299
|
+
| Training analysis | `get-training-summary` | Summarize 1-12 weeks of workout activity and body-measurement trends in one call. |
|
|
300
|
+
| Workouts | `get-workouts` | List workouts from newest to oldest with exercise and timing details. |
|
|
301
|
+
| Workouts | `get-workout` | Get complete details for one workout by ID. |
|
|
302
|
+
| Workouts | `get-workout-count` | Return the account's total workout count. |
|
|
303
|
+
| Workouts | `get-workout-events` | List workout update and delete events since a timestamp. |
|
|
304
|
+
| Workouts | `create-workout` | Create a completed workout in Hevy. |
|
|
305
|
+
| Workouts | `update-workout` | Replace an existing workout by ID. |
|
|
306
|
+
| Routines | `search-routines` | Search routine titles and return compact metadata for discovery. |
|
|
307
|
+
| Routines | `get-routines` | List custom and default workout routines. |
|
|
308
|
+
| Routines | `get-routine` | Get one routine and its exercise configuration by ID. |
|
|
309
|
+
| Routines | `create-routine` | Create a reusable workout routine. |
|
|
310
|
+
| Routines | `update-routine` | Replace an existing routine's content. |
|
|
311
|
+
| Routine folders | `get-routine-folders` | List default and custom routine folders. |
|
|
312
|
+
| Routine folders | `get-routine-folder` | Get one routine folder's metadata by ID. |
|
|
313
|
+
| Routine folders | `create-routine-folder` | Create a routine folder. |
|
|
314
|
+
| Exercise templates | `get-exercise-templates` | List exercise templates with equipment and muscle metadata. |
|
|
315
|
+
| Exercise templates | `get-exercise-template` | Get complete metadata for one exercise template by ID. |
|
|
316
|
+
| Exercise templates | `search-exercise-templates` | Search the full exercise catalog by title substring. |
|
|
317
|
+
| Exercise templates | `create-exercise-template` | Create a custom exercise template. |
|
|
318
|
+
| Exercise history | `get-exercise-history` | Get past performed sets for one exercise template. |
|
|
319
|
+
| Body measurements | `get-body-measurements` | List dated body measurements. |
|
|
320
|
+
| Body measurements | `get-body-measurement` | Get the body measurement entry for one date. |
|
|
321
|
+
| Body measurements | `create-body-measurement` | Create a dated body measurement. |
|
|
322
|
+
| Body measurements | `update-body-measurement` | Update the body measurement for an existing date. |
|
|
323
|
+
| Account | `get-user-info` | Return the user's ID, display name, and public profile URL. |
|
|
324
|
+
|
|
325
|
+
The Hevy API currently exposes no delete endpoints for workouts, routines,
|
|
326
|
+
routine folders, exercise templates, or body measurements, so there are no
|
|
327
|
+
corresponding delete tools.
|
|
328
|
+
|
|
329
|
+
### Resources
|
|
330
|
+
|
|
331
|
+
| Name | URI | Description |
|
|
332
|
+
| -------------------- | --------------------------- | -------------------------------------------- |
|
|
333
|
+
| `user-profile` | `hevy://user` | Authenticated Hevy user profile. |
|
|
334
|
+
| `workout-count` | `hevy://workout-count` | Total number of workouts in the account. |
|
|
335
|
+
| `exercise-templates` | `hevy://exercise-templates` | Full formatted exercise template catalog. |
|
|
336
|
+
| `routine-folders` | `hevy://routine-folders` | Full formatted list of Hevy routine folders. |
|
|
337
|
+
|
|
338
|
+
## Hosted Cloudflare endpoint
|
|
339
|
+
|
|
340
|
+
The production MCP server is live at:
|
|
341
|
+
|
|
342
|
+
```text
|
|
343
|
+
https://hevy.chrisdoc.dev/mcp
|
|
344
|
+
```
|
|
360
345
|
|
|
361
|
-
|
|
346
|
+
It is the quickest way to use `hevy-mcp`: there is nothing to install or keep
|
|
347
|
+
running locally, and it exposes the same 25 tools as the npm package and Docker
|
|
348
|
+
image.
|
|
362
349
|
|
|
363
|
-
The
|
|
350
|
+
The Cloudflare Worker uses stateless **Streamable HTTP** at `POST /mcp`.
|
|
351
|
+
Clients must send their Hevy API key as a fixed authorization header:
|
|
364
352
|
|
|
365
|
-
```
|
|
366
|
-
|
|
353
|
+
```json
|
|
354
|
+
{
|
|
355
|
+
"mcpServers": {
|
|
356
|
+
"hevy": {
|
|
357
|
+
"url": "https://hevy.chrisdoc.dev/mcp",
|
|
358
|
+
"headers": {
|
|
359
|
+
"Authorization": "Bearer your-hevy-api-key"
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
367
364
|
```
|
|
368
365
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
366
|
+
The bearer value is your Hevy API key, not an OAuth token. The Worker validates
|
|
367
|
+
the key with Hevy on each request, does not store it, and forwards it upstream
|
|
368
|
+
only as Hevy's required `api-key` header.
|
|
369
|
+
|
|
370
|
+
The endpoint does not expose legacy SSE or a `GET` event stream. Clients that
|
|
371
|
+
require OAuth discovery, dynamic registration, token refresh, or legacy SSE are
|
|
372
|
+
not compatible unless they can send the fixed custom header above.
|
|
373
|
+
|
|
374
|
+
### Self-host the Worker
|
|
375
|
+
|
|
376
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) to deploy the Cloudflare Worker for
|
|
377
|
+
self-hosted Streamable HTTP.
|
|
378
|
+
|
|
379
|
+
## Advanced configuration
|
|
380
|
+
|
|
381
|
+
| Setting | Default | Scope | Notes |
|
|
382
|
+
| ---------------------- | ------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
383
|
+
| `HEVY_API_KEY` | None; required | Local stdio | Hevy API key from the Hevy app. Never pass it in a URL. |
|
|
384
|
+
| `HEVY_MCP_API_TIMEOUT` | `30000` ms | Local stdio | Positive Hevy API timeout in milliseconds. Invalid values fall back to 30 seconds. |
|
|
385
|
+
| `HEVY_MCP_DEBUG` | Disabled | Local stdio | Set to exactly `1` for privacy-bounded diagnostics on stderr. Stdout remains reserved for MCP JSON-RPC. |
|
|
386
|
+
| `MCP_ALLOWED_ORIGINS` | No browser origins allowed | Self-hosted Worker | Optional comma-separated exact origins. Wildcards are unsupported. Requests without `Origin`, such as desktop clients, remain accepted. |
|
|
387
|
+
| `XDG_CACHE_HOME` | `~/.cache` | Local stdio | Changes the root for the npm update-check cache at `hevy-mcp/update-check.json`. |
|
|
388
|
+
| `SENTRY_DSN` | Packaged project DSN | Optional local Node telemetry | Overrides the Sentry destination. An empty value disables Sentry export. The Worker does not import Node telemetry. |
|
|
389
|
+
| `SENTRY_RELEASE` | `hevy-mcp@<installed-version>` | Optional local Node telemetry | Overrides the release label attached to local Sentry events and traces. |
|
|
390
|
+
| `-h`, `--help` | N/A | Local stdio CLI | Print supported options and exit. |
|
|
391
|
+
| `-v`, `--version` | N/A | Local stdio CLI | Print the installed version and exit. |
|
|
392
|
+
|
|
393
|
+
The local executable is stdio-only. It does not support `PORT`,
|
|
394
|
+
`HEVY_MCP_TRANSPORT`, or `--transport`, and it does not provide local HTTP or
|
|
395
|
+
SSE behavior.
|
|
396
|
+
|
|
397
|
+
### Cache behavior
|
|
398
|
+
|
|
399
|
+
`search-exercise-templates` and `hevy://exercise-templates` share a
|
|
400
|
+
server-scoped in-memory catalog cache:
|
|
401
|
+
|
|
402
|
+
- Entries live for five minutes, and the cache holds at most one catalog.
|
|
403
|
+
- Concurrent catalog requests share an in-flight fetch when possible.
|
|
404
|
+
- `search-exercise-templates` accepts `refresh: true` to invalidate the cache.
|
|
405
|
+
- Paginated `get-exercise-templates` calls always fetch their requested page.
|
|
406
|
+
- Each hosted Worker request gets a fresh cache, preventing cross-key sharing.
|
|
407
|
+
|
|
408
|
+
## Security and mutations
|
|
409
|
+
|
|
410
|
+
- Keep `HEVY_API_KEY` out of source control, URLs, logs, and screenshots.
|
|
411
|
+
- Local clients provide the key through the child process environment.
|
|
412
|
+
- Hosted clients send the key only in the `Authorization: Bearer` header. The
|
|
413
|
+
Worker validates each key with Hevy, does not store it, and sends it upstream
|
|
414
|
+
only as Hevy's `api-key` header.
|
|
415
|
+
- Browser requests to a self-hosted Worker must exactly match an origin in
|
|
416
|
+
`MCP_ALLOWED_ORIGINS`; wildcard CORS is intentionally unsupported.
|
|
417
|
+
- Create operations can produce duplicates when retried. Update operations
|
|
418
|
+
replace existing records. Review tool inputs and use client confirmations.
|
|
419
|
+
|
|
420
|
+
## Troubleshooting
|
|
421
|
+
|
|
422
|
+
- **The server does not appear:** restart or reconnect your MCP client after
|
|
423
|
+
changing its configuration.
|
|
424
|
+
- **`npx` fails:** confirm that Node.js 20 or newer is installed, then run
|
|
425
|
+
`npx -y hevy-mcp --version` in a terminal.
|
|
426
|
+
- **Codex cannot see the server:** run `codex mcp list`, then start a new Codex
|
|
427
|
+
session after confirming the `hevy` entry exists.
|
|
428
|
+
- **Hosted authentication fails:** confirm the key is active, belongs to a Hevy
|
|
429
|
+
PRO account, and is sent as `Authorization: Bearer <HEVY_API_KEY>`.
|
|
430
|
+
- **Local authentication fails:** confirm the key is active and available to the
|
|
431
|
+
MCP child process as `HEVY_API_KEY`.
|
|
432
|
+
- **Need diagnostics:** set `HEVY_MCP_DEBUG=1`. Diagnostic output goes to stderr
|
|
433
|
+
and does not interfere with MCP messages on stdout.
|
|
434
|
+
|
|
435
|
+
If you find a bug or have a feature request, [open an issue](https://github.com/chrisdoc/hevy-mcp/issues).
|
|
436
|
+
|
|
437
|
+
## Contributing
|
|
438
|
+
|
|
439
|
+
Contributions are welcome. Developer setup, testing lanes, generated-client
|
|
440
|
+
workflows, Cloudflare Worker deployment, and pull request rules are documented
|
|
441
|
+
in [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
442
|
+
|
|
443
|
+
## License and acknowledgements
|
|
444
|
+
|
|
445
|
+
- **License:** [MIT](./LICENSE)
|
|
446
|
+
- **Credits:** [Model Context Protocol](https://github.com/modelcontextprotocol)
|
|
447
|
+
and [Hevy Fitness](https://www.hevyapp.com/)
|