hevy-mcp 3.4.1 → 4.1.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 CHANGED
@@ -181,6 +181,23 @@ npx -y hevy-mcp
181
181
  `npx` requires Node.js 20 or newer. Restart or reconnect your client after
182
182
  saving its configuration.
183
183
 
184
+ ### Programmatic API
185
+
186
+ The package exposes two named functions for applications that embed the MCP
187
+ server:
188
+
189
+ ```ts
190
+ import { createNodeMcpServer, runStdioServer } from "hevy-mcp";
191
+
192
+ const server = await createNodeMcpServer({ apiKey: process.env.HEVY_API_KEY! });
193
+ // Connect `server` to the transport owned by your application, or use:
194
+ await runStdioServer();
195
+ ```
196
+
197
+ `createNodeMcpServer` never reads environment variables, connects a transport,
198
+ or installs process lifecycle handlers. The CLI-only `runStdioServer` function
199
+ owns those concerns.
200
+
184
201
  <details>
185
202
  <summary><strong>Use bunx instead</strong></summary>
186
203
 
@@ -397,21 +414,39 @@ self-hosted Streamable HTTP.
397
414
 
398
415
  ## Advanced configuration
399
416
 
400
- | Setting | Default | Scope | Notes |
401
- | ---------------------- | ------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
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. |
408
- | `SENTRY_RELEASE` | `hevy-mcp@<installed-version>` | Optional local Node telemetry | Overrides the release label attached to local Sentry events and traces. |
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. |
411
-
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.
417
+ | Setting | Default | Scope | Notes |
418
+ | ---------------------------- | ------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- |
419
+ | `HEVY_API_KEY` | None; required | Local stdio or HTTP | Hevy API key from the Hevy app. Never pass it in a URL. |
420
+ | `HEVY_MCP_API_TIMEOUT` | `30000` ms | Local stdio | Positive Hevy API timeout in milliseconds. Invalid values fall back to 30 seconds. |
421
+ | `HEVY_MCP_DEBUG` | Disabled | Local Node | Set to exactly `1` for privacy-bounded diagnostics on stderr. Stdout remains reserved for MCP JSON-RPC. |
422
+ | `HEVY_MCP_HTTP_BEARER_TOKEN` | None | Non-loopback HTTP | Required when `--host` is not loopback; use a separate token, never the Hevy API key. |
423
+ | `XDG_CACHE_HOME` | `~/.cache` | Local stdio | Changes the root for the npm update-check cache at `hevy-mcp/update-check.json`. |
424
+ | `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. |
425
+ | `SENTRY_RELEASE` | `hevy-mcp@<installed-version>` | Optional local Node telemetry | Overrides the release label attached to local Sentry events and traces. |
426
+ | `-h`, `--help` | N/A | Local stdio CLI | Print supported options and exit. |
427
+ | `-v`, `--version` | N/A | Local stdio CLI | Print the installed version and exit. |
428
+
429
+ The local executable uses stdio by default. To opt into Streamable HTTP, run:
430
+
431
+ ```bash
432
+ HEVY_API_KEY=your-hevy-api-key npx hevy-mcp --transport http --host 127.0.0.1 --port 3000
433
+ ```
434
+
435
+ The MCP endpoint is `http://127.0.0.1:3000/mcp`. For a specific bind host,
436
+ HTTP mode validates the Host header and configured port to protect against DNS
437
+ rebinding. Loopback is the default. Wildcard binds (`0.0.0.0` or `::`) accept
438
+ any hostname so they can be used behind Docker port mappings or a reverse
439
+ proxy; they require `HEVY_MCP_HTTP_BEARER_TOKEN` and rely on that separate
440
+ authentication token. Do not expose an unprotected shared Hevy account to the
441
+ public internet. For Docker HTTP mode, publish the port explicitly:
442
+
443
+ ```bash
444
+ docker run --rm -p 3000:3000 -e HEVY_API_KEY -e HEVY_MCP_HTTP_BEARER_TOKEN \
445
+ ghcr.io/chrisdoc/hevy-mcp:latest --transport http --host 0.0.0.0 --port 3000
446
+ ```
447
+
448
+ Wildcard binds are allowed only with the separate bearer token; publish the
449
+ container port deliberately and keep that token private.
415
450
 
416
451
  ### Cache behavior
417
452
 
@@ -431,8 +466,9 @@ server-scoped in-memory catalog cache:
431
466
  - Hosted clients send the key only in the `Authorization: Bearer` header. The
432
467
  Worker validates each key with Hevy, does not store it, and sends it upstream
433
468
  only as Hevy's `api-key` header.
434
- - Browser requests to a self-hosted Worker must exactly match an origin in
435
- `MCP_ALLOWED_ORIGINS`; wildcard CORS is intentionally unsupported.
469
+ - Browser requests must come from an exact allowlisted origin. The default
470
+ allowlist includes Claude.ai, ChatGPT, VS Code for the Web, and github.dev;
471
+ self-hosted deployments can override it with `MCP_ALLOWED_ORIGINS`.
436
472
  - Create operations can produce duplicates when retried. Update operations
437
473
  replace existing records. Review tool inputs and use client confirmations.
438
474
 
package/dist/cli.mjs CHANGED
@@ -4,15 +4,16 @@
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.4.1" };
7
+ e.SENTRY_RELEASE = { id: "hevy-mcp@4.1.0" };
8
8
  var n = new e.Error().stack;
9
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "70926e8e-f4a5-4145-a01e-027bb707b27d", e._sentryDebugIdIdentifier = "sentry-dbid-70926e8e-f4a5-4145-a01e-027bb707b27d");
9
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "625c4c9c-e20d-40b3-96b1-4e799ef130f3", e._sentryDebugIdIdentifier = "sentry-dbid-625c4c9c-e20d-40b3-96b1-4e799ef130f3");
10
10
  } catch (e) {}
11
11
  })();
12
- import { a as flushTelemetry, i as createSafeErrorDiagnostic, r as runServer } from "./src-Ch2aS5wP.mjs";
12
+ import { a as createSafeErrorDiagnostic, i as MissingHevyApiKeyError, n as runServer, o as flushTelemetry } from "./src-wSWxe4LJ.mjs";
13
13
  //#region src/cli.ts
14
14
  runServer().catch(async (error) => {
15
- console.error("Fatal error in main()", createSafeErrorDiagnostic(error));
15
+ if (error instanceof MissingHevyApiKeyError) console.error(error.message);
16
+ else console.error("Fatal error in main()", createSafeErrorDiagnostic(error));
16
17
  try {
17
18
  await flushTelemetry();
18
19
  } catch {}
@@ -20,5 +21,3 @@ runServer().catch(async (error) => {
20
21
  });
21
22
  //#endregion
22
23
  export {};
23
-
24
- //# sourceMappingURL=cli.mjs.map
package/dist/index.d.mts CHANGED
@@ -1,17 +1,12 @@
1
1
 
2
- import { z } from "zod";
2
+ //#region src/utils/arguments.d.ts
3
+ type NodeTransport = "stdio" | "http";
4
+ //#endregion
3
5
  //#region src/index.d.ts
4
- declare const serverConfigSchema: z.ZodObject<{
5
- apiKey: z.ZodString;
6
- }, z.core.$strip>;
7
- declare const configSchema: z.ZodObject<{
8
- apiKey: z.ZodString;
9
- }, z.core.$strip>;
10
- type ServerConfig = z.infer<typeof serverConfigSchema>;
11
- declare function createServer({ config }: {
12
- config: ServerConfig;
13
- }): Promise<import("@modelcontextprotocol/sdk/server/mcp").McpServer>;
6
+ declare function createNodeMcpServer({ apiKey }: {
7
+ apiKey: string;
8
+ }, transport?: NodeTransport): Promise<import("@modelcontextprotocol/sdk/server/mcp").McpServer>;
9
+ declare function runStdioServer(): Promise<void>;
14
10
  declare function runServer(): Promise<void>;
15
11
  //#endregion
16
- export { configSchema, createServer, createServer as default, runServer };
17
- //# sourceMappingURL=index.d.mts.map
12
+ export { createNodeMcpServer, runServer, runStdioServer };
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.4.1" };
7
+ e.SENTRY_RELEASE = { id: "hevy-mcp@4.1.0" };
8
8
  var n = new e.Error().stack;
9
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "5b077b94-9ef8-4f24-a0b0-8dcfbf491be1", e._sentryDebugIdIdentifier = "sentry-dbid-5b077b94-9ef8-4f24-a0b0-8dcfbf491be1");
9
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "e9496b31-626b-4ad1-9416-47ba4ffd2995", e._sentryDebugIdIdentifier = "sentry-dbid-e9496b31-626b-4ad1-9416-47ba4ffd2995");
10
10
  } catch (e) {}
11
11
  })();
12
- import { n as createServer, r as runServer, t as configSchema } from "./src-Ch2aS5wP.mjs";
13
- export { configSchema, createServer, createServer as default, runServer };
12
+ import { n as runServer, r as runStdioServer, t as createNodeMcpServer } from "./src-wSWxe4LJ.mjs";
13
+ export { createNodeMcpServer, runServer, runStdioServer };