hevy-mcp 6.1.13 → 6.1.14
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# hevy-mcp
|
|
2
2
|
|
|
3
|
+
## 6.1.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1168](https://github.com/chrisdoc/hevy-mcp/pull/1168) [`6e61a84`](https://github.com/chrisdoc/hevy-mcp/commit/6e61a8439bf21bd74e74ee848c8ae5fdac78a52f) Thanks [@chrisdoc](https://github.com/chrisdoc)! - Expose string enum values for workout set RPE in tool input schemas to support Google Gemini and Vertex AI FunctionDeclaration validation, casting back to numeric values for downstream API calls.
|
|
8
|
+
|
|
9
|
+
- [#1165](https://github.com/chrisdoc/hevy-mcp/pull/1165) [`f35465e`](https://github.com/chrisdoc/hevy-mcp/commit/f35465e55023b9d77af993d674e5e218a3424785) Thanks [@dependabot](https://github.com/apps/dependabot)! - Regenerate the Hevy client with the updated Kubb toolchain.
|
|
10
|
+
|
|
11
|
+
- [#1168](https://github.com/chrisdoc/hevy-mcp/pull/1168) [`6e61a84`](https://github.com/chrisdoc/hevy-mcp/commit/6e61a8439bf21bd74e74ee848c8ae5fdac78a52f) Thanks [@chrisdoc](https://github.com/chrisdoc)! - Expose the client's maxGetRetries option through createNodeMcpServer. Embedders can set it to zero to disable automatic request retries, including PUT retries, and reconcile uncertain writes explicitly. Omitting the option preserves the existing client policy.
|
|
12
|
+
|
|
3
13
|
## 6.1.13
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/cli.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "d637b259-c547-4286-9669-7b858825b504", e._sentryDebugIdIdentifier = "sentry-dbid-d637b259-c547-4286-9669-7b858825b504");
|
|
9
9
|
} catch (e) {}
|
|
10
10
|
})();
|
|
11
|
-
import { i as handleFatalStartupError, r as getSafeStartupMessage, t as runServer } from "./runtime-
|
|
11
|
+
import { i as handleFatalStartupError, r as getSafeStartupMessage, t as runServer } from "./runtime-Dkm4I9j5.mjs";
|
|
12
12
|
//#region src/cli.ts
|
|
13
13
|
runServer().catch(async (error) => {
|
|
14
14
|
await handleFatalStartupError(error);
|
|
@@ -839,9 +839,19 @@ async function resolveAuth(params) {
|
|
|
839
839
|
return;
|
|
840
840
|
}
|
|
841
841
|
}
|
|
842
|
-
async function runValidator(validator, value) {
|
|
842
|
+
async function runValidator({ validator, value, context, onValidationError }) {
|
|
843
843
|
if (!validator) return value;
|
|
844
|
-
|
|
844
|
+
try {
|
|
845
|
+
return await validateStandardSchema(validator, value);
|
|
846
|
+
} catch (error) {
|
|
847
|
+
if (!onValidationError || !(error instanceof ParseError)) throw error;
|
|
848
|
+
const handled = await onValidationError(error, {
|
|
849
|
+
...context,
|
|
850
|
+
value
|
|
851
|
+
});
|
|
852
|
+
if (!handled) throw error;
|
|
853
|
+
return handled.value;
|
|
854
|
+
}
|
|
845
855
|
}
|
|
846
856
|
/**
|
|
847
857
|
* The base media type of a `Content-Type` value, lowercased and stripped of any `; charset=...` parameters.
|
|
@@ -904,7 +914,16 @@ async function resolveRequest({ config, requestConfig }) {
|
|
|
904
914
|
const cookie = serializeCookies(requestConfig.cookies, requestConfig.styles?.cookie);
|
|
905
915
|
if (cookie) headers["Cookie"] = [headers["Cookie"], cookie].filter(Boolean).join("; ");
|
|
906
916
|
}
|
|
907
|
-
const validatedBody = await runValidator(
|
|
917
|
+
const validatedBody = await runValidator({
|
|
918
|
+
validator: requestConfig.validator?.request,
|
|
919
|
+
value: requestConfig.body,
|
|
920
|
+
context: {
|
|
921
|
+
direction: "request",
|
|
922
|
+
method: requestConfig.method,
|
|
923
|
+
url: requestConfig.url
|
|
924
|
+
},
|
|
925
|
+
onValidationError: requestConfig.onValidationError ?? config.onValidationError
|
|
926
|
+
});
|
|
908
927
|
const requestContentTypeBase = baseContentType(requestContentType);
|
|
909
928
|
const contentCodec = requestContentTypeBase ? codecs[requestContentTypeBase] : void 0;
|
|
910
929
|
const usesDefaultBodySerializer = !contentCodec?.serialize && bodySerializer === defaultBodySerializer;
|
|
@@ -947,7 +966,7 @@ async function resolveRequest({ config, requestConfig }) {
|
|
|
947
966
|
* validates it, and throws a `ResponseError` (after running the error interceptors) for a non-2xx
|
|
948
967
|
* response under `throwOnError`.
|
|
949
968
|
*/
|
|
950
|
-
async function settleResult({ result, codecs, throwOnError, validator, errorInterceptors }) {
|
|
969
|
+
async function settleResult({ result, request, codecs, throwOnError, validator, onValidationError, errorInterceptors }) {
|
|
951
970
|
const isSuccess = result.status >= 200 && result.status < 300;
|
|
952
971
|
const contentType = result.contentType ?? getResponseContentType(result.headers);
|
|
953
972
|
let decoded = result.data;
|
|
@@ -955,8 +974,21 @@ async function settleResult({ result, codecs, throwOnError, validator, errorInte
|
|
|
955
974
|
const codec = codecs[contentType];
|
|
956
975
|
if (codec?.deserialize) decoded = await codec.deserialize(result.data, contentType);
|
|
957
976
|
}
|
|
977
|
+
const validationContext = {
|
|
978
|
+
method: request.method,
|
|
979
|
+
url: request.url,
|
|
980
|
+
status: result.status
|
|
981
|
+
};
|
|
958
982
|
if (isSuccess) {
|
|
959
|
-
const data = await runValidator(
|
|
983
|
+
const data = await runValidator({
|
|
984
|
+
validator: validator?.response,
|
|
985
|
+
value: decoded,
|
|
986
|
+
context: {
|
|
987
|
+
direction: "response",
|
|
988
|
+
...validationContext
|
|
989
|
+
},
|
|
990
|
+
onValidationError
|
|
991
|
+
});
|
|
960
992
|
return {
|
|
961
993
|
status: result.status,
|
|
962
994
|
data,
|
|
@@ -966,7 +998,15 @@ async function settleResult({ result, codecs, throwOnError, validator, errorInte
|
|
|
966
998
|
response: result.response
|
|
967
999
|
};
|
|
968
1000
|
}
|
|
969
|
-
const error = await runValidator(
|
|
1001
|
+
const error = await runValidator({
|
|
1002
|
+
validator: validator?.error,
|
|
1003
|
+
value: decoded,
|
|
1004
|
+
context: {
|
|
1005
|
+
direction: "error",
|
|
1006
|
+
...validationContext
|
|
1007
|
+
},
|
|
1008
|
+
onValidationError
|
|
1009
|
+
});
|
|
970
1010
|
if (throwOnError) {
|
|
971
1011
|
const responseError = new ResponseError({
|
|
972
1012
|
data: error,
|
|
@@ -1008,9 +1048,11 @@ function createClientCore(options) {
|
|
|
1008
1048
|
const resolvedRequest = await interceptors.request.run(request);
|
|
1009
1049
|
return settleResult({
|
|
1010
1050
|
result: await interceptors.response.run(await transport(resolvedRequest)),
|
|
1051
|
+
request: resolvedRequest,
|
|
1011
1052
|
codecs,
|
|
1012
1053
|
throwOnError: requestConfig.throwOnError ?? config.throwOnError ?? true,
|
|
1013
1054
|
validator: requestConfig.validator,
|
|
1055
|
+
onValidationError: requestConfig.onValidationError ?? config.onValidationError,
|
|
1014
1056
|
errorInterceptors: interceptors.error
|
|
1015
1057
|
});
|
|
1016
1058
|
});
|
|
@@ -5562,16 +5604,16 @@ const calendarDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, CALENDAR_DATE_MESSA
|
|
|
5562
5604
|
const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
|
|
5563
5605
|
return !Number.isNaN(parsed.getTime()) && parsed.toISOString().startsWith(value);
|
|
5564
5606
|
}, CALENDAR_DATE_MESSAGE);
|
|
5565
|
-
const rpeEnum = z.
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
]);
|
|
5607
|
+
const rpeEnum = z.preprocess((val) => isFiniteNumber$1(val) ? String(val) : val, z.enum([
|
|
5608
|
+
"6",
|
|
5609
|
+
"7",
|
|
5610
|
+
"7.5",
|
|
5611
|
+
"8",
|
|
5612
|
+
"8.5",
|
|
5613
|
+
"9",
|
|
5614
|
+
"9.5",
|
|
5615
|
+
"10"
|
|
5616
|
+
])).transform((val) => Number(val));
|
|
5575
5617
|
const workoutSetFields = {
|
|
5576
5618
|
type: setTypeEnum,
|
|
5577
5619
|
weight_kg: z.coerce.number().optional().nullable(),
|
|
@@ -6685,7 +6727,7 @@ function readBuildGlobal(value) {
|
|
|
6685
6727
|
}
|
|
6686
6728
|
}
|
|
6687
6729
|
const buildName = readBuildGlobal(() => "hevy-mcp");
|
|
6688
|
-
const buildVersion = readBuildGlobal(() => "6.1.
|
|
6730
|
+
const buildVersion = readBuildGlobal(() => "6.1.14");
|
|
6689
6731
|
const SERVER_NAME = readBuildString(buildName, "hevy-mcp");
|
|
6690
6732
|
const SERVER_VERSION = readBuildString(buildVersion, "dev");
|
|
6691
6733
|
const SERVER_INSTRUCTIONS = [
|
|
@@ -7253,4 +7295,4 @@ function assertApiKey(apiKey) {
|
|
|
7253
7295
|
//#endregion
|
|
7254
7296
|
export { SAFE_USER_HASH_PATTERN as a, mergeAbortSignals as c, createHevyClient as d, SAFE_OBSERVATION_CODES as f, isHevyHttpError as h, createHevyMcpServer as i, createSafeErrorDiagnostic as l, metricEndpointIdentity as m, assertApiKey as n, USER_HASH_CONTEXT as o, diagnosticEndpointIdentity as p, parseConfig as r, createExecutionProjection as s, MissingHevyApiKeyError as t, bucketCount as u };
|
|
7255
7297
|
|
|
7256
|
-
//# sourceMappingURL=config-
|
|
7298
|
+
//# sourceMappingURL=config-C3y5yJ8b.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -17,8 +17,14 @@ interface NodeLifecycleHandle {
|
|
|
17
17
|
* telemetry, or connect a transport. The embedding application owns those
|
|
18
18
|
* concerns and the transport lifecycle.
|
|
19
19
|
*/
|
|
20
|
-
export declare function createNodeMcpServer({ apiKey }: {
|
|
20
|
+
export declare function createNodeMcpServer({ apiKey, maxGetRetries }: {
|
|
21
21
|
apiKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Client retry budget (also applies to PUT). Set to 0 to disable all
|
|
24
|
+
* automatic request retries; reconcile uncertain writes before retrying.
|
|
25
|
+
* Omit to retain the client's existing retry policy.
|
|
26
|
+
*/
|
|
27
|
+
maxGetRetries?: number;
|
|
22
28
|
}, _transport?: NodeTransport, lifecycleSignal?: AbortSignal): Promise<import("@modelcontextprotocol/server").McpServer>;
|
|
23
29
|
/**
|
|
24
30
|
* Compatibility wrapper for the executable runtime. Importing this module
|
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 { d as createHevyClient, i as createHevyMcpServer, n as assertApiKey } from "./config-
|
|
4
|
+
import { d as createHevyClient, i as createHevyMcpServer, n as assertApiKey } from "./config-C3y5yJ8b.mjs";
|
|
5
5
|
//#region src/index.ts
|
|
6
6
|
/**
|
|
7
7
|
* Create an unconnected MCP server for embedding in a Node application.
|
|
@@ -11,12 +11,13 @@ import { d as createHevyClient, i as createHevyMcpServer, n as assertApiKey } fr
|
|
|
11
11
|
* telemetry, or connect a transport. The embedding application owns those
|
|
12
12
|
* concerns and the transport lifecycle.
|
|
13
13
|
*/
|
|
14
|
-
async function createNodeMcpServer({ apiKey }, _transport = "stdio", lifecycleSignal) {
|
|
14
|
+
async function createNodeMcpServer({ apiKey, maxGetRetries }, _transport = "stdio", lifecycleSignal) {
|
|
15
15
|
assertApiKey(apiKey);
|
|
16
16
|
return await createHevyMcpServer({
|
|
17
17
|
createClient: ({ onLog }) => createHevyClient({
|
|
18
18
|
apiKey,
|
|
19
|
-
onLog
|
|
19
|
+
onLog,
|
|
20
|
+
...maxGetRetries === void 0 ? {} : { maxGetRetries }
|
|
20
21
|
}),
|
|
21
22
|
lifecycleSignal
|
|
22
23
|
});
|
|
@@ -26,7 +27,7 @@ async function createNodeMcpServer({ apiKey }, _transport = "stdio", lifecycleSi
|
|
|
26
27
|
* does not evaluate the runtime bootstrap; it is loaded only when invoked.
|
|
27
28
|
*/
|
|
28
29
|
async function runStdioServer() {
|
|
29
|
-
const { runStdioServer: run } = await import("./runtime-
|
|
30
|
+
const { runStdioServer: run } = await import("./runtime-Dkm4I9j5.mjs").then((n) => n.n);
|
|
30
31
|
return run();
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
@@ -34,7 +35,7 @@ async function runStdioServer() {
|
|
|
34
35
|
* does not evaluate the runtime bootstrap; it is loaded only when invoked.
|
|
35
36
|
*/
|
|
36
37
|
async function runServer() {
|
|
37
|
-
const { runServer: run } = await import("./runtime-
|
|
38
|
+
const { runServer: run } = await import("./runtime-Dkm4I9j5.mjs").then((n) => n.n);
|
|
38
39
|
return run();
|
|
39
40
|
}
|
|
40
41
|
//#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] = "cd83062e-356a-42d7-888c-2b912349753c", e._sentryDebugIdIdentifier = "sentry-dbid-cd83062e-356a-42d7-888c-2b912349753c");
|
|
9
9
|
} catch (e) {}
|
|
10
10
|
})();
|
|
11
|
-
import { a as SAFE_USER_HASH_PATTERN, c as mergeAbortSignals, d as createHevyClient, f as SAFE_OBSERVATION_CODES, h as isHevyHttpError, i as createHevyMcpServer, l as createSafeErrorDiagnostic, m as metricEndpointIdentity, n as assertApiKey, o as USER_HASH_CONTEXT, p as diagnosticEndpointIdentity, r as parseConfig, s as createExecutionProjection, t as MissingHevyApiKeyError, u as bucketCount } from "./config-
|
|
11
|
+
import { a as SAFE_USER_HASH_PATTERN, c as mergeAbortSignals, d as createHevyClient, f as SAFE_OBSERVATION_CODES, h as isHevyHttpError, i as createHevyMcpServer, l as createSafeErrorDiagnostic, m as metricEndpointIdentity, n as assertApiKey, o as USER_HASH_CONTEXT, p as diagnosticEndpointIdentity, r as parseConfig, s as createExecutionProjection, t as MissingHevyApiKeyError, u as bucketCount } from "./config-C3y5yJ8b.mjs";
|
|
12
12
|
import { ZodError, z } from "zod";
|
|
13
13
|
import { Data, Duration, Effect, Exit, Fiber, Layer, Scope, Semaphore } from "effect";
|
|
14
14
|
import { deserializeMessage } from "@modelcontextprotocol/server";
|
|
@@ -410,7 +410,7 @@ function parseBuildString(value, fallback) {
|
|
|
410
410
|
return z.string().parse(value ?? fallback);
|
|
411
411
|
}
|
|
412
412
|
const name$1 = parseBuildString(readBuildGlobal(() => "hevy-mcp"), "hevy-mcp");
|
|
413
|
-
const version$1 = parseBuildString(readBuildGlobal(() => "6.1.
|
|
413
|
+
const version$1 = parseBuildString(readBuildGlobal(() => "6.1.14"), "dev");
|
|
414
414
|
const telemetryEnabled = process.env.HEVY_MCP_TELEMETRY !== "0";
|
|
415
415
|
const collectorToken = z.string().safeParse(readBuildGlobal(() => "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo")).data ?? process.env.OTEL_COLLECTOR_TOKEN ?? "";
|
|
416
416
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
@@ -2958,4 +2958,4 @@ async function runServer() {
|
|
|
2958
2958
|
//#endregion
|
|
2959
2959
|
export { handleFatalStartupError as i, runtime_exports as n, getSafeStartupMessage as r, runServer as t };
|
|
2960
2960
|
|
|
2961
|
-
//# sourceMappingURL=runtime-
|
|
2961
|
+
//# sourceMappingURL=runtime-Dkm4I9j5.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hevy-mcp",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A Model Context Protocol (MCP) server implementation that interfaces with the Hevy fitness tracking app and its API.",
|
|
6
6
|
"repository": {
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"zod": "^4.6.5"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@hevy-mcp/core": "0.2.
|
|
47
|
-
"@hevy-mcp/hevy-client": "0.2.
|
|
46
|
+
"@hevy-mcp/core": "0.2.13",
|
|
47
|
+
"@hevy-mcp/hevy-client": "0.2.9",
|
|
48
48
|
"@sentry/core": "^10.74.0",
|
|
49
49
|
"@types/node": "^26.5.1",
|
|
50
50
|
"cross-env": "^10.1.0",
|
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.14",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "hevy-mcp",
|
|
15
|
-
"version": "6.1.
|
|
15
|
+
"version": "6.1.14",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|