hevy-mcp 5.0.2 → 5.0.3
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 +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{src-DBkGttYB.mjs → src-BGQCPTet.mjs} +84 -8
- package/package.json +1 -1
- package/server.json +2 -2
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@5.0.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@5.0.3" };
|
|
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-BGQCPTet.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@5.0.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@5.0.3" };
|
|
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-BGQCPTet.mjs";
|
|
13
13
|
export { createNodeMcpServer, runServer, runStdioServer };
|
|
@@ -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@5.0.
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@5.0.3" };
|
|
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] = "b75e442e-2372-4f08-83bb-f0c392f5101b", e._sentryDebugIdIdentifier = "sentry-dbid-b75e442e-2372-4f08-83bb-f0c392f5101b");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
12
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -79,12 +79,48 @@ function sanitizeSentryMcpSpan(span) {
|
|
|
79
79
|
* Sentry SDK: error events, performance traces, release tracking
|
|
80
80
|
* OTel Collector → Honeycomb: performance traces, metrics
|
|
81
81
|
*/
|
|
82
|
+
function normalizeTelemetryError(error) {
|
|
83
|
+
const name = error instanceof Error && error.name ? error.name : "Exception";
|
|
84
|
+
return new Error(name);
|
|
85
|
+
}
|
|
86
|
+
function recordTelemetryException(error, attributes, span) {
|
|
87
|
+
if (!telemetryEnabled) return;
|
|
88
|
+
try {
|
|
89
|
+
const target = span ?? trace.getActiveSpan();
|
|
90
|
+
if (!target) return;
|
|
91
|
+
target.recordException(normalizeTelemetryError(error));
|
|
92
|
+
if (attributes) target.setAttributes(attributes);
|
|
93
|
+
target.setStatus({ code: SpanStatusCode.ERROR });
|
|
94
|
+
} catch {}
|
|
95
|
+
}
|
|
96
|
+
function installProcessExceptionTracking(processLike = process) {
|
|
97
|
+
if (!telemetryEnabled) return () => {};
|
|
98
|
+
const recordProcessException = (source, error) => {
|
|
99
|
+
try {
|
|
100
|
+
tracer.startActiveSpan(`mcp.process.${source}`, (span) => {
|
|
101
|
+
recordTelemetryException(error, { "exception.source": source }, span);
|
|
102
|
+
span.end();
|
|
103
|
+
});
|
|
104
|
+
} catch {}
|
|
105
|
+
};
|
|
106
|
+
const uncaughtException = (error) => recordProcessException("uncaughtException", error);
|
|
107
|
+
const unhandledRejection = (error) => recordProcessException("unhandledRejection", error);
|
|
108
|
+
processLike.on("uncaughtExceptionMonitor", uncaughtException);
|
|
109
|
+
processLike.on("unhandledRejection", unhandledRejection);
|
|
110
|
+
let cleaned = false;
|
|
111
|
+
return () => {
|
|
112
|
+
if (cleaned) return;
|
|
113
|
+
cleaned = true;
|
|
114
|
+
processLike.removeListener("uncaughtExceptionMonitor", uncaughtException);
|
|
115
|
+
processLike.removeListener("unhandledRejection", unhandledRejection);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
82
118
|
const name$1 = "hevy-mcp";
|
|
83
|
-
const version$1 = "5.0.
|
|
119
|
+
const version$1 = "5.0.3";
|
|
84
120
|
const telemetryEnabled = process.env.HEVY_MCP_TELEMETRY !== "0";
|
|
85
121
|
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
86
122
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
87
|
-
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@5.0.
|
|
123
|
+
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@5.0.3`;
|
|
88
124
|
const resource = resourceFromAttributes({
|
|
89
125
|
"service.name": name$1,
|
|
90
126
|
"service.version": version$1
|
|
@@ -2644,7 +2680,7 @@ function registerHevyResources(server, runtime) {
|
|
|
2644
2680
|
//#endregion
|
|
2645
2681
|
//#region ../core/src/server-metadata.ts
|
|
2646
2682
|
const SERVER_NAME = "hevy-mcp";
|
|
2647
|
-
const SERVER_VERSION = "5.0.
|
|
2683
|
+
const SERVER_VERSION = "5.0.3";
|
|
2648
2684
|
const SERVER_INSTRUCTIONS = [
|
|
2649
2685
|
"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.",
|
|
2650
2686
|
"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.",
|
|
@@ -4007,6 +4043,18 @@ function registerHevyTools(server, runtime) {
|
|
|
4007
4043
|
/**
|
|
4008
4044
|
* Centralized error handling utility for MCP tools
|
|
4009
4045
|
*/
|
|
4046
|
+
function createMcpToolFailureEvent(toolName, errorType, diagnostic) {
|
|
4047
|
+
return {
|
|
4048
|
+
event: "mcp.tool.failure",
|
|
4049
|
+
"mcp.tool.name": toolName,
|
|
4050
|
+
"error.type": errorType,
|
|
4051
|
+
"error.category": diagnostic.category,
|
|
4052
|
+
...diagnostic.code ? { "error.code": diagnostic.code } : {},
|
|
4053
|
+
...diagnostic.status !== void 0 ? { "http.status_code": diagnostic.status } : {},
|
|
4054
|
+
...diagnostic.method ? { "http.method": diagnostic.method } : {},
|
|
4055
|
+
...diagnostic.endpoint ? { "hevy.api.endpoint": diagnostic.endpoint } : {}
|
|
4056
|
+
};
|
|
4057
|
+
}
|
|
4010
4058
|
/**
|
|
4011
4059
|
* Create a standardized error response for MCP tools
|
|
4012
4060
|
*
|
|
@@ -4030,7 +4078,7 @@ function createErrorResponse(error, context) {
|
|
|
4030
4078
|
axios: axiosErrorContext ?? void 0
|
|
4031
4079
|
};
|
|
4032
4080
|
const formattedMessage = `${context ? `[${context}] ` : ""}Error: ${policy.message}`;
|
|
4033
|
-
console.error(
|
|
4081
|
+
console.error(createMcpToolFailureEvent(context || "unknown", policy.type, diagnostic));
|
|
4034
4082
|
return {
|
|
4035
4083
|
content: [{
|
|
4036
4084
|
type: "text",
|
|
@@ -5077,11 +5125,13 @@ function captureSafeToolFailure(invocation, completion) {
|
|
|
5077
5125
|
try {
|
|
5078
5126
|
Sentry.withScope((scope) => {
|
|
5079
5127
|
const isPrompt = invocation.kind === "prompt";
|
|
5128
|
+
scope.setTag("mcp.tool.name", invocation.name);
|
|
5080
5129
|
if (isPrompt) scope.setTag("mcp.prompt.name", invocation.name);
|
|
5081
|
-
|
|
5130
|
+
scope.setTag("error.type", completion.errorType ?? "UNKNOWN_ERROR");
|
|
5082
5131
|
scope.setTag("error.category", category);
|
|
5083
5132
|
if (diagnostic?.code) scope.setTag("error.code", diagnostic.code);
|
|
5084
5133
|
if (diagnostic?.status !== void 0) scope.setTag("http.status_code", String(diagnostic.status));
|
|
5134
|
+
if (diagnostic?.method) scope.setTag("http.method", diagnostic.method);
|
|
5085
5135
|
if (diagnostic?.endpoint) scope.setTag("hevy.api.endpoint", diagnostic.endpoint);
|
|
5086
5136
|
scope.setContext(invocation.kind === "prompt" ? "mcpPrompt" : "mcpTool", {
|
|
5087
5137
|
context: invocation.name,
|
|
@@ -5134,7 +5184,27 @@ function createNodeToolObserver() {
|
|
|
5134
5184
|
activeSpan.setStatus({ code: nextCompletion.outcome === "success" && nextCompletion.result?.isError !== true ? SpanStatusCode.OK : SpanStatusCode.ERROR });
|
|
5135
5185
|
activeSpan.setAttribute("mcp.tool.outcome", nextCompletion.outcome);
|
|
5136
5186
|
setResultAttributes(activeSpan, nextCompletion);
|
|
5137
|
-
if (nextCompletion.outcome === "thrown_error")
|
|
5187
|
+
if (nextCompletion.outcome === "thrown_error") {
|
|
5188
|
+
errorType = setSafeErrorAttributes(activeSpan, nextCompletion);
|
|
5189
|
+
bestEffort(() => recordTelemetryException(new Error(nextCompletion.error?.category ?? errorType), {
|
|
5190
|
+
[invocation.kind === "prompt" ? "mcp.prompt.name" : "mcp.tool.name"]: invocation.name,
|
|
5191
|
+
"error.type": errorType ?? "UNKNOWN_ERROR",
|
|
5192
|
+
"error.category": nextCompletion.error?.category ?? "UnknownError",
|
|
5193
|
+
...nextCompletion.error?.code ? { "error.code": nextCompletion.error.code } : {},
|
|
5194
|
+
...nextCompletion.error?.status !== void 0 ? { "http.status_code": nextCompletion.error.status } : {},
|
|
5195
|
+
...nextCompletion.error?.method ? { "http.method": nextCompletion.error.method } : {},
|
|
5196
|
+
...nextCompletion.error?.endpoint ? { "hevy.api.endpoint": nextCompletion.error.endpoint } : {}
|
|
5197
|
+
}, activeSpan));
|
|
5198
|
+
}
|
|
5199
|
+
if (nextCompletion.outcome === "returned_error") bestEffort(() => recordTelemetryException(new Error(nextCompletion.error?.category ?? "UnknownError"), {
|
|
5200
|
+
[invocation.kind === "prompt" ? "mcp.prompt.name" : "mcp.tool.name"]: invocation.name,
|
|
5201
|
+
"error.type": nextCompletion.errorType ?? "UNKNOWN_ERROR",
|
|
5202
|
+
"error.category": nextCompletion.error?.category ?? "UnknownError",
|
|
5203
|
+
...nextCompletion.error?.code ? { "error.code": nextCompletion.error.code } : {},
|
|
5204
|
+
...nextCompletion.error?.status !== void 0 ? { "http.status_code": nextCompletion.error.status } : {},
|
|
5205
|
+
...nextCompletion.error?.method ? { "http.method": nextCompletion.error.method } : {},
|
|
5206
|
+
...nextCompletion.error?.endpoint ? { "hevy.api.endpoint": nextCompletion.error.endpoint } : {}
|
|
5207
|
+
}, activeSpan));
|
|
5138
5208
|
}
|
|
5139
5209
|
} catch {} finally {
|
|
5140
5210
|
if (nextCompletion.outcome === "thrown_error") {
|
|
@@ -5622,6 +5692,7 @@ async function runStdioServer() {
|
|
|
5622
5692
|
console.log(HELP_TEXT);
|
|
5623
5693
|
return;
|
|
5624
5694
|
}
|
|
5695
|
+
const cleanupProcessExceptionTracking = installProcessExceptionTracking();
|
|
5625
5696
|
serverStartups.add(1, { version });
|
|
5626
5697
|
const configuredApiKey = process.env.HEVY_API_KEY;
|
|
5627
5698
|
if (configuredApiKey) setTelemetryUser(configuredApiKey);
|
|
@@ -5653,6 +5724,7 @@ async function runStdioServer() {
|
|
|
5653
5724
|
target: server,
|
|
5654
5725
|
onComplete: async (succeeded) => {
|
|
5655
5726
|
recordMcpSessionTermination(resolveSessionTerminationCategory(succeeded));
|
|
5727
|
+
cleanupProcessExceptionTracking();
|
|
5656
5728
|
await flushTelemetry();
|
|
5657
5729
|
}
|
|
5658
5730
|
});
|
|
@@ -5660,6 +5732,7 @@ async function runStdioServer() {
|
|
|
5660
5732
|
} catch (e) {
|
|
5661
5733
|
recordMcpSessionTermination(connectAttempted ? "connect_failure" : "startup_failure");
|
|
5662
5734
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
5735
|
+
cleanupProcessExceptionTracking();
|
|
5663
5736
|
throw e;
|
|
5664
5737
|
} finally {
|
|
5665
5738
|
span.end();
|
|
@@ -5682,6 +5755,7 @@ async function runServer() {
|
|
|
5682
5755
|
await runStdioServer();
|
|
5683
5756
|
return;
|
|
5684
5757
|
}
|
|
5758
|
+
const cleanupProcessExceptionTracking = installProcessExceptionTracking();
|
|
5685
5759
|
await tracer.startActiveSpan("mcp.server.run", { attributes: { "mcp.transport": "http" } }, async (span) => {
|
|
5686
5760
|
let listening = false;
|
|
5687
5761
|
serverStartups.add(1, { version });
|
|
@@ -5700,6 +5774,7 @@ async function runServer() {
|
|
|
5700
5774
|
installGracefulShutdown({
|
|
5701
5775
|
target: handle,
|
|
5702
5776
|
onComplete: async () => {
|
|
5777
|
+
cleanupProcessExceptionTracking();
|
|
5703
5778
|
await flushTelemetry();
|
|
5704
5779
|
}
|
|
5705
5780
|
});
|
|
@@ -5707,6 +5782,7 @@ async function runServer() {
|
|
|
5707
5782
|
} catch (error) {
|
|
5708
5783
|
recordMcpSessionTermination(listening ? "unknown" : "startup_failure");
|
|
5709
5784
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
5785
|
+
cleanupProcessExceptionTracking();
|
|
5710
5786
|
throw error;
|
|
5711
5787
|
} finally {
|
|
5712
5788
|
span.end();
|
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": "5.0.
|
|
10
|
+
"version": "5.0.3",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "hevy-mcp",
|
|
15
|
-
"version": "5.0.
|
|
15
|
+
"version": "5.0.3",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|