hevy-mcp 6.1.1 → 6.1.2
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/dist/cli.mjs
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "d805d34c-9cce-4622-8b67-728aa0cacb5d", e._sentryDebugIdIdentifier = "sentry-dbid-d805d34c-9cce-4622-8b67-728aa0cacb5d");
|
|
9
9
|
} catch (e) {}
|
|
10
10
|
})();
|
|
11
|
-
import { i as flushTelemetry, r as MissingHevyApiKeyError, t as runServer } from "./runtime-
|
|
12
|
-
import { a as createSafeErrorDiagnostic } from "./src-
|
|
11
|
+
import { i as flushTelemetry, r as MissingHevyApiKeyError, t as runServer } from "./runtime-C0tBW0Rj.mjs";
|
|
12
|
+
import { a as createSafeErrorDiagnostic } from "./src-ITv7b8-Y.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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Generated with tsdown
|
|
3
3
|
// https://tsdown.dev
|
|
4
|
-
import { o as createHevyClient, t as createHevyMcpServer } from "./src-
|
|
4
|
+
import { o as createHevyClient, t as createHevyMcpServer } from "./src-ITv7b8-Y.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
//#region src/index.ts
|
|
7
7
|
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).") });
|
|
@@ -32,7 +32,7 @@ function createNodeMcpServer({ apiKey }, _transport = "stdio", lifecycleSignal)
|
|
|
32
32
|
* does not evaluate the runtime bootstrap; it is loaded only when invoked.
|
|
33
33
|
*/
|
|
34
34
|
async function runStdioServer() {
|
|
35
|
-
const { runStdioServer: run } = await import("./runtime-
|
|
35
|
+
const { runStdioServer: run } = await import("./runtime-C0tBW0Rj.mjs").then((n) => n.n);
|
|
36
36
|
return run();
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
@@ -40,7 +40,7 @@ async function runStdioServer() {
|
|
|
40
40
|
* does not evaluate the runtime bootstrap; it is loaded only when invoked.
|
|
41
41
|
*/
|
|
42
42
|
async function runServer() {
|
|
43
|
-
const { runServer: run } = await import("./runtime-
|
|
43
|
+
const { runServer: run } = await import("./runtime-C0tBW0Rj.mjs").then((n) => n.n);
|
|
44
44
|
return run();
|
|
45
45
|
}
|
|
46
46
|
//#endregion
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
7
|
var n = new e.Error().stack;
|
|
8
|
-
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "
|
|
8
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "74fe8f19-5598-43b9-8f97-71b400eea539", e._sentryDebugIdIdentifier = "sentry-dbid-74fe8f19-5598-43b9-8f97-71b400eea539");
|
|
9
9
|
} catch (e) {}
|
|
10
10
|
})();
|
|
11
|
-
import { a as createSafeErrorDiagnostic, c as diagnosticEndpointIdentity, i as bucketCount, l as metricEndpointIdentity, n as createExecutionProjection, o as createHevyClient, r as mergeAbortSignals, s as SAFE_OBSERVATION_CODES, t as createHevyMcpServer, u as isHevyHttpError } from "./src-
|
|
11
|
+
import { a as createSafeErrorDiagnostic, c as diagnosticEndpointIdentity, i as bucketCount, l as metricEndpointIdentity, n as createExecutionProjection, o as createHevyClient, r as mergeAbortSignals, s as SAFE_OBSERVATION_CODES, t as createHevyMcpServer, u as isHevyHttpError } from "./src-ITv7b8-Y.mjs";
|
|
12
12
|
import { ZodError, z } from "zod";
|
|
13
13
|
import { deserializeMessage } from "@modelcontextprotocol/server";
|
|
14
|
-
import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
14
|
+
import { createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
15
15
|
import * as Sentry from "@sentry/node";
|
|
16
16
|
import { SpanStatusCode, context, metrics, trace } from "@opentelemetry/api";
|
|
17
17
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
@@ -365,7 +365,7 @@ function installProcessExceptionTracking(processLike = process) {
|
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
367
|
const name$1 = "hevy-mcp";
|
|
368
|
-
const version$1 = "6.1.
|
|
368
|
+
const version$1 = "6.1.2";
|
|
369
369
|
const telemetryEnabled = process.env.HEVY_MCP_TELEMETRY !== "0";
|
|
370
370
|
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
371
371
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
@@ -1364,6 +1364,7 @@ function createNodeCacheObserver() {
|
|
|
1364
1364
|
//#endregion
|
|
1365
1365
|
//#region src/utils/tool-observer.ts
|
|
1366
1366
|
const DISCOVERY_TOOL_NAMES = /* @__PURE__ */ new Set(["search-routines"]);
|
|
1367
|
+
const SAFE_USER_HASH_PATTERN = /^[0-9a-f]{10}$/u;
|
|
1367
1368
|
const WORKFLOW_PAGINATION_RESOURCES = /* @__PURE__ */ new Set([
|
|
1368
1369
|
"workouts",
|
|
1369
1370
|
"bodyMeasurements",
|
|
@@ -1384,7 +1385,7 @@ function metricAttributes(invocation, clientAttributes) {
|
|
|
1384
1385
|
...clientAttributes
|
|
1385
1386
|
};
|
|
1386
1387
|
}
|
|
1387
|
-
function createAttributes(invocation) {
|
|
1388
|
+
function createAttributes(invocation, userHash) {
|
|
1388
1389
|
const clientMetadata = getCurrentMcpClientMetadata();
|
|
1389
1390
|
const isPrompt = invocation.kind === "prompt";
|
|
1390
1391
|
const sessionId = getCurrentMcpSessionId();
|
|
@@ -1397,6 +1398,7 @@ function createAttributes(invocation) {
|
|
|
1397
1398
|
"mcp.client.version": clientMetadata.version,
|
|
1398
1399
|
"mcp.protocol.version": clientMetadata.protocolVersion,
|
|
1399
1400
|
"mcp.transport": getCurrentMcpTransport(),
|
|
1401
|
+
...userHash ? { "user.hash": userHash } : {},
|
|
1400
1402
|
"mcp.tool.args.key_count_bucket": invocation.argumentKeyCountBucket ?? "unknown",
|
|
1401
1403
|
"mcp.tool.args.keys": invocation.argumentKeys?.join(",") ?? "",
|
|
1402
1404
|
...sessionId ? { "mcp.session.id": sessionId } : {}
|
|
@@ -1452,7 +1454,8 @@ function bestEffort(operation) {
|
|
|
1452
1454
|
} catch {}
|
|
1453
1455
|
}
|
|
1454
1456
|
/** Node-only adapter from core's privacy-safe observation contract to OTel. */
|
|
1455
|
-
function createNodeToolObserver() {
|
|
1457
|
+
function createNodeToolObserver(options = {}) {
|
|
1458
|
+
const userHash = typeof options.userHash === "string" && SAFE_USER_HASH_PATTERN.test(options.userHash) ? options.userHash : void 0;
|
|
1456
1459
|
return { start(invocation) {
|
|
1457
1460
|
const startedAt = Date.now();
|
|
1458
1461
|
const metrics = metricAttributes(invocation, recordMcpToolInvocation());
|
|
@@ -1462,7 +1465,7 @@ function createNodeToolObserver() {
|
|
|
1462
1465
|
let thrownError;
|
|
1463
1466
|
return {
|
|
1464
1467
|
run(operation) {
|
|
1465
|
-
return tracer.startActiveSpan(`mcp.tool.${invocation.name}`, { attributes: createAttributes(invocation) }, async (span) => {
|
|
1468
|
+
return tracer.startActiveSpan(`mcp.tool.${invocation.name}`, { attributes: createAttributes(invocation, userHash) }, async (span) => {
|
|
1466
1469
|
activeSpan = span;
|
|
1467
1470
|
try {
|
|
1468
1471
|
return await operation();
|
|
@@ -1528,6 +1531,22 @@ function createNodeToolObserver() {
|
|
|
1528
1531
|
} };
|
|
1529
1532
|
}
|
|
1530
1533
|
//#endregion
|
|
1534
|
+
//#region src/utils/user-hash.ts
|
|
1535
|
+
const USER_HASH_CONTEXT = "hevy-mcp:sentry-user-id:v1";
|
|
1536
|
+
const USER_HASH_LENGTH = 10;
|
|
1537
|
+
/**
|
|
1538
|
+
* Derive the short, deterministic HMAC pseudonym shared with the Worker
|
|
1539
|
+
* telemetry contract without exporting or logging the caller's Hevy API key.
|
|
1540
|
+
*/
|
|
1541
|
+
function createNodeUserHash(apiKey) {
|
|
1542
|
+
if (apiKey.length === 0) return void 0;
|
|
1543
|
+
try {
|
|
1544
|
+
return createHmac("sha256", apiKey).update(USER_HASH_CONTEXT, "utf8").digest("hex").slice(0, USER_HASH_LENGTH);
|
|
1545
|
+
} catch {
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
//#endregion
|
|
1531
1550
|
//#region src/utils/stdio-observability.ts
|
|
1532
1551
|
const UTF8_BOM = "";
|
|
1533
1552
|
/** Maximum escaped characters included in a malformed stdin shape preview. */
|
|
@@ -2424,7 +2443,7 @@ function buildServer(apiKey, transport = "stdio", lifecycleSignal) {
|
|
|
2424
2443
|
}),
|
|
2425
2444
|
lifecycleSignal,
|
|
2426
2445
|
onToolsRegistered: (count) => span.setAttribute("mcp.tools.count", count),
|
|
2427
|
-
observer: createNodeToolObserver(),
|
|
2446
|
+
observer: createNodeToolObserver({ userHash: createNodeUserHash(apiKey) }),
|
|
2428
2447
|
cacheObserver: createNodeCacheObserver()
|
|
2429
2448
|
});
|
|
2430
2449
|
installSdkErrorTracking(server, transport);
|
|
@@ -2527,4 +2546,4 @@ async function runServer() {
|
|
|
2527
2546
|
//#endregion
|
|
2528
2547
|
export { flushTelemetry as i, runtime_exports as n, MissingHevyApiKeyError as r, runServer as t };
|
|
2529
2548
|
|
|
2530
|
-
//# sourceMappingURL=runtime-
|
|
2549
|
+
//# sourceMappingURL=runtime-C0tBW0Rj.mjs.map
|
|
@@ -4512,7 +4512,7 @@ function registerHevyResources(server, runtime) {
|
|
|
4512
4512
|
//#endregion
|
|
4513
4513
|
//#region ../core/src/server-metadata.ts
|
|
4514
4514
|
const SERVER_NAME = "hevy-mcp";
|
|
4515
|
-
const SERVER_VERSION = "6.1.
|
|
4515
|
+
const SERVER_VERSION = "6.1.2";
|
|
4516
4516
|
const SERVER_INSTRUCTIONS = [
|
|
4517
4517
|
"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.",
|
|
4518
4518
|
"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.",
|
|
@@ -5090,4 +5090,4 @@ function createHevyMcpServer(options) {
|
|
|
5090
5090
|
//#endregion
|
|
5091
5091
|
export { createSafeErrorDiagnostic as a, diagnosticEndpointIdentity as c, bucketCount as i, metricEndpointIdentity as l, createExecutionProjection as n, createHevyClient as o, mergeAbortSignals as r, SAFE_OBSERVATION_CODES as s, createHevyMcpServer as t, isHevyHttpError as u };
|
|
5092
5092
|
|
|
5093
|
-
//# sourceMappingURL=src-
|
|
5093
|
+
//# sourceMappingURL=src-ITv7b8-Y.mjs.map
|
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": "6.1.
|
|
10
|
+
"version": "6.1.2",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "hevy-mcp",
|
|
15
|
-
"version": "6.1.
|
|
15
|
+
"version": "6.1.2",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|