hevy-mcp 6.1.0 → 6.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
CHANGED
|
@@ -80,7 +80,7 @@ so your client does not need Node.js, Bun, Docker, or a local server process.
|
|
|
80
80
|
Production URL:
|
|
81
81
|
|
|
82
82
|
```text
|
|
83
|
-
https://hevy.
|
|
83
|
+
https://mcp.hevy-mcp.dev/mcp
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
The endpoint uses Streamable HTTP. Send your Hevy API key as a bearer token on
|
|
@@ -95,7 +95,7 @@ Codex, then add the hosted server:
|
|
|
95
95
|
```bash
|
|
96
96
|
export HEVY_API_KEY=your-hevy-api-key
|
|
97
97
|
codex mcp add hevy \
|
|
98
|
-
--url https://hevy.
|
|
98
|
+
--url https://mcp.hevy-mcp.dev/mcp \
|
|
99
99
|
--bearer-token-env-var HEVY_API_KEY
|
|
100
100
|
```
|
|
101
101
|
|
|
@@ -111,7 +111,7 @@ Clients that accept a remote MCP URL and fixed headers commonly use this shape:
|
|
|
111
111
|
{
|
|
112
112
|
"mcpServers": {
|
|
113
113
|
"hevy": {
|
|
114
|
-
"url": "https://hevy.
|
|
114
|
+
"url": "https://mcp.hevy-mcp.dev/mcp",
|
|
115
115
|
"headers": {
|
|
116
116
|
"Authorization": "Bearer your-hevy-api-key"
|
|
117
117
|
}
|
|
@@ -363,7 +363,7 @@ corresponding delete tools.
|
|
|
363
363
|
The production MCP server is live at:
|
|
364
364
|
|
|
365
365
|
```text
|
|
366
|
-
https://hevy.
|
|
366
|
+
https://mcp.hevy-mcp.dev/mcp
|
|
367
367
|
```
|
|
368
368
|
|
|
369
369
|
It is the quickest way to use `hevy-mcp`: there is nothing to install or keep
|
|
@@ -377,7 +377,7 @@ Clients must send their Hevy API key as a fixed authorization header:
|
|
|
377
377
|
{
|
|
378
378
|
"mcpServers": {
|
|
379
379
|
"hevy": {
|
|
380
|
-
"url": "https://hevy.
|
|
380
|
+
"url": "https://mcp.hevy-mcp.dev/mcp",
|
|
381
381
|
"headers": {
|
|
382
382
|
"Authorization": "Bearer your-hevy-api-key"
|
|
383
383
|
}
|
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-CQ5qda5F.mjs";
|
|
12
|
+
import { a as createSafeErrorDiagnostic } from "./src-c7i9L8Mm.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-c7i9L8Mm.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-CQ5qda5F.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-CQ5qda5F.mjs").then((n) => n.n);
|
|
44
44
|
return run();
|
|
45
45
|
}
|
|
46
46
|
//#endregion
|
|
@@ -5,10 +5,10 @@
|
|
|
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] = "c292bf26-255c-46b3-9cb2-3343afe7b7ce", e._sentryDebugIdIdentifier = "sentry-dbid-c292bf26-255c-46b3-9cb2-3343afe7b7ce");
|
|
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-c7i9L8Mm.mjs";
|
|
12
12
|
import { ZodError, z } from "zod";
|
|
13
13
|
import { deserializeMessage } from "@modelcontextprotocol/server";
|
|
14
14
|
import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -69,6 +69,7 @@ function removeHomePath(value) {
|
|
|
69
69
|
const home = process.env.HOME?.trim();
|
|
70
70
|
return (home ? value.replace(new RegExp(escapeRegExp(home), "g"), "~") : value).replace(/\/(?:Users|home)\/[^/\s]+/g, "~");
|
|
71
71
|
}
|
|
72
|
+
const EMAIL = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
|
|
72
73
|
function removeControlCharacters(value) {
|
|
73
74
|
let output = "";
|
|
74
75
|
let inEscapeSequence = false;
|
|
@@ -90,7 +91,7 @@ function removeControlCharacters(value) {
|
|
|
90
91
|
}
|
|
91
92
|
/** Remove common credentials and URL payloads without inspecting object fields. */
|
|
92
93
|
function sanitizeDiagnosticText(value, maxLength = MAX_MESSAGE_LENGTH) {
|
|
93
|
-
return truncate(removeHomePath(removeControlCharacters(value).replace(/\bBearer\s+[^\s,;]+/gi, "Bearer [REDACTED]").replace(/\b(api[-_ ]?key|authorization|password|secret|token)\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi, "$1=[REDACTED]").replace(/\bhttps?:\/\/[^\s)<>]+/gi, "[URL]")).trim(), maxLength);
|
|
94
|
+
return truncate(removeHomePath(removeControlCharacters(value).replace(/\bBearer\s+[^\s,;]+/gi, "Bearer [REDACTED]").replace(/\b(api[-_ ]?key|authorization|password|secret|token)\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi, "$1=[REDACTED]").replace(EMAIL, "[EMAIL_REDACTED]").replace(/\bhttps?:\/\/[^\s)<>]+/gi, "[URL]")).trim(), maxLength);
|
|
94
95
|
}
|
|
95
96
|
function sanitizeAttributeValue(_key, value) {
|
|
96
97
|
if (typeof value !== "string") return value;
|
|
@@ -162,6 +163,7 @@ function normalizeFailure(error, context) {
|
|
|
162
163
|
const text = getExceptionText(error);
|
|
163
164
|
const message = DIAGNOSTIC_DETAILS_ENABLED && text.message ? sanitizeDiagnosticText(text.message) : void 0;
|
|
164
165
|
const stack = DIAGNOSTIC_DETAILS_ENABLED && text.stack ? sanitizeDiagnosticText(text.stack, MAX_STACK_LENGTH) : void 0;
|
|
166
|
+
const responseError = DIAGNOSTIC_DETAILS_ENABLED && isHevyHttpError(error) && error.responseError ? sanitizeDiagnosticText(error.responseError, MAX_ATTRIBUTE_LENGTH) : void 0;
|
|
165
167
|
attributes["exception.type"] = exceptionType;
|
|
166
168
|
addErrorAttributes(attributes, diagnostic, context.expected);
|
|
167
169
|
addHttpAttributes(attributes, diagnostic);
|
|
@@ -171,6 +173,7 @@ function normalizeFailure(error, context) {
|
|
|
171
173
|
exceptionType,
|
|
172
174
|
...message ? { message } : {},
|
|
173
175
|
...stack ? { stack } : {},
|
|
176
|
+
...responseError ? { responseError } : {},
|
|
174
177
|
exception: {
|
|
175
178
|
name: exceptionType,
|
|
176
179
|
...message ? { message } : {},
|
|
@@ -289,13 +292,17 @@ function captureFailure(error, context) {
|
|
|
289
292
|
scope.setFingerprint([...record.fingerprint]);
|
|
290
293
|
scope.setContext("mcp", {
|
|
291
294
|
kind: context.kind,
|
|
292
|
-
...record.attributes
|
|
295
|
+
...record.attributes,
|
|
296
|
+
...record.responseError ? { "hevy.api.response_error": record.responseError } : {}
|
|
293
297
|
});
|
|
294
298
|
return Sentry.captureException(createSentryError(record));
|
|
295
299
|
});
|
|
296
300
|
} catch {}
|
|
297
301
|
if (span) try {
|
|
298
|
-
if (!duplicate && !context.expected)
|
|
302
|
+
if (!duplicate && !context.expected) {
|
|
303
|
+
span.recordException(record.exception);
|
|
304
|
+
if (record.responseError) span.addEvent("mcp.failure.detail", { "hevy.api.response_error": record.responseError });
|
|
305
|
+
}
|
|
299
306
|
setSpanAttributes(span, record.attributes);
|
|
300
307
|
if (!context.expected) span.setStatus({ code: SpanStatusCode.ERROR });
|
|
301
308
|
if (eventId) span.setAttribute("sentry.event_id", eventId);
|
|
@@ -358,7 +365,7 @@ function installProcessExceptionTracking(processLike = process) {
|
|
|
358
365
|
};
|
|
359
366
|
}
|
|
360
367
|
const name$1 = "hevy-mcp";
|
|
361
|
-
const version$1 = "6.1.
|
|
368
|
+
const version$1 = "6.1.1";
|
|
362
369
|
const telemetryEnabled = process.env.HEVY_MCP_TELEMETRY !== "0";
|
|
363
370
|
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
364
371
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
@@ -1237,6 +1244,9 @@ function safeErrorAttributes(observation) {
|
|
|
1237
1244
|
...code && SAFE_OBSERVATION_CODES.has(code) ? { error_code: code } : {}
|
|
1238
1245
|
};
|
|
1239
1246
|
}
|
|
1247
|
+
function getDiagnosticResponseError(observation) {
|
|
1248
|
+
return process.env.HEVY_MCP_TELEMETRY_DIAGNOSTICS === "0" ? void 0 : observation.error?.response_error;
|
|
1249
|
+
}
|
|
1240
1250
|
function startApiSpan(start) {
|
|
1241
1251
|
const sessionId = getCurrentMcpSessionId();
|
|
1242
1252
|
const diagnosticEndpoint = diagnosticEndpointIdentity(start.endpoint);
|
|
@@ -1256,10 +1266,14 @@ function finishApiSpan(span, observation) {
|
|
|
1256
1266
|
if (observation.expectedReason) span.setAttribute("hevy.api.expected_reason", observation.expectedReason);
|
|
1257
1267
|
for (const [key, value] of Object.entries(errorAttributes)) span.setAttribute(key, value);
|
|
1258
1268
|
span.setStatus({ code: observation.outcome === "success" || observation.outcome === "expected" ? SpanStatusCode.OK : SpanStatusCode.ERROR });
|
|
1259
|
-
if (observation.outcome !== "success" && observation.outcome !== "expected")
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1269
|
+
if (observation.outcome !== "success" && observation.outcome !== "expected") {
|
|
1270
|
+
const responseError = getDiagnosticResponseError(observation);
|
|
1271
|
+
span.addEvent("hevy.api.failure", {
|
|
1272
|
+
"error.category": errorAttributes.error_category ?? "HevyHttpError",
|
|
1273
|
+
...errorAttributes.error_code ? { "error.code": errorAttributes.error_code } : {},
|
|
1274
|
+
...responseError ? { "hevy.api.response_error": responseError } : {}
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1263
1277
|
span.end();
|
|
1264
1278
|
}
|
|
1265
1279
|
/** Node-only adapter; the Worker graph never imports telemetry or metrics. */
|
|
@@ -1283,6 +1297,7 @@ function createNodeHevyClientOptions() {
|
|
|
1283
1297
|
onRequestComplete(observation) {
|
|
1284
1298
|
const retryCountBucket = bucketCount(observation.retryCount);
|
|
1285
1299
|
const errorAttributes = safeErrorAttributes(observation);
|
|
1300
|
+
const responseError = getDiagnosticResponseError(observation);
|
|
1286
1301
|
const metricEndpoint = metricEndpointIdentity(observation.endpoint);
|
|
1287
1302
|
const diagnosticEndpoint = diagnosticEndpointIdentity(observation.endpoint);
|
|
1288
1303
|
const metricExecutionAttributes = projectExecutionAttributes(observation, "metric");
|
|
@@ -1312,6 +1327,7 @@ function createNodeHevyClientOptions() {
|
|
|
1312
1327
|
status: observation.status || null,
|
|
1313
1328
|
retryCountBucket,
|
|
1314
1329
|
outcome: observation.outcome,
|
|
1330
|
+
...responseError ? { response_error: responseError } : {},
|
|
1315
1331
|
...errorAttributes
|
|
1316
1332
|
});
|
|
1317
1333
|
},
|
|
@@ -1905,7 +1921,15 @@ function installToolCallTracking(handlers, transport) {
|
|
|
1905
1921
|
} else span.setStatus({ code: SpanStatusCode.OK });
|
|
1906
1922
|
return result;
|
|
1907
1923
|
} catch (error) {
|
|
1908
|
-
|
|
1924
|
+
const validation = error instanceof Error ? classifySdkValidation(error.message) : {
|
|
1925
|
+
kind: "unknown",
|
|
1926
|
+
expected: false
|
|
1927
|
+
};
|
|
1928
|
+
if (validation.kind === "tool_not_found") markSdkToolFailure(span, error, toolName, "validation", {
|
|
1929
|
+
expected: true,
|
|
1930
|
+
validationKind: validation.kind
|
|
1931
|
+
});
|
|
1932
|
+
else markSdkToolFailure(span, error, toolName);
|
|
1909
1933
|
throw error;
|
|
1910
1934
|
} finally {
|
|
1911
1935
|
span.end();
|
|
@@ -2503,4 +2527,4 @@ async function runServer() {
|
|
|
2503
2527
|
//#endregion
|
|
2504
2528
|
export { flushTelemetry as i, runtime_exports as n, MissingHevyApiKeyError as r, runServer as t };
|
|
2505
2529
|
|
|
2506
|
-
//# sourceMappingURL=runtime-
|
|
2530
|
+
//# sourceMappingURL=runtime-CQ5qda5F.mjs.map
|
|
@@ -291,6 +291,70 @@ const getV1WorkoutsWorkoutid200Schema = z$1.lazy(() => workoutSchema);
|
|
|
291
291
|
z$1.any();
|
|
292
292
|
z$1.lazy(() => getV1WorkoutsWorkoutid200Schema);
|
|
293
293
|
//#endregion
|
|
294
|
+
//#region ../hevy-client/src/response-error.ts
|
|
295
|
+
const MAX_RESPONSE_ERROR_INPUT_LENGTH = 4096;
|
|
296
|
+
const MAX_RESPONSE_ERROR_LENGTH = 256;
|
|
297
|
+
const RESPONSE_ERROR_KEYS = [
|
|
298
|
+
"error",
|
|
299
|
+
"message",
|
|
300
|
+
"detail"
|
|
301
|
+
];
|
|
302
|
+
const COOKIE_ASSIGNMENT = /(\b(?:cookie|set-cookie)\s*[:=]\s*)[^;\s]+/gi;
|
|
303
|
+
const SECRET_ASSIGNMENT = /(\b(?:authorization|proxy-authorization|api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|id[-_ ]?token|token|client[-_ ]?secret|password|passwd|secret|credential|signature)\b\s*[:=]\s*)(?:"[^"]*"|'[^']*'|(?:Bearer\s+)?[^\s,;}"]+)/gi;
|
|
304
|
+
const BEARER_TOKEN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
|
|
305
|
+
const JSON_WEB_TOKEN = /\beyJ[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\.[A-Za-z0-9_-]{5,}\b/g;
|
|
306
|
+
const SECRET_QUERY_PARAMETER = /([?&](?:api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|signature|password|secret)=)[^&#\s]+/gi;
|
|
307
|
+
const HTTP_URL = /\bhttps?:\/\/[^\s<>"']+/gi;
|
|
308
|
+
const EMAIL = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
|
|
309
|
+
const UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi;
|
|
310
|
+
function isResponseErrorBody(value) {
|
|
311
|
+
return typeof value === "object" && value !== null;
|
|
312
|
+
}
|
|
313
|
+
function ownValue(value, key) {
|
|
314
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
315
|
+
return descriptor && "value" in descriptor ? descriptor.value : void 0;
|
|
316
|
+
}
|
|
317
|
+
function responseErrorText(value) {
|
|
318
|
+
if (!isResponseErrorBody(value)) return void 0;
|
|
319
|
+
for (const key of RESPONSE_ERROR_KEYS) {
|
|
320
|
+
const candidate = ownValue(value, key);
|
|
321
|
+
if (typeof candidate === "string") return candidate;
|
|
322
|
+
if (!isResponseErrorBody(candidate)) continue;
|
|
323
|
+
const nestedMessage = ownValue(candidate, "message");
|
|
324
|
+
if (typeof nestedMessage === "string") return nestedMessage;
|
|
325
|
+
const nestedDetail = ownValue(candidate, "detail");
|
|
326
|
+
if (typeof nestedDetail === "string") return nestedDetail;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function removeControlCharacters(value) {
|
|
330
|
+
let output = "";
|
|
331
|
+
for (const character of value) {
|
|
332
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
333
|
+
if (codePoint <= 31 || codePoint === 127) {
|
|
334
|
+
if (codePoint === 9 || codePoint === 10 || codePoint === 13) output += " ";
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
output += character;
|
|
338
|
+
}
|
|
339
|
+
return output;
|
|
340
|
+
}
|
|
341
|
+
function truncate(value) {
|
|
342
|
+
return value.length > MAX_RESPONSE_ERROR_LENGTH ? `${value.slice(0, MAX_RESPONSE_ERROR_LENGTH - 1)}…` : value;
|
|
343
|
+
}
|
|
344
|
+
function sanitizeResponseErrorText(value) {
|
|
345
|
+
return truncate(removeControlCharacters(value.slice(0, MAX_RESPONSE_ERROR_INPUT_LENGTH)).replace(COOKIE_ASSIGNMENT, "$1[REDACTED]").replace(SECRET_ASSIGNMENT, "$1[REDACTED]").replace(BEARER_TOKEN, "Bearer [REDACTED]").replace(JSON_WEB_TOKEN, "[JWT_REDACTED]").replace(SECRET_QUERY_PARAMETER, "$1[REDACTED]").replace(HTTP_URL, "[URL_REDACTED]").replace(EMAIL, "[EMAIL_REDACTED]").replace(UUID, "[ID_REDACTED]").replace(/\s+/g, " ").trim());
|
|
346
|
+
}
|
|
347
|
+
/** Extract one bounded, sanitized diagnostic string from an upstream error body. */
|
|
348
|
+
function extractSafeResponseError(data) {
|
|
349
|
+
try {
|
|
350
|
+
const text = responseErrorText(data);
|
|
351
|
+
if (!text) return void 0;
|
|
352
|
+
return sanitizeResponseErrorText(text) || void 0;
|
|
353
|
+
} catch {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
294
358
|
//#region ../hevy-client/src/hevy-http-error.ts
|
|
295
359
|
const HEVY_RETRY_EXHAUSTED_ERROR_CODE = "HEVY_RETRY_EXHAUSTED";
|
|
296
360
|
const HEVY_REQUEST_ABORTED_ERROR_CODE = "HEVY_REQUEST_ABORTED";
|
|
@@ -300,6 +364,7 @@ var HevyHttpError = class extends Error {
|
|
|
300
364
|
status;
|
|
301
365
|
statusText;
|
|
302
366
|
data;
|
|
367
|
+
responseError;
|
|
303
368
|
headers;
|
|
304
369
|
method;
|
|
305
370
|
endpoint;
|
|
@@ -322,6 +387,7 @@ var HevyHttpError = class extends Error {
|
|
|
322
387
|
this.status = options.status;
|
|
323
388
|
this.statusText = options.statusText;
|
|
324
389
|
this.data = options.data;
|
|
390
|
+
this.responseError = extractSafeResponseError(options.data);
|
|
325
391
|
this.headers = options.headers;
|
|
326
392
|
this.method = options.method;
|
|
327
393
|
this.endpoint = options.endpoint;
|
|
@@ -1530,7 +1596,8 @@ function createFailureObservation(options, failure, error, commitState, safeToRe
|
|
|
1530
1596
|
error: {
|
|
1531
1597
|
status: error.status,
|
|
1532
1598
|
code: typeof error.code === "string" && SAFE_OBSERVATION_CODES.has(error.code) ? error.code : void 0,
|
|
1533
|
-
category: error.status === void 0 ? "NetworkError" : "HevyHttpError"
|
|
1599
|
+
category: error.status === void 0 ? "NetworkError" : "HevyHttpError",
|
|
1600
|
+
...error.responseError ? { response_error: error.responseError } : {}
|
|
1534
1601
|
}
|
|
1535
1602
|
};
|
|
1536
1603
|
}
|
|
@@ -4445,7 +4512,7 @@ function registerHevyResources(server, runtime) {
|
|
|
4445
4512
|
//#endregion
|
|
4446
4513
|
//#region ../core/src/server-metadata.ts
|
|
4447
4514
|
const SERVER_NAME = "hevy-mcp";
|
|
4448
|
-
const SERVER_VERSION = "6.1.
|
|
4515
|
+
const SERVER_VERSION = "6.1.1";
|
|
4449
4516
|
const SERVER_INSTRUCTIONS = [
|
|
4450
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.",
|
|
4451
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.",
|
|
@@ -5023,4 +5090,4 @@ function createHevyMcpServer(options) {
|
|
|
5023
5090
|
//#endregion
|
|
5024
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 };
|
|
5025
5092
|
|
|
5026
|
-
//# sourceMappingURL=src-
|
|
5093
|
+
//# sourceMappingURL=src-c7i9L8Mm.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.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "hevy-mcp",
|
|
15
|
-
"version": "6.1.
|
|
15
|
+
"version": "6.1.1",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|