hevy-mcp 1.26.4 → 1.26.6
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
|
@@ -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@1.26.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@1.26.6" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
9
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "03cf150f-6466-4ca3-9cf1-e423cc0e3cd2", e._sentryDebugIdIdentifier = "sentry-dbid-03cf150f-6466-4ca3-9cf1-e423cc0e3cd2");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
-
import { r as runServer } from "./src-
|
|
12
|
+
import { r as runServer } from "./src-B9KZiN70.mjs";
|
|
13
13
|
//#region src/cli.ts
|
|
14
14
|
runServer().catch((error) => {
|
|
15
15
|
console.error("Fatal error in main():", error);
|
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@1.26.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@1.26.6" };
|
|
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-B9KZiN70.mjs";
|
|
13
13
|
export { configSchema, createServer, createServer as default, runServer };
|
|
@@ -4,9 +4,9 @@
|
|
|
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@1.26.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@1.26.6" };
|
|
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] = "523f4f6a-5f55-463e-ace9-ee2022739238", e._sentryDebugIdIdentifier = "sentry-dbid-523f4f6a-5f55-463e-ace9-ee2022739238");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
12
|
import * as Sentry from "@sentry/node";
|
|
@@ -36,10 +36,10 @@ import { deserializeMessage } from "@modelcontextprotocol/sdk/shared/stdio.js";
|
|
|
36
36
|
* OTel Collector → Honeycomb: performance traces, metrics
|
|
37
37
|
*/
|
|
38
38
|
const name$1 = "hevy-mcp";
|
|
39
|
-
const version$1 = "1.26.
|
|
40
|
-
const collectorToken =
|
|
39
|
+
const version$1 = "1.26.6";
|
|
40
|
+
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
41
41
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
42
|
-
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@1.26.
|
|
42
|
+
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@1.26.6`;
|
|
43
43
|
const resource = resourceFromAttributes({
|
|
44
44
|
"service.name": name$1,
|
|
45
45
|
"service.version": version$1
|
|
@@ -56,7 +56,7 @@ const sentryClient = Sentry.init({
|
|
|
56
56
|
ignoreErrors: ["EPIPE", "broken pipe"]
|
|
57
57
|
});
|
|
58
58
|
const spanProcessors = [new SentrySpanProcessor()];
|
|
59
|
-
|
|
59
|
+
spanProcessors.push(new BatchSpanProcessor(new OTLPTraceExporter({
|
|
60
60
|
url: `${COLLECTOR_ENDPOINT}/traces`,
|
|
61
61
|
headers: { Authorization: `Bearer ${collectorToken}` }
|
|
62
62
|
})));
|
|
@@ -69,7 +69,7 @@ tracerProvider.register({
|
|
|
69
69
|
propagator: new SentryPropagator(),
|
|
70
70
|
contextManager: new Sentry.SentryContextManager()
|
|
71
71
|
});
|
|
72
|
-
|
|
72
|
+
{
|
|
73
73
|
const meterProvider = new MeterProvider({
|
|
74
74
|
resource,
|
|
75
75
|
readers: [new PeriodicExportingMetricReader({
|
|
@@ -258,6 +258,40 @@ function determineErrorType(error, message) {
|
|
|
258
258
|
if (nameLower.includes("api") || messageLower.includes("api") || messageLower.includes("server error") || messageLower.includes("500")) return "API_ERROR";
|
|
259
259
|
return "UNKNOWN_ERROR";
|
|
260
260
|
}
|
|
261
|
+
/** Whitelist of safe argument keys that can be logged as span attributes without exposing PII. */
|
|
262
|
+
const ARGUMENT_WHITELIST = /* @__PURE__ */ new Set([
|
|
263
|
+
"page",
|
|
264
|
+
"pageSize",
|
|
265
|
+
"since",
|
|
266
|
+
"workoutId",
|
|
267
|
+
"routineId",
|
|
268
|
+
"folderId",
|
|
269
|
+
"exerciseTemplateId",
|
|
270
|
+
"date",
|
|
271
|
+
"startDate",
|
|
272
|
+
"endDate",
|
|
273
|
+
"updatedSince",
|
|
274
|
+
"includeCustom",
|
|
275
|
+
"limit",
|
|
276
|
+
"offset",
|
|
277
|
+
"refresh",
|
|
278
|
+
"query",
|
|
279
|
+
"primaryMuscleGroup"
|
|
280
|
+
]);
|
|
281
|
+
/**
|
|
282
|
+
* Extract safe (non-PII) parameters from the tool arguments to include as span attributes.
|
|
283
|
+
*/
|
|
284
|
+
function extractSafeArgs(args) {
|
|
285
|
+
const attributes = {};
|
|
286
|
+
for (const [key, value] of Object.entries(args)) if (ARGUMENT_WHITELIST.has(key)) {
|
|
287
|
+
const type = typeof value;
|
|
288
|
+
if (type === "string" || type === "number" || type === "boolean") if (key === "query" && type === "string") {
|
|
289
|
+
const strVal = value;
|
|
290
|
+
attributes[`mcp.tool.args.${key}`] = strVal.length > 100 ? `${strVal.slice(0, 100)}...` : strVal;
|
|
291
|
+
} else attributes[`mcp.tool.args.${key}`] = value;
|
|
292
|
+
}
|
|
293
|
+
return attributes;
|
|
294
|
+
}
|
|
261
295
|
/**
|
|
262
296
|
* Wrap an async function with standardized error handling
|
|
263
297
|
*
|
|
@@ -270,25 +304,41 @@ function determineErrorType(error, message) {
|
|
|
270
304
|
* @returns A function that catches errors and returns standardized error responses
|
|
271
305
|
*/
|
|
272
306
|
function withErrorHandling(fn, context) {
|
|
273
|
-
return async (
|
|
307
|
+
return async (rawArgs) => {
|
|
308
|
+
const args = rawArgs ?? {};
|
|
274
309
|
const argumentKeyCount = Object.keys(args).length;
|
|
275
310
|
const startTime = Date.now();
|
|
276
311
|
toolInvocations.add(1, { tool_name: context });
|
|
312
|
+
const userId = getCurrentUserId();
|
|
313
|
+
const safeArgs = extractSafeArgs(args);
|
|
314
|
+
const whitelistedKeys = Object.keys(safeArgs).map((k) => k.replace("mcp.tool.args.", ""));
|
|
277
315
|
return tracer.startActiveSpan(`mcp.tool.${context}`, { attributes: {
|
|
278
316
|
"mcp.tool.name": context,
|
|
279
317
|
"mcp.tool.args.key_count": argumentKeyCount,
|
|
280
|
-
|
|
318
|
+
"mcp.tool.args.keys": whitelistedKeys.join(","),
|
|
319
|
+
...userId ? { "user.id": userId } : {},
|
|
320
|
+
...safeArgs
|
|
281
321
|
} }, async (span) => {
|
|
322
|
+
let isError = false;
|
|
282
323
|
try {
|
|
283
324
|
const result = await fn(args);
|
|
284
|
-
|
|
285
|
-
span.
|
|
325
|
+
isError = Boolean(result.isError);
|
|
326
|
+
span.setStatus({ code: isError ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
327
|
+
span.setAttribute("mcp.tool.result.is_error", isError);
|
|
328
|
+
if (result.content) {
|
|
329
|
+
span.setAttribute("mcp.tool.result.content_count", result.content.length);
|
|
330
|
+
const textLength = result.content.reduce((sum, item) => sum + (item.text?.length ?? 0), 0);
|
|
331
|
+
span.setAttribute("mcp.tool.result.text_length", textLength);
|
|
332
|
+
}
|
|
286
333
|
return result;
|
|
287
334
|
} catch (error) {
|
|
335
|
+
isError = true;
|
|
288
336
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
289
337
|
span.recordException(error);
|
|
290
338
|
const errorType = determineErrorType(error, error instanceof Error ? error.message : String(error));
|
|
291
339
|
span.setAttribute("error.type", errorType);
|
|
340
|
+
const rawCode = error instanceof Error && "code" in error ? error.code : void 0;
|
|
341
|
+
if (rawCode !== void 0 && rawCode !== null) span.setAttribute("error.code", String(rawCode));
|
|
292
342
|
toolErrors.add(1, {
|
|
293
343
|
tool_name: context,
|
|
294
344
|
error_type: errorType
|
|
@@ -303,7 +353,10 @@ function withErrorHandling(fn, context) {
|
|
|
303
353
|
});
|
|
304
354
|
return createErrorResponse(error, context);
|
|
305
355
|
} finally {
|
|
306
|
-
toolDuration.record(Date.now() - startTime, {
|
|
356
|
+
toolDuration.record(Date.now() - startTime, {
|
|
357
|
+
tool_name: context,
|
|
358
|
+
is_error: String(isError)
|
|
359
|
+
});
|
|
307
360
|
span.end();
|
|
308
361
|
}
|
|
309
362
|
});
|
|
@@ -2371,7 +2424,7 @@ function getCliAction(args) {
|
|
|
2371
2424
|
const HEVY_API_BASEURL = "https://api.hevyapp.com";
|
|
2372
2425
|
const SENTRY_USER_ID_CONTEXT = "hevy-mcp:sentry-user-id:v1";
|
|
2373
2426
|
function fingerprintApiKey(apiKey) {
|
|
2374
|
-
return createHmac("sha256", apiKey).update(SENTRY_USER_ID_CONTEXT).digest("hex");
|
|
2427
|
+
return createHmac("sha256", apiKey).update(SENTRY_USER_ID_CONTEXT).digest("hex").slice(0, 10);
|
|
2375
2428
|
}
|
|
2376
2429
|
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).") });
|
|
2377
2430
|
const configSchema = serverConfigSchema;
|
|
@@ -2467,4 +2520,4 @@ async function runServer() {
|
|
|
2467
2520
|
//#endregion
|
|
2468
2521
|
export { createServer as n, runServer as r, configSchema as t };
|
|
2469
2522
|
|
|
2470
|
-
//# sourceMappingURL=src-
|
|
2523
|
+
//# sourceMappingURL=src-B9KZiN70.mjs.map
|