hevy-mcp 4.1.0 → 4.1.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 +48 -11
- package/dist/cli.mjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{src-wSWxe4LJ.mjs → src-BPbLELQf.mjs} +61 -60
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -414,17 +414,18 @@ self-hosted Streamable HTTP.
|
|
|
414
414
|
|
|
415
415
|
## Advanced configuration
|
|
416
416
|
|
|
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
|
-
| `
|
|
424
|
-
| `
|
|
425
|
-
| `
|
|
426
|
-
|
|
|
427
|
-
| `-
|
|
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
|
+
| `HEVY_MCP_TELEMETRY` | Enabled | Local Node | Set to exactly `0` before startup/import to disable Sentry errors/traces and OTLP traces/metrics. Takes precedence over `SENTRY_DSN` and packaged/runtime collector credentials. |
|
|
424
|
+
| `XDG_CACHE_HOME` | `~/.cache` | Local stdio | Changes the root for the npm update-check cache at `hevy-mcp/update-check.json`. |
|
|
425
|
+
| `SENTRY_DSN` | Packaged project DSN | Optional local Node telemetry | Sentry-only override for the destination. An empty value disables Sentry export. The Worker does not import Node telemetry. |
|
|
426
|
+
| `SENTRY_RELEASE` | `hevy-mcp@<installed-version>` | Optional local Node telemetry | Overrides the release label attached to local Sentry events and traces. |
|
|
427
|
+
| `-h`, `--help` | N/A | Local stdio CLI | Print supported options and exit. |
|
|
428
|
+
| `-v`, `--version` | N/A | Local stdio CLI | Print the installed version and exit. |
|
|
428
429
|
|
|
429
430
|
The local executable uses stdio by default. To opt into Streamable HTTP, run:
|
|
430
431
|
|
|
@@ -459,6 +460,42 @@ server-scoped in-memory catalog cache:
|
|
|
459
460
|
- Paginated `get-exercise-templates` calls always fetch their requested page.
|
|
460
461
|
- Each hosted Worker request gets a fresh cache, preventing cross-key sharing.
|
|
461
462
|
|
|
463
|
+
### Local Node telemetry and privacy
|
|
464
|
+
|
|
465
|
+
The local Node package enables project telemetry by default. It is local Node
|
|
466
|
+
behavior only; the Cloudflare Worker does not import Node telemetry. Set
|
|
467
|
+
`HEVY_MCP_TELEMETRY=0` before startup or import to disable all project
|
|
468
|
+
telemetry. Only the literal value `0` opts out: an unset value, an empty value,
|
|
469
|
+
`1`, `false`, and every other value remain enabled. The master setting takes
|
|
470
|
+
precedence over `SENTRY_DSN` and packaged or runtime `OTEL_COLLECTOR_TOKEN`
|
|
471
|
+
credentials, so the disabled path creates no telemetry exporters or periodic
|
|
472
|
+
metric readers and makes no telemetry network requests. `SENTRY_DSN` remains a
|
|
473
|
+
Sentry-only setting; when telemetry is enabled, an empty value disables only
|
|
474
|
+
Sentry export.
|
|
475
|
+
|
|
476
|
+
When enabled, errors and traces are sent to the packaged Sentry project at
|
|
477
|
+
<https://o4508975499575296.ingest.de.sentry.io/4509049671647312>. Traces and
|
|
478
|
+
metrics are sent to the collector at
|
|
479
|
+
<https://otel.chrisdoc.dev/v1/traces> and
|
|
480
|
+
<https://otel.chrisdoc.dev/v1/metrics>, which forward to Honeycomb. Metrics
|
|
481
|
+
export every 10 seconds.
|
|
482
|
+
|
|
483
|
+
The API key is never exported. Enabled telemetry derives a deterministic
|
|
484
|
+
ten-character HMAC-SHA-256 pseudonym from it solely for cross-span
|
|
485
|
+
correlation. The pseudonym is attached to spans only, never used as a metric
|
|
486
|
+
dimension, and is not intended for per-user behavior histories.
|
|
487
|
+
|
|
488
|
+
The privacy allowlist contains service/version/transport; fixed tool feature,
|
|
489
|
+
read/write kind, operation, and short-lived tool name; bounded
|
|
490
|
+
outcome/error/count/retry/duration/session/cache/workflow values; normalized API
|
|
491
|
+
method/endpoint/status; shape-only key names, presence, count, and boolean
|
|
492
|
+
fields; sanitized client/protocol tokens; and the span-only pseudonym. It
|
|
493
|
+
explicitly prohibits raw prompts, tool argument values, tool result content,
|
|
494
|
+
request bodies, API keys, raw identifiers/queries/exact dates,
|
|
495
|
+
workout/routine/folder/template/body-measurement content, names/titles/
|
|
496
|
+
descriptions/notes, measurement values, arbitrary client metadata, and
|
|
497
|
+
unnormalized endpoint paths.
|
|
498
|
+
|
|
462
499
|
## Security and mutations
|
|
463
500
|
|
|
464
501
|
- Keep `HEVY_API_KEY` out of source control, URLs, logs, and screenshots.
|
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@4.1.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@4.1.1" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
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 createSafeErrorDiagnostic, i as MissingHevyApiKeyError, n as runServer, o as flushTelemetry } from "./src-
|
|
12
|
+
import { a as createSafeErrorDiagnostic, i as MissingHevyApiKeyError, n as runServer, o as flushTelemetry } from "./src-BPbLELQf.mjs";
|
|
13
13
|
//#region src/cli.ts
|
|
14
14
|
runServer().catch(async (error) => {
|
|
15
15
|
if (error instanceof MissingHevyApiKeyError) console.error(error.message);
|
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@4.1.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@4.1.1" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
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 runServer, r as runStdioServer, t as createNodeMcpServer } from "./src-
|
|
12
|
+
import { n as runServer, r as runStdioServer, t as createNodeMcpServer } from "./src-BPbLELQf.mjs";
|
|
13
13
|
export { createNodeMcpServer, runServer, runStdioServer };
|
|
@@ -4,11 +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@4.1.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@4.1.1" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
|
-
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "
|
|
9
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "3ad9084e-6d6c-4681-ad27-9168114359ab", e._sentryDebugIdIdentifier = "sentry-dbid-3ad9084e-6d6c-4681-ad27-9168114359ab");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
+
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
12
13
|
import * as Sentry from "@sentry/node";
|
|
13
14
|
import { SentryPropagator, SentrySampler, SentrySpanProcessor } from "@sentry/opentelemetry";
|
|
14
15
|
import { SpanStatusCode, metrics, trace } from "@opentelemetry/api";
|
|
@@ -18,7 +19,6 @@ import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
|
18
19
|
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
19
20
|
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
20
21
|
import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
21
|
-
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
22
22
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -81,26 +81,15 @@ function sanitizeSentryMcpSpan(span) {
|
|
|
81
81
|
* OTel Collector → Honeycomb: performance traces, metrics
|
|
82
82
|
*/
|
|
83
83
|
const name$1 = "hevy-mcp";
|
|
84
|
-
const version$1 = "4.1.
|
|
84
|
+
const version$1 = "4.1.1";
|
|
85
|
+
const telemetryEnabled = process.env.HEVY_MCP_TELEMETRY !== "0";
|
|
85
86
|
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
86
87
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
87
|
-
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@4.1.
|
|
88
|
+
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@4.1.1`;
|
|
88
89
|
const resource = resourceFromAttributes({
|
|
89
90
|
"service.name": name$1,
|
|
90
91
|
"service.version": version$1
|
|
91
92
|
});
|
|
92
|
-
const rawDsn = process.env.SENTRY_DSN ?? "https://ce696d8333b507acbf5203eb877bce0f@o4508975499575296.ingest.de.sentry.io/4509049671647312";
|
|
93
|
-
const isValidDsn = typeof rawDsn === "string" && rawDsn.length > 0 && !rawDsn.startsWith("*");
|
|
94
|
-
const sentryClient = Sentry.init({
|
|
95
|
-
dsn: isValidDsn ? rawDsn : void 0,
|
|
96
|
-
beforeSendSpan: sanitizeSentryMcpSpan,
|
|
97
|
-
release: sentryRelease,
|
|
98
|
-
tracesSampleRate: 1,
|
|
99
|
-
sendDefaultPii: false,
|
|
100
|
-
skipOpenTelemetrySetup: true,
|
|
101
|
-
registerEsmLoaderHooks: false,
|
|
102
|
-
ignoreErrors: ["EPIPE", "broken pipe"]
|
|
103
|
-
});
|
|
104
93
|
let currentUserHash;
|
|
105
94
|
var UserHashSpanProcessor = class {
|
|
106
95
|
onStart(span) {
|
|
@@ -110,37 +99,53 @@ var UserHashSpanProcessor = class {
|
|
|
110
99
|
async forceFlush() {}
|
|
111
100
|
async shutdown() {}
|
|
112
101
|
};
|
|
113
|
-
|
|
114
|
-
spanProcessors.push(new BatchSpanProcessor(new OTLPTraceExporter({
|
|
115
|
-
url: `${COLLECTOR_ENDPOINT}/traces`,
|
|
116
|
-
headers: { Authorization: `Bearer ${collectorToken}` }
|
|
117
|
-
})));
|
|
118
|
-
const tracerProvider = new NodeTracerProvider({
|
|
119
|
-
resource,
|
|
120
|
-
sampler: sentryClient ? new SentrySampler(sentryClient) : void 0,
|
|
121
|
-
spanProcessors
|
|
122
|
-
});
|
|
123
|
-
tracerProvider.register({
|
|
124
|
-
propagator: new SentryPropagator(),
|
|
125
|
-
contextManager: new Sentry.SentryContextManager()
|
|
126
|
-
});
|
|
102
|
+
let tracerProvider;
|
|
127
103
|
let meterProvider;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
104
|
+
if (telemetryEnabled) {
|
|
105
|
+
const rawDsn = process.env.SENTRY_DSN ?? "https://ce696d8333b507acbf5203eb877bce0f@o4508975499575296.ingest.de.sentry.io/4509049671647312";
|
|
106
|
+
const isValidDsn = typeof rawDsn === "string" && rawDsn.length > 0 && !rawDsn.startsWith("*");
|
|
107
|
+
const sentryClient = Sentry.init({
|
|
108
|
+
dsn: isValidDsn ? rawDsn : void 0,
|
|
109
|
+
beforeSendSpan: sanitizeSentryMcpSpan,
|
|
110
|
+
release: sentryRelease,
|
|
111
|
+
tracesSampleRate: 1,
|
|
112
|
+
sendDefaultPii: false,
|
|
113
|
+
skipOpenTelemetrySetup: true,
|
|
114
|
+
registerEsmLoaderHooks: false,
|
|
115
|
+
ignoreErrors: ["EPIPE", "broken pipe"]
|
|
116
|
+
});
|
|
117
|
+
const spanProcessors = [new UserHashSpanProcessor(), new SentrySpanProcessor()];
|
|
118
|
+
spanProcessors.push(new BatchSpanProcessor(new OTLPTraceExporter({
|
|
119
|
+
url: `${COLLECTOR_ENDPOINT}/traces`,
|
|
120
|
+
headers: { Authorization: `Bearer ${collectorToken}` }
|
|
121
|
+
})));
|
|
122
|
+
tracerProvider = new NodeTracerProvider({
|
|
123
|
+
resource,
|
|
124
|
+
sampler: sentryClient ? new SentrySampler(sentryClient) : void 0,
|
|
125
|
+
spanProcessors
|
|
126
|
+
});
|
|
127
|
+
tracerProvider.register({
|
|
128
|
+
propagator: new SentryPropagator(),
|
|
129
|
+
contextManager: new Sentry.SentryContextManager()
|
|
130
|
+
});
|
|
131
|
+
meterProvider = new MeterProvider({
|
|
132
|
+
resource,
|
|
133
|
+
readers: [new PeriodicExportingMetricReader({
|
|
134
|
+
exporter: new OTLPMetricExporter({
|
|
135
|
+
url: `${COLLECTOR_ENDPOINT}/metrics`,
|
|
136
|
+
headers: { Authorization: `Bearer ${collectorToken}` }
|
|
137
|
+
}),
|
|
138
|
+
exportIntervalMillis: 1e4
|
|
139
|
+
})]
|
|
140
|
+
});
|
|
141
|
+
metrics.setGlobalMeterProvider(meterProvider);
|
|
142
|
+
trace.setGlobalTracerProvider(tracerProvider);
|
|
143
|
+
Sentry.validateOpenTelemetrySetup();
|
|
144
|
+
}
|
|
141
145
|
async function flushTelemetry(timeoutMs = 1e3) {
|
|
146
|
+
if (!telemetryEnabled) return;
|
|
142
147
|
const flushPromise = Promise.allSettled([
|
|
143
|
-
tracerProvider.forceFlush(),
|
|
148
|
+
...tracerProvider ? [tracerProvider.forceFlush()] : [],
|
|
144
149
|
...meterProvider ? [meterProvider.forceFlush()] : [],
|
|
145
150
|
Sentry.flush(timeoutMs)
|
|
146
151
|
]);
|
|
@@ -156,8 +161,12 @@ async function flushTelemetry(timeoutMs = 1e3) {
|
|
|
156
161
|
}
|
|
157
162
|
const tracer = trace.getTracer(name$1);
|
|
158
163
|
const meter = metrics.getMeter(name$1);
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
const SENTRY_USER_ID_CONTEXT = "hevy-mcp:sentry-user-id:v1";
|
|
165
|
+
function setTelemetryUser(apiKey) {
|
|
166
|
+
if (!telemetryEnabled) return;
|
|
167
|
+
const userHash = createHmac("sha256", apiKey).update(SENTRY_USER_ID_CONTEXT).digest("hex").slice(0, 10);
|
|
168
|
+
currentUserHash = userHash;
|
|
169
|
+
Sentry.setUser({ id: userHash });
|
|
161
170
|
}
|
|
162
171
|
//#endregion
|
|
163
172
|
//#region src/utils/metrics.ts
|
|
@@ -2586,7 +2595,7 @@ function registerHevyResources(server, runtime) {
|
|
|
2586
2595
|
//#endregion
|
|
2587
2596
|
//#region ../core/src/server-metadata.ts
|
|
2588
2597
|
const SERVER_NAME = "hevy-mcp";
|
|
2589
|
-
const SERVER_VERSION = "4.1.
|
|
2598
|
+
const SERVER_VERSION = "4.1.1";
|
|
2590
2599
|
const SERVER_INSTRUCTIONS = [
|
|
2591
2600
|
"Hevy MCP connects clients to the authenticated user's Hevy workout-tracking data, including workouts, routines, exercise templates, routine folders, body measurements, and profile information. HEVY_API_KEY must contain a valid Hevy API key for local stdio use.",
|
|
2592
2601
|
"Safety: all get-* and search-* tools are read-only. create-* and update-* tools mutate Hevy data. Creates are additive and non-idempotent, so repeating one can create duplicates. Updates can overwrite existing data. Delete operations are not available.",
|
|
@@ -5542,6 +5551,7 @@ const HELP_TEXT = [
|
|
|
5542
5551
|
" HEVY_API_KEY=<api-key> Hevy API key from Hevy app settings",
|
|
5543
5552
|
" HEVY_MCP_DEBUG=1 Enable verbose diagnostics on stderr",
|
|
5544
5553
|
" HEVY_MCP_HTTP_BEARER_TOKEN Protect non-loopback HTTP deployments",
|
|
5554
|
+
" HEVY_MCP_TELEMETRY=0 Disable all project telemetry",
|
|
5545
5555
|
"",
|
|
5546
5556
|
"Examples:",
|
|
5547
5557
|
" HEVY_API_KEY=your-key npx hevy-mcp",
|
|
@@ -5570,10 +5580,6 @@ const SAFE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
5570
5580
|
"ETIMEDOUT",
|
|
5571
5581
|
"HEVY_RETRY_EXHAUSTED"
|
|
5572
5582
|
]);
|
|
5573
|
-
const SENTRY_USER_ID_CONTEXT = "hevy-mcp:sentry-user-id:v1";
|
|
5574
|
-
function fingerprintApiKey(apiKey) {
|
|
5575
|
-
return createHmac("sha256", apiKey).update(SENTRY_USER_ID_CONTEXT).digest("hex").slice(0, 10);
|
|
5576
|
-
}
|
|
5577
5583
|
const serverConfigSchema = z.object({ apiKey: z.string().min(1, "Hevy API key is required").describe("Your Hevy API key (available in the Hevy app settings).") });
|
|
5578
5584
|
function getHttpStatus(error) {
|
|
5579
5585
|
if (isHevyHttpError(error)) return error.status;
|
|
@@ -5638,9 +5644,7 @@ function buildServer(apiKey, transport = "stdio") {
|
|
|
5638
5644
|
}
|
|
5639
5645
|
async function createNodeMcpServer({ apiKey }, transport = "stdio") {
|
|
5640
5646
|
const { apiKey: validatedApiKey } = serverConfigSchema.parse({ apiKey });
|
|
5641
|
-
|
|
5642
|
-
setCurrentUserHash(userHash);
|
|
5643
|
-
Sentry.setUser({ id: userHash });
|
|
5647
|
+
setTelemetryUser(validatedApiKey);
|
|
5644
5648
|
await validateApiKey(validatedApiKey);
|
|
5645
5649
|
return buildServer(validatedApiKey, transport);
|
|
5646
5650
|
}
|
|
@@ -5656,11 +5660,7 @@ async function runStdioServer() {
|
|
|
5656
5660
|
}
|
|
5657
5661
|
serverStartups.add(1, { version });
|
|
5658
5662
|
const configuredApiKey = process.env.HEVY_API_KEY;
|
|
5659
|
-
|
|
5660
|
-
if (initialUserHash) {
|
|
5661
|
-
setCurrentUserHash(initialUserHash);
|
|
5662
|
-
Sentry.setUser({ id: initialUserHash });
|
|
5663
|
-
}
|
|
5663
|
+
if (configuredApiKey) setTelemetryUser(configuredApiKey);
|
|
5664
5664
|
let connectAttempted = false;
|
|
5665
5665
|
await tracer.startActiveSpan("mcp.server.run", { attributes: { "mcp.transport": "stdio" } }, async (span) => {
|
|
5666
5666
|
try {
|
|
@@ -5724,6 +5724,7 @@ async function runServer() {
|
|
|
5724
5724
|
try {
|
|
5725
5725
|
const cfg = parseConfig(process.env);
|
|
5726
5726
|
assertApiKey(cfg.apiKey);
|
|
5727
|
+
setTelemetryUser(cfg.apiKey);
|
|
5727
5728
|
await validateApiKey(cfg.apiKey);
|
|
5728
5729
|
const handle = await startStreamableHttpServer(options, cfg.apiKey, (params) => Promise.resolve(buildServer(params.apiKey, "http")));
|
|
5729
5730
|
listening = true;
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/chrisdoc/hevy-mcp",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "4.1.
|
|
10
|
+
"version": "4.1.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "hevy-mcp",
|
|
15
|
-
"version": "4.1.
|
|
15
|
+
"version": "4.1.1",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|