hevy-mcp 2.0.0 → 3.0.0
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 +10 -6
- package/dist/cli.mjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{src-c3mB-R0m.mjs → src-BBzEvkOX.mjs} +22 -54
- package/dist/src-BBzEvkOX.mjs.map +1 -0
- package/package.json +15 -2
- package/server.json +2 -2
- package/dist/src-c3mB-R0m.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-BBzEvkOX.mjs","names":["name","version","getSafePageCount","normalizeHeaderValue","getHeaderValue","z","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","fetch","createClient","api.getV1Workouts","api.getV1WorkoutsWorkoutid","api.postV1Workouts","api.putV1WorkoutsWorkoutid","api.getV1WorkoutsCount","api.getV1WorkoutsEvents","api.getV1Routines","api.getV1RoutinesRoutineid","api.postV1Routines","api.putV1RoutinesRoutineid","api.getV1ExerciseTemplates","api.getV1ExerciseTemplatesExercisetemplateid","api.getV1ExerciseHistoryExercisetemplateid","api.postV1ExerciseTemplates","api.getV1RoutineFolders","api.postV1RoutineFolders","api.getV1RoutineFoldersFolderid","api.getV1BodyMeasurements","api.getV1BodyMeasurementsDate","api.postV1BodyMeasurements","api.putV1BodyMeasurementsDate","api.getV1UserInfo","createKubbClient","serviceName","serviceVersion"],"sources":["../src/utils/telemetry.ts","../src/utils/metrics.ts","../src/prompts/workouts.ts","../src/utils/cache.ts","../src/utils/exercise-template-catalog.ts","../src/utils/formatters.ts","../src/utils/tool-helpers.ts","../src/resources/hevy.ts","../src/utils/error-classification.ts","../src/utils/error-handler.ts","../src/utils/debug.ts","../src/utils/telemetry-wrapper.ts","../src/utils/observability-wrapper.ts","../src/generated/client/schemas/userInfoSchema.ts","../src/utils/output-schemas.ts","../src/utils/response-formatter.ts","../src/utils/tool-annotations.ts","../src/utils/tool-descriptions.ts","../src/utils/schemas.ts","../src/tools/body-measurements.ts","../src/tools/folders.ts","../src/utils/json-parser.ts","../src/tools/routines.ts","../src/tools/templates.ts","../src/tools/user.ts","../src/tools/workouts.ts","../src/tools/register.ts","../src/utils/config.ts","../src/utils/graceful-shutdown.ts","../src/generated/.kubb/fetch.ts","../src/generated/client/api/getV1BodyMeasurements.ts","../src/generated/client/api/getV1BodyMeasurementsDate.ts","../src/generated/client/api/getV1ExerciseHistoryExercisetemplateid.ts","../src/generated/client/api/getV1ExerciseTemplates.ts","../src/generated/client/api/getV1ExerciseTemplatesExercisetemplateid.ts","../src/generated/client/api/getV1RoutineFolders.ts","../src/generated/client/api/getV1RoutineFoldersFolderid.ts","../src/generated/client/api/getV1Routines.ts","../src/generated/client/api/getV1RoutinesRoutineid.ts","../src/generated/client/api/getV1UserInfo.ts","../src/generated/client/api/getV1Workouts.ts","../src/generated/client/api/getV1WorkoutsCount.ts","../src/generated/client/api/getV1WorkoutsEvents.ts","../src/generated/client/api/getV1WorkoutsWorkoutid.ts","../src/generated/client/api/postV1BodyMeasurements.ts","../src/generated/client/api/postV1ExerciseTemplates.ts","../src/generated/client/api/postV1RoutineFolders.ts","../src/generated/client/api/postV1Routines.ts","../src/generated/client/api/postV1Workouts.ts","../src/generated/client/api/putV1BodyMeasurementsDate.ts","../src/generated/client/api/putV1RoutinesRoutineid.ts","../src/generated/client/api/putV1WorkoutsWorkoutid.ts","../src/utils/hevyClientKubb.ts","../src/utils/hevyClient.ts","../src/utils/mcp-client-logger.ts","../src/utils/stdio-observability.ts","../src/utils/version-check.ts","../src/index.ts"],"sourcesContent":["/**\n * Centralized telemetry initialization.\n *\n * This module MUST be imported before any other application code.\n * It sets up OpenTelemetry with dual export: Sentry (error events +\n * traces) and an OTel Collector (traces + metrics to Honeycomb).\n *\n * Sentry SDK: error events, performance traces, release tracking\n * OTel Collector → Honeycomb: performance traces, metrics\n */\n\nimport * as Sentry from \"@sentry/node\";\nimport {\n\tSentryPropagator,\n\tSentrySampler,\n\tSentrySpanProcessor,\n} from \"@sentry/opentelemetry\";\nimport { trace, metrics } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport { OTLPMetricExporter } from \"@opentelemetry/exporter-metrics-otlp-http\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { BatchSpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport type { SpanProcessor } from \"@opentelemetry/sdk-trace\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport {\n\tMeterProvider,\n\tPeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\n\ndeclare const __HEVY_MCP_NAME__: string | undefined;\ndeclare const __HEVY_MCP_VERSION__: string | undefined;\ndeclare const __HEVY_MCP_BUILD__: boolean | undefined;\ndeclare const __OTEL_COLLECTOR_TOKEN__: string | undefined;\n\nconst name =\n\ttypeof __HEVY_MCP_NAME__ === \"string\" ? __HEVY_MCP_NAME__ : \"hevy-mcp\";\nconst version =\n\ttypeof __HEVY_MCP_VERSION__ === \"string\" ? __HEVY_MCP_VERSION__ : \"dev\";\n\n// Collector token is injected at build time from the OTEL_COLLECTOR_TOKEN\n// GitHub secret via tsdown.config.ts define. The collector forwards\n// traces and metrics to Honeycomb, keeping the Honeycomb API key off the\n// client. The collector endpoint is public (behind Cloudflare Tunnel).\nconst collectorToken =\n\ttypeof __OTEL_COLLECTOR_TOKEN__ === \"string\" && __OTEL_COLLECTOR_TOKEN__\n\t\t? __OTEL_COLLECTOR_TOKEN__\n\t\t: (process.env.OTEL_COLLECTOR_TOKEN ?? \"\");\n\nconst COLLECTOR_ENDPOINT = \"https://otel.chrisdoc.dev/v1\";\n\nconst sentryRelease = process.env.SENTRY_RELEASE ?? `${name}@${version}`;\n\nconst resource = resourceFromAttributes({\n\t\"service.name\": name,\n\t\"service.version\": version,\n});\n\nconst bakedDsn =\n\t\"https://ce696d8333b507acbf5203eb877bce0f@o4508975499575296.ingest.de.sentry.io/4509049671647312\";\nconst rawDsn = process.env.SENTRY_DSN ?? bakedDsn;\nconst isValidDsn =\n\ttypeof rawDsn === \"string\" && rawDsn.length > 0 && !rawDsn.startsWith(\"*\");\n\n// --- Sentry (error monitoring + traces) ---\nconst sentryClient = Sentry.init({\n\tdsn: isValidDsn ? rawDsn : undefined,\n\trelease: sentryRelease,\n\ttracesSampleRate: 1.0,\n\tsendDefaultPii: false,\n\tskipOpenTelemetrySetup: true,\n\tregisterEsmLoaderHooks: false,\n\tignoreErrors: [\"EPIPE\", \"broken pipe\"],\n});\n\n// --- OpenTelemetry tracer provider (dual export) ---\nconst spanProcessors: SpanProcessor[] = [new SentrySpanProcessor()];\n\n// Span processor 2: OTel Collector → Honeycomb (traces) — only if token is available\nif (collectorToken) {\n\tspanProcessors.push(\n\t\tnew BatchSpanProcessor(\n\t\t\tnew OTLPTraceExporter({\n\t\t\t\turl: `${COLLECTOR_ENDPOINT}/traces`,\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${collectorToken}`,\n\t\t\t\t},\n\t\t\t}),\n\t\t),\n\t);\n}\n\nconst tracerProvider = new NodeTracerProvider({\n\tresource,\n\tsampler: sentryClient ? new SentrySampler(sentryClient) : undefined,\n\tspanProcessors,\n});\n\ntracerProvider.register({\n\tpropagator: new SentryPropagator(),\n\tcontextManager: new Sentry.SentryContextManager(),\n});\n\n// --- OpenTelemetry meter provider (→ Collector → Honeycomb metrics) ---\nif (collectorToken) {\n\tconst meterProvider = new MeterProvider({\n\t\tresource,\n\t\treaders: [\n\t\t\tnew PeriodicExportingMetricReader({\n\t\t\t\texporter: new OTLPMetricExporter({\n\t\t\t\t\turl: `${COLLECTOR_ENDPOINT}/metrics`,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${collectorToken}`,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\texportIntervalMillis: 10_000,\n\t\t\t}),\n\t\t],\n\t});\n\tmetrics.setGlobalMeterProvider(meterProvider);\n}\n\ntrace.setGlobalTracerProvider(tracerProvider);\n\n// Validate that Sentry + OpenTelemetry are wired correctly\nSentry.validateOpenTelemetrySetup();\n\n// --- Shared instances for the rest of the codebase ---\nexport const tracer = trace.getTracer(name);\nexport const meter = metrics.getMeter(name);\nexport { Sentry };\n\n/**\n * Bundled service identity — avoids passing name and version as\n * separate primitives throughout the codebase (Data Clumps smell).\n */\nexport interface ServiceInfo {\n\treadonly name: string;\n\treadonly version: string;\n}\n\nexport const serviceInfo: ServiceInfo = { name, version } as const;\n\n// Keep individual exports for backward compatibility\nexport { name as serviceName, version as serviceVersion };\n\n// --- User context for span attributes ---\nlet currentUserId: string | undefined;\n\nexport function setCurrentUserId(id: string): void {\n\tcurrentUserId = id;\n}\n\nexport function getCurrentUserId(): string | undefined {\n\treturn currentUserId;\n}\n","/**\n * Metric instruments for Honeycomb.\n *\n * These are created once from the shared meter provider and exported\n * for use throughout the codebase. All instruments are sent to Honeycomb\n * via the OTLP metrics exporter configured in telemetry.ts.\n */\n\nimport { meter } from \"./telemetry.js\";\n\n/** Total MCP tool invocations, grouped by tool name. */\nexport const toolInvocations = meter.createCounter(\"mcp.tool.invocations\", {\n\tdescription: \"Total MCP tool invocations\",\n});\n\n/** Total MCP tool errors, grouped by tool name and error type. */\nexport const toolErrors = meter.createCounter(\"mcp.tool.errors\", {\n\tdescription: \"Total MCP tool errors\",\n});\n\n/** MCP tool execution duration in milliseconds. */\nexport const toolDuration = meter.createHistogram(\"mcp.tool.duration_ms\", {\n\tdescription: \"MCP tool execution duration in milliseconds\",\n\tunit: \"ms\",\n});\n\n/** Total Hevy API calls, grouped by method, endpoint, and status code. */\nexport const apiCalls = meter.createCounter(\"hevy.api.calls\", {\n\tdescription: \"Total Hevy API calls\",\n});\n\n/** Hevy API response time in milliseconds. */\nexport const apiDuration = meter.createHistogram(\"hevy.api.duration_ms\", {\n\tdescription: \"Hevy API response time in milliseconds\",\n\tunit: \"ms\",\n});\n\n/** Total stdio JSON parse errors, grouped by failure location. */\nexport const stdioParseErrors = meter.createCounter(\"mcp.stdio.parse_errors\", {\n\tdescription: \"Total stdio JSON parse errors\",\n});\n\n/** Total server startup count, grouped by version. */\nexport const serverStartups = meter.createCounter(\"mcp.server.startups\", {\n\tdescription: \"Total server startup count\",\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nconst utcSecondTimestamp = z\n\t.string()\n\t.regex(\n\t\t/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/,\n\t\t\"Must use the UTC format YYYY-MM-DDTHH:mm:ssZ\",\n\t);\n\n/** Register guided workout workflow prompts. */\nexport function registerWorkoutPrompts(server: McpServer) {\n\tserver.registerPrompt(\n\t\t\"analyze-workout-progress\",\n\t\t{\n\t\t\ttitle: \"Analyze Workout Progress\",\n\t\t\tdescription: \"Analyze recent workout and body-measurement trends.\",\n\t\t\targsSchema: {\n\t\t\t\tweeks: z.coerce\n\t\t\t\t\t.number()\n\t\t\t\t\t.int()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(12)\n\t\t\t\t\t.default(4)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Number of recent weeks to analyze (1-12).\"),\n\t\t\t},\n\t\t},\n\t\t({ weeks = 4 }) => ({\n\t\t\tmessages: [\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: [\n\t\t\t\t\t\t\t`Analyze my workout progress over the last ${weeks} weeks.`,\n\t\t\t\t\t\t\t\"Use get-workout-count to establish the available workout total.\",\n\t\t\t\t\t\t\t\"Then call get-workouts with pageSize=10 and continue through pages until the requested date window is fully covered or no more workouts remain.\",\n\t\t\t\t\t\t\t\"Also call get-body-measurements with pageSize=10 and paginate until the same date window is covered or no more measurements remain.\",\n\t\t\t\t\t\t\t\"Base the analysis on retrieved evidence and discuss workout frequency, training volume, exercise variety, consistency, and body-measurement trends.\",\n\t\t\t\t\t\t\t\"Distinguish observations from suggestions, note missing or limited data, and do not make unsupported claims or medical conclusions.\",\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t);\n\n\tserver.registerPrompt(\n\t\t\"create-workout-from-routine\",\n\t\t{\n\t\t\ttitle: \"Create Workout From Routine\",\n\t\t\tdescription: \"Create a completed workout from an existing routine.\",\n\t\t\targsSchema: {\n\t\t\t\troutineId: z.string().min(1).describe(\"Routine ID to use as a guide.\"),\n\t\t\t\tstartTime: utcSecondTimestamp.describe(\n\t\t\t\t\t\"Workout start time in UTC as YYYY-MM-DDTHH:mm:ssZ.\",\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t({ routineId, startTime }) => ({\n\t\t\tmessages: [\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: [\n\t\t\t\t\t\t\t`Create a workout from routine ${routineId}, starting at ${startTime}.`,\n\t\t\t\t\t\t\t\"First call get-routine with the routineId and map supported plan fields: routine title to workout title, plus each exerciseTemplateId, supersetId, exercise notes, and set type.\",\n\t\t\t\t\t\t\t\"Do not copy routine-only restSeconds or repRange fields into create-workout.\",\n\t\t\t\t\t\t\t\"Before calling create-workout, confirm or collect the user's actual completed set data for every set, including applicable weight, reps, distance, duration, RPE, or custom metric values.\",\n\t\t\t\t\t\t\t\"Also collect the required endTime in strict UTC YYYY-MM-DDTHH:mm:ssZ format and confirm any other missing required workout fields.\",\n\t\t\t\t\t\t\t\"Never invent completion data. If the actual results or endTime are unavailable, ask the user for them instead of creating the workout.\",\n\t\t\t\t\t\t\t\"Once confirmed, call create-workout with only fields supported by that tool.\",\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t);\n}\n","export interface AsyncCacheOptions {\n\tttlMs: number;\n\tmaxSize: number;\n}\n\nexport interface CacheGetOptions {\n\trefresh?: boolean;\n}\n\ninterface CacheEntry<TValue> {\n\tvalue: TValue;\n\texpiresAt: number;\n}\n\ninterface InFlightEntry<TValue> {\n\tpromise: Promise<TValue>;\n\trequestId: number;\n}\n\n/**\n * Shared in-memory cache for async fetches with TTL, LRU eviction,\n * in-flight de-duplication, and explicit refresh/invalidation support.\n */\nexport class AsyncTtlCache<TKey, TValue> {\n\tprivate readonly ttlMs: number;\n\tprivate readonly maxSize: number;\n\tprivate readonly now: () => number;\n\tprivate readonly entries = new Map<TKey, CacheEntry<TValue>>();\n\tprivate readonly inFlight = new Map<TKey, InFlightEntry<TValue>>();\n\tprivate requestCounter = 0;\n\n\tconstructor(options: AsyncCacheOptions, now: () => number = Date.now) {\n\t\tconst { ttlMs, maxSize } = options;\n\t\tif (ttlMs <= 0) {\n\t\t\tthrow new Error(\"Cache ttlMs must be greater than 0.\");\n\t\t}\n\t\tif (maxSize <= 0) {\n\t\t\tthrow new Error(\"Cache maxSize must be greater than 0.\");\n\t\t}\n\n\t\tthis.ttlMs = ttlMs;\n\t\tthis.maxSize = maxSize;\n\t\tthis.now = now;\n\t}\n\n\tasync getOrFetch(\n\t\tkey: TKey,\n\t\tfetcher: () => Promise<TValue>,\n\t\toptions: CacheGetOptions = {},\n\t): Promise<TValue> {\n\t\tconst { refresh = false } = options;\n\n\t\tif (refresh) {\n\t\t\tthis.invalidate(key);\n\t\t} else {\n\t\t\tconst cachedEntry = this.entries.get(key);\n\t\t\tif (cachedEntry !== undefined) {\n\t\t\t\tif (cachedEntry.expiresAt > this.now()) {\n\t\t\t\t\tthis.markAsRecentlyUsed(key, cachedEntry);\n\t\t\t\t\treturn cachedEntry.value;\n\t\t\t\t}\n\n\t\t\t\tthis.entries.delete(key);\n\t\t\t}\n\n\t\t\tconst inFlightEntry = this.inFlight.get(key);\n\t\t\tif (inFlightEntry !== undefined) {\n\t\t\t\treturn inFlightEntry.promise;\n\t\t\t}\n\t\t}\n\n\t\tconst requestId = ++this.requestCounter;\n\t\tconst request = (async () => {\n\t\t\ttry {\n\t\t\t\tconst value = await fetcher();\n\n\t\t\t\tif (this.isCurrentRequest(key, requestId)) {\n\t\t\t\t\tthis.setValue(key, value);\n\t\t\t\t}\n\n\t\t\t\treturn value;\n\t\t\t} finally {\n\t\t\t\tconst inFlightEntry = this.inFlight.get(key);\n\t\t\t\tif (inFlightEntry?.requestId === requestId) {\n\t\t\t\t\tthis.inFlight.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t})();\n\n\t\tthis.inFlight.set(key, { promise: request, requestId });\n\t\treturn request;\n\t}\n\n\tinvalidate(key: TKey): void {\n\t\tthis.entries.delete(key);\n\t\tthis.inFlight.delete(key);\n\t}\n\n\tclear(): void {\n\t\tthis.entries.clear();\n\t\tthis.inFlight.clear();\n\t}\n\n\tget size(): number {\n\t\treturn this.entries.size;\n\t}\n\n\tprivate isCurrentRequest(key: TKey, requestId: number): boolean {\n\t\treturn this.inFlight.get(key)?.requestId === requestId;\n\t}\n\n\tprivate markAsRecentlyUsed(key: TKey, entry: CacheEntry<TValue>): void {\n\t\tthis.entries.delete(key);\n\t\tthis.entries.set(key, entry);\n\t}\n\n\tprivate setValue(key: TKey, value: TValue): void {\n\t\tthis.entries.delete(key);\n\t\tthis.entries.set(key, {\n\t\t\tvalue,\n\t\t\texpiresAt: this.now() + this.ttlMs,\n\t\t});\n\n\t\tthis.evictLeastRecentlyUsed();\n\t}\n\n\tprivate evictLeastRecentlyUsed(): void {\n\t\twhile (this.entries.size > this.maxSize) {\n\t\t\tconst oldestKey = this.entries.keys().next().value;\n\t\t\tif (oldestKey === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.entries.delete(oldestKey);\n\t\t}\n\t}\n}\n","import type {\n\tExerciseTemplate,\n\tGetV1ExerciseTemplates200,\n} from \"../generated/client/types/index.js\";\nimport { AsyncTtlCache } from \"./cache.js\";\n\ntype HevyClient = ReturnType<typeof import(\"./hevyClientKubb.js\").createClient>;\n\nconst EXERCISE_TEMPLATE_CATALOG_CACHE_KEY = \"exercise-template-catalog\";\nconst EXERCISE_TEMPLATE_CATALOG_CACHE_TTL_MS = 5 * 60 * 1000;\nconst EXERCISE_TEMPLATE_CATALOG_CACHE_MAX_SIZE = 1;\n\nconst exerciseTemplateCatalogCache = new AsyncTtlCache<\n\tstring,\n\tExerciseTemplate[]\n>({\n\tttlMs: EXERCISE_TEMPLATE_CATALOG_CACHE_TTL_MS,\n\tmaxSize: EXERCISE_TEMPLATE_CATALOG_CACHE_MAX_SIZE,\n});\n\nexport type ExerciseTemplateCatalogRefreshReason =\n\t| \"explicit-refresh\"\n\t| \"initial-load\"\n\t| \"ttl-expired\";\n\ninterface ExerciseTemplateCatalogOptions {\n\trefresh?: boolean;\n\tonRefreshed?: (\n\t\tcatalog: ExerciseTemplate[],\n\t\treason: ExerciseTemplateCatalogRefreshReason,\n\t) => void;\n}\n\nfunction getSafePageCount(\n\tdata: GetV1ExerciseTemplates200,\n\tcurrentPage: number,\n) {\n\tconst pageCount = data?.page_count;\n\tif (\n\t\ttypeof pageCount !== \"number\" ||\n\t\t!Number.isSafeInteger(pageCount) ||\n\t\tpageCount < currentPage\n\t) {\n\t\treturn currentPage;\n\t}\n\n\treturn pageCount;\n}\n\nasync function fetchExerciseTemplateCatalog(\n\thevyClient: HevyClient,\n): Promise<ExerciseTemplate[]> {\n\tconst allTemplates: ExerciseTemplate[] = [];\n\tlet page = 1;\n\tlet pageCount = 1;\n\n\tdo {\n\t\tconst data: GetV1ExerciseTemplates200 =\n\t\t\tawait hevyClient.getExerciseTemplates({\n\t\t\t\tpage,\n\t\t\t\tpageSize: 100,\n\t\t\t});\n\n\t\tallTemplates.push(...(data?.exercise_templates ?? []));\n\t\tpageCount = getSafePageCount(data, page);\n\t\tpage++;\n\t} while (page <= pageCount);\n\n\treturn allTemplates;\n}\n\nexport function getExerciseTemplateCatalog(\n\thevyClient: HevyClient,\n\toptions: ExerciseTemplateCatalogOptions = {},\n): Promise<ExerciseTemplate[]> {\n\tconst reason = options.refresh\n\t\t? \"explicit-refresh\"\n\t\t: exerciseTemplateCatalogCache.size === 0\n\t\t\t? \"initial-load\"\n\t\t\t: \"ttl-expired\";\n\n\treturn exerciseTemplateCatalogCache.getOrFetch(\n\t\tEXERCISE_TEMPLATE_CATALOG_CACHE_KEY,\n\t\tasync () => {\n\t\t\tconst catalog = await fetchExerciseTemplateCatalog(hevyClient);\n\t\t\toptions.onRefreshed?.(catalog, reason);\n\t\t\treturn catalog;\n\t\t},\n\t\toptions,\n\t);\n}\n\n/** Reset the exercise template catalog cache (exposed for testing). */\nexport function resetExerciseTemplateCatalogCache(): void {\n\texerciseTemplateCatalogCache.clear();\n}\n","import type {\n\tBodyMeasurement,\n\tExerciseHistoryEntry,\n\tExerciseTemplate,\n\tRoutine,\n\tRoutineFolder,\n\tWorkout,\n} from \"../generated/client/types/index.js\";\nimport type {\n\tFormattedBodyMeasurement,\n\tFormattedExerciseHistoryEntry,\n\tFormattedExerciseTemplate,\n\tFormattedRoutine,\n\tFormattedRoutineFolder,\n\tFormattedWorkout,\n} from \"./output-schemas.js\";\n\nexport type {\n\tFormattedBodyMeasurement,\n\tFormattedExerciseHistoryEntry,\n\tFormattedExerciseTemplate,\n\tFormattedRoutine,\n\tFormattedRoutineExercise,\n\tFormattedRoutineFolder,\n\tFormattedRoutineSet,\n\tFormattedWorkout,\n\tFormattedWorkoutExercise,\n\tFormattedWorkoutSet,\n} from \"./output-schemas.js\";\n\ntype ExerciseWithSupersetVariants = {\n\tsupersets_id?: number | null;\n\tsuperset_id?: number | null;\n};\n\nfunction getSupersetId(exercise: ExerciseWithSupersetVariants): number | null {\n\tif (exercise.superset_id !== undefined) {\n\t\treturn exercise.superset_id;\n\t}\n\n\tif (exercise.supersets_id !== undefined) {\n\t\treturn exercise.supersets_id;\n\t}\n\n\treturn null;\n}\n\n/**\n * Format a workout object for consistent presentation\n *\n * @param workout - The workout object from the API\n * @returns A formatted workout object with standardized properties\n */\nexport function formatWorkout(workout: Workout): FormattedWorkout {\n\treturn {\n\t\tid: workout.id,\n\t\ttitle: workout.title,\n\t\tdescription: workout.description,\n\t\tstartTime: workout.start_time,\n\t\tendTime: workout.end_time,\n\t\tcreatedAt: workout.created_at,\n\t\tupdatedAt: workout.updated_at,\n\t\tduration: calculateDuration(workout.start_time, workout.end_time),\n\t\texercises: workout.exercises?.map((exercise) => {\n\t\t\treturn {\n\t\t\t\tindex: exercise.index,\n\t\t\t\tname: exercise.title,\n\t\t\t\texerciseTemplateId: exercise.exercise_template_id,\n\t\t\t\tnotes: exercise.notes,\n\t\t\t\tsupersetsId: getSupersetId(exercise),\n\t\t\t\tsets: exercise.sets?.map((set) => ({\n\t\t\t\t\tindex: set.index,\n\t\t\t\t\ttype: set.type,\n\t\t\t\t\tweight: set.weight_kg,\n\t\t\t\t\treps: set.reps,\n\t\t\t\t\tdistance: set.distance_meters,\n\t\t\t\t\tduration: set.duration_seconds,\n\t\t\t\t\trpe: set.rpe,\n\t\t\t\t\tcustomMetric: set.custom_metric,\n\t\t\t\t})),\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Format a routine object for consistent presentation\n *\n * @param routine - The routine object from the API\n * @returns A formatted routine object with standardized properties\n */\nexport function formatRoutine(routine: Routine): FormattedRoutine {\n\treturn {\n\t\tid: routine.id,\n\t\ttitle: routine.title,\n\t\tfolderId: routine.folder_id,\n\t\tcreatedAt: routine.created_at,\n\t\tupdatedAt: routine.updated_at,\n\t\texercises: routine.exercises?.map((exercise) => {\n\t\t\treturn {\n\t\t\t\tname: exercise.title,\n\t\t\t\tindex: exercise.index,\n\t\t\t\texerciseTemplateId: exercise.exercise_template_id,\n\t\t\t\tnotes: exercise.notes,\n\t\t\t\tsupersetId: getSupersetId(exercise),\n\t\t\t\trestSeconds: exercise.rest_seconds,\n\t\t\t\tsets: exercise.sets?.map((set) => ({\n\t\t\t\t\tindex: set.index,\n\t\t\t\t\ttype: set.type,\n\t\t\t\t\tweight: set.weight_kg,\n\t\t\t\t\treps: set.reps,\n\t\t\t\t\t...(set.rep_range !== undefined && { repRange: set.rep_range }),\n\t\t\t\t\tdistance: set.distance_meters,\n\t\t\t\t\tduration: set.duration_seconds,\n\t\t\t\t\t...(set.rpe !== undefined && { rpe: set.rpe }),\n\t\t\t\t\tcustomMetric: set.custom_metric,\n\t\t\t\t})),\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Format a routine folder object for consistent presentation\n *\n * @param folder - The routine folder object from the API\n * @returns A formatted routine folder object with standardized properties\n */\nexport function formatRoutineFolder(\n\tfolder: RoutineFolder,\n): FormattedRoutineFolder {\n\treturn {\n\t\tid: folder.id,\n\t\ttitle: folder.title,\n\t\tcreatedAt: folder.created_at,\n\t\tupdatedAt: folder.updated_at,\n\t};\n}\n\n/**\n * Calculate duration between two ISO timestamp strings\n *\n * @param startTime - The start time as ISO string or timestamp\n * @param endTime - The end time as ISO string or timestamp\n * @returns A formatted duration string (e.g. \"1h 30m 45s\") or \"Unknown duration\" if inputs are invalid\n */\nexport function calculateDuration(\n\tstartTime: string | number | null | undefined,\n\tendTime: string | number | null | undefined,\n): string {\n\tif (!startTime || !endTime) return \"Unknown duration\";\n\n\ttry {\n\t\tconst start = new Date(startTime);\n\t\tconst end = new Date(endTime);\n\n\t\t// Validate dates\n\t\tif (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) {\n\t\t\treturn \"Unknown duration\";\n\t\t}\n\n\t\tconst durationMs = end.getTime() - start.getTime();\n\n\t\t// Handle negative durations\n\t\tif (durationMs < 0) {\n\t\t\treturn \"Invalid duration (end time before start time)\";\n\t\t}\n\n\t\tconst hours = Math.floor(durationMs / (1000 * 60 * 60));\n\t\tconst minutes = Math.floor((durationMs % (1000 * 60 * 60)) / (1000 * 60));\n\t\tconst seconds = Math.floor((durationMs % (1000 * 60)) / 1000);\n\n\t\treturn `${hours}h ${minutes}m ${seconds}s`;\n\t} catch (error) {\n\t\tconsole.error(\"Error calculating duration:\", error);\n\t\treturn \"Unknown duration\";\n\t}\n}\n\n/**\n * Format an exercise template object for consistent presentation\n *\n * @param template - The exercise template object from the API\n * @returns A formatted exercise template object with standardized properties\n */\nexport function formatExerciseTemplate(\n\ttemplate: ExerciseTemplate,\n): FormattedExerciseTemplate {\n\treturn {\n\t\tid: template.id,\n\t\ttitle: template.title,\n\t\ttype: template.type,\n\t\tprimaryMuscleGroup: template.primary_muscle_group,\n\t\tsecondaryMuscleGroups: template.secondary_muscle_groups,\n\t\tisCustom: template.is_custom,\n\t};\n}\n\nexport function formatExerciseHistoryEntry(\n\tentry: ExerciseHistoryEntry,\n): FormattedExerciseHistoryEntry {\n\treturn {\n\t\tworkoutId: entry.workout_id,\n\t\tworkoutTitle: entry.workout_title,\n\t\tworkoutStartTime: entry.workout_start_time,\n\t\tworkoutEndTime: entry.workout_end_time,\n\t\texerciseTemplateId: entry.exercise_template_id,\n\t\tweight: entry.weight_kg,\n\t\treps: entry.reps,\n\t\tdistance: entry.distance_meters,\n\t\tduration: entry.duration_seconds,\n\t\trpe: entry.rpe,\n\t\tcustomMetric: entry.custom_metric,\n\t\tsetType: entry.set_type,\n\t};\n}\n\nexport function formatBodyMeasurement(\n\tmeasurement: BodyMeasurement,\n): FormattedBodyMeasurement {\n\treturn {\n\t\tdate: measurement.date,\n\t\tweightKg: measurement.weight_kg ?? null,\n\t\tleanMassKg: measurement.lean_mass_kg ?? null,\n\t\tfatPercent: measurement.fat_percent ?? null,\n\t\tneckCm: measurement.neck_cm ?? null,\n\t\tshoulderCm: measurement.shoulder_cm ?? null,\n\t\tchestCm: measurement.chest_cm ?? null,\n\t\tleftBicepCm: measurement.left_bicep_cm ?? null,\n\t\trightBicepCm: measurement.right_bicep_cm ?? null,\n\t\tleftForearmCm: measurement.left_forearm_cm ?? null,\n\t\trightForearmCm: measurement.right_forearm_cm ?? null,\n\t\tabdomen: measurement.abdomen ?? null,\n\t\twaist: measurement.waist ?? null,\n\t\thips: measurement.hips ?? null,\n\t\tleftThigh: measurement.left_thigh ?? null,\n\t\trightThigh: measurement.right_thigh ?? null,\n\t\tleftCalf: measurement.left_calf ?? null,\n\t\trightCalf: measurement.right_calf ?? null,\n\t};\n}\n","/**\n * Type-safe utilities for MCP tool handlers\n */\n\nimport { z } from \"zod\";\nimport type { McpToolResponse } from \"./response-formatter.js\";\n\nexport const HEVY_CLIENT_NOT_INITIALIZED_ERROR =\n\t\"API client not initialized. Please provide HEVY_API_KEY.\";\n\n/**\n * Assert that the Hevy API client is initialized before running a tool.\n */\nexport function requireClient<TClient>(client: TClient | null): TClient {\n\tif (!client) {\n\t\tthrow new Error(HEVY_CLIENT_NOT_INITIALIZED_ERROR);\n\t}\n\n\treturn client;\n}\n\n/**\n * Infer TypeScript types from Zod schema objects\n *\n * @example\n * ```typescript\n * const schema = {\n * page: z.number(),\n * pageSize: z.number(),\n * } as const;\n *\n * type Params = InferToolParams<typeof schema>; // { page: number; pageSize: number }\n * ```\n */\nexport type InferToolParams<T extends Record<string, z.ZodTypeAny>> = z.infer<\n\tz.ZodObject<T>\n>;\n\n/**\n * Create a type-safe tool handler that validates and narrows args to inferred types\n *\n * This function wraps a handler with automatic Zod validation, ensuring runtime\n * type safety while maintaining compile-time type inference.\n *\n * @param schema - Zod schema object (e.g., { page: z.number(), ... })\n * @param handler - Handler function that receives validated, typed parameters\n * @returns A handler function that accepts Record<string, unknown> and validates it\n *\n * @example\n * ```typescript\n * const schema = {\n * page: z.coerce.number().int().gte(1).default(1),\n * pageSize: z.coerce.number().int().gte(1).lte(10).default(5),\n * } as const;\n *\n * const handler = createTypedToolHandler(schema, async (args) => {\n * // args is fully typed as { page: number; pageSize: number }\n * const { page, pageSize } = args;\n * // ...\n * });\n * ```\n */\nexport function createTypedToolHandler<T extends Record<string, z.ZodTypeAny>>(\n\tschema: T,\n\thandler: (args: InferToolParams<T>) => Promise<McpToolResponse>,\n): (args: Record<string, unknown>) => Promise<McpToolResponse> {\n\tconst zodSchema = z.object(schema);\n\treturn async (args: Record<string, unknown>) => {\n\t\tconst validated = zodSchema.parse(args);\n\t\treturn handler(validated);\n\t};\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type {\n\tGetV1RoutineFolders200,\n\tGetV1WorkoutsCount200,\n\tRoutineFolder,\n\tUserInfoResponse,\n} from \"../generated/client/types/index.js\";\nimport { getExerciseTemplateCatalog } from \"../utils/exercise-template-catalog.js\";\nimport {\n\tformatExerciseTemplate,\n\tformatRoutineFolder,\n} from \"../utils/formatters.js\";\nimport { requireClient } from \"../utils/tool-helpers.js\";\n\ntype HevyClient = ReturnType<\n\ttypeof import(\"../utils/hevyClientKubb.js\").createClient\n>;\n\nconst JSON_MIME_TYPE = \"application/json\";\n\nfunction createJsonResourceResult(uri: URL, data: unknown): ReadResourceResult {\n\treturn {\n\t\tcontents: [\n\t\t\t{\n\t\t\t\turi: uri.toString(),\n\t\t\t\tmimeType: JSON_MIME_TYPE,\n\t\t\t\ttext: JSON.stringify(data),\n\t\t\t},\n\t\t],\n\t};\n}\n\nfunction getSafePageCount(data: GetV1RoutineFolders200, currentPage: number) {\n\tconst pageCount = data?.page_count;\n\tif (\n\t\ttypeof pageCount !== \"number\" ||\n\t\t!Number.isSafeInteger(pageCount) ||\n\t\tpageCount < currentPage\n\t) {\n\t\treturn currentPage;\n\t}\n\n\treturn pageCount;\n}\n\nasync function fetchAllRoutineFolders(\n\thevyClient: HevyClient,\n): Promise<RoutineFolder[]> {\n\tconst allFolders: RoutineFolder[] = [];\n\tlet page = 1;\n\tlet pageCount = 1;\n\n\tdo {\n\t\tconst data: GetV1RoutineFolders200 = await hevyClient.getRoutineFolders({\n\t\t\tpage,\n\t\t\tpageSize: 10,\n\t\t});\n\t\tallFolders.push(...(data?.routine_folders ?? []));\n\t\tpageCount = getSafePageCount(data, page);\n\t\tpage++;\n\t} while (page <= pageCount);\n\n\treturn allFolders;\n}\n\nexport function registerHevyResources(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n): void {\n\tserver.registerResource(\n\t\t\"user-profile\",\n\t\t\"hevy://user\",\n\t\t{\n\t\t\tdescription: \"Authenticated Hevy user profile\",\n\t\t\tmimeType: JSON_MIME_TYPE,\n\t\t},\n\t\tasync (uri) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst data: UserInfoResponse = await client.getUserInfo();\n\t\t\treturn createJsonResourceResult(uri, data?.data ?? null);\n\t\t},\n\t);\n\n\tserver.registerResource(\n\t\t\"workout-count\",\n\t\t\"hevy://workout-count\",\n\t\t{\n\t\t\tdescription: \"Total number of workouts in the Hevy account\",\n\t\t\tmimeType: JSON_MIME_TYPE,\n\t\t},\n\t\tasync (uri) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst data: GetV1WorkoutsCount200 = await client.getWorkoutCount();\n\t\t\treturn createJsonResourceResult(uri, {\n\t\t\t\tcount: data?.workout_count ?? 0,\n\t\t\t});\n\t\t},\n\t);\n\n\tserver.registerResource(\n\t\t\"exercise-templates\",\n\t\t\"hevy://exercise-templates\",\n\t\t{\n\t\t\tdescription: \"Full formatted Hevy exercise template catalog\",\n\t\t\tmimeType: JSON_MIME_TYPE,\n\t\t},\n\t\tasync (uri) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst templates = await getExerciseTemplateCatalog(client);\n\t\t\treturn createJsonResourceResult(\n\t\t\t\turi,\n\t\t\t\ttemplates.map(formatExerciseTemplate),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerResource(\n\t\t\"routine-folders\",\n\t\t\"hevy://routine-folders\",\n\t\t{\n\t\t\tdescription: \"Full formatted list of Hevy routine folders\",\n\t\t\tmimeType: JSON_MIME_TYPE,\n\t\t},\n\t\tasync (uri) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst folders = await fetchAllRoutineFolders(client);\n\t\t\treturn createJsonResourceResult(uri, folders.map(formatRoutineFolder));\n\t\t},\n\t);\n}\n","import { isAxiosError } from \"axios\";\n\n/**\n * Specific error types for better categorization.\n */\nexport enum ErrorType {\n\tAPI_ERROR = \"API_ERROR\",\n\tRATE_LIMIT = \"RATE_LIMIT\",\n\tVALIDATION_ERROR = \"VALIDATION_ERROR\",\n\tNOT_FOUND = \"NOT_FOUND\",\n\tNETWORK_ERROR = \"NETWORK_ERROR\",\n\tUNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\ntype RetryAwareError = {\n\thevyRetryExhausted?: boolean;\n};\n\n/**\n * Determine the type of error based on error characteristics.\n */\nexport function determineErrorType(error: unknown, message: string): ErrorType {\n\tif (\n\t\terror !== null &&\n\t\ttypeof error === \"object\" &&\n\t\t(error as RetryAwareError).hevyRetryExhausted === true\n\t) {\n\t\treturn ErrorType.NETWORK_ERROR;\n\t}\n\n\tif (isAxiosError(error) && error.response?.status === 429) {\n\t\treturn ErrorType.RATE_LIMIT;\n\t}\n\n\tconst messageLower = message.toLowerCase();\n\tconst nameLower = error instanceof Error ? error.name.toLowerCase() : \"\";\n\n\tif (\n\t\tnameLower.includes(\"network\") ||\n\t\tmessageLower.includes(\"network\") ||\n\t\tnameLower.includes(\"fetch\") ||\n\t\tmessageLower.includes(\"fetch\") ||\n\t\tnameLower.includes(\"timeout\") ||\n\t\tmessageLower.includes(\"timeout\")\n\t) {\n\t\treturn ErrorType.NETWORK_ERROR;\n\t}\n\n\tif (\n\t\tnameLower.includes(\"validation\") ||\n\t\tmessageLower.includes(\"validation\") ||\n\t\tmessageLower.includes(\"invalid\") ||\n\t\tmessageLower.includes(\"required\")\n\t) {\n\t\treturn ErrorType.VALIDATION_ERROR;\n\t}\n\n\tif (\n\t\tmessageLower.includes(\"not found\") ||\n\t\tmessageLower.includes(\"404\") ||\n\t\tmessageLower.includes(\"does not exist\")\n\t) {\n\t\treturn ErrorType.NOT_FOUND;\n\t}\n\n\tif (\n\t\tnameLower.includes(\"api\") ||\n\t\tmessageLower.includes(\"api\") ||\n\t\tmessageLower.includes(\"server error\") ||\n\t\tmessageLower.includes(\"500\")\n\t) {\n\t\treturn ErrorType.API_ERROR;\n\t}\n\n\treturn ErrorType.UNKNOWN_ERROR;\n}\n","/**\n * Centralized error handling utility for MCP tools\n */\n\nimport { isAxiosError } from \"axios\";\nimport { determineErrorType, ErrorType } from \"./error-classification.js\";\nimport type { McpToolResponse } from \"./response-formatter.js\";\nimport { Sentry } from \"./telemetry.js\";\n\nexport { ErrorType } from \"./error-classification.js\";\n\n/**\n * Standard error response interface\n */\nexport interface ErrorResponse {\n\tmessage: string;\n\tcode?: string;\n\tdetails?: unknown;\n}\n\ntype RetryAwareError = {\n\thevyRetryCount?: number;\n\thevyRetryExhausted?: boolean;\n};\n\nfunction normalizeHeaderValue(value: unknown): string | undefined {\n\tif (typeof value === \"string\") {\n\t\tconst trimmed = value.trim();\n\t\treturn trimmed.length > 0 ? trimmed : undefined;\n\t}\n\n\tif (typeof value === \"number\" && Number.isFinite(value)) {\n\t\treturn String(value);\n\t}\n\n\tif (Array.isArray(value) && value.length > 0) {\n\t\treturn normalizeHeaderValue(value[0]);\n\t}\n\n\treturn undefined;\n}\n\nfunction getHeaderValue(headers: unknown, key: string): string | undefined {\n\tif (!headers || typeof headers !== \"object\") {\n\t\treturn undefined;\n\t}\n\n\tif (\n\t\t\"get\" in headers &&\n\t\ttypeof (headers as { get?: unknown }).get === \"function\"\n\t) {\n\t\tconst value = (headers as { get: (headerName: string) => unknown }).get(\n\t\t\tkey,\n\t\t);\n\t\treturn normalizeHeaderValue(value);\n\t}\n\n\tconst headerRecord = headers as Record<string, unknown>;\n\treturn normalizeHeaderValue(\n\t\theaderRecord[key] ??\n\t\t\theaderRecord[key.toLowerCase()] ??\n\t\t\theaderRecord[key.toUpperCase()],\n\t);\n}\n\nfunction formatSecondsLabel(seconds: number): string {\n\tconst roundedSeconds = Math.max(0, Math.round(seconds));\n\tconst suffix = roundedSeconds === 1 ? \"\" : \"s\";\n\treturn `${roundedSeconds} second${suffix}`;\n}\n\nfunction getRateLimitMessage(error: unknown): string {\n\tif (!isAxiosError(error)) {\n\t\treturn \"Rate limited by Hevy. Please wait and retry.\";\n\t}\n\n\tconst retryAfterHeader = getHeaderValue(\n\t\terror.response?.headers,\n\t\t\"retry-after\",\n\t);\n\tif (!retryAfterHeader) {\n\t\treturn \"Rate limited by Hevy (HTTP 429). Please wait and retry your request.\";\n\t}\n\n\tconst seconds = Number(retryAfterHeader);\n\tif (Number.isFinite(seconds) && seconds >= 0) {\n\t\treturn `Rate limited by Hevy (HTTP 429). Please wait about ${formatSecondsLabel(seconds)} before retrying.`;\n\t}\n\n\tconst retryAtMillis = Date.parse(retryAfterHeader);\n\tif (!Number.isNaN(retryAtMillis)) {\n\t\tconst secondsUntilRetry = Math.ceil(\n\t\t\tMath.max(0, retryAtMillis - Date.now()) / 1000,\n\t\t);\n\t\treturn `Rate limited by Hevy (HTTP 429). Please wait about ${formatSecondsLabel(secondsUntilRetry)} before retrying.`;\n\t}\n\n\treturn \"Rate limited by Hevy (HTTP 429). Please wait and retry your request.\";\n}\n\nfunction isRetryExhaustedError(error: unknown): boolean {\n\treturn (\n\t\t!!error &&\n\t\ttypeof error === \"object\" &&\n\t\t(error as RetryAwareError).hevyRetryExhausted === true\n\t);\n}\n\nfunction getRetryExhaustedMessage(error: unknown): string {\n\tconst retryCount =\n\t\ttypeof error === \"object\" && error !== null\n\t\t\t? (error as RetryAwareError).hevyRetryCount\n\t\t\t: undefined;\n\tconst attemptCount =\n\t\ttypeof retryCount === \"number\" && Number.isFinite(retryCount)\n\t\t\t? retryCount + 1\n\t\t\t: undefined;\n\n\tif (attemptCount) {\n\t\treturn `Unable to complete the request after ${attemptCount} attempts to the Hevy API due to transient failures. Please try again shortly.`;\n\t}\n\n\treturn \"Unable to complete the request after multiple attempts to the Hevy API due to transient failures. Please try again shortly.\";\n}\n\nfunction getUserFacingMessage(error: unknown, defaultMessage: string): string {\n\tif (isRetryExhaustedError(error)) {\n\t\treturn getRetryExhaustedMessage(error);\n\t}\n\n\tif (isAxiosError(error) && error.response?.status === 429) {\n\t\treturn getRateLimitMessage(error);\n\t}\n\n\treturn defaultMessage;\n}\n\n/**\n * Enhanced error response with type categorization\n */\nexport interface EnhancedErrorResponse extends ErrorResponse {\n\ttype: ErrorType;\n}\n\n/**\n * Structured debug context that preserves original error details\n */\nexport interface ErrorDebugContext {\n\tsourceContext?: string;\n\toriginalErrorMessage: string;\n\terrorCode?: string;\n\terrorType: ErrorType;\n\taxios?: {\n\t\tstatus?: number;\n\t\tstatusText?: string;\n\t\tdata?: unknown;\n\t\tmethod?: string;\n\t\turl?: string;\n\t};\n}\n\n/**\n * Create a standardized error response for MCP tools\n *\n * @param error - The error object or message\n * @param context - Optional context information about where the error occurred\n * @returns A formatted MCP tool response with error information\n */\nexport function createErrorResponse(\n\terror: unknown,\n\tcontext?: string,\n): McpToolResponse {\n\tconst originalErrorMessage = extractErrorMessage(error);\n\tlet errorMessage = originalErrorMessage;\n\tconst axiosErrorContext = extractAxiosErrorContext(error);\n\tconst mappedHevyErrorMessage = mapHevyErrorMessageByStatus(\n\t\taxiosErrorContext?.status,\n\t);\n\n\tif (mappedHevyErrorMessage) {\n\t\terrorMessage = mappedHevyErrorMessage;\n\t}\n\n\t// Check for axios error with response data\n\tif (!mappedHevyErrorMessage && axiosErrorContext?.data) {\n\t\terrorMessage = stringifyErrorData(axiosErrorContext.data);\n\t}\n\n\terrorMessage = getUserFacingMessage(error, errorMessage);\n\n\t// Extract error code if available (for logging purposes)\n\tconst errorCode =\n\t\terror instanceof Error && \"code\" in error\n\t\t\t? (error as { code?: string }).code\n\t\t\t: undefined;\n\n\t// Determine error type based on error characteristics\n\tconst errorType = determineErrorType(error, errorMessage);\n\tconst errorContext: ErrorDebugContext = {\n\t\tsourceContext: context,\n\t\toriginalErrorMessage,\n\t\terrorCode,\n\t\terrorType,\n\t\taxios: axiosErrorContext ?? undefined,\n\t};\n\n\tconst contextPrefix = context ? `[${context}] ` : \"\";\n\tconst formattedMessage = `${contextPrefix}Error: ${errorMessage}`;\n\tconst errorCodeSuffix = errorCode ? `, Code: ${errorCode}` : \"\";\n\n\t// Log the error for server-side debugging with type information\n\tconsole.error(\n\t\t`${formattedMessage} (Type: ${errorType}${errorCodeSuffix})`,\n\t\terror,\n\t);\n\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\" as const,\n\t\t\t\ttext: formattedMessage,\n\t\t\t},\n\t\t],\n\t\tisError: true,\n\t\terrorContext,\n\t};\n}\n\nfunction extractErrorMessage(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\n\tif (typeof error === \"string\") {\n\t\treturn error;\n\t}\n\n\tif (\n\t\terror &&\n\t\ttypeof error === \"object\" &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\"\n\t) {\n\t\treturn error.message;\n\t}\n\n\tif (error && typeof error === \"object\") {\n\t\ttry {\n\t\t\treturn JSON.stringify(error);\n\t\t} catch (_e) {\n\t\t\treturn \"Unknown error object\";\n\t\t}\n\t}\n\n\treturn String(error);\n}\n\nfunction extractAxiosErrorContext(\n\terror: unknown,\n): ErrorDebugContext[\"axios\"] | null {\n\tif (!isAxiosError(error)) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tstatus: error.response?.status,\n\t\tstatusText: error.response?.statusText,\n\t\tdata: error.response?.data,\n\t\tmethod: error.config?.method,\n\t\turl: error.config?.url,\n\t};\n}\n\nfunction mapHevyErrorMessageByStatus(status?: number): string | null {\n\tif (status === 401 || status === 403) {\n\t\treturn \"The Hevy API key is invalid or has expired. Check HEVY_API_KEY.\";\n\t}\n\n\tif (status === 404) {\n\t\treturn \"The requested resource was not found in Hevy.\";\n\t}\n\n\tif (status === 409) {\n\t\treturn \"A conflict occurred (e.g., a body measurement already exists for this date). Use the update tool instead.\";\n\t}\n\n\tif (status === 422) {\n\t\treturn \"The request failed Hevy validation. Check the field values and try again.\";\n\t}\n\n\tif (status === 429) {\n\t\treturn \"Rate limited by Hevy. Please wait and retry.\";\n\t}\n\n\tif (status && status >= 500 && status <= 599) {\n\t\treturn \"Hevy API experienced an error. Please retry later.\";\n\t}\n\n\treturn null;\n}\n\nfunction stringifyErrorData(data: unknown): string {\n\tif (typeof data === \"string\") {\n\t\treturn data;\n\t}\n\n\tif (data && typeof data === \"object\") {\n\t\ttry {\n\t\t\treturn JSON.stringify(data);\n\t\t} catch (_e) {\n\t\t\treturn \"Unable to serialize error response data\";\n\t\t}\n\t}\n\n\treturn String(data);\n}\n\n/**\n * Wrap an async function with standardized error handling\n *\n * This function preserves the parameter types of the wrapped function while\n * providing error handling. The returned function accepts Record<string, unknown>\n * (as required by MCP SDK) but internally casts to the original parameter type.\n *\n * @param fn - The async function to wrap\n * @param context - Context information for error messages\n * @returns A function that catches errors and returns standardized error responses\n */\nexport function withErrorHandling<TParams extends Record<string, unknown>>(\n\tfn: (args: TParams) => Promise<McpToolResponse>,\n\tcontext: string,\n): (args: Record<string, unknown>) => Promise<McpToolResponse> {\n\treturn async (rawArgs: Record<string, unknown>) => {\n\t\tconst args = rawArgs ?? {};\n\t\ttry {\n\t\t\treturn await fn(args as TParams);\n\t\t} catch (error) {\n\t\t\tSentry.withScope((scope) => {\n\t\t\t\tscope.setTag(\"mcp.tool.context\", context);\n\t\t\t\tscope.setContext(\"mcpTool\", {\n\t\t\t\t\tcontext,\n\t\t\t\t\targumentKeyCount: Object.keys(args).length,\n\t\t\t\t});\n\t\t\t\tSentry.captureException(error);\n\t\t\t});\n\n\t\t\treturn createErrorResponse(error, context);\n\t\t}\n\t};\n}\n","const DEBUG_PREFIX = \"[hevy-mcp:debug] \";\nconst MAX_DEBUG_RECORD_LENGTH = 8_192;\nconst MAX_REDACTION_DEPTH = 4;\nconst MAX_OBJECT_KEYS = 20;\n\ntype RedactedValue =\n\t| number\n\t| string\n\t| {\n\t\t\ttype: \"array\";\n\t\t\tlength: number;\n\t\t\titems: Record<string, RedactedValue> | \"[max-depth]\";\n\t\t\ttruncatedItems?: number;\n\t }\n\t| {\n\t\t\ttype: \"object\";\n\t\t\tfieldCount: number;\n\t\t\tfields: Record<string, RedactedValue> | \"[max-depth]\";\n\t\t\ttruncatedFields?: number;\n\t };\n\nexport function isDebugEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n\treturn env.HEVY_MCP_DEBUG === \"1\";\n}\n\nfunction redactValue(\n\tvalue: unknown,\n\tdepth: number,\n\tseen: WeakSet<object>,\n): RedactedValue {\n\tif (value === null) {\n\t\treturn \"[null]\";\n\t}\n\n\tif (typeof value !== \"object\") {\n\t\treturn `[${typeof value}]`;\n\t}\n\n\tif (seen.has(value)) {\n\t\treturn \"[circular]\";\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tconst lengthDescriptor = Object.getOwnPropertyDescriptor(value, \"length\");\n\t\tconst length =\n\t\t\tlengthDescriptor &&\n\t\t\t\"value\" in lengthDescriptor &&\n\t\t\ttypeof lengthDescriptor.value === \"number\"\n\t\t\t\t? lengthDescriptor.value\n\t\t\t\t: 0;\n\t\tif (depth >= MAX_REDACTION_DEPTH) {\n\t\t\treturn { type: \"array\", length, items: \"[max-depth]\" };\n\t\t}\n\n\t\tseen.add(value);\n\t\ttry {\n\t\t\tconst itemCount = Math.min(length, MAX_OBJECT_KEYS);\n\t\t\tconst items: Record<string, RedactedValue> = {};\n\t\t\tfor (let index = 0; index < itemCount; index += 1) {\n\t\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(\n\t\t\t\t\tvalue,\n\t\t\t\t\tString(index),\n\t\t\t\t);\n\t\t\t\titems[`item-${index + 1}`] =\n\t\t\t\t\tdescriptor && \"value\" in descriptor\n\t\t\t\t\t\t? redactValue(descriptor.value, depth + 1, seen)\n\t\t\t\t\t\t: \"[empty-or-accessor]\";\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttype: \"array\",\n\t\t\t\tlength,\n\t\t\t\titems,\n\t\t\t\t...(length > MAX_OBJECT_KEYS\n\t\t\t\t\t? { truncatedItems: length - MAX_OBJECT_KEYS }\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t} finally {\n\t\t\tseen.delete(value);\n\t\t}\n\t}\n\n\tconst keys = Object.keys(value);\n\tif (depth >= MAX_REDACTION_DEPTH) {\n\t\treturn {\n\t\t\ttype: \"object\",\n\t\t\tfieldCount: keys.length,\n\t\t\tfields: \"[max-depth]\",\n\t\t};\n\t}\n\n\tseen.add(value);\n\ttry {\n\t\tconst fields: Record<string, RedactedValue> = {};\n\t\tfor (const [index, rawKey] of keys.slice(0, MAX_OBJECT_KEYS).entries()) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(value, rawKey);\n\t\t\tfields[`field-${index + 1}`] =\n\t\t\t\tdescriptor && \"value\" in descriptor\n\t\t\t\t\t? redactValue(descriptor.value, depth + 1, seen)\n\t\t\t\t\t: \"[accessor]\";\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"object\",\n\t\t\tfieldCount: keys.length,\n\t\t\tfields,\n\t\t\t...(keys.length > MAX_OBJECT_KEYS\n\t\t\t\t? { truncatedFields: keys.length - MAX_OBJECT_KEYS }\n\t\t\t\t: {}),\n\t\t};\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Redact every input scalar while preserving bounded argument structure. */\nexport function redactToolArgs(args: unknown): RedactedValue {\n\ttry {\n\t\treturn redactValue(args, 0, new WeakSet<object>());\n\t} catch {\n\t\treturn \"[unavailable]\";\n\t}\n}\n\n/**\n * Write a single bounded structured debug record to stderr without throwing.\n */\nexport function debugLog(event: string, data: Record<string, unknown>): void {\n\tif (!isDebugEnabled()) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst record = JSON.stringify({ event, ...data });\n\t\tconst output =\n\t\t\trecord.length <= MAX_DEBUG_RECORD_LENGTH\n\t\t\t\t? record\n\t\t\t\t: JSON.stringify({ event, truncated: true });\n\t\tprocess.stderr.write(`${DEBUG_PREFIX}${output}\\n`);\n\t} catch {\n\t\t// Diagnostics must never affect tool or API behavior.\n\t}\n}\n","import { SpanStatusCode } from \"@opentelemetry/api\";\nimport { debugLog, isDebugEnabled, redactToolArgs } from \"./debug.js\";\nimport { determineErrorType } from \"./error-classification.js\";\nimport { toolDuration, toolErrors, toolInvocations } from \"./metrics.js\";\nimport type { McpToolResponse } from \"./response-formatter.js\";\nimport { getCurrentUserId, tracer } from \"./telemetry.js\";\n\n/** Whitelist of safe argument keys that can be logged without exposing PII. */\nconst ARGUMENT_WHITELIST = new Set([\n\t\"page\",\n\t\"pageSize\",\n\t\"since\",\n\t\"workoutId\",\n\t\"routineId\",\n\t\"folderId\",\n\t\"exerciseTemplateId\",\n\t\"date\",\n\t\"startDate\",\n\t\"endDate\",\n\t\"updatedSince\",\n\t\"includeCustom\",\n\t\"limit\",\n\t\"offset\",\n\t\"refresh\",\n\t\"query\",\n\t\"primaryMuscleGroup\",\n]);\n\nfunction extractSafeArgs(\n\targs: Record<string, unknown>,\n): Record<string, string | number | boolean> {\n\tconst attributes: Record<string, string | number | boolean> = {};\n\tfor (const [key, value] of Object.entries(args)) {\n\t\tif (!ARGUMENT_WHITELIST.has(key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (\n\t\t\ttypeof value !== \"string\" &&\n\t\t\ttypeof value !== \"number\" &&\n\t\t\ttypeof value !== \"boolean\"\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tattributes[`mcp.tool.args.${key}`] =\n\t\t\tkey === \"query\" && typeof value === \"string\" && value.length > 100\n\t\t\t\t? `${value.slice(0, 100)}...`\n\t\t\t\t: value;\n\t}\n\treturn attributes;\n}\n\n/**\n * Wrap an MCP tool handler with its existing OpenTelemetry span and metrics.\n */\nexport function withTelemetry<TParams extends Record<string, unknown>>(\n\tfn: (args: TParams) => Promise<McpToolResponse>,\n\tcontext: string,\n): (args: Record<string, unknown>) => Promise<McpToolResponse> {\n\treturn async (rawArgs: Record<string, unknown>) => {\n\t\tconst args = rawArgs ?? {};\n\t\tif (isDebugEnabled()) {\n\t\t\tdebugLog(\"tool_invocation\", {\n\t\t\t\ttool: context,\n\t\t\t\tparams: redactToolArgs(args),\n\t\t\t});\n\t\t}\n\t\tconst argumentKeyCount = Object.keys(args).length;\n\t\tconst startTime = Date.now();\n\t\tlet isError = false;\n\n\t\ttoolInvocations.add(1, { tool_name: context });\n\n\t\tconst userId = getCurrentUserId();\n\t\tconst safeArgs = extractSafeArgs(args);\n\t\tconst whitelistedKeys = Object.keys(safeArgs).map((key) =>\n\t\t\tkey.replace(\"mcp.tool.args.\", \"\"),\n\t\t);\n\n\t\treturn tracer.startActiveSpan(\n\t\t\t`mcp.tool.${context}`,\n\t\t\t{\n\t\t\t\tattributes: {\n\t\t\t\t\t\"mcp.tool.name\": context,\n\t\t\t\t\t\"mcp.tool.args.key_count\": argumentKeyCount,\n\t\t\t\t\t\"mcp.tool.args.keys\": whitelistedKeys.join(\",\"),\n\t\t\t\t\t...(userId ? { \"user.id\": userId } : {}),\n\t\t\t\t\t...safeArgs,\n\t\t\t\t},\n\t\t\t},\n\t\t\tasync (span) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await fn(args as TParams);\n\t\t\t\t\tisError = Boolean(result.isError);\n\t\t\t\t\tspan.setStatus({\n\t\t\t\t\t\tcode: isError ? SpanStatusCode.ERROR : SpanStatusCode.OK,\n\t\t\t\t\t});\n\t\t\t\t\tspan.setAttribute(\"mcp.tool.result.is_error\", isError);\n\t\t\t\t\tif (result.content) {\n\t\t\t\t\t\tspan.setAttribute(\n\t\t\t\t\t\t\t\"mcp.tool.result.content_count\",\n\t\t\t\t\t\t\tresult.content.length,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst textLength = result.content.reduce(\n\t\t\t\t\t\t\t(sum, item) => sum + (item.text?.length ?? 0),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tspan.setAttribute(\"mcp.tool.result.text_length\", textLength);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tisError = true;\n\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\tspan.recordException(error as Error);\n\n\t\t\t\t\tconst errorType = determineErrorType(\n\t\t\t\t\t\terror,\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\t);\n\t\t\t\t\tspan.setAttribute(\"error.type\", errorType);\n\n\t\t\t\t\tconst rawCode =\n\t\t\t\t\t\terror instanceof Error && \"code\" in error\n\t\t\t\t\t\t\t? (error as { code?: unknown }).code\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\tif (rawCode !== undefined && rawCode !== null) {\n\t\t\t\t\t\tspan.setAttribute(\"error.code\", String(rawCode as string | number));\n\t\t\t\t\t}\n\n\t\t\t\t\ttoolErrors.add(1, {\n\t\t\t\t\t\ttool_name: context,\n\t\t\t\t\t\terror_type: errorType,\n\t\t\t\t\t});\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\ttoolDuration.record(Date.now() - startTime, {\n\t\t\t\t\t\ttool_name: context,\n\t\t\t\t\t\tis_error: String(isError),\n\t\t\t\t\t});\n\t\t\t\t\tspan.end();\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t};\n}\n","import { withErrorHandling } from \"./error-handler.js\";\nimport type { McpToolResponse } from \"./response-formatter.js\";\nimport { withTelemetry } from \"./telemetry-wrapper.js\";\n\n/**\n * Wrap an MCP tool handler with telemetry inside error response handling.\n */\nexport function withObservability<TParams extends Record<string, unknown>>(\n\tfn: (args: TParams) => Promise<McpToolResponse>,\n\tcontext: string,\n): (args: Record<string, unknown>) => Promise<McpToolResponse> {\n\treturn withErrorHandling(withTelemetry(fn, context), context);\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport { z } from \"zod/v4\";\n\nexport const userInfoSchema = z.object({\n id: z.optional(z.string().describe(\"The user ID.\")),\n name: z.optional(z.string().describe(\"The user's display name.\")),\n url: z.optional(z.string().describe(\"The user's public profile URL.\")),\n});\n","import { z } from \"zod\";\n\nimport { userInfoSchema } from \"../generated/client/schemas/userInfoSchema.js\";\n\nconst optionalNullableNumber = z.number().nullable().optional();\n\nexport const formattedWorkoutSetSchema = z.object({\n\tindex: z.number().optional(),\n\ttype: z.string().optional(),\n\tweight: optionalNullableNumber,\n\treps: optionalNullableNumber,\n\tdistance: optionalNullableNumber,\n\tduration: optionalNullableNumber,\n\trpe: optionalNullableNumber,\n\tcustomMetric: optionalNullableNumber,\n});\n\nexport const formattedWorkoutExerciseSchema = z.object({\n\tindex: z.number().optional(),\n\tname: z.string().optional(),\n\texerciseTemplateId: z.string().optional(),\n\tnotes: z.string().nullable().optional(),\n\tsupersetsId: optionalNullableNumber,\n\tsets: z.array(formattedWorkoutSetSchema).optional(),\n});\n\nexport const formattedWorkoutSchema = z.object({\n\tid: z.string().optional(),\n\ttitle: z.string().optional(),\n\tdescription: z.string().nullable().optional(),\n\tstartTime: z.union([z.string(), z.number()]).optional(),\n\tendTime: z.union([z.string(), z.number()]).optional(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n\tduration: z.string(),\n\texercises: z.array(formattedWorkoutExerciseSchema).optional(),\n});\n\nexport const formattedRoutineSetSchema = z.object({\n\tindex: z.number().optional(),\n\ttype: z.string().optional(),\n\tweight: optionalNullableNumber,\n\treps: optionalNullableNumber,\n\tdistance: optionalNullableNumber,\n\tduration: optionalNullableNumber,\n\tcustomMetric: optionalNullableNumber,\n\trepRange: z\n\t\t.object({\n\t\t\tstart: z.number().nullable().optional(),\n\t\t\tend: z.number().nullable().optional(),\n\t\t})\n\t\t.nullable()\n\t\t.optional(),\n\trpe: optionalNullableNumber,\n});\n\nexport const formattedRoutineExerciseSchema = z.object({\n\tname: z.string().optional(),\n\tindex: z.number().optional(),\n\texerciseTemplateId: z.string().optional(),\n\tnotes: z.string().nullable().optional(),\n\tsupersetId: optionalNullableNumber,\n\trestSeconds: z.union([z.string(), z.number()]).nullable().optional(),\n\tsets: z.array(formattedRoutineSetSchema).optional(),\n});\n\nexport const formattedRoutineSchema = z.object({\n\tid: z.string().optional(),\n\ttitle: z.string().optional(),\n\tfolderId: z.number().nullable().optional(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n\texercises: z.array(formattedRoutineExerciseSchema).optional(),\n});\n\nexport const formattedRoutineFolderSchema = z.object({\n\tid: z.number().optional(),\n\ttitle: z.string().optional(),\n\tcreatedAt: z.string().optional(),\n\tupdatedAt: z.string().optional(),\n});\n\nexport const formattedExerciseTemplateSchema = z.object({\n\tid: z.string().optional(),\n\ttitle: z.string().optional(),\n\ttype: z.string().optional(),\n\tprimaryMuscleGroup: z.string().optional(),\n\tsecondaryMuscleGroups: z.array(z.string()).optional(),\n\tisCustom: z.boolean().optional(),\n});\n\nexport const formattedExerciseHistoryEntrySchema = z.object({\n\tworkoutId: z.string().optional(),\n\tworkoutTitle: z.string().optional(),\n\tworkoutStartTime: z.string().optional(),\n\tworkoutEndTime: z.string().optional(),\n\texerciseTemplateId: z.string().optional(),\n\tweight: optionalNullableNumber,\n\treps: optionalNullableNumber,\n\tdistance: optionalNullableNumber,\n\tduration: optionalNullableNumber,\n\trpe: optionalNullableNumber,\n\tcustomMetric: optionalNullableNumber,\n\tsetType: z.string().optional(),\n});\n\nexport const formattedBodyMeasurementSchema = z.object({\n\tdate: z.string(),\n\tweightKg: z.number().nullable(),\n\tleanMassKg: z.number().nullable(),\n\tfatPercent: z.number().nullable(),\n\tneckCm: z.number().nullable(),\n\tshoulderCm: z.number().nullable(),\n\tchestCm: z.number().nullable(),\n\tleftBicepCm: z.number().nullable(),\n\trightBicepCm: z.number().nullable(),\n\tleftForearmCm: z.number().nullable(),\n\trightForearmCm: z.number().nullable(),\n\tabdomen: z.number().nullable(),\n\twaist: z.number().nullable(),\n\thips: z.number().nullable(),\n\tleftThigh: z.number().nullable(),\n\trightThigh: z.number().nullable(),\n\tleftCalf: z.number().nullable(),\n\trightCalf: z.number().nullable(),\n});\n\nexport type FormattedWorkoutSet = z.infer<typeof formattedWorkoutSetSchema>;\nexport type FormattedWorkoutExercise = z.infer<\n\ttypeof formattedWorkoutExerciseSchema\n>;\nexport type FormattedWorkout = z.infer<typeof formattedWorkoutSchema>;\nexport type FormattedRoutineSet = z.infer<typeof formattedRoutineSetSchema>;\nexport type FormattedRoutineExercise = z.infer<\n\ttypeof formattedRoutineExerciseSchema\n>;\nexport type FormattedRoutine = z.infer<typeof formattedRoutineSchema>;\nexport type FormattedRoutineFolder = z.infer<\n\ttypeof formattedRoutineFolderSchema\n>;\nexport type FormattedExerciseTemplate = z.infer<\n\ttypeof formattedExerciseTemplateSchema\n>;\nexport type FormattedExerciseHistoryEntry = z.infer<\n\ttypeof formattedExerciseHistoryEntrySchema\n>;\nexport type FormattedBodyMeasurement = z.infer<\n\ttypeof formattedBodyMeasurementSchema\n>;\n\nexport const workoutsOutputSchema = {\n\tworkouts: z.array(formattedWorkoutSchema),\n} as const;\nexport const workoutOutputSchema = {\n\tworkout: formattedWorkoutSchema.nullable(),\n} as const;\nexport const workoutCountOutputSchema = { count: z.number().int() } as const;\nexport const formattedUpdatedWorkoutSchema = z.object({\n\ttype: z.literal(\"updated\"),\n\tworkout: formattedWorkoutSchema,\n});\n\nexport const formattedDeletedWorkoutSchema = z.object({\n\ttype: z.literal(\"deleted\"),\n\tid: z.string(),\n\tdeletedAt: z.string().optional(),\n});\n\nexport const workoutEventsOutputSchema = {\n\tevents: z.array(\n\t\tz.union([formattedUpdatedWorkoutSchema, formattedDeletedWorkoutSchema]),\n\t),\n} as const;\nexport const routinesOutputSchema = {\n\troutines: z.array(formattedRoutineSchema),\n} as const;\nexport const routineOutputSchema = {\n\troutine: formattedRoutineSchema.nullable(),\n} as const;\nexport const exerciseTemplatesOutputSchema = {\n\texerciseTemplates: z.array(formattedExerciseTemplateSchema),\n} as const;\nexport const exerciseTemplateOutputSchema = {\n\texerciseTemplate: formattedExerciseTemplateSchema.nullable(),\n} as const;\nexport const exerciseHistoryOutputSchema = {\n\texerciseHistory: z.array(formattedExerciseHistoryEntrySchema),\n} as const;\nexport const routineFoldersOutputSchema = {\n\troutineFolders: z.array(formattedRoutineFolderSchema),\n} as const;\nexport const routineFolderOutputSchema = {\n\troutineFolder: formattedRoutineFolderSchema.nullable(),\n} as const;\nexport const bodyMeasurementsOutputSchema = {\n\tbodyMeasurements: z.array(formattedBodyMeasurementSchema),\n} as const;\nexport const bodyMeasurementOutputSchema = {\n\tbodyMeasurement: formattedBodyMeasurementSchema.nullable(),\n} as const;\nexport const userOutputSchema = { user: userInfoSchema.nullable() } as const;\n","import type {\n\tCallToolResult,\n\tTextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * MCP tool response type aligned with MCP SDK CallToolResult while keeping\n * content narrowed to text blocks for this server.\n */\nexport type McpToolResponse = Omit<CallToolResult, \"content\"> & {\n\tcontent: TextContent[];\n};\n\nexport type StructuredMcpToolResponse<T extends Record<string, unknown>> =\n\tMcpToolResponse & {\n\t\tstructuredContent: T;\n\t};\n\n/**\n * Format options for JSON responses\n */\nexport interface JsonFormatOptions {\n\t/** Whether to pretty-print the JSON with indentation */\n\tpretty?: boolean;\n\t/** Indentation spaces for pretty-printing (default: 2) */\n\tindent?: number;\n}\n\n/**\n * Create a standardized success response with JSON data\n *\n * @param data - The data to include in the response\n * @param options - Formatting options\n * @returns A formatted MCP tool response with the data as JSON\n */\nexport function createJsonResponse(\n\tdata: unknown,\n\toptions: JsonFormatOptions = { pretty: true, indent: 2 },\n): McpToolResponse {\n\tconst jsonString =\n\t\t(options.pretty\n\t\t\t? JSON.stringify(data, null, options.indent)\n\t\t\t: JSON.stringify(data)) ?? \"null\";\n\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: jsonString,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * Create a JSON text response with a typed machine-readable payload.\n *\n * The text content is produced by the legacy JSON formatter so existing MCP\n * clients receive byte-for-byte identical output.\n */\nexport function createStructuredJsonResponse<T extends Record<string, unknown>>(\n\tdata: unknown,\n\tstructuredContent: T,\n\toptions: JsonFormatOptions = { pretty: true, indent: 2 },\n): StructuredMcpToolResponse<T> {\n\treturn {\n\t\t...createJsonResponse(data, options),\n\t\tstructuredContent,\n\t};\n}\n\n/**\n * Create a standardized success response with text data\n *\n * @param message - The text message to include in the response\n * @returns A formatted MCP tool response with the text message\n */\nexport function createTextResponse(message: string): McpToolResponse {\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: message,\n\t\t\t},\n\t\t],\n\t};\n}\n\n/**\n * Create a standardized success response for empty or null results\n *\n * @param message - Optional message to include (default: \"No data found\")\n * @returns A formatted MCP tool response for empty results\n */\nexport function createEmptyResponse(\n\tmessage = \"No data found\",\n): McpToolResponse {\n\treturn createTextResponse(message);\n}\n\n/**\n * Create an empty/not-found text response with a valid structured payload.\n */\nexport function createStructuredEmptyResponse<\n\tT extends Record<string, unknown>,\n>(message: string, structuredContent: T): StructuredMcpToolResponse<T> {\n\treturn {\n\t\t...createEmptyResponse(message),\n\t\tstructuredContent,\n\t};\n}\n","/**\n * Shared MCP tool annotation factories.\n *\n * All hevy-mcp tools talk to the Hevy API, a closed, fully specified domain\n * limited to the authenticated user's own data, so openWorldHint is false\n * across the board.\n */\n\nimport type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\n\n/** Read-only tools (get-*, search-*): no side effects. */\nexport function readOnlyAnnotations(title: string): ToolAnnotations {\n\treturn { title, readOnlyHint: true, openWorldHint: false };\n}\n\n/** Create tools (create-*): additive writes, repeating creates duplicates. */\nexport function createAnnotations(title: string): ToolAnnotations {\n\treturn {\n\t\ttitle,\n\t\treadOnlyHint: false,\n\t\tdestructiveHint: false,\n\t\tidempotentHint: false,\n\t\topenWorldHint: false,\n\t};\n}\n\n/**\n * Update tools (update-*): PUT-style overwrites that replace prior data,\n * hence destructive; repeating the same call yields the same state.\n */\nexport function updateAnnotations(title: string): ToolAnnotations {\n\treturn {\n\t\ttitle,\n\t\treadOnlyHint: false,\n\t\tdestructiveHint: true,\n\t\tidempotentHint: true,\n\t\topenWorldHint: false,\n\t};\n}\n\n/** Delete tools (delete-*): destructive and idempotent. */\nexport function destructiveAnnotations(title: string): ToolAnnotations {\n\treturn {\n\t\ttitle,\n\t\treadOnlyHint: false,\n\t\tdestructiveHint: true,\n\t\tidempotentHint: true,\n\t\topenWorldHint: false,\n\t};\n}\n","interface ToolDescriptionParts {\n\tsummary: string;\n\taliases: readonly string[];\n\tuseCase: string;\n\timportantNotes: string;\n}\n\nexport function describeTool({\n\tsummary,\n\taliases,\n\tuseCase,\n\timportantNotes,\n}: ToolDescriptionParts): string {\n\treturn [\n\t\tsummary,\n\t\t`Aliases: ${aliases.join(\", \")}.`,\n\t\t`<use_case>${useCase}</use_case>`,\n\t\t`<important_notes>${importantNotes}</important_notes>`,\n\t].join(\" \");\n}\n","import { z } from \"zod\";\n\nfunction coerceNullishNumberInput(value: unknown): unknown {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value !== \"string\") {\n\t\treturn value;\n\t}\n\n\tconst trimmed = value.trim();\n\tif (trimmed === \"\") {\n\t\treturn undefined;\n\t}\n\n\tconst lowered = trimmed.toLowerCase();\n\tif (lowered === \"null\") {\n\t\treturn null;\n\t}\n\tif (lowered === \"undefined\") {\n\t\treturn undefined;\n\t}\n\n\tconst asNumber = Number(trimmed);\n\tif (Number.isNaN(asNumber)) {\n\t\treturn value;\n\t}\n\n\treturn asNumber;\n}\n\nexport const zNullableInt = z.preprocess(\n\tcoerceNullishNumberInput,\n\tz.number().int().nullable().optional(),\n);\n\nexport const zNullableNumber = z.preprocess(\n\t(value) => (value === \"\" ? undefined : value),\n\tz.coerce.number().nullable().optional(),\n);\n\nexport const zOptionalRepRange = z.preprocess(\n\t(value) => (value === null ? undefined : value),\n\tz\n\t\t.object({\n\t\t\tstart: zNullableInt,\n\t\t\tend: zNullableInt,\n\t\t})\n\t\t.optional(),\n);\n\nconst setTypeValues = [\"warmup\", \"normal\", \"failure\", \"dropset\"] as const;\nexport const setTypeEnum = z.enum(setTypeValues).default(\"normal\");\n\nconst muscleGroupValues = [\n\t\"abdominals\",\n\t\"shoulders\",\n\t\"biceps\",\n\t\"triceps\",\n\t\"forearms\",\n\t\"quadriceps\",\n\t\"hamstrings\",\n\t\"calves\",\n\t\"glutes\",\n\t\"abductors\",\n\t\"adductors\",\n\t\"lats\",\n\t\"upper_back\",\n\t\"traps\",\n\t\"lower_back\",\n\t\"chest\",\n\t\"cardio\",\n\t\"neck\",\n\t\"full_body\",\n\t\"other\",\n] as const;\nexport const muscleGroupEnum = z.enum(muscleGroupValues);\n\nconst exerciseTypeValues = [\n\t\"weight_reps\",\n\t\"reps_only\",\n\t\"bodyweight_reps\",\n\t\"bodyweight_assisted_reps\",\n\t\"duration\",\n\t\"weight_duration\",\n\t\"distance_duration\",\n\t\"short_distance_weight\",\n] as const;\nexport const exerciseTypeEnum = z.enum(exerciseTypeValues);\n\nconst equipmentCategoryValues = [\n\t\"none\",\n\t\"barbell\",\n\t\"dumbbell\",\n\t\"kettlebell\",\n\t\"machine\",\n\t\"plate\",\n\t\"resistance_band\",\n\t\"suspension\",\n\t\"other\",\n] as const;\nexport const equipmentCategoryEnum = z.enum(equipmentCategoryValues);\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport type {\n\tBodyMeasurement,\n\tGetV1BodyMeasurements200,\n\tGetV1BodyMeasurementsDate200,\n} from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport { formatBodyMeasurement } from \"../utils/formatters.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport {\n\tbodyMeasurementOutputSchema,\n\tbodyMeasurementsOutputSchema,\n} from \"../utils/output-schemas.js\";\nimport {\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n\tcreateTextResponse,\n} from \"../utils/response-formatter.js\";\nimport {\n\tcreateAnnotations,\n\treadOnlyAnnotations,\n\tupdateAnnotations,\n} from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\nimport { zNullableNumber } from \"../utils/schemas.js\";\n\nconst bodyMeasurementFieldsSchema = {\n\tweightKg: zNullableNumber.describe(\"Body weight in kilograms\"),\n\tleanMassKg: zNullableNumber.describe(\"Lean body mass in kilograms\"),\n\tfatPercent: zNullableNumber.describe(\"Body fat percentage\"),\n\tneckCm: zNullableNumber.describe(\"Neck circumference in centimeters\"),\n\tshoulderCm: zNullableNumber.describe(\"Shoulder circumference in centimeters\"),\n\tchestCm: zNullableNumber.describe(\"Chest circumference in centimeters\"),\n\tleftBicepCm: zNullableNumber.describe(\n\t\t\"Left bicep circumference in centimeters\",\n\t),\n\trightBicepCm: zNullableNumber.describe(\n\t\t\"Right bicep circumference in centimeters\",\n\t),\n\tleftForearmCm: zNullableNumber.describe(\n\t\t\"Left forearm circumference in centimeters\",\n\t),\n\trightForearmCm: zNullableNumber.describe(\n\t\t\"Right forearm circumference in centimeters\",\n\t),\n\tabdomen: zNullableNumber.describe(\"Abdomen circumference in centimeters\"),\n\twaist: zNullableNumber.describe(\"Waist circumference in centimeters\"),\n\thips: zNullableNumber.describe(\"Hips circumference in centimeters\"),\n\tleftThigh: zNullableNumber.describe(\n\t\t\"Left thigh circumference in centimeters\",\n\t),\n\trightThigh: zNullableNumber.describe(\n\t\t\"Right thigh circumference in centimeters\",\n\t),\n\tleftCalf: zNullableNumber.describe(\"Left calf circumference in centimeters\"),\n\trightCalf: zNullableNumber.describe(\n\t\t\"Right calf circumference in centimeters\",\n\t),\n} as const;\n\nconst MEASUREMENT_FIELD_TO_API_KEY = {\n\tweightKg: \"weight_kg\",\n\tleanMassKg: \"lean_mass_kg\",\n\tfatPercent: \"fat_percent\",\n\tneckCm: \"neck_cm\",\n\tshoulderCm: \"shoulder_cm\",\n\tchestCm: \"chest_cm\",\n\tleftBicepCm: \"left_bicep_cm\",\n\trightBicepCm: \"right_bicep_cm\",\n\tleftForearmCm: \"left_forearm_cm\",\n\trightForearmCm: \"right_forearm_cm\",\n\tabdomen: \"abdomen\",\n\twaist: \"waist\",\n\thips: \"hips\",\n\tleftThigh: \"left_thigh\",\n\trightThigh: \"right_thigh\",\n\tleftCalf: \"left_calf\",\n\trightCalf: \"right_calf\",\n} as const satisfies Record<\n\tkeyof typeof bodyMeasurementFieldsSchema,\n\tkeyof Omit<BodyMeasurement, \"date\">\n>;\n\ntype MeasurementFieldArgs = Partial<\n\tRecord<keyof typeof MEASUREMENT_FIELD_TO_API_KEY, number | null>\n>;\n\n// The Hevy API rejects null for omitted fields, so only fields with actual\n// values are included in the payload (#341).\nfunction buildMeasurementPayload(\n\targs: MeasurementFieldArgs,\n): Omit<BodyMeasurement, \"date\"> {\n\tconst payload: Omit<BodyMeasurement, \"date\"> = {};\n\tfor (const [camelKey, apiKey] of Object.entries(\n\t\tMEASUREMENT_FIELD_TO_API_KEY,\n\t) as [keyof MeasurementFieldArgs, keyof Omit<BodyMeasurement, \"date\">][]) {\n\t\tconst value = args[camelKey];\n\t\tif (value != null) {\n\t\t\tpayload[apiKey] = value;\n\t\t}\n\t}\n\treturn payload;\n}\n\nexport function registerBodyMeasurementTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n) {\n\t// Get body measurements (paginated list)\n\tconst getBodyMeasurementsSchema = {\n\t\tpage: z.coerce.number().int().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(10).default(10),\n\t} as const;\n\ttype GetBodyMeasurementsParams = InferToolParams<\n\t\ttypeof getBodyMeasurementsSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-body-measurements\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary: \"Read-only. Lists dated body measurements for the account.\",\n\t\t\t\taliases: [\"body stats history\", \"list weigh-ins\", \"measurement log\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to browse measurement history; use get-body-measurement for one exact date.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Results are paginated; page starts at 1 and pageSize is limited to 10.\",\n\t\t\t}),\n\t\t\tinputSchema: getBodyMeasurementsSchema,\n\t\t\toutputSchema: bodyMeasurementsOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Body Measurements\"),\n\t\t},\n\t\twithObservability(async (args: GetBodyMeasurementsParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize } = args;\n\t\t\tconst data: GetV1BodyMeasurements200 = await client.getBodyMeasurements({\n\t\t\t\tpage,\n\t\t\t\tpageSize,\n\t\t\t});\n\n\t\t\tconst measurements =\n\t\t\t\tdata?.body_measurements?.map((measurement: BodyMeasurement) =>\n\t\t\t\t\tformatBodyMeasurement(measurement),\n\t\t\t\t) || [];\n\n\t\t\tif (measurements.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No body measurements found for the specified parameters\",\n\t\t\t\t\t{ bodyMeasurements: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(measurements, {\n\t\t\t\tbodyMeasurements: measurements,\n\t\t\t});\n\t\t}, \"get-body-measurements\"),\n\t);\n\n\t// Get single body measurement by date\n\tconst getBodyMeasurementSchema = {\n\t\tdate: z\n\t\t\t.string()\n\t\t\t.regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"Date must be in YYYY-MM-DD format\")\n\t\t\t.describe(\"The date of the body measurement (YYYY-MM-DD)\"),\n\t} as const;\n\ttype GetBodyMeasurementParams = InferToolParams<\n\t\ttypeof getBodyMeasurementSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-body-measurement\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Retrieves the body measurement entry for one date.\",\n\t\t\t\taliases: [\"get weigh-in\", \"show body stats\", \"measurement by date\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use when the exact measurement date is known; use get-body-measurements to browse dates.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"date must use YYYY-MM-DD; at most one entry exists per date.\",\n\t\t\t}),\n\t\t\tinputSchema: getBodyMeasurementSchema,\n\t\t\toutputSchema: bodyMeasurementOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Body Measurement\"),\n\t\t},\n\t\twithObservability(async (args: GetBodyMeasurementParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { date } = args;\n\t\t\tconst data: GetV1BodyMeasurementsDate200 =\n\t\t\t\tawait client.getBodyMeasurement(date);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`No body measurement found for date ${date}`,\n\t\t\t\t\t{ bodyMeasurement: null },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst bodyMeasurement = formatBodyMeasurement(data);\n\t\t\treturn createStructuredJsonResponse(bodyMeasurement, {\n\t\t\t\tbodyMeasurement,\n\t\t\t});\n\t\t}, \"get-body-measurement\"),\n\t);\n\n\t// Create body measurement\n\tconst createBodyMeasurementSchema = {\n\t\tdate: z\n\t\t\t.string()\n\t\t\t.regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"Date must be in YYYY-MM-DD format\")\n\t\t\t.describe(\n\t\t\t\t\"The date of the body measurement (YYYY-MM-DD). Must be unique — returns 409 if an entry already exists for this date.\",\n\t\t\t),\n\t\t...bodyMeasurementFieldsSchema,\n\t} as const;\n\ttype CreateBodyMeasurementParams = InferToolParams<\n\t\ttypeof createBodyMeasurementSchema\n\t>;\n\n\tserver.tool(\n\t\t\"create-body-measurement\",\n\t\tdescribeTool({\n\t\t\tsummary:\n\t\t\t\t\"Writes to the Hevy account by creating a dated body measurement.\",\n\t\t\taliases: [\"log weigh-in\", \"add body stats\", \"record measurements\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use for a date without an entry; use update-body-measurement when that date already exists.\",\n\t\t\timportantNotes:\n\t\t\t\t\"date must use YYYY-MM-DD and be unique. Null fields are omitted and cannot clear values; an existing date returns 409.\",\n\t\t}),\n\t\tcreateBodyMeasurementSchema,\n\t\tcreateAnnotations(\"Create Body Measurement\"),\n\t\twithObservability(async (args: CreateBodyMeasurementParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { date, ...fields } = args;\n\t\t\tawait client.createBodyMeasurement({\n\t\t\t\tdate,\n\t\t\t\t...buildMeasurementPayload(fields),\n\t\t\t});\n\n\t\t\treturn createTextResponse(\n\t\t\t\t`Body measurement for ${date} created successfully.`,\n\t\t\t);\n\t\t}, \"create-body-measurement\"),\n\t);\n\n\t// Update body measurement\n\tconst updateBodyMeasurementSchema = {\n\t\tdate: z\n\t\t\t.string()\n\t\t\t.regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"Date must be in YYYY-MM-DD format\")\n\t\t\t.describe(\n\t\t\t\t\"The date of the body measurement to update (YYYY-MM-DD). Must already exist — returns 404 otherwise.\",\n\t\t\t),\n\t\t...bodyMeasurementFieldsSchema,\n\t} as const;\n\ttype UpdateBodyMeasurementParams = InferToolParams<\n\t\ttypeof updateBodyMeasurementSchema\n\t>;\n\n\tserver.tool(\n\t\t\"update-body-measurement\",\n\t\tdescribeTool({\n\t\t\tsummary:\n\t\t\t\t\"Mutates the Hevy account by updating a body measurement for a date.\",\n\t\t\taliases: [\"edit weigh-in\", \"correct body stats\", \"change measurements\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use to change fields on an existing date; use create-body-measurement for a new date.\",\n\t\t\timportantNotes:\n\t\t\t\t\"date must use YYYY-MM-DD and already exist. Provide at least one numeric field; nulls are omitted and cannot clear stored values.\",\n\t\t}),\n\t\tupdateBodyMeasurementSchema,\n\t\tupdateAnnotations(\"Update Body Measurement\"),\n\t\twithObservability(async (args: UpdateBodyMeasurementParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { date, ...fields } = args;\n\t\t\tconst payload = buildMeasurementPayload(fields);\n\t\t\tif (Object.keys(payload).length === 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"No measurement fields provided. Include at least one numeric measurement field (e.g. weightKg) to update.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait client.updateBodyMeasurement(date, payload);\n\n\t\t\treturn createTextResponse(\n\t\t\t\t`Body measurement for ${date} updated successfully.`,\n\t\t\t);\n\t\t}, \"update-body-measurement\"),\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n// Import types from generated client\nimport type {\n\tGetV1RoutineFolders200,\n\tGetV1RoutineFoldersFolderid200,\n\tPostV1RoutineFolders201,\n\tRoutineFolder,\n} from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport { formatRoutineFolder } from \"../utils/formatters.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport {\n\troutineFolderOutputSchema,\n\troutineFoldersOutputSchema,\n} from \"../utils/output-schemas.js\";\nimport {\n\tcreateEmptyResponse,\n\tcreateJsonResponse,\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n} from \"../utils/response-formatter.js\";\nimport {\n\tcreateAnnotations,\n\treadOnlyAnnotations,\n} from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\n\n/**\n * Register all routine folder-related tools with the MCP server\n */\nexport function registerFolderTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n) {\n\t// Get routine folders\n\tconst getRoutineFoldersSchema = {\n\t\tpage: z.coerce.number().int().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(10).default(5),\n\t} as const;\n\ttype GetRoutineFoldersParams = InferToolParams<\n\t\ttypeof getRoutineFoldersSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-routine-folders\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary: \"Read-only. Lists default and custom routine folders.\",\n\t\t\t\taliases: [\"list folders\", \"browse routine groups\", \"show plan folders\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to browse folder organization or discover folder IDs for routine creation.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Results are paginated; page starts at 1 and pageSize is limited to 10.\",\n\t\t\t}),\n\t\t\tinputSchema: getRoutineFoldersSchema,\n\t\t\toutputSchema: routineFoldersOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Routine Folders\"),\n\t\t},\n\t\twithObservability(async (args: GetRoutineFoldersParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize } = args;\n\t\t\tconst data: GetV1RoutineFolders200 = await client.getRoutineFolders({\n\t\t\t\tpage,\n\t\t\t\tpageSize,\n\t\t\t});\n\n\t\t\t// Process routine folders to extract relevant information\n\t\t\tconst folders =\n\t\t\t\tdata?.routine_folders?.map((folder: RoutineFolder) =>\n\t\t\t\t\tformatRoutineFolder(folder),\n\t\t\t\t) || [];\n\n\t\t\tif (folders.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No routine folders found for the specified parameters\",\n\t\t\t\t\t{ routineFolders: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(folders, {\n\t\t\t\troutineFolders: folders,\n\t\t\t});\n\t\t}, \"get-routine-folders\"),\n\t);\n\n\t// Get single routine folder by ID\n\tconst getRoutineFolderSchema = {\n\t\tfolderId: z.string().min(1),\n\t} as const;\n\ttype GetRoutineFolderParams = InferToolParams<typeof getRoutineFolderSchema>;\n\n\tserver.registerTool(\n\t\t\"get-routine-folder\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary: \"Read-only. Retrieves one routine folder's metadata by ID.\",\n\t\t\t\taliases: [\"show folder\", \"folder details\", \"routine folder metadata\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use for one known folder; use get-routine-folders to browse or discover folder IDs.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Requires a folderId from get-routine-folders or a prior create response.\",\n\t\t\t}),\n\t\t\tinputSchema: getRoutineFolderSchema,\n\t\t\toutputSchema: routineFolderOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Routine Folder\"),\n\t\t},\n\t\twithObservability(async (args: GetRoutineFolderParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { folderId } = args;\n\t\t\tconst data: GetV1RoutineFoldersFolderid200 =\n\t\t\t\tawait client.getRoutineFolder(folderId);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`Routine folder with ID ${folderId} not found`,\n\t\t\t\t\t{ routineFolder: null },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst folder = formatRoutineFolder(data);\n\t\t\treturn createStructuredJsonResponse(folder, { routineFolder: folder });\n\t\t}, \"get-routine-folder\"),\n\t);\n\n\t// Create new routine folder\n\tconst createRoutineFolderSchema = {\n\t\tname: z.string().min(1),\n\t} as const;\n\ttype CreateRoutineFolderParams = InferToolParams<\n\t\ttypeof createRoutineFolderSchema\n\t>;\n\n\tserver.tool(\n\t\t\"create-routine-folder\",\n\t\tdescribeTool({\n\t\t\tsummary: \"Writes to the Hevy account by creating a new routine folder.\",\n\t\t\taliases: [\"add folder\", \"organize routines\", \"create plan group\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use to create an organizational destination before assigning new routines to a folderId.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires a non-empty name. Retrying or reusing a name can create duplicate folders.\",\n\t\t}),\n\t\tcreateRoutineFolderSchema,\n\t\tcreateAnnotations(\"Create Routine Folder\"),\n\t\twithObservability(async (args: CreateRoutineFolderParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { name } = args;\n\t\t\tconst data: PostV1RoutineFolders201 = await client.createRoutineFolder({\n\t\t\t\troutine_folder: {\n\t\t\t\t\ttitle: name,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!data) {\n\t\t\t\treturn createEmptyResponse(\n\t\t\t\t\t\"Failed to create routine folder: Server returned no data\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst folder = formatRoutineFolder(data);\n\t\t\treturn createJsonResponse(folder, {\n\t\t\t\tpretty: true,\n\t\t\t\tindent: 2,\n\t\t\t});\n\t\t}, \"create-routine-folder\"),\n\t);\n}\n","/**\n * Preprocessor to handle MCP clients that send JSON-stringified arrays\n * instead of native arrays for complex parameters.\n *\n * This is used with Zod's z.preprocess to handle cases where MCP clients\n * serialize complex nested structures as JSON strings.\n *\n * @param val - The value to potentially parse\n * @returns The parsed array if val is a valid JSON string, otherwise returns val unchanged\n */\nexport function parseJsonArray(val: unknown): unknown {\n\t// Handle case where MCP client sends JSON string instead of array\n\tif (typeof val === \"string\") {\n\t\ttry {\n\t\t\treturn JSON.parse(val);\n\t\t} catch {\n\t\t\t// Let Zod validation handle the error\n\t\t\treturn val;\n\t\t}\n\t}\n\treturn val;\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n// Import types from generated client\nimport type {\n\tGetV1Routines200,\n\tGetV1RoutinesRoutineid200,\n\tPostRoutinesRequestExercise,\n\tPostRoutinesRequestSet,\n\tPostRoutinesRequestSetTypeEnumKey,\n\tPostV1Routines201,\n\tPutRoutinesRequestExercise,\n\tPutRoutinesRequestSet,\n\tPutRoutinesRequestSetTypeEnumKey,\n\tPutV1RoutinesRoutineid200,\n\tRoutine,\n} from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport { formatRoutine } from \"../utils/formatters.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport { parseJsonArray } from \"../utils/json-parser.js\";\nimport {\n\troutineOutputSchema,\n\troutinesOutputSchema,\n} from \"../utils/output-schemas.js\";\nimport {\n\tcreateEmptyResponse,\n\tcreateJsonResponse,\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n} from \"../utils/response-formatter.js\";\nimport {\n\tcreateAnnotations,\n\treadOnlyAnnotations,\n\tupdateAnnotations,\n} from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\nimport {\n\tsetTypeEnum,\n\tzNullableInt,\n\tzOptionalRepRange,\n} from \"../utils/schemas.js\";\n\nfunction buildRepRange(repRange?: {\n\tstart?: number | null;\n\tend?: number | null;\n}): { start?: number; end?: number } | null {\n\tif (!repRange) {\n\t\treturn null;\n\t}\n\n\tconst start = repRange.start ?? undefined;\n\tconst end = repRange.end ?? undefined;\n\tif (start === undefined && end === undefined) {\n\t\treturn null;\n\t}\n\n\treturn { start, end };\n}\n\n/**\n * Returns a fixed rep count when `repRange` is a fixed range (start and end are\n * both non-null and equal). Otherwise returns null.\n */\nfunction getFixedRepsFromRepRange(\n\trepRange:\n\t\t| {\n\t\t\t\tstart?: number | null;\n\t\t\t\tend?: number | null;\n\t\t }\n\t\t| null\n\t\t| undefined,\n): number | null {\n\tif (!repRange) {\n\t\treturn null;\n\t}\n\n\tconst start = repRange.start ?? null;\n\tconst end = repRange.end ?? null;\n\tif (start === null || end === null) {\n\t\treturn null;\n\t}\n\tif (start !== end) {\n\t\treturn null;\n\t}\n\n\treturn start;\n}\n\nconst repRangeDisplayWarningText =\n\t\"Note: Hevy's public API stores rep ranges (rep_range), but the Hevy apps may \" +\n\t\"not display them because they rely on an internal-only exercise field \" +\n\t\"(input_modifier). See https://github.com/chrisdoc/hevy-mcp/issues/261 for \" +\n\t\"details/workarounds.\";\n\n/**\n * Register all routine-related tools with the MCP server\n */\nexport function registerRoutineTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n) {\n\t// Get routines\n\tconst getRoutinesSchema = {\n\t\tpage: z.coerce.number().int().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(10).default(5),\n\t} as const;\n\ttype GetRoutinesParams = InferToolParams<typeof getRoutinesSchema>;\n\n\tserver.registerTool(\n\t\t\"get-routines\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary: \"Read-only. Lists custom and default workout routines.\",\n\t\t\t\taliases: [\n\t\t\t\t\t\"list routines\",\n\t\t\t\t\t\"show workout plans\",\n\t\t\t\t\t\"browse saved routines\",\n\t\t\t\t],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to browse routines or discover a routine ID; use get-routine for one known routine.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Results are paginated; page starts at 1 and pageSize is limited to 10.\",\n\t\t\t}),\n\t\t\tinputSchema: getRoutinesSchema,\n\t\t\toutputSchema: routinesOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Routines\"),\n\t\t},\n\t\twithObservability(async (args: GetRoutinesParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize } = args;\n\t\t\tconst data: GetV1Routines200 = await client.getRoutines({\n\t\t\t\tpage,\n\t\t\t\tpageSize,\n\t\t\t});\n\n\t\t\t// Process routines to extract relevant information\n\t\t\tconst routines =\n\t\t\t\tdata?.routines?.map((routine: Routine) => formatRoutine(routine)) || [];\n\n\t\t\tif (routines.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No routines found for the specified parameters\",\n\t\t\t\t\t{ routines: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(routines, { routines });\n\t\t}, \"get-routines\"),\n\t);\n\n\t// Get single routine by ID (new, direct endpoint)\n\tconst getRoutineSchema = {\n\t\troutineId: z.string().min(1),\n\t} as const;\n\ttype GetRoutineParams = InferToolParams<typeof getRoutineSchema>;\n\n\tserver.registerTool(\n\t\t\"get-routine\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Retrieves one routine and its exercise configuration by ID.\",\n\t\t\t\taliases: [\"show routine\", \"fetch workout plan\", \"routine details\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use when the routineId is known; use get-routines to browse or discover IDs.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Requires a routineId from get-routines or a prior create response.\",\n\t\t\t}),\n\t\t\tinputSchema: getRoutineSchema,\n\t\t\toutputSchema: routineOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Routine\"),\n\t\t},\n\t\twithObservability(async (args: GetRoutineParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { routineId } = args;\n\t\t\tconst data: GetV1RoutinesRoutineid200 = await client.getRoutineById(\n\t\t\t\tString(routineId),\n\t\t\t);\n\t\t\tif (!data || !data.routine) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`Routine with ID ${routineId} not found`,\n\t\t\t\t\t{ routine: null },\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst routine = formatRoutine(data.routine);\n\t\t\treturn createStructuredJsonResponse(routine, { routine });\n\t\t}, \"get-routine\"),\n\t);\n\n\t// Create new routine\n\tconst createRoutineSchema = {\n\t\ttitle: z.string().min(1),\n\t\tfolderId: z.coerce.number().nullable().optional(),\n\t\tnotes: z.string().optional(),\n\t\texercises: z.preprocess(\n\t\t\tparseJsonArray,\n\t\t\tz.array(\n\t\t\t\tz.object({\n\t\t\t\t\texerciseTemplateId: z.string().min(1),\n\t\t\t\t\tsupersetId: z.coerce.number().nullable().optional(),\n\t\t\t\t\trestSeconds: z.coerce.number().int().min(0).optional(),\n\t\t\t\t\tnotes: z.string().optional(),\n\t\t\t\t\tsets: z.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\ttype: setTypeEnum,\n\t\t\t\t\t\t\tweight: z.coerce.number().optional(),\n\t\t\t\t\t\t\tweightKg: z.coerce.number().optional(),\n\t\t\t\t\t\t\treps: zNullableInt,\n\t\t\t\t\t\t\tdistance: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tdistanceMeters: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tduration: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tdurationSeconds: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tcustomMetric: z.coerce.number().optional(),\n\t\t\t\t\t\t\trepRange: zOptionalRepRange,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t} as const;\n\ttype CreateRoutineParams = InferToolParams<typeof createRoutineSchema>;\n\n\tserver.tool(\n\t\t\"create-routine\",\n\t\tdescribeTool({\n\t\t\tsummary: \"Writes to the Hevy account by creating a new workout routine.\",\n\t\t\taliases: [\"add routine\", \"build workout plan\", \"save training template\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use to create a reusable plan; use create-workout to log a completed session.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires exercise template IDs; folderId is optional. Retrying can create duplicates, and non-fixed rep ranges may not display in Hevy apps.\",\n\t\t}),\n\t\tcreateRoutineSchema,\n\t\tcreateAnnotations(\"Create Routine\"),\n\t\twithObservability(async (args: CreateRoutineParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { title, folderId, notes, exercises } = args;\n\t\t\tlet usesRepRanges = false;\n\t\t\tconst data: PostV1Routines201 = await client.createRoutine({\n\t\t\t\troutine: {\n\t\t\t\t\ttitle,\n\t\t\t\t\tfolder_id: folderId ?? null,\n\t\t\t\t\tnotes: notes ?? \"\",\n\t\t\t\t\texercises: exercises.map((exercise): PostRoutinesRequestExercise => {\n\t\t\t\t\t\tconst sets = exercise.sets.map((set): PostRoutinesRequestSet => {\n\t\t\t\t\t\t\tconst repRange = buildRepRange(set.repRange);\n\t\t\t\t\t\t\tconst fixedReps = getFixedRepsFromRepRange(repRange);\n\t\t\t\t\t\t\tconst reps = typeof set.reps === \"number\" ? set.reps : fixedReps;\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: set.type as PostRoutinesRequestSetTypeEnumKey,\n\t\t\t\t\t\t\t\tweight_kg: set.weight ?? set.weightKg ?? null,\n\t\t\t\t\t\t\t\treps: reps ?? null,\n\t\t\t\t\t\t\t\tdistance_meters: set.distance ?? set.distanceMeters ?? null,\n\t\t\t\t\t\t\t\tduration_seconds: set.duration ?? set.durationSeconds ?? null,\n\t\t\t\t\t\t\t\tcustom_metric: set.customMetric ?? null,\n\t\t\t\t\t\t\t\trep_range: repRange,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tsets.some(\n\t\t\t\t\t\t\t\t(set) =>\n\t\t\t\t\t\t\t\t\tset.rep_range != null &&\n\t\t\t\t\t\t\t\t\tgetFixedRepsFromRepRange(set.rep_range) === null,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tusesRepRanges = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\texercise_template_id: exercise.exerciseTemplateId,\n\t\t\t\t\t\t\tsuperset_id: exercise.supersetId ?? null,\n\t\t\t\t\t\t\trest_seconds: exercise.restSeconds ?? null,\n\t\t\t\t\t\t\tnotes: exercise.notes ?? null,\n\t\t\t\t\t\t\tsets,\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!data) {\n\t\t\t\treturn createEmptyResponse(\n\t\t\t\t\t\"Failed to create routine: Server returned no data\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst routine = formatRoutine(data);\n\t\t\tconst response = createJsonResponse(routine, {\n\t\t\t\tpretty: true,\n\t\t\t\tindent: 2,\n\t\t\t});\n\n\t\t\tif (usesRepRanges) {\n\t\t\t\tresponse.content.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: repRangeDisplayWarningText,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn response;\n\t\t}, \"create-routine\"),\n\t);\n\n\t// Update existing routine\n\tconst updateRoutineSchema = {\n\t\troutineId: z.string().min(1),\n\t\ttitle: z.string().min(1),\n\t\tnotes: z.string().optional(),\n\t\texercises: z.preprocess(\n\t\t\tparseJsonArray,\n\t\t\tz.array(\n\t\t\t\tz.object({\n\t\t\t\t\texerciseTemplateId: z.string().min(1),\n\t\t\t\t\tsupersetId: z.coerce.number().nullable().optional(),\n\t\t\t\t\trestSeconds: z.coerce.number().int().min(0).optional(),\n\t\t\t\t\tnotes: z.string().optional(),\n\t\t\t\t\tsets: z.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\ttype: setTypeEnum,\n\t\t\t\t\t\t\tweight: z.coerce.number().optional(),\n\t\t\t\t\t\t\tweightKg: z.coerce.number().optional(),\n\t\t\t\t\t\t\treps: zNullableInt,\n\t\t\t\t\t\t\tdistance: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tdistanceMeters: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tduration: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tdurationSeconds: z.coerce.number().int().optional(),\n\t\t\t\t\t\t\tcustomMetric: z.coerce.number().optional(),\n\t\t\t\t\t\t\trepRange: zOptionalRepRange,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t} as const;\n\ttype UpdateRoutineParams = InferToolParams<typeof updateRoutineSchema>;\n\n\tserver.tool(\n\t\t\"update-routine\",\n\t\tdescribeTool({\n\t\t\tsummary:\n\t\t\t\t\"Mutates the Hevy account by replacing an existing routine's content.\",\n\t\t\taliases: [\n\t\t\t\t\"edit routine\",\n\t\t\t\t\"revise workout plan\",\n\t\t\t\t\"replace routine exercises\",\n\t\t\t],\n\t\t\tuseCase:\n\t\t\t\t\"Use to change a known routine; use create-routine for a separate new plan.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires routineId and the complete title and exercises payload; omitted exercises are removed. Non-fixed rep ranges may not display in Hevy apps.\",\n\t\t}),\n\t\tupdateRoutineSchema,\n\t\tupdateAnnotations(\"Update Routine\"),\n\t\twithObservability(async (args: UpdateRoutineParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { routineId, title, notes, exercises } = args;\n\t\t\tlet usesRepRanges = false;\n\t\t\tconst data: PutV1RoutinesRoutineid200 = await client.updateRoutine(\n\t\t\t\troutineId,\n\t\t\t\t{\n\t\t\t\t\troutine: {\n\t\t\t\t\t\ttitle,\n\t\t\t\t\t\tnotes: notes ?? null,\n\t\t\t\t\t\texercises: exercises.map((exercise): PutRoutinesRequestExercise => {\n\t\t\t\t\t\t\tconst sets = exercise.sets.map((set): PutRoutinesRequestSet => {\n\t\t\t\t\t\t\t\tconst repRange = buildRepRange(set.repRange);\n\t\t\t\t\t\t\t\tconst fixedReps = getFixedRepsFromRepRange(repRange);\n\t\t\t\t\t\t\t\tconst reps =\n\t\t\t\t\t\t\t\t\ttypeof set.reps === \"number\" ? set.reps : fixedReps;\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\ttype: set.type as PutRoutinesRequestSetTypeEnumKey,\n\t\t\t\t\t\t\t\t\tweight_kg: set.weight ?? set.weightKg ?? null,\n\t\t\t\t\t\t\t\t\treps: reps ?? null,\n\t\t\t\t\t\t\t\t\tdistance_meters: set.distance ?? set.distanceMeters ?? null,\n\t\t\t\t\t\t\t\t\tduration_seconds: set.duration ?? set.durationSeconds ?? null,\n\t\t\t\t\t\t\t\t\tcustom_metric: set.customMetric ?? null,\n\t\t\t\t\t\t\t\t\t...(repRange ? { rep_range: repRange } : {}),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tsets.some(\n\t\t\t\t\t\t\t\t\t(set) =>\n\t\t\t\t\t\t\t\t\t\tset.rep_range != null &&\n\t\t\t\t\t\t\t\t\t\tgetFixedRepsFromRepRange(set.rep_range) === null,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tusesRepRanges = true;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\texercise_template_id: exercise.exerciseTemplateId,\n\t\t\t\t\t\t\t\tsuperset_id: exercise.supersetId ?? null,\n\t\t\t\t\t\t\t\trest_seconds: exercise.restSeconds ?? null,\n\t\t\t\t\t\t\t\tnotes: exercise.notes ?? null,\n\t\t\t\t\t\t\t\tsets,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createEmptyResponse(\n\t\t\t\t\t`Failed to update routine with ID ${routineId}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst routine = formatRoutine(data);\n\t\t\tconst response = createJsonResponse(routine, {\n\t\t\t\tpretty: true,\n\t\t\t\tindent: 2,\n\t\t\t});\n\n\t\t\tif (usesRepRanges) {\n\t\t\t\tresponse.content.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: repRangeDisplayWarningText,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn response;\n\t\t}, \"update-routine\"),\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n// Import types from generated client\nimport type {\n\tExerciseTemplate,\n\tGetV1ExerciseHistoryExercisetemplateid200,\n\tGetV1ExerciseTemplates200,\n\tGetV1ExerciseTemplatesExercisetemplateid200,\n\tPostV1ExerciseTemplates200,\n} from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport {\n\tgetExerciseTemplateCatalog,\n\tresetExerciseTemplateCatalogCache,\n} from \"../utils/exercise-template-catalog.js\";\nimport {\n\tformatExerciseHistoryEntry,\n\tformatExerciseTemplate,\n} from \"../utils/formatters.js\";\nimport type { McpClientLogger } from \"../utils/mcp-client-logger.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport {\n\texerciseHistoryOutputSchema,\n\texerciseTemplateOutputSchema,\n\texerciseTemplatesOutputSchema,\n} from \"../utils/output-schemas.js\";\nimport {\n\tcreateJsonResponse,\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n} from \"../utils/response-formatter.js\";\nimport {\n\tcreateAnnotations,\n\treadOnlyAnnotations,\n} from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\nimport {\n\tequipmentCategoryEnum,\n\texerciseTypeEnum,\n\tmuscleGroupEnum,\n} from \"../utils/schemas.js\";\n\nexport interface TemplateToolOptions {\n\tlogger?: McpClientLogger;\n}\n/** Reset the exercise template cache (exposed for testing). */\nexport function resetExerciseTemplateCache(): void {\n\tresetExerciseTemplateCatalogCache();\n}\n\n/**\n * Register all exercise template-related tools with the MCP server\n */\nexport function registerTemplateTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n\toptions: TemplateToolOptions = {},\n) {\n\tconst { logger } = options;\n\t// Get exercise templates\n\tconst getExerciseTemplatesSchema = {\n\t\tpage: z.coerce.number().int().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(100).default(5),\n\t} as const;\n\ttype GetExerciseTemplatesParams = InferToolParams<\n\t\ttypeof getExerciseTemplatesSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-exercise-templates\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Lists default and custom exercise templates with equipment and muscle metadata.\",\n\t\t\t\taliases: [\n\t\t\t\t\t\"browse exercises\",\n\t\t\t\t\t\"list exercise catalog\",\n\t\t\t\t\t\"show movements\",\n\t\t\t\t],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use for page-by-page catalog browsing; use search-exercise-templates for a name lookup across the full catalog.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Results are paginated; page starts at 1 and pageSize is limited to 100.\",\n\t\t\t}),\n\t\t\tinputSchema: getExerciseTemplatesSchema,\n\t\t\toutputSchema: exerciseTemplatesOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Exercise Templates\"),\n\t\t},\n\t\twithObservability(async (args: GetExerciseTemplatesParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize } = args;\n\t\t\tconst data: GetV1ExerciseTemplates200 = await client.getExerciseTemplates(\n\t\t\t\t{\n\t\t\t\t\tpage,\n\t\t\t\t\tpageSize,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Process exercise templates to extract relevant information\n\t\t\tconst templates =\n\t\t\t\tdata?.exercise_templates?.map((template: ExerciseTemplate) =>\n\t\t\t\t\tformatExerciseTemplate(template),\n\t\t\t\t) || [];\n\n\t\t\tif (templates.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No exercise templates found for the specified parameters\",\n\t\t\t\t\t{ exerciseTemplates: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(templates, {\n\t\t\t\texerciseTemplates: templates,\n\t\t\t});\n\t\t}, \"get-exercise-templates\"),\n\t);\n\n\t// Get single exercise template by ID\n\tconst getExerciseTemplateSchema = {\n\t\texerciseTemplateId: z.string().min(1),\n\t} as const;\n\ttype GetExerciseTemplateParams = InferToolParams<\n\t\ttypeof getExerciseTemplateSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-exercise-template\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Retrieves complete metadata for one exercise template by ID.\",\n\t\t\t\taliases: [\n\t\t\t\t\t\"show exercise details\",\n\t\t\t\t\t\"fetch movement\",\n\t\t\t\t\t\"exercise template info\",\n\t\t\t\t],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use after locating an exact template; use search-exercise-templates when only a name is known.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Requires an exerciseTemplateId from a template list, search, routine, or workout.\",\n\t\t\t}),\n\t\t\tinputSchema: getExerciseTemplateSchema,\n\t\t\toutputSchema: exerciseTemplateOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Exercise Template\"),\n\t\t},\n\t\twithObservability(async (args: GetExerciseTemplateParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { exerciseTemplateId } = args;\n\t\t\tconst data: GetV1ExerciseTemplatesExercisetemplateid200 =\n\t\t\t\tawait client.getExerciseTemplate(exerciseTemplateId);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`Exercise template with ID ${exerciseTemplateId} not found`,\n\t\t\t\t\t{ exerciseTemplate: null },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst template = formatExerciseTemplate(data);\n\t\t\treturn createStructuredJsonResponse(template, {\n\t\t\t\texerciseTemplate: template,\n\t\t\t});\n\t\t}, \"get-exercise-template\"),\n\t);\n\n\t// Get exercise history for a template\n\tconst getExerciseHistorySchema = {\n\t\texerciseTemplateId: z.string().min(1),\n\t\tstartDate: z\n\t\t\t.string()\n\t\t\t.datetime({ offset: true })\n\t\t\t.describe(\"ISO 8601 start date for filtering history\")\n\t\t\t.optional(),\n\t\tendDate: z\n\t\t\t.string()\n\t\t\t.datetime({ offset: true })\n\t\t\t.describe(\"ISO 8601 end date for filtering history\")\n\t\t\t.optional(),\n\t} as const;\n\ttype GetExerciseHistoryParams = InferToolParams<\n\t\ttypeof getExerciseHistorySchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"get-exercise-history\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Retrieves past performed sets for one exercise template.\",\n\t\t\t\taliases: [\"exercise progress\", \"past sets\", \"movement history\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to analyze performance for one movement; use get-workouts for complete sessions.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Requires an exerciseTemplateId. Optional startDate and endDate must be ISO 8601 datetimes with an offset.\",\n\t\t\t}),\n\t\t\tinputSchema: getExerciseHistorySchema,\n\t\t\toutputSchema: exerciseHistoryOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Exercise History\"),\n\t\t},\n\t\twithObservability(async (args: GetExerciseHistoryParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { exerciseTemplateId, startDate, endDate } = args;\n\t\t\tconst data: GetV1ExerciseHistoryExercisetemplateid200 =\n\t\t\t\tawait client.getExerciseHistory(exerciseTemplateId, {\n\t\t\t\t\t...(startDate ? { start_date: startDate } : {}),\n\t\t\t\t\t...(endDate ? { end_date: endDate } : {}),\n\t\t\t\t});\n\n\t\t\tconst history =\n\t\t\t\tdata?.exercise_history?.map((entry) =>\n\t\t\t\t\tformatExerciseHistoryEntry(entry),\n\t\t\t\t) || [];\n\n\t\t\tif (history.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`No exercise history found for template ${exerciseTemplateId}`,\n\t\t\t\t\t{ exerciseHistory: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(history, {\n\t\t\t\texerciseHistory: history,\n\t\t\t});\n\t\t}, \"get-exercise-history\"),\n\t);\n\n\t// Create a custom exercise template\n\tconst createExerciseTemplateSchema = {\n\t\ttitle: z.string().min(1),\n\t\texerciseType: exerciseTypeEnum,\n\t\tequipmentCategory: equipmentCategoryEnum,\n\t\tmuscleGroup: muscleGroupEnum,\n\t\totherMuscles: z.array(muscleGroupEnum).default([]),\n\t} as const;\n\ttype CreateExerciseTemplateParams = InferToolParams<\n\t\ttypeof createExerciseTemplateSchema\n\t>;\n\n\tserver.tool(\n\t\t\"create-exercise-template\",\n\t\tdescribeTool({\n\t\t\tsummary:\n\t\t\t\t\"Writes to the Hevy account by creating a custom exercise template.\",\n\t\t\taliases: [\"add custom exercise\", \"create movement\", \"define exercise\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use only when the needed movement is absent; search-exercise-templates should check existing templates first.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires title, exercise type, equipment category, and primary muscle group. Retrying or reusing a title can create duplicates.\",\n\t\t}),\n\t\tcreateExerciseTemplateSchema,\n\t\tcreateAnnotations(\"Create Exercise Template\"),\n\t\twithObservability(async (args: CreateExerciseTemplateParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst {\n\t\t\t\ttitle,\n\t\t\t\texerciseType,\n\t\t\t\tequipmentCategory,\n\t\t\t\tmuscleGroup,\n\t\t\t\totherMuscles,\n\t\t\t} = args;\n\n\t\t\tconst response: PostV1ExerciseTemplates200 =\n\t\t\t\tawait client.createExerciseTemplate({\n\t\t\t\t\texercise: {\n\t\t\t\t\t\ttitle,\n\t\t\t\t\t\texercise_type: exerciseType,\n\t\t\t\t\t\tequipment_category: equipmentCategory,\n\t\t\t\t\t\tmuscle_group: muscleGroup,\n\t\t\t\t\t\tother_muscles: otherMuscles,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\treturn createJsonResponse({\n\t\t\t\tid: response?.id,\n\t\t\t\tmessage: \"Exercise template created successfully\",\n\t\t\t});\n\t\t}, \"create-exercise-template\"),\n\t);\n\n\t// Search exercise templates (cached)\n\tconst searchExerciseTemplatesSchema = {\n\t\tquery: z\n\t\t\t.string()\n\t\t\t.min(1)\n\t\t\t.describe(\n\t\t\t\t\"Case-insensitive substring to match against exercise template titles\",\n\t\t\t),\n\t\tprimaryMuscleGroup: muscleGroupEnum\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional filter to restrict results to a specific primary muscle group\",\n\t\t\t),\n\t\trefresh: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.default(false)\n\t\t\t.describe(\n\t\t\t\t\"Set to true to invalidate the catalog cache and re-fetch all templates from the API\",\n\t\t\t),\n\t} as const;\n\ttype SearchExerciseTemplatesParams = InferToolParams<\n\t\ttypeof searchExerciseTemplatesSchema\n\t>;\n\n\tserver.registerTool(\n\t\t\"search-exercise-templates\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only for the Hevy account. Searches the full exercise template catalog by title substring.\",\n\t\t\t\taliases: [\"find exercise\", \"look up movement\", \"search exercise IDs\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use when a name or partial name is known, especially to discover IDs for workouts and routines; use get-exercise-templates for page browsing.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Matching is case-insensitive. The catalog is cached locally for 5 minutes; refresh:true re-fetches all pages and changes only local cache state.\",\n\t\t\t}),\n\t\t\tinputSchema: searchExerciseTemplatesSchema,\n\t\t\toutputSchema: exerciseTemplatesOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Search Exercise Templates\"),\n\t\t},\n\t\twithObservability(async (args: SearchExerciseTemplatesParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { query, primaryMuscleGroup, refresh } = args;\n\t\t\tconst catalog = await getExerciseTemplateCatalog(client, {\n\t\t\t\trefresh,\n\t\t\t\tonRefreshed: (refreshedCatalog, reason) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlogger?.({\n\t\t\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\t\t\tlogger: \"hevy-cache\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tmessage: \"Exercise template catalog refreshed\",\n\t\t\t\t\t\t\t\tcount: refreshedCatalog.length,\n\t\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\"Failed to emit structured exercise template cache log\",\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Filter by query (case-insensitive title substring match)\n\t\t\tconst queryLower = query.toLowerCase();\n\t\t\tlet results = catalog.filter((t) =>\n\t\t\t\t(t.title ?? \"\").toLowerCase().includes(queryLower),\n\t\t\t);\n\n\t\t\t// Optional primary muscle group filter\n\t\t\tif (primaryMuscleGroup !== undefined) {\n\t\t\t\tresults = results.filter(\n\t\t\t\t\t(t) => t.primary_muscle_group === primaryMuscleGroup,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (results.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`No exercise templates found matching \"${query}\"${primaryMuscleGroup ? ` with primary muscle group \"${primaryMuscleGroup}\"` : \"\"}`,\n\t\t\t\t\t{ exerciseTemplates: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst exerciseTemplates = results.map(formatExerciseTemplate);\n\t\t\treturn createStructuredJsonResponse(exerciseTemplates, {\n\t\t\t\texerciseTemplates,\n\t\t\t});\n\t\t}, \"search-exercise-templates\"),\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { UserInfoResponse } from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport { userOutputSchema } from \"../utils/output-schemas.js\";\nimport {\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n} from \"../utils/response-formatter.js\";\nimport { readOnlyAnnotations } from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\n\nexport function registerUserTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n) {\n\t// Get user info\n\tconst getUserInfoSchema = {} as const;\n\ttype GetUserInfoParams = InferToolParams<typeof getUserInfoSchema>;\n\n\tserver.registerTool(\n\t\t\"get-user-info\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Returns the authenticated account's user ID, display name, and public profile URL.\",\n\t\t\t\taliases: [\"who am I\", \"account info\", \"verify Hevy user\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to confirm which Hevy account is connected before reading or writing account data.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Accepts no inputs and reports only the account associated with the configured credentials.\",\n\t\t\t}),\n\t\t\tinputSchema: getUserInfoSchema,\n\t\t\toutputSchema: userOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get User Info\"),\n\t\t},\n\t\twithObservability(async (_args: GetUserInfoParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst data: UserInfoResponse = await client.getUserInfo();\n\t\t\tif (!data?.data) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No user info found for the authenticated user\",\n\t\t\t\t\t{ user: null },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn createStructuredJsonResponse(data.data, { user: data.data });\n\t\t}, \"get-user-info\"),\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport type {\n\tGetV1Workouts200,\n\tGetV1WorkoutsCount200,\n\tGetV1WorkoutsEvents200,\n\tGetV1WorkoutsWorkoutid200,\n\tPostV1Workouts201,\n\tPostWorkoutsRequestBody,\n\tPostWorkoutsRequestExercise,\n\tPostWorkoutsRequestSetRpeEnumKey,\n\tPostWorkoutsRequestSetTypeEnumKey,\n\tPutV1WorkoutsWorkoutid200,\n} from \"../generated/client/types/index.js\";\nimport { withObservability } from \"../utils/observability-wrapper.js\";\nimport { formatWorkout } from \"../utils/formatters.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport { parseJsonArray } from \"../utils/json-parser.js\";\nimport {\n\ttype FormattedWorkout,\n\tworkoutCountOutputSchema,\n\tworkoutEventsOutputSchema,\n\tworkoutOutputSchema,\n\tworkoutsOutputSchema,\n} from \"../utils/output-schemas.js\";\nimport {\n\tcreateEmptyResponse,\n\tcreateJsonResponse,\n\tcreateStructuredEmptyResponse,\n\tcreateStructuredJsonResponse,\n} from \"../utils/response-formatter.js\";\nimport {\n\tcreateAnnotations,\n\treadOnlyAnnotations,\n\tupdateAnnotations,\n} from \"../utils/tool-annotations.js\";\nimport { describeTool } from \"../utils/tool-descriptions.js\";\nimport { requireClient, type InferToolParams } from \"../utils/tool-helpers.js\";\nimport { setTypeEnum } from \"../utils/schemas.js\";\n\ntype WorkoutEvent = GetV1WorkoutsEvents200[\"events\"][number];\ntype FormattedWorkoutEvent =\n\t| { type: \"updated\"; workout: FormattedWorkout }\n\t| { type: \"deleted\"; id: string; deletedAt?: string };\n\nfunction formatWorkoutEvent(event: WorkoutEvent): FormattedWorkoutEvent {\n\tif (event.type === \"updated\" && \"workout\" in event) {\n\t\treturn {\n\t\t\ttype: \"updated\",\n\t\t\tworkout: formatWorkout(event.workout),\n\t\t};\n\t}\n\n\tif (event.type === \"deleted\" && \"id\" in event) {\n\t\treturn {\n\t\t\ttype: \"deleted\",\n\t\t\tid: event.id,\n\t\t\tdeletedAt: event.deleted_at,\n\t\t};\n\t}\n\n\tthrow new Error(`Unsupported workout event type: ${event.type}`);\n}\n\n/**\n * Register all workout-related tools with the MCP server\n */\nexport function registerWorkoutTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n) {\n\t// Get workouts\n\tconst getWorkoutsSchema = {\n\t\tpage: z.coerce.number().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(10).default(5),\n\t} as const;\n\ttype GetWorkoutsParams = InferToolParams<typeof getWorkoutsSchema>;\n\n\tserver.registerTool(\n\t\t\"get-workouts\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Lists workouts from newest to oldest with exercise and timing details.\",\n\t\t\t\taliases: [\n\t\t\t\t\t\"list workout history\",\n\t\t\t\t\t\"show recent workouts\",\n\t\t\t\t\t\"browse logs\",\n\t\t\t\t],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to browse or page through workout history; use get-workout when a workout ID is already known.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Results are paginated; page starts at 1 and pageSize is limited to 10.\",\n\t\t\t}),\n\t\t\tinputSchema: getWorkoutsSchema,\n\t\t\toutputSchema: workoutsOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Workouts\"),\n\t\t},\n\t\twithObservability(async (args: GetWorkoutsParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize } = args;\n\t\t\tconst data: GetV1Workouts200 = await client.getWorkouts({\n\t\t\t\tpage,\n\t\t\t\tpageSize,\n\t\t\t});\n\n\t\t\tconst workouts =\n\t\t\t\tdata?.workouts?.map((workout) => formatWorkout(workout)) || [];\n\n\t\t\tif (workouts.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t\"No workouts found for the specified parameters\",\n\t\t\t\t\t{ workouts: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(workouts, { workouts });\n\t\t}, \"get-workouts\"),\n\t);\n\n\t// Get single workout by ID\n\tconst getWorkoutSchema = {\n\t\tworkoutId: z.string().min(1),\n\t} as const;\n\ttype GetWorkoutParams = InferToolParams<typeof getWorkoutSchema>;\n\n\tserver.registerTool(\n\t\t\"get-workout\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Retrieves complete details for one workout by its ID.\",\n\t\t\t\taliases: [\"show workout\", \"fetch workout details\", \"open workout log\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use after get-workouts identifies the exact workout; do not use for browsing multiple workouts.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Requires a workoutId discovered from a workout list, event, or prior create response.\",\n\t\t\t}),\n\t\t\tinputSchema: getWorkoutSchema,\n\t\t\toutputSchema: workoutOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Workout\"),\n\t\t},\n\t\twithObservability(async (args: GetWorkoutParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { workoutId } = args;\n\t\t\tconst data: GetV1WorkoutsWorkoutid200 =\n\t\t\t\tawait client.getWorkout(workoutId);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`Workout with ID ${workoutId} not found`,\n\t\t\t\t\t{ workout: null },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst workout = formatWorkout(data);\n\t\t\treturn createStructuredJsonResponse(workout, { workout });\n\t\t}, \"get-workout\"),\n\t);\n\n\t// Get workout count\n\tserver.registerTool(\n\t\t\"get-workout-count\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary: \"Read-only. Returns the total workout count for the account.\",\n\t\t\t\taliases: [\"count workouts\", \"how many workouts\", \"workout total\"],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use for totals, statistics, or estimating pages; use get-workouts for actual workout records.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"Returns only a count and accepts no paging or date filters.\",\n\t\t\t}),\n\t\t\tinputSchema: {},\n\t\t\toutputSchema: workoutCountOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Workout Count\"),\n\t\t},\n\t\twithObservability(async () => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst data: GetV1WorkoutsCount200 = await client.getWorkoutCount();\n\t\t\tconst count = data?.workout_count ?? 0;\n\t\t\treturn createStructuredJsonResponse({ count }, { count });\n\t\t}, \"get-workout-count\"),\n\t);\n\n\t// Get workout events (updates/deletes)\n\tconst getWorkoutEventsSchema = {\n\t\tpage: z.coerce.number().int().gte(1).default(1),\n\t\tpageSize: z.coerce.number().int().gte(1).lte(10).default(5),\n\t\tsince: z.string().default(\"1970-01-01T00:00:00Z\"),\n\t} as const;\n\ttype GetWorkoutEventsParams = InferToolParams<typeof getWorkoutEventsSchema>;\n\n\tserver.registerTool(\n\t\t\"get-workout-events\",\n\t\t{\n\t\t\tdescription: describeTool({\n\t\t\t\tsummary:\n\t\t\t\t\t\"Read-only. Lists workout update and delete events since a timestamp, newest first.\",\n\t\t\t\taliases: [\n\t\t\t\t\t\"sync workout changes\",\n\t\t\t\t\t\"workout change feed\",\n\t\t\t\t\t\"deleted workouts\",\n\t\t\t\t],\n\t\t\t\tuseCase:\n\t\t\t\t\t\"Use to incrementally synchronize a local workout cache; use get-workouts for the current workout list.\",\n\t\t\t\timportantNotes:\n\t\t\t\t\t\"since must be a timestamp string; events are paginated with pageSize at most 10, and the default since value reads from 1970.\",\n\t\t\t}),\n\t\t\tinputSchema: getWorkoutEventsSchema,\n\t\t\toutputSchema: workoutEventsOutputSchema,\n\t\t\tannotations: readOnlyAnnotations(\"Get Workout Events\"),\n\t\t},\n\t\twithObservability(async (args: GetWorkoutEventsParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { page, pageSize, since } = args;\n\t\t\tconst data: GetV1WorkoutsEvents200 = await client.getWorkoutEvents({\n\t\t\t\tpage,\n\t\t\t\tpageSize,\n\t\t\t\tsince,\n\t\t\t});\n\n\t\t\tconst events = data?.events?.map(formatWorkoutEvent) || [];\n\n\t\t\tif (events.length === 0) {\n\t\t\t\treturn createStructuredEmptyResponse(\n\t\t\t\t\t`No workout events found for the specified parameters since ${since}`,\n\t\t\t\t\t{ events: [] },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn createStructuredJsonResponse(events, { events });\n\t\t}, \"get-workout-events\"),\n\t);\n\n\t// Create workout\n\tconst createWorkoutSchema = {\n\t\ttitle: z.string().min(1),\n\t\tdescription: z.string().optional().nullable(),\n\t\tstartTime: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/),\n\t\tendTime: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/),\n\t\tisPrivate: z.boolean().default(false),\n\t\texercises: z.preprocess(\n\t\t\tparseJsonArray,\n\t\t\tz.array(\n\t\t\t\tz.object({\n\t\t\t\t\texerciseTemplateId: z.string().min(1),\n\t\t\t\t\tsupersetId: z.coerce.number().nullable().optional(),\n\t\t\t\t\tnotes: z.string().optional().nullable(),\n\t\t\t\t\tsets: z.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\ttype: setTypeEnum,\n\t\t\t\t\t\t\tweight: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\tweightKg: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\treps: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdistance: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdistanceMeters: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tduration: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdurationSeconds: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\trpe: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\tcustomMetric: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t} as const;\n\ttype CreateWorkoutParams = InferToolParams<typeof createWorkoutSchema>;\n\n\tserver.tool(\n\t\t\"create-workout\",\n\t\tdescribeTool({\n\t\t\tsummary: \"Writes to the Hevy account by creating a new workout.\",\n\t\t\taliases: [\"log workout\", \"add workout\", \"record training session\"],\n\t\t\tuseCase:\n\t\t\t\t\"Use to add a completed workout; use update-workout only when modifying an existing workout ID.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires UTC startTime/endTime in YYYY-MM-DDTHH:mm:ssZ form and exercise template IDs. Retrying can create duplicates.\",\n\t\t}),\n\t\tcreateWorkoutSchema,\n\t\tcreateAnnotations(\"Create Workout\"),\n\t\twithObservability(async (args: CreateWorkoutParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst { title, description, startTime, endTime, isPrivate, exercises } =\n\t\t\t\targs;\n\t\t\tconst workoutPayload: NonNullable<PostWorkoutsRequestBody[\"workout\"]> = {\n\t\t\t\ttitle,\n\t\t\t\tdescription: description ?? null,\n\t\t\t\tstart_time: startTime,\n\t\t\t\tend_time: endTime,\n\t\t\t\tis_private: isPrivate,\n\t\t\t\texercises: exercises.map(\n\t\t\t\t\t(exercise): PostWorkoutsRequestExercise => ({\n\t\t\t\t\t\texercise_template_id: exercise.exerciseTemplateId,\n\t\t\t\t\t\tsuperset_id: exercise.supersetId ?? null,\n\t\t\t\t\t\tnotes: exercise.notes ?? null,\n\t\t\t\t\t\tsets: exercise.sets.map((set) => ({\n\t\t\t\t\t\t\ttype: set.type as PostWorkoutsRequestSetTypeEnumKey,\n\t\t\t\t\t\t\tweight_kg: set.weight ?? set.weightKg ?? null,\n\t\t\t\t\t\t\treps: set.reps ?? null,\n\t\t\t\t\t\t\tdistance_meters: set.distance ?? set.distanceMeters ?? null,\n\t\t\t\t\t\t\tduration_seconds: set.duration ?? set.durationSeconds ?? null,\n\t\t\t\t\t\t\trpe: (set.rpe as PostWorkoutsRequestSetRpeEnumKey | null) ?? null,\n\t\t\t\t\t\t\tcustom_metric: set.customMetric ?? null,\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst requestBody: PostWorkoutsRequestBody = { workout: workoutPayload };\n\n\t\t\tconst data: PostV1Workouts201 = await client.createWorkout(requestBody);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createEmptyResponse(\n\t\t\t\t\t\"Failed to create workout: Server returned no data\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst workout = formatWorkout(data);\n\t\t\treturn createJsonResponse(workout, {\n\t\t\t\tpretty: true,\n\t\t\t\tindent: 2,\n\t\t\t});\n\t\t}, \"create-workout\"),\n\t);\n\n\t// Update workout\n\tconst updateWorkoutSchema = {\n\t\tworkoutId: z.string().min(1),\n\t\ttitle: z.string().min(1),\n\t\tdescription: z.string().optional().nullable(),\n\t\tstartTime: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/),\n\t\tendTime: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/),\n\t\tisPrivate: z.boolean().default(false),\n\t\texercises: z.preprocess(\n\t\t\tparseJsonArray,\n\t\t\tz.array(\n\t\t\t\tz.object({\n\t\t\t\t\texerciseTemplateId: z.string().min(1),\n\t\t\t\t\tsupersetId: z.coerce.number().nullable().optional(),\n\t\t\t\t\tnotes: z.string().optional().nullable(),\n\t\t\t\t\tsets: z.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\ttype: setTypeEnum,\n\t\t\t\t\t\t\tweight: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\tweightKg: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\treps: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdistance: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdistanceMeters: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tduration: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\tdurationSeconds: z.coerce.number().int().optional().nullable(),\n\t\t\t\t\t\t\trpe: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t\tcustomMetric: z.coerce.number().optional().nullable(),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t} as const;\n\ttype UpdateWorkoutParams = InferToolParams<typeof updateWorkoutSchema>;\n\n\tserver.tool(\n\t\t\"update-workout\",\n\t\tdescribeTool({\n\t\t\tsummary: \"Mutates the Hevy account by replacing an existing workout.\",\n\t\t\taliases: [\n\t\t\t\t\"edit workout\",\n\t\t\t\t\"correct workout log\",\n\t\t\t\t\"replace workout details\",\n\t\t\t],\n\t\t\tuseCase:\n\t\t\t\t\"Use to revise a known workout; use create-workout for a new training session.\",\n\t\t\timportantNotes:\n\t\t\t\t\"Requires workoutId plus the complete title, times, privacy, exercises, and sets payload; omitted optional values may be cleared or defaulted.\",\n\t\t}),\n\t\tupdateWorkoutSchema,\n\t\tupdateAnnotations(\"Update Workout\"),\n\t\twithObservability(async (args: UpdateWorkoutParams) => {\n\t\t\tconst client = requireClient(hevyClient);\n\t\t\tconst {\n\t\t\t\tworkoutId,\n\t\t\t\ttitle,\n\t\t\t\tdescription,\n\t\t\t\tstartTime,\n\t\t\t\tendTime,\n\t\t\t\tisPrivate,\n\t\t\t\texercises,\n\t\t\t} = args;\n\t\t\tconst workoutPayload: NonNullable<PostWorkoutsRequestBody[\"workout\"]> = {\n\t\t\t\ttitle,\n\t\t\t\tdescription: description ?? null,\n\t\t\t\tstart_time: startTime,\n\t\t\t\tend_time: endTime,\n\t\t\t\tis_private: isPrivate,\n\t\t\t\texercises: exercises.map(\n\t\t\t\t\t(exercise): PostWorkoutsRequestExercise => ({\n\t\t\t\t\t\texercise_template_id: exercise.exerciseTemplateId,\n\t\t\t\t\t\tsuperset_id: exercise.supersetId ?? null,\n\t\t\t\t\t\tnotes: exercise.notes ?? null,\n\t\t\t\t\t\tsets: exercise.sets.map((set) => ({\n\t\t\t\t\t\t\ttype: set.type as PostWorkoutsRequestSetTypeEnumKey,\n\t\t\t\t\t\t\tweight_kg: set.weight ?? set.weightKg ?? null,\n\t\t\t\t\t\t\treps: set.reps ?? null,\n\t\t\t\t\t\t\tdistance_meters: set.distance ?? set.distanceMeters ?? null,\n\t\t\t\t\t\t\tduration_seconds: set.duration ?? set.durationSeconds ?? null,\n\t\t\t\t\t\t\trpe: (set.rpe as PostWorkoutsRequestSetRpeEnumKey | null) ?? null,\n\t\t\t\t\t\t\tcustom_metric: set.customMetric ?? null,\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst requestBody: PostWorkoutsRequestBody = { workout: workoutPayload };\n\n\t\t\tconst data: PutV1WorkoutsWorkoutid200 = await client.updateWorkout(\n\t\t\t\tworkoutId,\n\t\t\t\trequestBody,\n\t\t\t);\n\n\t\t\tif (!data) {\n\t\t\t\treturn createEmptyResponse(\n\t\t\t\t\t`Failed to update workout with ID ${workoutId}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst workout = formatWorkout(data);\n\t\t\treturn createJsonResponse(workout, {\n\t\t\t\tpretty: true,\n\t\t\t\tindent: 2,\n\t\t\t});\n\t\t}, \"update-workout-operation\"),\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { McpClientLogger } from \"../utils/mcp-client-logger.js\";\nimport type { HevyClient } from \"../utils/hevyClient.js\";\nimport { registerBodyMeasurementTools } from \"./body-measurements.js\";\nimport { registerFolderTools } from \"./folders.js\";\nimport { registerRoutineTools } from \"./routines.js\";\nimport { registerTemplateTools } from \"./templates.js\";\nimport { registerUserTools } from \"./user.js\";\nimport { registerWorkoutTools } from \"./workouts.js\";\n\nexport interface RegisterHevyToolsOptions {\n\tlogger?: McpClientLogger;\n}\n\n/** Register every Hevy tool in its production ordering. */\nexport function registerHevyTools(\n\tserver: McpServer,\n\thevyClient: HevyClient | null,\n\toptions: RegisterHevyToolsOptions = {},\n) {\n\tregisterWorkoutTools(server, hevyClient);\n\tregisterRoutineTools(server, hevyClient);\n\tregisterTemplateTools(server, hevyClient, { logger: options.logger });\n\tregisterFolderTools(server, hevyClient);\n\tregisterBodyMeasurementTools(server, hevyClient);\n\tregisterUserTools(server, hevyClient);\n}\n","export interface HevyConfig {\n\tapiKey?: string;\n}\n\nexport function parseConfig(env: NodeJS.ProcessEnv): HevyConfig {\n\treturn {\n\t\tapiKey: env.HEVY_API_KEY || \"\",\n\t};\n}\n\nexport function assertApiKey(\n\tapiKey: string | undefined,\n): asserts apiKey is string {\n\tif (!apiKey) {\n\t\tconsole.error(\n\t\t\t\"Hevy API key is required. Provide it via the HEVY_API_KEY environment variable.\",\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n","export type ShutdownSignal = \"SIGINT\" | \"SIGTERM\";\n\ninterface CloseTarget {\n\tclose(): Promise<void>;\n}\n\ninterface ProcessLike {\n\texitCode?: number | string | null;\n\texit(code?: number | string | null): never;\n\ton(signal: ShutdownSignal, listener: () => void): unknown;\n\tremoveListener(signal: ShutdownSignal, listener: () => void): unknown;\n}\n\ninterface FlushableStdout {\n\twrite(chunk: string, callback: (error?: Error | null) => void): boolean;\n}\n\ninterface ForcedExitTimer {\n\tunref(): void;\n}\n\ntype ScheduleForcedExit = (\n\tcallback: () => void,\n\ttimeoutMs: number,\n) => ForcedExitTimer;\n\ninterface GracefulShutdownOptions {\n\ttarget: CloseTarget;\n\tprocess?: ProcessLike;\n\tlogError?: (message: string) => void;\n\tflush?: () => Promise<void>;\n\tforcedExitTimeoutMs?: number;\n\tscheduleForcedExit?: ScheduleForcedExit;\n}\n\nexport interface GracefulShutdownController {\n\tcleanup(): void;\n\tgetShutdownPromise(): Promise<void> | undefined;\n}\n\nconst shutdownSignals: ShutdownSignal[] = [\"SIGINT\", \"SIGTERM\"];\n\n// Long enough for normal stdio flushing, but bounded so unrelated handles or a\n// stalled close cannot keep a signal-terminated process alive indefinitely.\nexport const FORCED_EXIT_TIMEOUT_MS = 5_000;\n\nexport function flushStdout(\n\tstdout: FlushableStdout = process.stdout,\n): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\ttry {\n\t\t\tstdout.write(\"\", (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresolve();\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treject(error);\n\t\t}\n\t});\n}\n\nexport function installGracefulShutdown({\n\ttarget,\n\tprocess: processLike = process,\n\tlogError = console.error,\n\tflush = flushStdout,\n\tforcedExitTimeoutMs = FORCED_EXIT_TIMEOUT_MS,\n\tscheduleForcedExit = setTimeout,\n}: GracefulShutdownOptions): GracefulShutdownController {\n\tlet listenersInstalled = true;\n\tlet shutdownSettled = false;\n\tlet shutdownPromise: Promise<void> | undefined;\n\n\tconst cleanup = () => {\n\t\tif (!listenersInstalled || (shutdownPromise && !shutdownSettled)) {\n\t\t\treturn;\n\t\t}\n\n\t\tlistenersInstalled = false;\n\t\tfor (const signal of shutdownSignals) {\n\t\t\tconst listener = signalListeners.get(signal);\n\t\t\tif (listener) {\n\t\t\t\tprocessLike.removeListener(signal, listener);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleSignal = (signal: ShutdownSignal) => {\n\t\tif (shutdownPromise) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (processLike.exitCode == null) {\n\t\t\tprocessLike.exitCode = 0;\n\t\t}\n\n\t\tconst forcedExitTimer = scheduleForcedExit(() => {\n\t\t\tprocessLike.exit(processLike.exitCode ?? 0);\n\t\t}, forcedExitTimeoutMs);\n\t\t// This fallback must survive successful shutdown so it can terminate a\n\t\t// process held open by unrelated handles, without keeping the process alive\n\t\t// when the event loop drains normally.\n\t\tforcedExitTimer.unref();\n\n\t\tshutdownPromise = (async () => {\n\t\t\tlogError(`Shutting down gracefully after ${signal}`);\n\t\t\tlet shutdownFailed = false;\n\t\t\tlet shutdownError: unknown;\n\n\t\t\ttry {\n\t\t\t\tawait target.close();\n\t\t\t} catch (error) {\n\t\t\t\tshutdownFailed = true;\n\t\t\t\tshutdownError = error;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait flush();\n\t\t\t} catch (error) {\n\t\t\t\tif (!shutdownFailed) {\n\t\t\t\t\tshutdownError = error;\n\t\t\t\t}\n\t\t\t\tshutdownFailed = true;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif (shutdownFailed) {\n\t\t\t\t\tconst message =\n\t\t\t\t\t\tshutdownError instanceof Error\n\t\t\t\t\t\t\t? shutdownError.message\n\t\t\t\t\t\t\t: \"Unknown shutdown error\";\n\t\t\t\t\tlogError(`Graceful shutdown failed: ${message}`);\n\t\t\t\t\tprocessLike.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tshutdownSettled = true;\n\t\t\t\tcleanup();\n\t\t\t}\n\t\t})();\n\t};\n\tconst signalListeners = new Map<ShutdownSignal, () => void>(\n\t\tshutdownSignals.map((signal) => [signal, () => handleSignal(signal)]),\n\t);\n\n\tfor (const signal of shutdownSignals) {\n\t\tconst listener = signalListeners.get(signal);\n\t\tif (listener) {\n\t\t\tprocessLike.on(signal, listener);\n\t\t}\n\t}\n\n\treturn {\n\t\tcleanup,\n\t\tgetShutdownPromise: () => shutdownPromise,\n\t};\n}\n","import type { AxiosError, AxiosRequestConfig, AxiosResponse } from \"axios\";\nimport axios from \"axios\";\n\ndeclare const AXIOS_BASE: string;\ndeclare const AXIOS_HEADERS: string;\n\n/**\n * Subset of AxiosRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string;\n url?: string;\n method?: \"GET\" | \"PUT\" | \"PATCH\" | \"POST\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\";\n params?: unknown;\n data?: TData | FormData;\n responseType?:\n | \"arraybuffer\"\n | \"blob\"\n | \"document\"\n | \"json\"\n | \"text\"\n | \"stream\";\n signal?: AbortSignal;\n validateStatus?: (status: number) => boolean;\n headers?: AxiosRequestConfig[\"headers\"];\n};\n\n/**\n * Subset of AxiosResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData;\n status: number;\n statusText: string;\n headers: AxiosResponse[\"headers\"];\n};\n\nexport type ResponseErrorConfig<TError = unknown> = AxiosError<TError>;\n\nexport type Client = <TData, _TError = unknown, TVariables = unknown>(\n config: RequestConfig<TVariables>,\n) => Promise<ResponseConfig<TData>>;\n\nlet _config: Partial<RequestConfig> = {\n baseURL: typeof AXIOS_BASE !== \"undefined\" ? AXIOS_BASE : undefined,\n headers:\n typeof AXIOS_HEADERS !== \"undefined\"\n ? JSON.parse(AXIOS_HEADERS)\n : undefined,\n};\n\nexport const getConfig = () => _config;\n\nexport const setConfig = (config: RequestConfig) => {\n _config = config;\n return getConfig();\n};\n\nexport const mergeConfig = <T extends RequestConfig>(\n ...configs: Array<Partial<T>>\n): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...merged.headers,\n ...config.headers,\n },\n };\n }, {});\n};\n\nexport const axiosInstance = axios.create(getConfig());\n\nexport const fetch = async <TData, TError = unknown, TVariables = unknown>(\n config: RequestConfig<TVariables>,\n): Promise<ResponseConfig<TData>> => {\n return axiosInstance\n .request<TData, ResponseConfig<TData>>(mergeConfig(getConfig(), config))\n .catch((e: AxiosError<TError>) => {\n throw e;\n });\n};\n\nfetch.getConfig = getConfig;\nfetch.setConfig = setConfig;\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1BodyMeasurementsQueryResponse,\n GetV1BodyMeasurementsQueryParams,\n GetV1BodyMeasurementsHeaderParams,\n GetV1BodyMeasurements400,\n GetV1BodyMeasurements404,\n} from \"../types/GetV1BodyMeasurements.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1BodyMeasurementsUrl() {\n const res = { method: \"GET\", url: `/v1/body_measurements` as const };\n return res;\n}\n\n/**\n * @summary Get a paginated list of body measurements for the authenticated user\n * {@link /v1/body_measurements}\n */\nexport async function getV1BodyMeasurements(\n headers: GetV1BodyMeasurementsHeaderParams,\n params?: GetV1BodyMeasurementsQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1BodyMeasurementsQueryResponse,\n ResponseErrorConfig<GetV1BodyMeasurements400 | GetV1BodyMeasurements404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1BodyMeasurementsUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1BodyMeasurementsDateQueryResponse,\n GetV1BodyMeasurementsDatePathParams,\n GetV1BodyMeasurementsDateHeaderParams,\n GetV1BodyMeasurementsDate404,\n} from \"../types/GetV1BodyMeasurementsDate.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1BodyMeasurementsDateUrl(\n date: GetV1BodyMeasurementsDatePathParams[\"date\"],\n) {\n const res = { method: \"GET\", url: `/v1/body_measurements/${date}` as const };\n return res;\n}\n\n/**\n * @summary Get a single body measurement by date\n * {@link /v1/body_measurements/:date}\n */\nexport async function getV1BodyMeasurementsDate(\n date: GetV1BodyMeasurementsDatePathParams[\"date\"],\n headers: GetV1BodyMeasurementsDateHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1BodyMeasurementsDateQueryResponse,\n ResponseErrorConfig<GetV1BodyMeasurementsDate404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1BodyMeasurementsDateUrl(date).url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1ExerciseHistoryExercisetemplateidQueryResponse,\n GetV1ExerciseHistoryExercisetemplateidPathParams,\n GetV1ExerciseHistoryExercisetemplateidQueryParams,\n GetV1ExerciseHistoryExercisetemplateidHeaderParams,\n GetV1ExerciseHistoryExercisetemplateid400,\n} from \"../types/GetV1ExerciseHistoryExercisetemplateid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1ExerciseHistoryExercisetemplateidUrl(\n exerciseTemplateId: GetV1ExerciseHistoryExercisetemplateidPathParams[\"exerciseTemplateId\"],\n) {\n const res = {\n method: \"GET\",\n url: `/v1/exercise_history/${exerciseTemplateId}` as const,\n };\n return res;\n}\n\n/**\n * @summary Get exercise history for a specific exercise template\n * {@link /v1/exercise_history/:exerciseTemplateId}\n */\nexport async function getV1ExerciseHistoryExercisetemplateid(\n exerciseTemplateId: GetV1ExerciseHistoryExercisetemplateidPathParams[\"exerciseTemplateId\"],\n headers: GetV1ExerciseHistoryExercisetemplateidHeaderParams,\n params?: GetV1ExerciseHistoryExercisetemplateidQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1ExerciseHistoryExercisetemplateidQueryResponse,\n ResponseErrorConfig<GetV1ExerciseHistoryExercisetemplateid400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1ExerciseHistoryExercisetemplateidUrl(\n exerciseTemplateId,\n ).url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1ExerciseTemplatesQueryResponse,\n GetV1ExerciseTemplatesQueryParams,\n GetV1ExerciseTemplatesHeaderParams,\n GetV1ExerciseTemplates400,\n} from \"../types/GetV1ExerciseTemplates.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1ExerciseTemplatesUrl() {\n const res = { method: \"GET\", url: `/v1/exercise_templates` as const };\n return res;\n}\n\n/**\n * @summary Get a paginated list of exercise templates available on the account.\n * {@link /v1/exercise_templates}\n */\nexport async function getV1ExerciseTemplates(\n headers: GetV1ExerciseTemplatesHeaderParams,\n params?: GetV1ExerciseTemplatesQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1ExerciseTemplatesQueryResponse,\n ResponseErrorConfig<GetV1ExerciseTemplates400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1ExerciseTemplatesUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1ExerciseTemplatesExercisetemplateidQueryResponse,\n GetV1ExerciseTemplatesExercisetemplateidPathParams,\n GetV1ExerciseTemplatesExercisetemplateidHeaderParams,\n GetV1ExerciseTemplatesExercisetemplateid404,\n} from \"../types/GetV1ExerciseTemplatesExercisetemplateid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1ExerciseTemplatesExercisetemplateidUrl(\n exerciseTemplateId: GetV1ExerciseTemplatesExercisetemplateidPathParams[\"exerciseTemplateId\"],\n) {\n const res = {\n method: \"GET\",\n url: `/v1/exercise_templates/${exerciseTemplateId}` as const,\n };\n return res;\n}\n\n/**\n * @summary Get a single exercise template by id.\n * {@link /v1/exercise_templates/:exerciseTemplateId}\n */\nexport async function getV1ExerciseTemplatesExercisetemplateid(\n exerciseTemplateId: GetV1ExerciseTemplatesExercisetemplateidPathParams[\"exerciseTemplateId\"],\n headers: GetV1ExerciseTemplatesExercisetemplateidHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1ExerciseTemplatesExercisetemplateidQueryResponse,\n ResponseErrorConfig<GetV1ExerciseTemplatesExercisetemplateid404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1ExerciseTemplatesExercisetemplateidUrl(\n exerciseTemplateId,\n ).url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1RoutineFoldersQueryResponse,\n GetV1RoutineFoldersQueryParams,\n GetV1RoutineFoldersHeaderParams,\n GetV1RoutineFolders400,\n} from \"../types/GetV1RoutineFolders.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1RoutineFoldersUrl() {\n const res = { method: \"GET\", url: `/v1/routine_folders` as const };\n return res;\n}\n\n/**\n * @summary Get a paginated list of routine folders available on the account.\n * {@link /v1/routine_folders}\n */\nexport async function getV1RoutineFolders(\n headers: GetV1RoutineFoldersHeaderParams,\n params?: GetV1RoutineFoldersQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1RoutineFoldersQueryResponse,\n ResponseErrorConfig<GetV1RoutineFolders400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1RoutineFoldersUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1RoutineFoldersFolderidQueryResponse,\n GetV1RoutineFoldersFolderidPathParams,\n GetV1RoutineFoldersFolderidHeaderParams,\n GetV1RoutineFoldersFolderid404,\n} from \"../types/GetV1RoutineFoldersFolderid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1RoutineFoldersFolderidUrl(\n folderId: GetV1RoutineFoldersFolderidPathParams[\"folderId\"],\n) {\n const res = {\n method: \"GET\",\n url: `/v1/routine_folders/${folderId}` as const,\n };\n return res;\n}\n\n/**\n * @summary Get a single routine folder by id.\n * {@link /v1/routine_folders/:folderId}\n */\nexport async function getV1RoutineFoldersFolderid(\n folderId: GetV1RoutineFoldersFolderidPathParams[\"folderId\"],\n headers: GetV1RoutineFoldersFolderidHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1RoutineFoldersFolderidQueryResponse,\n ResponseErrorConfig<GetV1RoutineFoldersFolderid404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1RoutineFoldersFolderidUrl(folderId).url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1RoutinesQueryResponse,\n GetV1RoutinesQueryParams,\n GetV1RoutinesHeaderParams,\n GetV1Routines400,\n} from \"../types/GetV1Routines.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1RoutinesUrl() {\n const res = { method: \"GET\", url: `/v1/routines` as const };\n return res;\n}\n\n/**\n * @summary Get a paginated list of routines\n * {@link /v1/routines}\n */\nexport async function getV1Routines(\n headers: GetV1RoutinesHeaderParams,\n params?: GetV1RoutinesQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1RoutinesQueryResponse,\n ResponseErrorConfig<GetV1Routines400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1RoutinesUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1RoutinesRoutineidQueryResponse,\n GetV1RoutinesRoutineidPathParams,\n GetV1RoutinesRoutineidHeaderParams,\n GetV1RoutinesRoutineid400,\n} from \"../types/GetV1RoutinesRoutineid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1RoutinesRoutineidUrl(\n routineId: GetV1RoutinesRoutineidPathParams[\"routineId\"],\n) {\n const res = { method: \"GET\", url: `/v1/routines/${routineId}` as const };\n return res;\n}\n\n/**\n * @summary Get a routine by its Id\n * {@link /v1/routines/:routineId}\n */\nexport async function getV1RoutinesRoutineid(\n routineId: GetV1RoutinesRoutineidPathParams[\"routineId\"],\n headers: GetV1RoutinesRoutineidHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1RoutinesRoutineidQueryResponse,\n ResponseErrorConfig<GetV1RoutinesRoutineid400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1RoutinesRoutineidUrl(routineId).url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1UserInfoQueryResponse,\n GetV1UserInfoHeaderParams,\n GetV1UserInfo404,\n} from \"../types/GetV1UserInfo.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1UserInfoUrl() {\n const res = { method: \"GET\", url: `/v1/user/info` as const };\n return res;\n}\n\n/**\n * @summary Get user info\n * {@link /v1/user/info}\n */\nexport async function getV1UserInfo(\n headers: GetV1UserInfoHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1UserInfoQueryResponse,\n ResponseErrorConfig<GetV1UserInfo404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1UserInfoUrl().url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1WorkoutsQueryResponse,\n GetV1WorkoutsQueryParams,\n GetV1WorkoutsHeaderParams,\n GetV1Workouts400,\n} from \"../types/GetV1Workouts.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1WorkoutsUrl() {\n const res = { method: \"GET\", url: `/v1/workouts` as const };\n return res;\n}\n\n/**\n * @summary Get a paginated list of workouts\n * {@link /v1/workouts}\n */\nexport async function getV1Workouts(\n headers: GetV1WorkoutsHeaderParams,\n params?: GetV1WorkoutsQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1WorkoutsQueryResponse,\n ResponseErrorConfig<GetV1Workouts400>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1WorkoutsUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1WorkoutsCountQueryResponse,\n GetV1WorkoutsCountHeaderParams,\n} from \"../types/GetV1WorkoutsCount.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1WorkoutsCountUrl() {\n const res = { method: \"GET\", url: `/v1/workouts/count` as const };\n return res;\n}\n\n/**\n * @summary Get the total number of workouts on the account\n * {@link /v1/workouts/count}\n */\nexport async function getV1WorkoutsCount(\n headers: GetV1WorkoutsCountHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1WorkoutsCountQueryResponse,\n ResponseErrorConfig<Error>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1WorkoutsCountUrl().url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1WorkoutsEventsQueryResponse,\n GetV1WorkoutsEventsQueryParams,\n GetV1WorkoutsEventsHeaderParams,\n GetV1WorkoutsEvents500,\n} from \"../types/GetV1WorkoutsEvents.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1WorkoutsEventsUrl() {\n const res = { method: \"GET\", url: `/v1/workouts/events` as const };\n return res;\n}\n\n/**\n * @description Returns a paginated array of workout events, indicating updates or deletions.\n * @summary Retrieve a paged list of workout events (updates or deletes) since a given date. Events are ordered from newest to oldest. The intention is to allow clients to keep their local cache of workouts up to date without having to fetch the entire list of workouts.\n * {@link /v1/workouts/events}\n */\nexport async function getV1WorkoutsEvents(\n headers: GetV1WorkoutsEventsHeaderParams,\n params?: GetV1WorkoutsEventsQueryParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1WorkoutsEventsQueryResponse,\n ResponseErrorConfig<GetV1WorkoutsEvents500>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1WorkoutsEventsUrl().url.toString(),\n params,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n GetV1WorkoutsWorkoutidQueryResponse,\n GetV1WorkoutsWorkoutidPathParams,\n GetV1WorkoutsWorkoutidHeaderParams,\n GetV1WorkoutsWorkoutid404,\n} from \"../types/GetV1WorkoutsWorkoutid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getGetV1WorkoutsWorkoutidUrl(\n workoutId: GetV1WorkoutsWorkoutidPathParams[\"workoutId\"],\n) {\n const res = { method: \"GET\", url: `/v1/workouts/${workoutId}` as const };\n return res;\n}\n\n/**\n * @summary Get a single workout’s complete details by the workoutId\n * {@link /v1/workouts/:workoutId}\n */\nexport async function getV1WorkoutsWorkoutid(\n workoutId: GetV1WorkoutsWorkoutidPathParams[\"workoutId\"],\n headers: GetV1WorkoutsWorkoutidHeaderParams,\n config: Partial<RequestConfig> & { client?: Client } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const res = await request<\n GetV1WorkoutsWorkoutidQueryResponse,\n ResponseErrorConfig<GetV1WorkoutsWorkoutid404>,\n unknown\n >({\n method: \"GET\",\n url: getGetV1WorkoutsWorkoutidUrl(workoutId).url.toString(),\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PostV1BodyMeasurementsMutationRequest,\n PostV1BodyMeasurementsMutationResponse,\n PostV1BodyMeasurementsHeaderParams,\n PostV1BodyMeasurements400,\n PostV1BodyMeasurements409,\n} from \"../types/PostV1BodyMeasurements.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPostV1BodyMeasurementsUrl() {\n const res = { method: \"POST\", url: `/v1/body_measurements` as const };\n return res;\n}\n\n/**\n * @summary Create a body measurement entry for a given date. Returns 409 if an entry already exists for that date.\n * {@link /v1/body_measurements}\n */\nexport async function postV1BodyMeasurements(\n data: PostV1BodyMeasurementsMutationRequest,\n headers: PostV1BodyMeasurementsHeaderParams,\n config: Partial<RequestConfig<PostV1BodyMeasurementsMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PostV1BodyMeasurementsMutationResponse,\n ResponseErrorConfig<PostV1BodyMeasurements400 | PostV1BodyMeasurements409>,\n PostV1BodyMeasurementsMutationRequest\n >({\n method: \"POST\",\n url: getPostV1BodyMeasurementsUrl().url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PostV1ExerciseTemplatesMutationRequest,\n PostV1ExerciseTemplatesMutationResponse,\n PostV1ExerciseTemplatesHeaderParams,\n PostV1ExerciseTemplates400,\n PostV1ExerciseTemplates403,\n} from \"../types/PostV1ExerciseTemplates.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPostV1ExerciseTemplatesUrl() {\n const res = { method: \"POST\", url: `/v1/exercise_templates` as const };\n return res;\n}\n\n/**\n * @summary Create a new custom exercise template.\n * {@link /v1/exercise_templates}\n */\nexport async function postV1ExerciseTemplates(\n data: PostV1ExerciseTemplatesMutationRequest,\n headers: PostV1ExerciseTemplatesHeaderParams,\n config: Partial<RequestConfig<PostV1ExerciseTemplatesMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PostV1ExerciseTemplatesMutationResponse,\n ResponseErrorConfig<\n PostV1ExerciseTemplates400 | PostV1ExerciseTemplates403\n >,\n PostV1ExerciseTemplatesMutationRequest\n >({\n method: \"POST\",\n url: getPostV1ExerciseTemplatesUrl().url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PostV1RoutineFoldersMutationRequest,\n PostV1RoutineFoldersMutationResponse,\n PostV1RoutineFoldersHeaderParams,\n PostV1RoutineFolders400,\n} from \"../types/PostV1RoutineFolders.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPostV1RoutineFoldersUrl() {\n const res = { method: \"POST\", url: `/v1/routine_folders` as const };\n return res;\n}\n\n/**\n * @summary Create a new routine folder. The folder will be created at index 0, and all other folders will have their indexes incremented.\n * {@link /v1/routine_folders}\n */\nexport async function postV1RoutineFolders(\n data: PostV1RoutineFoldersMutationRequest,\n headers: PostV1RoutineFoldersHeaderParams,\n config: Partial<RequestConfig<PostV1RoutineFoldersMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PostV1RoutineFoldersMutationResponse,\n ResponseErrorConfig<PostV1RoutineFolders400>,\n PostV1RoutineFoldersMutationRequest\n >({\n method: \"POST\",\n url: getPostV1RoutineFoldersUrl().url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PostV1RoutinesMutationRequest,\n PostV1RoutinesMutationResponse,\n PostV1RoutinesHeaderParams,\n PostV1Routines400,\n PostV1Routines403,\n} from \"../types/PostV1Routines.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPostV1RoutinesUrl() {\n const res = { method: \"POST\", url: `/v1/routines` as const };\n return res;\n}\n\n/**\n * @summary Create a new routine\n * {@link /v1/routines}\n */\nexport async function postV1Routines(\n data: PostV1RoutinesMutationRequest,\n headers: PostV1RoutinesHeaderParams,\n config: Partial<RequestConfig<PostV1RoutinesMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PostV1RoutinesMutationResponse,\n ResponseErrorConfig<PostV1Routines400 | PostV1Routines403>,\n PostV1RoutinesMutationRequest\n >({\n method: \"POST\",\n url: getPostV1RoutinesUrl().url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PostV1WorkoutsMutationRequest,\n PostV1WorkoutsMutationResponse,\n PostV1WorkoutsHeaderParams,\n PostV1Workouts400,\n} from \"../types/PostV1Workouts.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPostV1WorkoutsUrl() {\n const res = { method: \"POST\", url: `/v1/workouts` as const };\n return res;\n}\n\n/**\n * @summary Create a new workout\n * {@link /v1/workouts}\n */\nexport async function postV1Workouts(\n data: PostV1WorkoutsMutationRequest,\n headers: PostV1WorkoutsHeaderParams,\n config: Partial<RequestConfig<PostV1WorkoutsMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PostV1WorkoutsMutationResponse,\n ResponseErrorConfig<PostV1Workouts400>,\n PostV1WorkoutsMutationRequest\n >({\n method: \"POST\",\n url: getPostV1WorkoutsUrl().url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PutV1BodyMeasurementsDateMutationRequest,\n PutV1BodyMeasurementsDateMutationResponse,\n PutV1BodyMeasurementsDatePathParams,\n PutV1BodyMeasurementsDateHeaderParams,\n PutV1BodyMeasurementsDate400,\n PutV1BodyMeasurementsDate404,\n} from \"../types/PutV1BodyMeasurementsDate.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPutV1BodyMeasurementsDateUrl(\n date: PutV1BodyMeasurementsDatePathParams[\"date\"],\n) {\n const res = { method: \"PUT\", url: `/v1/body_measurements/${date}` as const };\n return res;\n}\n\n/**\n * @summary Update an existing body measurement entry for a given date. All fields are overwritten; omitted fields are set to null.\n * {@link /v1/body_measurements/:date}\n */\nexport async function putV1BodyMeasurementsDate(\n date: PutV1BodyMeasurementsDatePathParams[\"date\"],\n data: PutV1BodyMeasurementsDateMutationRequest,\n headers: PutV1BodyMeasurementsDateHeaderParams,\n config: Partial<RequestConfig<PutV1BodyMeasurementsDateMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PutV1BodyMeasurementsDateMutationResponse,\n ResponseErrorConfig<\n PutV1BodyMeasurementsDate400 | PutV1BodyMeasurementsDate404\n >,\n PutV1BodyMeasurementsDateMutationRequest\n >({\n method: \"PUT\",\n url: getPutV1BodyMeasurementsDateUrl(date).url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PutV1RoutinesRoutineidMutationRequest,\n PutV1RoutinesRoutineidMutationResponse,\n PutV1RoutinesRoutineidPathParams,\n PutV1RoutinesRoutineidHeaderParams,\n PutV1RoutinesRoutineid400,\n PutV1RoutinesRoutineid404,\n} from \"../types/PutV1RoutinesRoutineid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPutV1RoutinesRoutineidUrl(\n routineId: PutV1RoutinesRoutineidPathParams[\"routineId\"],\n) {\n const res = { method: \"PUT\", url: `/v1/routines/${routineId}` as const };\n return res;\n}\n\n/**\n * @summary Update an existing routine\n * {@link /v1/routines/:routineId}\n */\nexport async function putV1RoutinesRoutineid(\n routineId: PutV1RoutinesRoutineidPathParams[\"routineId\"],\n data: PutV1RoutinesRoutineidMutationRequest,\n headers: PutV1RoutinesRoutineidHeaderParams,\n config: Partial<RequestConfig<PutV1RoutinesRoutineidMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PutV1RoutinesRoutineidMutationResponse,\n ResponseErrorConfig<PutV1RoutinesRoutineid400 | PutV1RoutinesRoutineid404>,\n PutV1RoutinesRoutineidMutationRequest\n >({\n method: \"PUT\",\n url: getPutV1RoutinesRoutineidUrl(routineId).url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","/**\n * Generated by Kubb (https://kubb.dev/).\n * Do not edit manually.\n */\n\nimport type {\n Client,\n RequestConfig,\n ResponseErrorConfig,\n} from \"../../.kubb/fetch.ts\";\nimport type {\n PutV1WorkoutsWorkoutidMutationRequest,\n PutV1WorkoutsWorkoutidMutationResponse,\n PutV1WorkoutsWorkoutidPathParams,\n PutV1WorkoutsWorkoutidHeaderParams,\n PutV1WorkoutsWorkoutid400,\n} from \"../types/PutV1WorkoutsWorkoutid.ts\";\nimport { fetch } from \"../../.kubb/fetch.ts\";\n\nfunction getPutV1WorkoutsWorkoutidUrl(\n workoutId: PutV1WorkoutsWorkoutidPathParams[\"workoutId\"],\n) {\n const res = { method: \"PUT\", url: `/v1/workouts/${workoutId}` as const };\n return res;\n}\n\n/**\n * @summary Update an existing workout\n * {@link /v1/workouts/:workoutId}\n */\nexport async function putV1WorkoutsWorkoutid(\n workoutId: PutV1WorkoutsWorkoutidPathParams[\"workoutId\"],\n data: PutV1WorkoutsWorkoutidMutationRequest,\n headers: PutV1WorkoutsWorkoutidHeaderParams,\n config: Partial<RequestConfig<PutV1WorkoutsWorkoutidMutationRequest>> & {\n client?: Client;\n } = {},\n) {\n const { client: request = fetch, ...requestConfig } = config;\n\n const requestData = data;\n\n const res = await request<\n PutV1WorkoutsWorkoutidMutationResponse,\n ResponseErrorConfig<PutV1WorkoutsWorkoutid400>,\n PutV1WorkoutsWorkoutidMutationRequest\n >({\n method: \"PUT\",\n url: getPutV1WorkoutsWorkoutidUrl(workoutId).url.toString(),\n data: requestData,\n ...requestConfig,\n headers: { ...headers, ...requestConfig.headers },\n });\n return res.data;\n}\n","import type {\n\tRequestConfig,\n\tResponseConfig,\n} from \"../generated/.kubb/fetch.ts\";\nimport { SpanStatusCode, type Span } from \"@opentelemetry/api\";\nimport axios, {\n\tisAxiosError,\n\ttype AxiosError,\n\ttype AxiosInstance,\n\ttype AxiosRequestConfig,\n\ttype InternalAxiosRequestConfig,\n} from \"axios\";\nimport * as api from \"../generated/client/api\";\nimport type {\n\tMcpClientLogger,\n\tMcpClientLogMessage,\n} from \"./mcp-client-logger.js\";\nimport { debugLog } from \"./debug.js\";\nimport { getCurrentUserId, tracer } from \"./telemetry.js\";\nimport { apiCalls, apiDuration } from \"./metrics.js\";\nimport type {\n\tGetV1BodyMeasurementsQueryParams,\n\tGetV1ExerciseHistoryExercisetemplateidQueryParams,\n\tGetV1ExerciseTemplatesQueryParams,\n\tGetV1RoutineFoldersQueryParams,\n\tGetV1RoutinesQueryParams,\n\tGetV1WorkoutsEventsQueryParams,\n\tGetV1WorkoutsQueryParams,\n\tPostV1BodyMeasurementsMutationRequest,\n\tPostV1ExerciseTemplatesMutationRequest,\n\tPostV1RoutineFoldersMutationRequest,\n\tPostV1RoutinesMutationRequest,\n\tPostV1WorkoutsMutationRequest,\n\tPutV1BodyMeasurementsDateMutationRequest,\n\tPutV1RoutinesRoutineidMutationRequest,\n\tPutV1WorkoutsWorkoutidMutationRequest,\n} from \"../generated/client/types\";\n\n// Define a proper client type that matches the Kubb client interface\ntype KubbClient = {\n\t<TData, _TError = unknown, TVariables = unknown>(\n\t\tconfig: RequestConfig<TVariables>,\n\t): Promise<ResponseConfig<TData>>;\n\tgetConfig: () => Partial<RequestConfig<unknown>>;\n\tsetConfig: (config: RequestConfig) => Partial<RequestConfig<unknown>>;\n};\n\n/**\n * Type-safe wrapper helper that enforces parameter types match the generated API.\n * This prevents arg-order regressions by using Parameters<> to extract expected types.\n *\n * Usage: wrapApi(api.postV1ExerciseTemplates)(data, headers, { client })\n * TypeScript will error if arguments don't match the generated signature.\n */\nfunction wrapApi<T extends (...args: Parameters<T>) => ReturnType<T>>(\n\tfn: T,\n): (...args: Parameters<T>) => ReturnType<T> {\n\treturn fn;\n}\n\nexport const DEFAULT_API_TIMEOUT_MS = 30_000;\nexport const MAX_GET_RETRIES = 3;\nexport const RETRY_BACKOFF_BASE_MS = 300;\nconst RETRY_BACKOFF_MAX_MS = 5_000;\n\nexport const HEVY_RETRY_EXHAUSTED_ERROR_CODE = \"HEVY_RETRY_EXHAUSTED\";\n\nexport interface HevyClientOptions {\n\tlogger?: McpClientLogger;\n\tmaxGetRetries?: number;\n\ttimeoutMs?: number;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504]);\n\nconst RETRYABLE_NETWORK_ERROR_CODES = new Set([\n\t\"ECONNABORTED\",\n\t\"ECONNREFUSED\",\n\t\"ECONNRESET\",\n\t\"EAI_AGAIN\",\n\t\"ENETUNREACH\",\n\t\"ENOTFOUND\",\n\t\"ERR_NETWORK\",\n\t\"ERR_SOCKET_TIMEOUT\",\n\t\"ETIMEDOUT\",\n]);\n\nconst SAFE_STATIC_ENDPOINTS = new Set([\n\t\"/v1/body_measurements\",\n\t\"/v1/exercise_templates\",\n\t\"/v1/routine_folders\",\n\t\"/v1/routines\",\n\t\"/v1/user/info\",\n\t\"/v1/workouts\",\n\t\"/v1/workouts/count\",\n\t\"/v1/workouts/events\",\n]);\n\nconst SAFE_DYNAMIC_ENDPOINTS = [\n\t[\"/v1/body_measurements/\", \"/v1/body_measurements/:date\"],\n\t[\"/v1/exercise_history/\", \"/v1/exercise_history/:exerciseTemplateId\"],\n\t[\"/v1/exercise_templates/\", \"/v1/exercise_templates/:exerciseTemplateId\"],\n\t[\"/v1/routine_folders/\", \"/v1/routine_folders/:folderId\"],\n\t[\"/v1/routines/\", \"/v1/routines/:routineId\"],\n\t[\"/v1/workouts/\", \"/v1/workouts/:workoutId\"],\n] as const;\n\ntype RetryAwareAxiosError = AxiosError & {\n\thevyRetryCount?: number;\n\thevyRetryExhausted?: boolean;\n\thevyRetryStatus?: number;\n\thevyRetryOriginalCode?: string;\n};\n\nfunction getApiTimeoutMs(): number {\n\tconst rawValue = process.env.HEVY_MCP_API_TIMEOUT;\n\tif (!rawValue) {\n\t\treturn DEFAULT_API_TIMEOUT_MS;\n\t}\n\n\tconst parsed = Number(rawValue);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\treturn DEFAULT_API_TIMEOUT_MS;\n\t}\n\n\treturn Math.trunc(parsed);\n}\n\nfunction normalizeMaxGetRetries(value: number | undefined): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 0) {\n\t\treturn MAX_GET_RETRIES;\n\t}\n\n\treturn Math.floor(value);\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n\tif (value === undefined || !Number.isFinite(value) || value <= 0) {\n\t\treturn getApiTimeoutMs();\n\t}\n\n\tconst normalizedValue = Math.floor(value);\n\treturn normalizedValue > 0 ? normalizedValue : getApiTimeoutMs();\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nfunction isGetRequest(config: RequestConfig<unknown>): boolean {\n\treturn config.method?.toUpperCase() === \"GET\";\n}\n\nfunction isRetryableStatus(status: number | undefined): boolean {\n\tif (status === undefined) {\n\t\treturn false;\n\t}\n\n\treturn RETRYABLE_STATUS_CODES.has(status);\n}\n\nfunction isTransientNetworkError(error: AxiosError): boolean {\n\tif (error.code === \"ERR_CANCELED\") {\n\t\treturn false;\n\t}\n\n\tif (error.code && RETRYABLE_NETWORK_ERROR_CODES.has(error.code)) {\n\t\treturn true;\n\t}\n\n\tif (error.response) {\n\t\treturn false;\n\t}\n\n\tconst message = error.message.toLowerCase();\n\treturn (\n\t\tmessage.includes(\"network\") ||\n\t\tmessage.includes(\"socket hang up\") ||\n\t\tmessage.includes(\"timeout\")\n\t);\n}\n\nfunction normalizeHeaderValue(value: unknown): string | undefined {\n\tif (typeof value === \"string\") {\n\t\tconst trimmed = value.trim();\n\t\treturn trimmed.length > 0 ? trimmed : undefined;\n\t}\n\n\tif (typeof value === \"number\" && Number.isFinite(value)) {\n\t\treturn String(value);\n\t}\n\n\tif (Array.isArray(value) && value.length > 0) {\n\t\treturn normalizeHeaderValue(value[0]);\n\t}\n\n\treturn undefined;\n}\n\nfunction getHeaderValue(headers: unknown, key: string): string | undefined {\n\tif (!headers || typeof headers !== \"object\") {\n\t\treturn undefined;\n\t}\n\n\tif (\n\t\t\"get\" in headers &&\n\t\ttypeof (headers as { get?: unknown }).get === \"function\"\n\t) {\n\t\tconst value = (\n\t\t\theaders as {\n\t\t\t\tget: (headerName: string) => unknown;\n\t\t\t}\n\t\t).get(key);\n\t\treturn normalizeHeaderValue(value);\n\t}\n\n\tconst headerRecord = headers as Record<string, unknown>;\n\treturn normalizeHeaderValue(\n\t\theaderRecord[key] ??\n\t\t\theaderRecord[key.toLowerCase()] ??\n\t\t\theaderRecord[key.toUpperCase()],\n\t);\n}\n\nfunction parseRetryAfterMs(value: string): number | undefined {\n\tconst numericSeconds = Number(value);\n\tif (Number.isFinite(numericSeconds) && numericSeconds >= 0) {\n\t\treturn Math.min(RETRY_BACKOFF_MAX_MS, Math.round(numericSeconds * 1000));\n\t}\n\n\tconst dateMillis = Date.parse(value);\n\tif (Number.isNaN(dateMillis)) {\n\t\treturn undefined;\n\t}\n\n\treturn Math.min(RETRY_BACKOFF_MAX_MS, Math.max(0, dateMillis - Date.now()));\n}\n\nfunction getRetryAfterDelayMs(error: AxiosError): number | undefined {\n\tif (error.response?.status !== 429) {\n\t\treturn undefined;\n\t}\n\n\tconst retryAfterHeader = getHeaderValue(\n\t\terror.response.headers,\n\t\t\"retry-after\",\n\t);\n\tif (!retryAfterHeader) {\n\t\treturn undefined;\n\t}\n\n\treturn parseRetryAfterMs(retryAfterHeader);\n}\n\nfunction getExponentialBackoffMs(retryAttempt: number): number {\n\tconst exponent = Math.max(0, retryAttempt - 1);\n\tconst delay = RETRY_BACKOFF_BASE_MS * 2 ** exponent;\n\treturn Math.min(RETRY_BACKOFF_MAX_MS, delay);\n}\n\nfunction getRetryDelayMs(error: AxiosError, retryAttempt: number): number {\n\tconst exponentialDelay = getExponentialBackoffMs(retryAttempt);\n\tconst retryAfterDelay = getRetryAfterDelayMs(error);\n\n\tif (retryAfterDelay === undefined) {\n\t\treturn exponentialDelay;\n\t}\n\n\treturn Math.min(\n\t\tRETRY_BACKOFF_MAX_MS,\n\t\tMath.max(exponentialDelay, retryAfterDelay),\n\t);\n}\n\nfunction shouldRetryRequest(\n\tconfig: RequestConfig<unknown>,\n\terror: AxiosError,\n): boolean {\n\tif (!isGetRequest(config)) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tisRetryableStatus(error.response?.status) || isTransientNetworkError(error)\n\t);\n}\n\nfunction getRequestContext(config: { method?: string; url?: string }) {\n\tconst method = (config.method ?? \"GET\").toUpperCase();\n\tconst url = config.url ?? \"\";\n\tconst rawEndpoint = url.split(\"?\")[0] ?? url;\n\n\tlet endpoint = \"unknown\";\n\tif (SAFE_STATIC_ENDPOINTS.has(rawEndpoint)) {\n\t\tendpoint = rawEndpoint;\n\t} else {\n\t\tendpoint =\n\t\t\tSAFE_DYNAMIC_ENDPOINTS.find(([prefix]) =>\n\t\t\t\trawEndpoint.startsWith(prefix),\n\t\t\t)?.[1] ?? \"unknown\";\n\t}\n\treturn { method, endpoint };\n}\n\nfunction emitClientLog(\n\tlogger: McpClientLogger | undefined,\n\tmessage: McpClientLogMessage,\n): void {\n\ttry {\n\t\tlogger?.(message);\n\t} catch (error) {\n\t\tconsole.error(\"Failed to emit structured Hevy API log\", error);\n\t}\n}\n\nfunction markRetryExhausted(error: AxiosError, retryCount: number): void {\n\tconst retryError = error as RetryAwareAxiosError;\n\tretryError.hevyRetryExhausted = true;\n\tretryError.hevyRetryCount = retryCount;\n\tretryError.hevyRetryStatus = error.response?.status;\n\n\tif (retryError.code) {\n\t\tretryError.hevyRetryOriginalCode = retryError.code;\n\t}\n\n\tretryError.code = HEVY_RETRY_EXHAUSTED_ERROR_CODE;\n}\n\nasync function requestWithRetries<TData, TVariables>(\n\taxiosInstance: AxiosInstance,\n\tconfig: RequestConfig<TVariables>,\n\tmaxGetRetries: number,\n\tlogger?: McpClientLogger,\n): Promise<ResponseConfig<TData>> {\n\tlet retryCount = 0;\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn await axiosInstance.request<\n\t\t\t\tTData,\n\t\t\t\tResponseConfig<TData>,\n\t\t\t\tTVariables\n\t\t\t>(config as AxiosRequestConfig<TVariables>);\n\t\t} catch (error) {\n\t\t\tif (!isAxiosError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst normalizedConfig = config as RequestConfig<unknown>;\n\t\t\tconst { method, endpoint } = getRequestContext(normalizedConfig);\n\t\t\tconst status = error.response?.status ?? null;\n\t\t\tif (!shouldRetryRequest(normalizedConfig, error)) {\n\t\t\t\temitClientLog(logger, {\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tlogger: \"hevy-api\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmessage: \"Hevy API request failed without retry\",\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tendpoint,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (retryCount >= maxGetRetries) {\n\t\t\t\temitClientLog(logger, {\n\t\t\t\t\tlevel: status === 429 ? \"warning\" : \"error\",\n\t\t\t\t\tlogger: \"hevy-api\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tmessage: \"Hevy API request failed after retries\",\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\tattempt: retryCount + 1,\n\t\t\t\t\t\tmaxAttempts: maxGetRetries + 1,\n\t\t\t\t\t\tmethod,\n\t\t\t\t\t\tendpoint,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tmarkRetryExhausted(error, retryCount);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tretryCount += 1;\n\t\t\tconst retryDelayMs = getRetryDelayMs(error, retryCount);\n\t\t\tconst retryAfterMs = getRetryAfterDelayMs(error);\n\t\t\temitClientLog(logger, {\n\t\t\t\tlevel: status === 429 ? \"warning\" : \"debug\",\n\t\t\t\tlogger: \"hevy-api\",\n\t\t\t\tdata: {\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tstatus === 429\n\t\t\t\t\t\t\t? \"Hevy API rate limit; retrying request\"\n\t\t\t\t\t\t\t: \"Retrying Hevy API request\",\n\t\t\t\t\tstatus,\n\t\t\t\t\tattempt: retryCount + 1,\n\t\t\t\t\tmaxAttempts: maxGetRetries + 1,\n\t\t\t\t\tdelayMs: retryDelayMs,\n\t\t\t\t\t...(status === 429 ? { retryAfterMs: retryAfterMs ?? null } : {}),\n\t\t\t\t\tmethod,\n\t\t\t\t\tendpoint,\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait sleep(retryDelayMs);\n\t\t}\n\t}\n}\n\nfunction createResilientClient(\n\taxiosInstance: AxiosInstance,\n\tmaxGetRetries: number,\n\tlogger?: McpClientLogger,\n): KubbClient {\n\tlet clientConfig: Partial<RequestConfig<unknown>> = {\n\t\tbaseURL: axiosInstance.defaults.baseURL,\n\t};\n\n\tconst resilientClient = (async <\n\t\tTData,\n\t\t_TError = unknown,\n\t\tTVariables = unknown,\n\t>(\n\t\tconfig: RequestConfig<TVariables>,\n\t): Promise<ResponseConfig<TData>> => {\n\t\treturn requestWithRetries<TData, TVariables>(\n\t\t\taxiosInstance,\n\t\t\tconfig,\n\t\t\tmaxGetRetries,\n\t\t\tlogger,\n\t\t);\n\t}) as KubbClient;\n\n\tresilientClient.getConfig = () => ({\n\t\t...clientConfig,\n\t});\n\n\tresilientClient.setConfig = (config: RequestConfig) => {\n\t\tclientConfig = {\n\t\t\t...clientConfig,\n\t\t\t...config,\n\t\t};\n\n\t\tif (config.baseURL !== undefined) {\n\t\t\taxiosInstance.defaults.baseURL = config.baseURL;\n\t\t}\n\n\t\treturn resilientClient.getConfig();\n\t};\n\n\treturn resilientClient;\n}\n\n// --- Interceptor helpers ---\n\ntype TracedConfig = InternalAxiosRequestConfig & {\n\t_span?: Span;\n\t_startTime?: number;\n};\n\n/**\n * Extract common request metadata from an Axios config.\n * Shared between the success and error response interceptors to avoid\n * duplicating the method/url/endpoint/duration extraction logic.\n */\nfunction extractRequestMeta(config: {\n\tmethod?: string;\n\turl?: string;\n\t_startTime?: number;\n}) {\n\tconst method = (config.method ?? \"get\").toUpperCase();\n\tconst url = config.url ?? \"\";\n\tconst endpoint = url.split(\"?\")[0] ?? url;\n\tconst now = Date.now();\n\tconst durationMs = now - (config._startTime ?? now);\n\treturn { method, url, endpoint, durationMs };\n}\n\n/**\n * Finalize a traced span and record metrics for a completed HTTP request.\n */\nfunction finalizeRequestTrace(opts: {\n\tspan: Span | undefined;\n\tstatusCode: number;\n\tdurationMs: number;\n\tmethod: string;\n\tendpoint: string;\n\terror?: unknown;\n}) {\n\tconst { span, statusCode, durationMs, method, endpoint, error } = opts;\n\n\tif (span) {\n\t\tspan.setAttribute(\"http.status_code\", statusCode);\n\t\tspan.setAttribute(\"http.response.duration_ms\", durationMs);\n\t\tif (error) {\n\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\tspan.recordException(error as Error);\n\t\t} else {\n\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t}\n\t\tspan.end();\n\t}\n\n\tapiCalls.add(1, { method, endpoint, status_code: statusCode });\n\tapiDuration.record(durationMs, { method, endpoint });\n}\n\nexport function createClient(\n\tapiKey: string,\n\tbaseUrl = \"https://api.hevyapp.com\",\n\toptions: HevyClientOptions = {},\n) {\n\tconst { logger } = options;\n\tconst maxGetRetries = normalizeMaxGetRetries(options.maxGetRetries);\n\tconst timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n\t// Create an axios instance with the API key\n\tconst axiosInstance = axios.create({\n\t\tbaseURL: baseUrl,\n\t\ttimeout: timeoutMs,\n\t\theaders: {\n\t\t\t\"api-key\": apiKey,\n\t\t},\n\t});\n\n\t// --- Axios interceptors for HTTP tracing and metrics ---\n\taxiosInstance.interceptors.request.use((config) => {\n\t\tconst tracedConfig = config as TracedConfig;\n\t\tconst method = (config.method ?? \"get\").toUpperCase();\n\t\tconst url = config.url ?? \"\";\n\t\t// Extract clean endpoint path without query params for high-cardinality safety\n\t\tconst endpoint = url.split(\"?\")[0] ?? url;\n\t\tconst userId = getCurrentUserId();\n\t\ttracedConfig._span = tracer.startSpan(`hevy.api.${method}`, {\n\t\t\tattributes: {\n\t\t\t\t\"http.method\": method,\n\t\t\t\t\"http.url\": url,\n\t\t\t\t\"http.base_url\": config.baseURL ?? \"\",\n\t\t\t\t\"hevy.api.endpoint\": endpoint,\n\t\t\t\t...(userId ? { \"user.id\": userId } : {}),\n\t\t\t},\n\t\t});\n\t\ttracedConfig._startTime = Date.now();\n\t\treturn config;\n\t});\n\n\taxiosInstance.interceptors.response.use(\n\t\t(response) => {\n\t\t\tconst tracedConfig = response.config as TracedConfig;\n\t\t\tconst { method, endpoint, durationMs } = extractRequestMeta({\n\t\t\t\tmethod: response.config.method,\n\t\t\t\turl: response.config.url,\n\t\t\t\t_startTime: tracedConfig._startTime,\n\t\t\t});\n\t\t\tconst requestContext = getRequestContext(response.config);\n\t\t\tdebugLog(\"api_response\", {\n\t\t\t\tmethod: requestContext.method,\n\t\t\t\tendpoint: requestContext.endpoint,\n\t\t\t\tdurationMs,\n\t\t\t\tstatus: response.status,\n\t\t\t});\n\n\t\t\tfinalizeRequestTrace({\n\t\t\t\tspan: tracedConfig._span,\n\t\t\t\tstatusCode: response.status,\n\t\t\t\tdurationMs,\n\t\t\t\tmethod,\n\t\t\t\tendpoint,\n\t\t\t});\n\n\t\t\treturn response;\n\t\t},\n\t\t(error) => {\n\t\t\tconst tracedConfig = (error.config ?? {}) as TracedConfig;\n\t\t\tconst { method, endpoint, durationMs } = extractRequestMeta({\n\t\t\t\tmethod: error.config?.method,\n\t\t\t\turl: error.config?.url,\n\t\t\t\t_startTime: tracedConfig._startTime,\n\t\t\t});\n\t\t\tconst requestContext = getRequestContext(error.config ?? {});\n\t\t\tdebugLog(\"api_response\", {\n\t\t\t\tmethod: requestContext.method,\n\t\t\t\tendpoint: requestContext.endpoint,\n\t\t\t\tdurationMs,\n\t\t\t\tstatus: error.response?.status ?? null,\n\t\t\t});\n\n\t\t\tfinalizeRequestTrace({\n\t\t\t\tspan: tracedConfig._span,\n\t\t\t\tstatusCode: error.response?.status ?? 0,\n\t\t\t\tdurationMs,\n\t\t\t\tmethod,\n\t\t\t\tendpoint,\n\t\t\t\terror,\n\t\t\t});\n\n\t\t\tthrow error;\n\t\t},\n\t);\n\n\t// Create headers object with API key\n\tconst headers = {\n\t\t\"api-key\": apiKey,\n\t};\n\n\tconst client = createResilientClient(axiosInstance, maxGetRetries, logger);\n\n\t// Return an object with all the API methods using ReturnType for automatic type inference\n\t// All API calls use wrapApi to ensure TypeScript validates arg order matches generated API\n\treturn {\n\t\t// Workouts\n\t\tgetWorkouts: (\n\t\t\tparams?: GetV1WorkoutsQueryParams,\n\t\t): ReturnType<typeof api.getV1Workouts> =>\n\t\t\twrapApi(api.getV1Workouts)(headers, params, { client }),\n\t\tgetWorkout: (\n\t\t\tworkoutId: string,\n\t\t): ReturnType<typeof api.getV1WorkoutsWorkoutid> =>\n\t\t\twrapApi(api.getV1WorkoutsWorkoutid)(workoutId, headers, { client }),\n\t\tcreateWorkout: (\n\t\t\tdata: PostV1WorkoutsMutationRequest,\n\t\t): ReturnType<typeof api.postV1Workouts> =>\n\t\t\twrapApi(api.postV1Workouts)(data, headers, { client }),\n\t\tupdateWorkout: (\n\t\t\tworkoutId: string,\n\t\t\tdata: PutV1WorkoutsWorkoutidMutationRequest,\n\t\t): ReturnType<typeof api.putV1WorkoutsWorkoutid> =>\n\t\t\twrapApi(api.putV1WorkoutsWorkoutid)(workoutId, data, headers, {\n\t\t\t\tclient,\n\t\t\t}),\n\t\tgetWorkoutCount: (): ReturnType<typeof api.getV1WorkoutsCount> =>\n\t\t\twrapApi(api.getV1WorkoutsCount)(headers, { client }),\n\t\tgetWorkoutEvents: (\n\t\t\tparams?: GetV1WorkoutsEventsQueryParams,\n\t\t): ReturnType<typeof api.getV1WorkoutsEvents> =>\n\t\t\twrapApi(api.getV1WorkoutsEvents)(headers, params, { client }),\n\n\t\t// Routines\n\t\tgetRoutines: (\n\t\t\tparams?: GetV1RoutinesQueryParams,\n\t\t): ReturnType<typeof api.getV1Routines> =>\n\t\t\twrapApi(api.getV1Routines)(headers, params, { client }),\n\t\tgetRoutineById: (\n\t\t\troutineId: string,\n\t\t): ReturnType<typeof api.getV1RoutinesRoutineid> =>\n\t\t\twrapApi(api.getV1RoutinesRoutineid)(routineId, headers, { client }),\n\t\tcreateRoutine: (\n\t\t\tdata: PostV1RoutinesMutationRequest,\n\t\t): ReturnType<typeof api.postV1Routines> =>\n\t\t\twrapApi(api.postV1Routines)(data, headers, { client }),\n\t\tupdateRoutine: (\n\t\t\troutineId: string,\n\t\t\tdata: PutV1RoutinesRoutineidMutationRequest,\n\t\t): ReturnType<typeof api.putV1RoutinesRoutineid> =>\n\t\t\twrapApi(api.putV1RoutinesRoutineid)(routineId, data, headers, {\n\t\t\t\tclient,\n\t\t\t}),\n\n\t\t// Exercise Templates\n\t\tgetExerciseTemplates: (\n\t\t\tparams?: GetV1ExerciseTemplatesQueryParams,\n\t\t): ReturnType<typeof api.getV1ExerciseTemplates> =>\n\t\t\twrapApi(api.getV1ExerciseTemplates)(headers, params, { client }),\n\t\tgetExerciseTemplate: (\n\t\t\ttemplateId: string,\n\t\t): ReturnType<typeof api.getV1ExerciseTemplatesExercisetemplateid> =>\n\t\t\twrapApi(api.getV1ExerciseTemplatesExercisetemplateid)(\n\t\t\t\ttemplateId,\n\t\t\t\theaders,\n\t\t\t\t{\n\t\t\t\t\tclient,\n\t\t\t\t},\n\t\t\t),\n\t\tgetExerciseHistory: (\n\t\t\texerciseTemplateId: string,\n\t\t\tparams?: GetV1ExerciseHistoryExercisetemplateidQueryParams,\n\t\t): ReturnType<typeof api.getV1ExerciseHistoryExercisetemplateid> =>\n\t\t\twrapApi(api.getV1ExerciseHistoryExercisetemplateid)(\n\t\t\t\texerciseTemplateId,\n\t\t\t\theaders,\n\t\t\t\tparams,\n\t\t\t\t{ client },\n\t\t\t),\n\t\tcreateExerciseTemplate: (\n\t\t\tdata: PostV1ExerciseTemplatesMutationRequest,\n\t\t): ReturnType<typeof api.postV1ExerciseTemplates> =>\n\t\t\twrapApi(api.postV1ExerciseTemplates)(data, headers, { client }),\n\n\t\t// Routine Folders\n\t\tgetRoutineFolders: (\n\t\t\tparams?: GetV1RoutineFoldersQueryParams,\n\t\t): ReturnType<typeof api.getV1RoutineFolders> =>\n\t\t\twrapApi(api.getV1RoutineFolders)(headers, params, { client }),\n\t\tcreateRoutineFolder: (\n\t\t\tdata: PostV1RoutineFoldersMutationRequest,\n\t\t): ReturnType<typeof api.postV1RoutineFolders> =>\n\t\t\twrapApi(api.postV1RoutineFolders)(data, headers, { client }),\n\t\tgetRoutineFolder: (\n\t\t\tfolderId: string,\n\t\t): ReturnType<typeof api.getV1RoutineFoldersFolderid> =>\n\t\t\twrapApi(api.getV1RoutineFoldersFolderid)(folderId, headers, {\n\t\t\t\tclient,\n\t\t\t}),\n\n\t\t// Body Measurements\n\t\tgetBodyMeasurements: (\n\t\t\tparams?: GetV1BodyMeasurementsQueryParams,\n\t\t): ReturnType<typeof api.getV1BodyMeasurements> =>\n\t\t\twrapApi(api.getV1BodyMeasurements)(headers, params, { client }),\n\t\tgetBodyMeasurement: (\n\t\t\tdate: string,\n\t\t): ReturnType<typeof api.getV1BodyMeasurementsDate> =>\n\t\t\twrapApi(api.getV1BodyMeasurementsDate)(date, headers, { client }),\n\t\tcreateBodyMeasurement: (\n\t\t\tdata: PostV1BodyMeasurementsMutationRequest,\n\t\t): ReturnType<typeof api.postV1BodyMeasurements> =>\n\t\t\twrapApi(api.postV1BodyMeasurements)(data, headers, { client }),\n\t\tupdateBodyMeasurement: (\n\t\t\tdate: string,\n\t\t\tdata: PutV1BodyMeasurementsDateMutationRequest,\n\t\t): ReturnType<typeof api.putV1BodyMeasurementsDate> =>\n\t\t\twrapApi(api.putV1BodyMeasurementsDate)(date, data, headers, {\n\t\t\t\tclient,\n\t\t\t}),\n\n\t\t// User\n\t\tgetUserInfo: (): ReturnType<typeof api.getV1UserInfo> =>\n\t\t\twrapApi(api.getV1UserInfo)(headers, { client }),\n\t};\n}\n\n/**\n * Type representing the Hevy API client returned by createClient.\n * Useful for typing variables that hold the client instance.\n */\nexport type HevyApiClient = ReturnType<typeof createClient>;\n","// Import the Kubb-based client\nimport { createClient as createKubbClient } from \"./hevyClientKubb.js\";\nimport type { HevyClientOptions } from \"./hevyClientKubb.js\";\n\nexport function createClient(\n\tapiKey: string,\n\tbaseUrl: string,\n\toptions: HevyClientOptions = {},\n) {\n\treturn createKubbClient(apiKey, baseUrl, options);\n}\n\n// Export the HevyClient type for use in other modules\nexport type HevyClient = ReturnType<typeof createClient>;\n","import type { LoggingMessageNotification } from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type McpClientLogMessage = LoggingMessageNotification[\"params\"];\nexport type McpClientLogger = (message: McpClientLogMessage) => void;\n\ninterface LoggingServer {\n\tisConnected(): boolean;\n\tsendLoggingMessage(message: McpClientLogMessage): Promise<void>;\n}\n\nconst SEND_FAILURE_MESSAGE =\n\t\"Failed to send structured log message to MCP client\";\nconst DISCONNECTED_MESSAGE =\n\t\"Skipped structured MCP client log because the server is not connected\";\n\n/**\n * Create a best-effort, fire-and-forget logger for an MCP server connection.\n * Logging failures are reported to stderr and never escape into tool behavior.\n */\nexport function createMcpClientLogger(server: LoggingServer): McpClientLogger {\n\treturn (message) => {\n\t\ttry {\n\t\t\tif (!server.isConnected()) {\n\t\t\t\tconsole.error(DISCONNECTED_MESSAGE);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvoid server.sendLoggingMessage(message).catch((error: unknown) => {\n\t\t\t\tconsole.error(SEND_FAILURE_MESSAGE, error);\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(SEND_FAILURE_MESSAGE, error);\n\t\t}\n\t};\n}\n","import { SpanStatusCode } from \"@opentelemetry/api\";\nimport type { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { deserializeMessage } from \"@modelcontextprotocol/sdk/shared/stdio.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport { Sentry, tracer } from \"./telemetry.js\";\nimport { stdioParseErrors } from \"./metrics.js\";\n\nconst UTF8_BOM = \"\\uFEFF\";\n/** Maximum escaped characters included in a malformed stdin shape preview. */\nconst STDIN_PARSE_SHAPE_PREVIEW_MAX_LENGTH = 200;\nconst REDACTED_CONTENT_MARKER = \"[REDACTED]\";\n\nexport interface StdioChunkSnapshot {\n\tlastChunkByteLength: number;\n\tlastChunkStartsWithUtf8Bom: boolean;\n}\n\ninterface MutableReadBuffer {\n\t_buffer?: Buffer;\n\treadMessage: () => JSONRPCMessage | null;\n}\n\ntype MutableStdioServerTransport = {\n\t_readBuffer?: MutableReadBuffer;\n\t_ondata?: (chunk: Buffer) => void;\n};\n\ninterface SdkPrivateStdioAdapter {\n\twrapOnData: (onChunk: (chunk: Buffer) => void) => void;\n\tinstallReadMessageHook: (\n\t\tonReadLine: (line: string) => JSONRPCMessage,\n\t) => boolean;\n}\n\n/**\n * Adapter boundary around MCP SDK stdio internals.\n *\n * MCP SDK v1.29.0 exposes public message-level hooks but does not expose a\n * public raw-chunk hook on `StdioServerTransport`. To capture chunk metadata,\n * we currently rely on private internals (`_ondata`, `_readBuffer`, `_buffer`)\n * in this one place.\n *\n * If those internals change in a future SDK release, this adapter should fail\n * closed and preserve default transport behavior (no instrumentation patching).\n */\nfunction createSdkPrivateStdioAdapter(\n\ttransport: StdioServerTransport,\n): SdkPrivateStdioAdapter {\n\tconst mutableTransport = transport as unknown as MutableStdioServerTransport;\n\n\treturn {\n\t\twrapOnData(onChunk) {\n\t\t\tconst originalOnData = mutableTransport._ondata;\n\t\t\tif (typeof originalOnData !== \"function\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmutableTransport._ondata = (chunk: Buffer) => {\n\t\t\t\tonChunk(chunk);\n\t\t\t\toriginalOnData(chunk);\n\t\t\t};\n\t\t},\n\t\tinstallReadMessageHook(onReadLine) {\n\t\t\tconst readBuffer = mutableTransport._readBuffer;\n\t\t\tif (!readBuffer || typeof readBuffer.readMessage !== \"function\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treadBuffer.readMessage = () => {\n\t\t\t\tconst buffer = readBuffer._buffer;\n\t\t\t\tif (!buffer) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst index = buffer.indexOf(\"\\n\");\n\t\t\t\tif (index === -1) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst lineBuffer = buffer.subarray(0, index);\n\t\t\t\treadBuffer._buffer = buffer.subarray(index + 1);\n\t\t\t\tconst line = lineBuffer.toString(\"utf8\").replace(/\\r$/, \"\");\n\t\t\t\treturn onReadLine(line);\n\t\t\t};\n\n\t\t\treturn true;\n\t\t},\n\t};\n}\n\nfunction hasUtf8BomPrefix(chunk: Buffer): boolean {\n\treturn (\n\t\tchunk.length >= 3 &&\n\t\tchunk[0] === 0xef &&\n\t\tchunk[1] === 0xbb &&\n\t\tchunk[2] === 0xbf\n\t);\n}\n\nfunction parseFailurePosition(error: unknown): number | null {\n\tif (!(error instanceof Error)) {\n\t\treturn null;\n\t}\n\n\tconst match = error.message.match(/position\\s+(\\d+)/i);\n\tif (!match || !match[1]) {\n\t\treturn null;\n\t}\n\n\tconst position = Number.parseInt(match[1], 10);\n\treturn Number.isFinite(position) ? position : null;\n}\n\nfunction getFailureLocation(\n\tfailurePosition: number | null,\n\tlineHadLeadingBom: boolean,\n): string {\n\tif (lineHadLeadingBom) {\n\t\treturn \"line_start_bom\";\n\t}\n\tif (failurePosition === 0) {\n\t\treturn \"line_start\";\n\t}\n\tif (failurePosition !== null) {\n\t\treturn \"line_body\";\n\t}\n\treturn \"unknown\";\n}\n\nfunction createStructuralShapePreview(line: string): {\n\tshapePreview: string;\n\ttruncated: boolean;\n} {\n\tlet shapePreview = \"\";\n\tlet inContentRun = false;\n\tlet inWhitespaceRun = false;\n\n\tconst append = (token: string): boolean => {\n\t\tif (\n\t\t\tshapePreview.length + token.length >\n\t\t\tSTDIN_PARSE_SHAPE_PREVIEW_MAX_LENGTH\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tshapePreview += token;\n\t\treturn true;\n\t};\n\n\tfor (const character of line) {\n\t\tif ('{}[]:,\"'.includes(character)) {\n\t\t\tinContentRun = false;\n\t\t\tinWhitespaceRun = false;\n\t\t\tif (!append(character === '\"' ? \"\\\\u0022\" : character)) {\n\t\t\t\treturn { shapePreview, truncated: true };\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/\\s/u.test(character)) {\n\t\t\tinContentRun = false;\n\t\t\tif (!inWhitespaceRun) {\n\t\t\t\tif (!append(\"\\\\s\")) {\n\t\t\t\t\treturn { shapePreview, truncated: true };\n\t\t\t\t}\n\t\t\t\tinWhitespaceRun = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tinWhitespaceRun = false;\n\t\tif (!inContentRun) {\n\t\t\tif (!append(REDACTED_CONTENT_MARKER)) {\n\t\t\t\treturn { shapePreview, truncated: true };\n\t\t\t}\n\t\t\tinContentRun = true;\n\t\t}\n\t}\n\n\treturn {\n\t\tshapePreview,\n\t\ttruncated: false,\n\t};\n}\n\nfunction getSafeErrorKind(\n\terror: unknown,\n): \"SyntaxError\" | \"Error\" | \"UnknownError\" {\n\tif (error instanceof SyntaxError) {\n\t\treturn \"SyntaxError\";\n\t}\n\tif (error instanceof Error) {\n\t\treturn \"Error\";\n\t}\n\treturn \"UnknownError\";\n}\n\nfunction reportStdinParseFailure(\n\terror: unknown,\n\tline: string,\n\tlineByteLength: number,\n\tfailureLocation: string,\n\tfailurePosition: number | null,\n): void {\n\ttry {\n\t\tconst errorKind = getSafeErrorKind(error);\n\t\tconst { shapePreview, truncated } = createStructuralShapePreview(line);\n\t\tconst position = failurePosition === null ? \"unknown\" : failurePosition;\n\n\t\tconsole.error(\n\t\t\t`Failed to parse MCP stdin message: error_kind=${errorKind} line_bytes=${lineByteLength} failure_location=${failureLocation} failure_position=${position} shape_preview=\"${shapePreview}\" shape_preview_redacted=true shape_preview_truncated=${truncated}`,\n\t\t);\n\t} catch {\n\t\t// Diagnostics are best-effort and must not replace the parser error.\n\t}\n}\n\nexport function deserializeMessageWithObservability(\n\tline: string,\n\tchunkSnapshot: StdioChunkSnapshot,\n): JSONRPCMessage {\n\tconst lineHadLeadingBom = line.startsWith(UTF8_BOM);\n\tconst normalizedLine = lineHadLeadingBom ? line.slice(1) : line;\n\tconst lineByteLength = Buffer.byteLength(line);\n\n\treturn tracer.startActiveSpan(\n\t\t\"mcp.stdio.deserialize\",\n\t\t{\n\t\t\tattributes: {\n\t\t\t\t\"mcp.transport\": \"stdio\",\n\t\t\t\t\"mcp.stdio.parse.line.char_length\": line.length,\n\t\t\t\t\"mcp.stdio.parse.line.byte_length\": lineByteLength,\n\t\t\t\t\"mcp.stdio.parse.line.had_leading_bom\": lineHadLeadingBom,\n\t\t\t\t\"mcp.stdio.parse.line.bom_stripped\": lineHadLeadingBom,\n\t\t\t\t\"mcp.stdio.parse.chunk.last_byte_length\":\n\t\t\t\t\tchunkSnapshot.lastChunkByteLength,\n\t\t\t\t\"mcp.stdio.parse.chunk.last_had_utf8_bom\":\n\t\t\t\t\tchunkSnapshot.lastChunkStartsWithUtf8Bom,\n\t\t\t},\n\t\t},\n\t\t(span) => {\n\t\t\ttry {\n\t\t\t\tconst message = deserializeMessage(normalizedLine);\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\tif (message && typeof message === \"object\" && \"method\" in message) {\n\t\t\t\t\tspan.setAttribute(\n\t\t\t\t\t\t\"mcp.method\",\n\t\t\t\t\t\tString((message as { method: unknown }).method),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn message;\n\t\t\t} catch (error) {\n\t\t\t\tconst failurePosition = parseFailurePosition(error);\n\t\t\t\tconst failureLocation = getFailureLocation(\n\t\t\t\t\tfailurePosition,\n\t\t\t\t\tlineHadLeadingBom,\n\t\t\t\t);\n\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\tspan.recordException(error as Error);\n\t\t\t\tspan.setAttribute(\"mcp.stdio.parse.failure.location\", failureLocation);\n\t\t\t\tif (failurePosition !== null) {\n\t\t\t\t\tspan.setAttribute(\n\t\t\t\t\t\t\"mcp.stdio.parse.failure.position\",\n\t\t\t\t\t\tfailurePosition,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tstdioParseErrors.add(1, { failure_location: failureLocation });\n\n\t\t\t\tSentry.withScope((scope) => {\n\t\t\t\t\tscope.setTag(\"mcp.transport\", \"stdio\");\n\t\t\t\t\tscope.setTag(\"mcp.stdio.parse.failure.location\", failureLocation);\n\t\t\t\t\tscope.setContext(\"mcpStdioParse\", {\n\t\t\t\t\t\tlineCharLength: line.length,\n\t\t\t\t\t\tlineByteLength,\n\t\t\t\t\t\tlineHadLeadingBom,\n\t\t\t\t\t\tbomStripped: lineHadLeadingBom,\n\t\t\t\t\t\tlastChunkByteLength: chunkSnapshot.lastChunkByteLength,\n\t\t\t\t\t\tlastChunkStartsWithUtf8Bom:\n\t\t\t\t\t\t\tchunkSnapshot.lastChunkStartsWithUtf8Bom,\n\t\t\t\t\t\tfailureLocation,\n\t\t\t\t\t\tfailurePosition,\n\t\t\t\t\t\tfailureStage: \"deserializeMessage\",\n\t\t\t\t\t\terrorName: error instanceof Error ? error.name : \"UnknownError\",\n\t\t\t\t\t});\n\t\t\t\t\tSentry.captureException(error);\n\t\t\t\t});\n\n\t\t\t\treportStdinParseFailure(\n\t\t\t\t\terror,\n\t\t\t\t\tline,\n\t\t\t\t\tlineByteLength,\n\t\t\t\t\tfailureLocation,\n\t\t\t\t\tfailurePosition,\n\t\t\t\t);\n\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n\nexport function createInstrumentedStdioTransport<\n\tT extends StdioServerTransport,\n>(transport: T): T {\n\tconst privateAdapter = createSdkPrivateStdioAdapter(transport);\n\tlet lastChunkSnapshot: StdioChunkSnapshot = {\n\t\tlastChunkByteLength: 0,\n\t\tlastChunkStartsWithUtf8Bom: false,\n\t};\n\n\tprivateAdapter.wrapOnData((chunk) => {\n\t\tlastChunkSnapshot = {\n\t\t\tlastChunkByteLength: chunk.byteLength,\n\t\t\tlastChunkStartsWithUtf8Bom: hasUtf8BomPrefix(chunk),\n\t\t};\n\t});\n\n\tconst didInstallReadMessageHook = privateAdapter.installReadMessageHook(\n\t\t(line) => deserializeMessageWithObservability(line, lastChunkSnapshot),\n\t);\n\tif (!didInstallReadMessageHook) {\n\t\treturn transport;\n\t}\n\n\treturn transport;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport semver from \"semver\";\n\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1_000;\nconst REQUEST_TIMEOUT_MS = 3_000;\nconst REGISTRY_URL = \"https://registry.npmjs.org\";\n\ninterface UpdateCheckOptions {\n\tpackageName: string;\n\tcurrentVersion: string;\n}\n\ninterface CacheEntry {\n\tcheckedAt: number;\n\tlatestVersion: string;\n}\n\ninterface ImmediateHandle {\n\tunref(): unknown;\n}\n\ninterface VersionCheckDependencies {\n\tfetch: typeof fetch;\n\treadFile: typeof readFile;\n\tmkdir: typeof mkdir;\n\twriteFile: typeof writeFile;\n\trename: typeof rename;\n\tunlink: typeof unlink;\n\thomedir: typeof homedir;\n\trandomUUID: typeof randomUUID;\n\tpid: number;\n\tnow: () => number;\n\tenv: NodeJS.ProcessEnv;\n\twriteStderr: (message: string) => unknown;\n}\n\ninterface SchedulerDependencies {\n\tsetImmediate: (callback: () => void) => ImmediateHandle;\n\tcheckForUpdate: (\n\t\toptions: UpdateCheckOptions,\n\t\tdependencies?: Partial<VersionCheckDependencies>,\n\t) => Promise<void>;\n}\n\nconst defaultDependencies: VersionCheckDependencies = {\n\tfetch,\n\treadFile,\n\tmkdir,\n\twriteFile,\n\trename,\n\tunlink,\n\thomedir,\n\trandomUUID,\n\tpid: process.pid,\n\tnow: Date.now,\n\tenv: process.env,\n\twriteStderr: (message) => process.stderr.write(message),\n};\n\nconst defaultSchedulerDependencies: SchedulerDependencies = {\n\tsetImmediate,\n\tcheckForUpdate,\n};\n\nfunction getCachePath(dependencies: VersionCheckDependencies): string {\n\tconst cacheRoot =\n\t\tdependencies.env.XDG_CACHE_HOME || join(dependencies.homedir(), \".cache\");\n\treturn join(cacheRoot, \"hevy-mcp\", \"update-check.json\");\n}\n\nfunction parseCacheEntry(value: string, now: number): CacheEntry | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value);\n\t\tif (\n\t\t\ttypeof parsed !== \"object\" ||\n\t\t\tparsed === null ||\n\t\t\t!(\"checkedAt\" in parsed) ||\n\t\t\t!(\"latestVersion\" in parsed)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { checkedAt, latestVersion } = parsed;\n\t\tif (\n\t\t\ttypeof checkedAt !== \"number\" ||\n\t\t\t!Number.isFinite(checkedAt) ||\n\t\t\ttypeof latestVersion !== \"string\" ||\n\t\t\t!semver.valid(latestVersion)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst age = now - checkedAt;\n\t\tif (age < 0 || age >= CACHE_TTL_MS) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn { checkedAt, latestVersion };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction parseLatestVersion(value: unknown): string | undefined {\n\tif (typeof value !== \"object\" || value === null || !(\"dist-tags\" in value)) {\n\t\treturn undefined;\n\t}\n\n\tconst distTags = value[\"dist-tags\"];\n\tif (\n\t\ttypeof distTags !== \"object\" ||\n\t\tdistTags === null ||\n\t\t!(\"latest\" in distTags) ||\n\t\ttypeof distTags.latest !== \"string\" ||\n\t\t!semver.valid(distTags.latest)\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn distTags.latest;\n}\n\nfunction shouldNotifyAboutUpdate(\n\tcurrentVersion: string,\n\tlatestVersion: string,\n): boolean {\n\tconst current = semver.parse(currentVersion);\n\tconst latest = semver.parse(latestVersion);\n\n\tif (\n\t\t!current ||\n\t\t!latest ||\n\t\tlatest.prerelease.length > 0 ||\n\t\t!semver.gt(latest, current)\n\t) {\n\t\treturn false;\n\t}\n\n\tif (latest.major > current.major) {\n\t\treturn true;\n\t}\n\n\treturn latest.major === current.major && latest.minor - current.minor > 2;\n}\n\nasync function readFreshCachedVersion(\n\tcachePath: string,\n\tdependencies: VersionCheckDependencies,\n): Promise<string | undefined> {\n\ttry {\n\t\tconst cache = await dependencies.readFile(cachePath, \"utf8\");\n\t\treturn parseCacheEntry(cache, dependencies.now())?.latestVersion;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function fetchLatestVersion(\n\tpackageName: string,\n\tdependencies: VersionCheckDependencies,\n): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await dependencies.fetch(\n\t\t\t`${REGISTRY_URL}/${encodeURIComponent(packageName)}`,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/vnd.npm.install-v1+json\",\n\t\t\t\t},\n\t\t\t\tsignal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n\t\t\t},\n\t\t);\n\t\tif (!response.ok) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn parseLatestVersion(await response.json());\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function writeCache(\n\tcachePath: string,\n\tentry: CacheEntry,\n\tdependencies: VersionCheckDependencies,\n): Promise<void> {\n\tconst temporaryPath = `${cachePath}.${dependencies.pid}.${dependencies.randomUUID()}.tmp`;\n\tconst payload = `${JSON.stringify(entry)}\\n`;\n\n\ttry {\n\t\tawait dependencies.mkdir(dirname(cachePath), { recursive: true });\n\t\tawait dependencies.writeFile(temporaryPath, payload, \"utf8\");\n\t} catch {\n\t\ttry {\n\t\t\tawait dependencies.unlink(temporaryPath);\n\t\t} catch {\n\t\t\t// Cache cleanup failures are non-fatal.\n\t\t}\n\t\treturn;\n\t}\n\n\ttry {\n\t\tawait dependencies.rename(temporaryPath, cachePath);\n\t\treturn;\n\t} catch {\n\t\ttry {\n\t\t\tawait dependencies.writeFile(cachePath, payload, \"utf8\");\n\t\t} catch {\n\t\t\t// Cache writes are deliberately non-fatal.\n\t\t}\n\t}\n\n\ttry {\n\t\tawait dependencies.unlink(temporaryPath);\n\t} catch {\n\t\t// Cache cleanup failures are non-fatal.\n\t}\n}\n\nexport async function checkForUpdate(\n\toptions: UpdateCheckOptions,\n\toverrides: Partial<VersionCheckDependencies> = {},\n): Promise<void> {\n\ttry {\n\t\tif (!semver.valid(options.currentVersion)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst dependencies = { ...defaultDependencies, ...overrides };\n\t\tconst cachePath = getCachePath(dependencies);\n\t\tlet latestVersion = await readFreshCachedVersion(cachePath, dependencies);\n\n\t\tif (!latestVersion) {\n\t\t\tlatestVersion = await fetchLatestVersion(\n\t\t\t\toptions.packageName,\n\t\t\t\tdependencies,\n\t\t\t);\n\t\t\tif (!latestVersion) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait writeCache(\n\t\t\t\tcachePath,\n\t\t\t\t{ checkedAt: dependencies.now(), latestVersion },\n\t\t\t\tdependencies,\n\t\t\t);\n\t\t}\n\n\t\tif (shouldNotifyAboutUpdate(options.currentVersion, latestVersion)) {\n\t\t\tdependencies.writeStderr(\n\t\t\t\t`Update available for ${options.packageName}: current ${options.currentVersion}, latest ${latestVersion}. Notices are shown for newer major versions or when more than two minor versions behind. Update using your preferred installation method (for example, npm install -g ${options.packageName}@latest).\\n`,\n\t\t\t);\n\t\t}\n\t} catch {\n\t\t// Update checks must never interfere with the MCP server lifecycle.\n\t}\n}\n\nexport function scheduleUpdateCheck(\n\toptions: UpdateCheckOptions,\n\toverrides: Partial<SchedulerDependencies> = {},\n): void {\n\tconst dependencies = { ...defaultSchedulerDependencies, ...overrides };\n\tconst immediate = dependencies.setImmediate(() => {\n\t\tvoid dependencies.checkForUpdate(options).catch(() => undefined);\n\t});\n\timmediate.unref();\n}\n","// Telemetry must be initialized before any other imports so that\n// OpenTelemetry and Sentry are ready before application code runs.\nimport {\n\tSentry,\n\ttracer,\n\tserviceName,\n\tserviceVersion,\n\tsetCurrentUserId,\n} from \"./utils/telemetry.js\";\nimport { serverStartups } from \"./utils/metrics.js\";\n\nimport { SpanStatusCode } from \"@opentelemetry/api\";\nimport { createHmac } from \"node:crypto\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { registerWorkoutPrompts } from \"./prompts/workouts.js\";\nimport { registerHevyResources } from \"./resources/hevy.js\";\nimport { registerHevyTools } from \"./tools/register.js\";\nimport { assertApiKey, parseConfig } from \"./utils/config.js\";\nimport { installGracefulShutdown } from \"./utils/graceful-shutdown.js\";\nimport { createClient } from \"./utils/hevyClient.js\";\nimport { createMcpClientLogger } from \"./utils/mcp-client-logger.js\";\nimport { createInstrumentedStdioTransport } from \"./utils/stdio-observability.js\";\nimport { scheduleUpdateCheck } from \"./utils/version-check.js\";\n\nconst name = serviceName;\nconst version = serviceVersion;\n\nconst SERVER_INSTRUCTIONS = [\n\t[\n\t\t\"Hevy MCP connects clients to the authenticated user's Hevy\",\n\t\t\"workout-tracking data, including workouts, routines, exercise templates,\",\n\t\t\"routine folders, body measurements, and profile information.\",\n\t\t\"HEVY_API_KEY must contain a valid Hevy API key.\",\n\t].join(\" \"),\n\t[\n\t\t\"Safety: all get-* and search-* tools are read-only. create-* and\",\n\t\t\"update-* tools mutate Hevy data. Creates are additive and\",\n\t\t\"non-idempotent, so repeating one can create duplicates. Updates can\",\n\t\t\"overwrite existing data. Delete operations are not available.\",\n\t].join(\" \"),\n\t[\n\t\t\"Workflow: search exercise templates first, then use the returned\",\n\t\t\"template IDs when creating workouts or routines. To create a completed\",\n\t\t\"workout from a routine, fetch the routine as a plan, then obtain the\",\n\t\t\"actual completed sets and end time from the user; never invent completion\",\n\t\t\"data. Use the built-in workflow prompts when they match the task.\",\n\t].join(\" \"),\n\t[\n\t\t\"Pagination: start at page 1 and fetch only the pages needed. Most list\",\n\t\t\"tools allow pageSize up to 10; get-exercise-templates allows up to 100.\",\n\t].join(\" \"),\n\t[\n\t\t\"Rate limits and retries: minimize repeated calls. If Hevy returns HTTP\",\n\t\t\"429, follow its retry guidance. Transient read requests retry\",\n\t\t\"automatically, but write requests do not; confirm uncertain write\",\n\t\t\"outcomes before trying again.\",\n\t].join(\" \"),\n].join(\"\\n\\n\");\n\nconst HELP_TEXT = [\n\t\"Usage:\",\n\t\" hevy-mcp [options]\",\n\t\"\",\n\t\"Options:\",\n\t\" -h, --help Show this help message and exit\",\n\t\" -v, --version Show version and exit\",\n\t\"\",\n\t\"Environment:\",\n\t\" HEVY_API_KEY=<api-key> Hevy API key from Hevy app settings\",\n\t\" HEVY_MCP_DEBUG=1 Enable verbose diagnostics on stderr\",\n\t\"\",\n\t\"Examples:\",\n\t\" HEVY_API_KEY=your-key npx hevy-mcp\",\n].join(\"\\n\");\n\nfunction getCliAction(args: string[]): \"start\" | \"version\" | \"help\" {\n\tfor (const arg of args) {\n\t\tif (arg === \"--version\" || arg === \"-v\") {\n\t\t\treturn \"version\";\n\t\t}\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\treturn \"help\";\n\t\t}\n\t}\n\n\treturn \"start\";\n}\n\nconst HEVY_API_BASEURL = \"https://api.hevyapp.com\";\nconst STARTUP_PROBE_TIMEOUT_MS = 5_000;\n\nconst INVALID_API_KEY_MESSAGE =\n\t\"HEVY_API_KEY is invalid or expired. Please check your API key in the Hevy app under Settings > API Key.\";\nconst API_KEY_VALIDATION_WARNING =\n\t\"Warning: HEVY_API_KEY could not be validated during startup. Startup will continue; check your network connection and Hevy API availability.\";\nconst SAFE_NETWORK_ERROR_CODES = new Set([\n\t\"EAI_AGAIN\",\n\t\"ECONNABORTED\",\n\t\"ECONNREFUSED\",\n\t\"ECONNRESET\",\n\t\"ENETUNREACH\",\n\t\"ENOTFOUND\",\n\t\"ERR_NETWORK\",\n\t\"ERR_SOCKET_TIMEOUT\",\n\t\"ETIMEDOUT\",\n\t\"HEVY_RETRY_EXHAUSTED\",\n]);\n\nconst SENTRY_USER_ID_CONTEXT = \"hevy-mcp:sentry-user-id:v1\";\n\nfunction fingerprintApiKey(apiKey: string) {\n\t// HMAC-SHA-256 gives Sentry a deterministic pseudonymous user ID without\n\t// sending, logging, or storing the raw Hevy API key.\n\t// Trimmed to 10 characters to keep it compact and readable in Sentry & OTel traces.\n\treturn createHmac(\"sha256\", apiKey)\n\t\t.update(SENTRY_USER_ID_CONTEXT)\n\t\t.digest(\"hex\")\n\t\t.slice(0, 10);\n}\nconst serverConfigSchema = z.object({\n\tapiKey: z\n\t\t.string()\n\t\t.min(1, \"Hevy API key is required\")\n\t\t.describe(\"Your Hevy API key (available in the Hevy app settings).\"),\n});\n\nexport const configSchema = serverConfigSchema;\ntype ServerConfig = z.infer<typeof serverConfigSchema>;\n\nfunction createToolCountingServer(server: McpServer) {\n\tlet count = 0;\n\n\tconst countingServer = new Proxy(server, {\n\t\tget(target, property, receiver) {\n\t\t\tif (property === \"tool\") {\n\t\t\t\treturn (...args: Parameters<McpServer[\"tool\"]>) => {\n\t\t\t\t\tconst registeredTool = target.tool(...args);\n\t\t\t\t\tcount += 1;\n\t\t\t\t\treturn registeredTool;\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (property === \"registerTool\") {\n\t\t\t\tconst registerTool: McpServer[\"registerTool\"] = (\n\t\t\t\t\tname,\n\t\t\t\t\tconfig,\n\t\t\t\t\tcallback,\n\t\t\t\t) => {\n\t\t\t\t\tconst registeredTool = target.registerTool(name, config, callback);\n\t\t\t\t\tcount += 1;\n\t\t\t\t\treturn registeredTool;\n\t\t\t\t};\n\t\t\t\treturn registerTool;\n\t\t\t}\n\n\t\t\treturn Reflect.get(target, property, receiver);\n\t\t},\n\t});\n\n\treturn {\n\t\tserver: countingServer,\n\t\tgetCount: () => count,\n\t};\n}\n\nfunction getHttpStatus(error: unknown): number | undefined {\n\tif (!error || typeof error !== \"object\" || !(\"response\" in error)) {\n\t\treturn undefined;\n\t}\n\n\tconst response = error.response;\n\tif (!response || typeof response !== \"object\" || !(\"status\" in response)) {\n\t\treturn undefined;\n\t}\n\n\treturn typeof response.status === \"number\" &&\n\t\tNumber.isInteger(response.status) &&\n\t\tresponse.status >= 100 &&\n\t\tresponse.status <= 599\n\t\t? response.status\n\t\t: undefined;\n}\n\nfunction getSafeValidationDiagnostic(error: unknown): string | undefined {\n\tconst status = getHttpStatus(error);\n\tif (status !== undefined) {\n\t\treturn `HTTP ${status}`;\n\t}\n\n\tif (!error || typeof error !== \"object\" || !(\"code\" in error)) {\n\t\treturn undefined;\n\t}\n\n\tconst code = error.code;\n\treturn typeof code === \"string\" && SAFE_NETWORK_ERROR_CODES.has(code)\n\t\t? code\n\t\t: undefined;\n}\n\nasync function validateApiKey(apiKey: string) {\n\t// Keep the startup probe separate from the normal MCP-aware client. The\n\t// server is not connected yet, so structured client logging is intentionally\n\t// omitted until the normal client is built below.\n\tconst startupProbeClient = createClient(apiKey, HEVY_API_BASEURL, {\n\t\tmaxGetRetries: 0,\n\t\ttimeoutMs: STARTUP_PROBE_TIMEOUT_MS,\n\t});\n\n\ttry {\n\t\tawait startupProbeClient.getUserInfo();\n\t} catch (error) {\n\t\tconst status = getHttpStatus(error);\n\t\tif (status === 401 || status === 403) {\n\t\t\tthrow new Error(INVALID_API_KEY_MESSAGE);\n\t\t}\n\n\t\tconst diagnostic = getSafeValidationDiagnostic(error);\n\t\tconsole.error(\n\t\t\tdiagnostic\n\t\t\t\t? `${API_KEY_VALIDATION_WARNING} Diagnostic: ${diagnostic}.`\n\t\t\t\t: API_KEY_VALIDATION_WARNING,\n\t\t);\n\t}\n}\n\nfunction buildServer(apiKey: string) {\n\tconst userId = fingerprintApiKey(apiKey);\n\n\treturn tracer.startActiveSpan(\n\t\t\"mcp.server.build\",\n\t\t{\n\t\t\tattributes: {\n\t\t\t\t\"mcp.server.name\": name,\n\t\t\t\t\"mcp.server.version\": version,\n\t\t\t\t\"mcp.transport\": \"stdio\",\n\t\t\t\t\"user.id\": userId,\n\t\t\t},\n\t\t},\n\t\t(span) => {\n\t\t\ttry {\n\t\t\t\tSentry.setUser({ id: userId });\n\t\t\t\tsetCurrentUserId(userId);\n\n\t\t\t\tconst baseServer = new McpServer(\n\t\t\t\t\t{\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tversion,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcapabilities: { logging: {} },\n\t\t\t\t\t\tinstructions: SERVER_INSTRUCTIONS,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconst server = Sentry.wrapMcpServerWithSentry(baseServer);\n\t\t\t\tconst clientLogger = createMcpClientLogger(server);\n\n\t\t\t\tconst hevyClient = tracer.startActiveSpan(\n\t\t\t\t\t\"mcp.hevy-client.initialize\",\n\t\t\t\t\t(childSpan) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn createClient(apiKey, HEVY_API_BASEURL, {\n\t\t\t\t\t\t\t\tlogger: clientLogger,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tchildSpan.end();\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tconsole.error(\"Hevy client initialized with API key\");\n\n\t\t\t\ttracer.startActiveSpan(\"mcp.tools.register\", (toolsSpan) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst counting = createToolCountingServer(server);\n\t\t\t\t\t\tregisterHevyTools(counting.server, hevyClient, {\n\t\t\t\t\t\t\tlogger: clientLogger,\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttoolsSpan.setAttribute(\"mcp.tools.count\", counting.getCount());\n\t\t\t\t\t} finally {\n\t\t\t\t\t\ttoolsSpan.end();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tregisterWorkoutPrompts(server);\n\t\t\t\ttracer.startActiveSpan(\n\t\t\t\t\t\"mcp.resources.register\",\n\t\t\t\t\t{\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\"mcp.resources.count\": 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t(resourcesSpan) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tregisterHevyResources(server, hevyClient);\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tresourcesSpan.end();\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\treturn server;\n\t\t\t} catch (e) {\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\tthrow e;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n\nexport async function createServer({ config }: { config: ServerConfig }) {\n\tconst { apiKey } = serverConfigSchema.parse(config);\n\tawait validateApiKey(apiKey);\n\treturn buildServer(apiKey);\n}\n\nexport default createServer;\n\nexport async function runServer() {\n\tconst args = process.argv.slice(2);\n\tconst cliAction = getCliAction(args);\n\n\tif (cliAction === \"version\") {\n\t\tconsole.error(`${name} v${version}`);\n\t\treturn;\n\t}\n\n\tif (cliAction === \"help\") {\n\t\tconsole.log(HELP_TEXT);\n\t\treturn;\n\t}\n\n\tserverStartups.add(1, { version });\n\n\tawait tracer.startActiveSpan(\n\t\t\"mcp.server.run\",\n\t\t{\n\t\t\tattributes: {\n\t\t\t\t\"mcp.transport\": \"stdio\",\n\t\t\t},\n\t\t},\n\t\tasync (span) => {\n\t\t\ttry {\n\t\t\t\tconst cfg = parseConfig(process.env);\n\t\t\t\tconst apiKey = cfg.apiKey;\n\t\t\t\tassertApiKey(apiKey);\n\n\t\t\t\tconst server = await createServer({ config: { apiKey } });\n\t\t\t\tconsole.error(\"Starting MCP server in stdio mode\");\n\t\t\t\tconst transport = createInstrumentedStdioTransport(\n\t\t\t\t\tnew StdioServerTransport(),\n\t\t\t\t);\n\n\t\t\t\tawait tracer.startActiveSpan(\n\t\t\t\t\t\"mcp.server.connect\",\n\t\t\t\t\t{\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\"mcp.transport\": \"stdio\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tasync (connectSpan) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait server.connect(transport);\n\t\t\t\t\t\t\tconnectSpan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tconnectSpan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\t\t\tthrow e;\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tconnectSpan.end();\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tscheduleUpdateCheck({\n\t\t\t\t\tpackageName: serviceName,\n\t\t\t\t\tcurrentVersion: serviceVersion,\n\t\t\t\t});\n\t\t\t\tinstallGracefulShutdown({ target: server });\n\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t} catch (e) {\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\tthrow e;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n"],"mappings":"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"}
|