hevy-mcp 3.1.1 → 3.3.0
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 +324 -129
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +1 -4
- package/dist/index.mjs +2 -2
- package/dist/{src-CkkrTrrg.mjs → src-B_mNqS1X.mjs} +1910 -1383
- package/dist/src-B_mNqS1X.mjs.map +1 -0
- package/package.json +4 -3
- package/server.json +2 -2
- package/dist/src-CkkrTrrg.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,39 +1,149 @@
|
|
|
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
|
-
|
|
9
|
-
to the [Hevy](https://www.hevyapp.com/) fitness API. Ask about workout history,
|
|
10
|
-
analyze progress, browse routines and exercises, or create and update Hevy data
|
|
11
|
-
without leaving your assistant.
|
|
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)
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
</div>
|
|
14
18
|
|
|
15
|
-
|
|
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.
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
HTTP setup is documented below but is temporarily unavailable.
|
|
25
|
+
> A Hevy API key, available with **Hevy PRO**, is required.
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
## See it in action
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
client starts the process and communicates through standard input/output; this
|
|
24
|
-
is not an interactive terminal command or an HTTP service.
|
|
29
|
+
[](https://raw.githubusercontent.com/chrisdoc/hevy-mcp/main/docs/assets/hevy-mcp-demo.mp4)
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
<p align="center"><sub>Click the preview to play the full-quality 18-second demo.</sub></p>
|
|
27
32
|
|
|
28
|
-
|
|
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.
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
both accept an `mcpServers` entry like this:
|
|
36
|
+
## What can you do with it?
|
|
32
37
|
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
- **
|
|
36
|
-
|
|
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.
|
|
52
|
+
|
|
53
|
+
Try asking:
|
|
54
|
+
|
|
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.
|
|
58
|
+
|
|
59
|
+
> Find my push-day routine and show its exercises and sets.
|
|
60
|
+
|
|
61
|
+
> Compare my recent body measurements with my training consistency.
|
|
62
|
+
|
|
63
|
+
> Create a completed workout from my saved routine. Ask me for any missing set
|
|
64
|
+
> results before writing it to Hevy.
|
|
65
|
+
|
|
66
|
+
## Quick start
|
|
67
|
+
|
|
68
|
+
### 1. Get your Hevy API key
|
|
69
|
+
|
|
70
|
+
Create an API key in Hevy, then keep it somewhere secure. API access currently
|
|
71
|
+
requires a Hevy PRO subscription.
|
|
72
|
+
|
|
73
|
+
### 2. Connect `hevy-mcp` to your client
|
|
74
|
+
|
|
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
|
+
|
|
78
|
+
#### Connect to the hosted endpoint
|
|
79
|
+
|
|
80
|
+
Production URL:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
https://hevy.chrisdoc.dev/mcp
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The endpoint uses Streamable HTTP. Send your Hevy API key as a bearer token on
|
|
87
|
+
every request.
|
|
88
|
+
|
|
89
|
+
##### Codex
|
|
90
|
+
|
|
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:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
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
|
|
100
|
+
```
|
|
101
|
+
|
|
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.
|
|
105
|
+
|
|
106
|
+
##### Other Streamable HTTP clients
|
|
107
|
+
|
|
108
|
+
Clients that accept a remote MCP URL and fixed headers commonly use this shape:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"mcpServers": {
|
|
113
|
+
"hevy": {
|
|
114
|
+
"url": "https://hevy.chrisdoc.dev/mcp",
|
|
115
|
+
"headers": {
|
|
116
|
+
"Authorization": "Bearer your-hevy-api-key"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Exact configuration keys vary by client. The hosted server requires support for
|
|
124
|
+
Streamable HTTP and a fixed `Authorization` header.
|
|
125
|
+
|
|
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.
|
|
130
|
+
|
|
131
|
+
#### Run locally instead
|
|
132
|
+
|
|
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.
|
|
135
|
+
|
|
136
|
+
##### Codex
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
codex mcp add hevy \
|
|
140
|
+
--env HEVY_API_KEY=your-hevy-api-key \
|
|
141
|
+
-- npx -y hevy-mcp
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
##### Claude Desktop or Cursor
|
|
145
|
+
|
|
146
|
+
Add this `mcpServers` entry to your client configuration:
|
|
37
147
|
|
|
38
148
|
```json
|
|
39
149
|
{
|
|
@@ -49,10 +159,32 @@ both accept an `mcpServers` entry like this:
|
|
|
49
159
|
}
|
|
50
160
|
```
|
|
51
161
|
|
|
52
|
-
|
|
162
|
+
Common local configuration locations:
|
|
53
163
|
|
|
54
|
-
|
|
55
|
-
|
|
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`
|
|
169
|
+
|
|
170
|
+
Restart or reconnect the client after saving the file.
|
|
171
|
+
|
|
172
|
+
##### Any stdio MCP client
|
|
173
|
+
|
|
174
|
+
Configure your client to launch this command with `HEVY_API_KEY` in the child
|
|
175
|
+
process environment:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
npx -y hevy-mcp
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`npx` requires Node.js 20 or newer. Restart or reconnect your client after
|
|
182
|
+
saving its configuration.
|
|
183
|
+
|
|
184
|
+
<details>
|
|
185
|
+
<summary><strong>Use bunx instead</strong></summary>
|
|
186
|
+
|
|
187
|
+
Requires [Bun](https://bun.sh/):
|
|
56
188
|
|
|
57
189
|
```json
|
|
58
190
|
{
|
|
@@ -68,10 +200,13 @@ launcher:
|
|
|
68
200
|
}
|
|
69
201
|
```
|
|
70
202
|
|
|
71
|
-
|
|
203
|
+
</details>
|
|
204
|
+
|
|
205
|
+
<details>
|
|
206
|
+
<summary><strong>Use Docker instead</strong></summary>
|
|
72
207
|
|
|
73
208
|
Official images support `linux/amd64` and `linux/arm64`. Keep stdin open with
|
|
74
|
-
`-i` because the container runs the
|
|
209
|
+
`-i` because the container runs the stdio MCP server:
|
|
75
210
|
|
|
76
211
|
```bash
|
|
77
212
|
export HEVY_API_KEY=your-hevy-api-key
|
|
@@ -102,29 +237,118 @@ the client to launch Docker:
|
|
|
102
237
|
Pin an exact image tag such as `ghcr.io/chrisdoc/hevy-mcp:X.Y.Z` when you need
|
|
103
238
|
reproducible upgrades.
|
|
104
239
|
|
|
105
|
-
|
|
240
|
+
</details>
|
|
241
|
+
|
|
242
|
+
You can also add the npm server to supported clients with
|
|
106
243
|
[`add-mcp`](https://github.com/neon-solutions/add-mcp):
|
|
107
244
|
|
|
108
245
|
```bash
|
|
109
246
|
npx add-mcp hevy-mcp --env "HEVY_API_KEY=your-hevy-api-key"
|
|
110
247
|
```
|
|
111
248
|
|
|
112
|
-
###
|
|
249
|
+
### 3. Ask your first question
|
|
113
250
|
|
|
114
|
-
|
|
115
|
-
> `https://hevy.chrisdoc.dev/mcp` is currently intercepted by an interactive
|
|
116
|
-
> Cloudflare challenge, so non-browser MCP clients cannot connect. Use local
|
|
117
|
-
> stdio until the route is restored.
|
|
251
|
+
Try one of these after restarting or reconnecting your MCP client:
|
|
118
252
|
|
|
119
|
-
|
|
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?”
|
|
258
|
+
|
|
259
|
+
Your assistant should ask for approval before mutation tools when the client
|
|
260
|
+
supports tool confirmations.
|
|
261
|
+
|
|
262
|
+
## How it works
|
|
263
|
+
|
|
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
|
+
```
|
|
268
|
+
|
|
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:
|
|
120
341
|
|
|
121
342
|
```text
|
|
122
343
|
https://hevy.chrisdoc.dev/mcp
|
|
123
344
|
```
|
|
124
345
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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.
|
|
349
|
+
|
|
350
|
+
The Cloudflare Worker uses stateless **Streamable HTTP** at `POST /mcp`.
|
|
351
|
+
Clients must send their Hevy API key as a fixed authorization header:
|
|
128
352
|
|
|
129
353
|
```json
|
|
130
354
|
{
|
|
@@ -139,108 +363,62 @@ that use `url` and `headers` commonly accept this shape:
|
|
|
139
363
|
}
|
|
140
364
|
```
|
|
141
365
|
|
|
142
|
-
The
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Clients that require OAuth discovery, dynamic registration, token refresh, or a
|
|
146
|
-
legacy SSE transport are not compatible unless they can send the fixed custom
|
|
147
|
-
header above.
|
|
148
|
-
|
|
149
|
-
### How to verify it is working
|
|
150
|
-
|
|
151
|
-
Restart or reconnect your MCP client after saving the configuration, then try:
|
|
152
|
-
|
|
153
|
-
- "What routines do I have saved on Hevy?"
|
|
154
|
-
- "Show my most recent workouts."
|
|
155
|
-
- "Which Hevy account is connected?"
|
|
156
|
-
- "Find exercise templates containing squat."
|
|
157
|
-
|
|
158
|
-
The assistant should ask for approval before mutation tools when the client
|
|
159
|
-
supports tool confirmations.
|
|
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.
|
|
160
369
|
|
|
161
|
-
|
|
370
|
+
### OAuth for Claude.ai and other remote MCP clients
|
|
162
371
|
|
|
163
|
-
|
|
372
|
+
Workers deployed with an `OAUTH_KV` namespace binding (see
|
|
373
|
+
[CONTRIBUTING.md](./CONTRIBUTING.md)) additionally expose a full OAuth 2.1
|
|
374
|
+
layer for clients that cannot send a fixed header, such as Claude.ai custom
|
|
375
|
+
connectors:
|
|
164
376
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
377
|
+
- RFC 8414 / RFC 9728 discovery metadata under `/.well-known/`
|
|
378
|
+
- Dynamic client registration (`/register`) and PKCE token exchange (`/token`)
|
|
379
|
+
- An `/authorize` page where you paste your Hevy API key once; the key is
|
|
380
|
+
validated with Hevy and stored encrypted inside the OAuth grant
|
|
169
381
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
## Capabilities
|
|
177
|
-
|
|
178
|
-
`hevy-mcp` registers 23 tools:
|
|
179
|
-
|
|
180
|
-
| Category | Tool | Description |
|
|
181
|
-
| -------------------------- | --------------------------- | --------------------------------------------------------------------- |
|
|
182
|
-
| Workouts | `get-workouts` | List workouts from newest to oldest with exercise and timing details. |
|
|
183
|
-
| Workouts | `get-workout` | Get complete details for one workout by ID. |
|
|
184
|
-
| Workouts | `get-workout-count` | Return the account's total workout count. |
|
|
185
|
-
| Workouts | `get-workout-events` | List workout update and delete events since a timestamp. |
|
|
186
|
-
| Workouts | `create-workout` | Create a completed workout in Hevy. |
|
|
187
|
-
| Workouts | `update-workout` | Replace an existing workout by ID. |
|
|
188
|
-
| Routines | `get-routines` | List custom and default workout routines. |
|
|
189
|
-
| Routines | `get-routine` | Get one routine and its exercise configuration by ID. |
|
|
190
|
-
| Routines | `create-routine` | Create a reusable workout routine. |
|
|
191
|
-
| Routines | `update-routine` | Replace an existing routine's content. |
|
|
192
|
-
| Routine folders | `get-routine-folders` | List default and custom routine folders. |
|
|
193
|
-
| Routine folders | `get-routine-folder` | Get one routine folder's metadata by ID. |
|
|
194
|
-
| Routine folders | `create-routine-folder` | Create a routine folder. |
|
|
195
|
-
| Exercise templates/history | `get-exercise-templates` | List exercise templates with equipment and muscle metadata. |
|
|
196
|
-
| Exercise templates/history | `get-exercise-template` | Get complete metadata for one exercise template by ID. |
|
|
197
|
-
| Exercise templates/history | `search-exercise-templates` | Search the full exercise catalog by title substring. |
|
|
198
|
-
| Exercise templates/history | `create-exercise-template` | Create a custom exercise template. |
|
|
199
|
-
| Exercise templates/history | `get-exercise-history` | Get past performed sets for one exercise template. |
|
|
200
|
-
| Body measurements | `get-body-measurements` | List dated body measurements. |
|
|
201
|
-
| Body measurements | `get-body-measurement` | Get the body measurement entry for one date. |
|
|
202
|
-
| Body measurements | `create-body-measurement` | Create a dated body measurement. |
|
|
203
|
-
| Body measurements | `update-body-measurement` | Update the body measurement for an existing date. |
|
|
204
|
-
| Account | `get-user-info` | Return the user's ID, display name, and public profile URL. |
|
|
382
|
+
Add the Worker URL ending in `/mcp` as a Claude.ai custom connector and
|
|
383
|
+
complete the authorization flow in the browser. Direct
|
|
384
|
+
`Authorization: Bearer <hevy-api-key>` requests keep working unchanged — the
|
|
385
|
+
OAuth layer is purely additive — and rotating your Hevy API key invalidates
|
|
386
|
+
every OAuth grant created with it.
|
|
205
387
|
|
|
206
|
-
The
|
|
207
|
-
|
|
208
|
-
|
|
388
|
+
The endpoint does not expose legacy SSE or a `GET` event stream. Without the
|
|
389
|
+
opt-in OAuth layer, clients that require OAuth discovery, dynamic
|
|
390
|
+
registration, or token refresh are not compatible unless they can send the
|
|
391
|
+
fixed custom header above.
|
|
209
392
|
|
|
210
|
-
###
|
|
393
|
+
### Self-host the Worker
|
|
211
394
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
| `user-profile` | `hevy://user` | Authenticated Hevy user profile. |
|
|
215
|
-
| `workout-count` | `hevy://workout-count` | Total number of workouts in the account. |
|
|
216
|
-
| `exercise-templates` | `hevy://exercise-templates` | Full formatted exercise template catalog. |
|
|
217
|
-
| `routine-folders` | `hevy://routine-folders` | Full formatted list of Hevy routine folders. |
|
|
395
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) to deploy the Cloudflare Worker for
|
|
396
|
+
self-hosted Streamable HTTP.
|
|
218
397
|
|
|
219
398
|
## Advanced configuration
|
|
220
399
|
|
|
221
400
|
| Setting | Default | Scope | Notes |
|
|
222
401
|
| ---------------------- | ------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
223
|
-
| `HEVY_API_KEY` | None; required | Local stdio | Hevy API key from the Hevy app.
|
|
224
|
-
| `HEVY_MCP_API_TIMEOUT` | `30000` ms | Local stdio | Positive Hevy API
|
|
225
|
-
| `HEVY_MCP_DEBUG` | Disabled | Local stdio |
|
|
226
|
-
| `MCP_ALLOWED_ORIGINS` | No browser origins allowed | Self-hosted
|
|
227
|
-
| `XDG_CACHE_HOME` | `~/.cache` | Local stdio | Changes the root for the
|
|
228
|
-
| `SENTRY_DSN` | Packaged project DSN | Optional local Node telemetry | Overrides the Sentry destination. An empty value disables Sentry export. The Worker
|
|
402
|
+
| `HEVY_API_KEY` | None; required | Local stdio | Hevy API key from the Hevy app. Never pass it in a URL. |
|
|
403
|
+
| `HEVY_MCP_API_TIMEOUT` | `30000` ms | Local stdio | Positive Hevy API timeout in milliseconds. Invalid values fall back to 30 seconds. |
|
|
404
|
+
| `HEVY_MCP_DEBUG` | Disabled | Local stdio | Set to exactly `1` for privacy-bounded diagnostics on stderr. Stdout remains reserved for MCP JSON-RPC. |
|
|
405
|
+
| `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. |
|
|
406
|
+
| `XDG_CACHE_HOME` | `~/.cache` | Local stdio | Changes the root for the npm update-check cache at `hevy-mcp/update-check.json`. |
|
|
407
|
+
| `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. |
|
|
229
408
|
| `SENTRY_RELEASE` | `hevy-mcp@<installed-version>` | Optional local Node telemetry | Overrides the release label attached to local Sentry events and traces. |
|
|
230
|
-
| `-h`, `--help` | N/A | Local stdio CLI | Print supported options and exit
|
|
231
|
-
| `-v`, `--version` | N/A | Local stdio CLI | Print the installed version and exit
|
|
409
|
+
| `-h`, `--help` | N/A | Local stdio CLI | Print supported options and exit. |
|
|
410
|
+
| `-v`, `--version` | N/A | Local stdio CLI | Print the installed version and exit. |
|
|
232
411
|
|
|
233
|
-
The local executable does
|
|
234
|
-
`--transport
|
|
235
|
-
behavior.
|
|
236
|
-
separate Cloudflare Worker when Streamable HTTP is required now.
|
|
412
|
+
The local executable is stdio-only. It does not support `PORT`,
|
|
413
|
+
`HEVY_MCP_TRANSPORT`, or `--transport`, and it does not provide local HTTP or
|
|
414
|
+
SSE behavior.
|
|
237
415
|
|
|
238
|
-
|
|
416
|
+
### Cache behavior
|
|
239
417
|
|
|
240
418
|
`search-exercise-templates` and `hevy://exercise-templates` share a
|
|
241
419
|
server-scoped in-memory catalog cache:
|
|
242
420
|
|
|
243
|
-
- Entries live for five minutes and the cache holds at most one catalog.
|
|
421
|
+
- Entries live for five minutes, and the cache holds at most one catalog.
|
|
244
422
|
- Concurrent catalog requests share an in-flight fetch when possible.
|
|
245
423
|
- `search-exercise-templates` accepts `refresh: true` to invalidate the cache.
|
|
246
424
|
- Paginated `get-exercise-templates` calls always fetch their requested page.
|
|
@@ -249,20 +427,37 @@ server-scoped in-memory catalog cache:
|
|
|
249
427
|
## Security and mutations
|
|
250
428
|
|
|
251
429
|
- Keep `HEVY_API_KEY` out of source control, URLs, logs, and screenshots.
|
|
252
|
-
- Local clients provide the key through the child process environment.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
430
|
+
- Local clients provide the key through the child process environment.
|
|
431
|
+
- Hosted clients send the key only in the `Authorization: Bearer` header. The
|
|
432
|
+
Worker validates each key with Hevy, does not store it, and sends it upstream
|
|
433
|
+
only as Hevy's `api-key` header.
|
|
256
434
|
- Browser requests to a self-hosted Worker must exactly match an origin in
|
|
257
435
|
`MCP_ALLOWED_ORIGINS`; wildcard CORS is intentionally unsupported.
|
|
258
436
|
- Create operations can produce duplicates when retried. Update operations
|
|
259
437
|
replace existing records. Review tool inputs and use client confirmations.
|
|
260
438
|
|
|
261
|
-
##
|
|
439
|
+
## Troubleshooting
|
|
440
|
+
|
|
441
|
+
- **The server does not appear:** restart or reconnect your MCP client after
|
|
442
|
+
changing its configuration.
|
|
443
|
+
- **`npx` fails:** confirm that Node.js 20 or newer is installed, then run
|
|
444
|
+
`npx -y hevy-mcp --version` in a terminal.
|
|
445
|
+
- **Codex cannot see the server:** run `codex mcp list`, then start a new Codex
|
|
446
|
+
session after confirming the `hevy` entry exists.
|
|
447
|
+
- **Hosted authentication fails:** confirm the key is active, belongs to a Hevy
|
|
448
|
+
PRO account, and is sent as `Authorization: Bearer <HEVY_API_KEY>`.
|
|
449
|
+
- **Local authentication fails:** confirm the key is active and available to the
|
|
450
|
+
MCP child process as `HEVY_API_KEY`.
|
|
451
|
+
- **Need diagnostics:** set `HEVY_MCP_DEBUG=1`. Diagnostic output goes to stderr
|
|
452
|
+
and does not interfere with MCP messages on stdout.
|
|
453
|
+
|
|
454
|
+
If you find a bug or have a feature request, [open an issue](https://github.com/chrisdoc/hevy-mcp/issues).
|
|
455
|
+
|
|
456
|
+
## Contributing
|
|
262
457
|
|
|
263
|
-
Developer setup, testing lanes, generated-client
|
|
264
|
-
deployment, and pull request rules
|
|
265
|
-
[
|
|
458
|
+
Contributions are welcome. Developer setup, testing lanes, generated-client
|
|
459
|
+
workflows, Cloudflare Worker deployment, and pull request rules are documented
|
|
460
|
+
in [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
266
461
|
|
|
267
462
|
## License and acknowledgements
|
|
268
463
|
|
package/dist/cli.mjs
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
(function() {
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
|
-
e.SENTRY_RELEASE = { id: "hevy-mcp@3.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@3.3.0" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
9
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "47a79c69-c982-44cf-abda-d010f962b955", e._sentryDebugIdIdentifier = "sentry-dbid-47a79c69-c982-44cf-abda-d010f962b955");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
-
import { i as createSafeErrorDiagnostic, r as runServer } from "./src-
|
|
12
|
+
import { i as createSafeErrorDiagnostic, r as runServer } from "./src-B_mNqS1X.mjs";
|
|
13
13
|
//#region src/cli.ts
|
|
14
14
|
runServer().catch((error) => {
|
|
15
15
|
console.error("Fatal error in main()", createSafeErrorDiagnostic(error));
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
|
|
4
3
|
//#region src/index.d.ts
|
|
5
4
|
declare const serverConfigSchema: z.ZodObject<{
|
|
6
5
|
apiKey: z.ZodString;
|
|
@@ -9,9 +8,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
9
8
|
apiKey: z.ZodString;
|
|
10
9
|
}, z.core.$strip>;
|
|
11
10
|
type ServerConfig = z.infer<typeof serverConfigSchema>;
|
|
12
|
-
declare function createServer({
|
|
13
|
-
config
|
|
14
|
-
}: {
|
|
11
|
+
declare function createServer({ config }: {
|
|
15
12
|
config: ServerConfig;
|
|
16
13
|
}): Promise<import("@modelcontextprotocol/sdk/server/mcp").McpServer>;
|
|
17
14
|
declare function runServer(): Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
(function() {
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
|
-
e.SENTRY_RELEASE = { id: "hevy-mcp@3.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@3.3.0" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
9
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "5b077b94-9ef8-4f24-a0b0-8dcfbf491be1", e._sentryDebugIdIdentifier = "sentry-dbid-5b077b94-9ef8-4f24-a0b0-8dcfbf491be1");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
-
import { n as createServer, r as runServer, t as configSchema } from "./src-
|
|
12
|
+
import { n as createServer, r as runServer, t as configSchema } from "./src-B_mNqS1X.mjs";
|
|
13
13
|
export { configSchema, createServer, createServer as default, runServer };
|