hevy-mcp 1.28.1-beta.1 → 2.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 +66 -26
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{src-CHT_Meh8.mjs → src-c3mB-R0m.mjs} +72 -16
- package/dist/{src-CHT_Meh8.mjs.map → src-c3mB-R0m.mjs.map} +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ A Model Context Protocol (MCP) server implementation that interfaces with the [H
|
|
|
15
15
|
- [Quick Start](#quick-start)
|
|
16
16
|
- [Prerequisites](#prerequisites)
|
|
17
17
|
- [Installation](#installation)
|
|
18
|
+
- [Run with Docker](#run-with-docker)
|
|
18
19
|
- [Claude Desktop Configuration](#claude-desktop-configuration)
|
|
19
20
|
- [Cursor Configuration](#cursor-configuration)
|
|
20
21
|
- [Other MCP Clients (via add-mcp)](#other-mcp-clients-via-add-mcp)
|
|
@@ -39,10 +40,11 @@ A Model Context Protocol (MCP) server implementation that interfaces with the [H
|
|
|
39
40
|
|
|
40
41
|
Pick the workflow that fits your setup:
|
|
41
42
|
|
|
42
|
-
| Scenario | Command
|
|
43
|
-
| :-------------------- |
|
|
44
|
-
| **One-off stdio run** | `HEVY_API_KEY=
|
|
45
|
-
| **
|
|
43
|
+
| Scenario | Command | Requirements |
|
|
44
|
+
| :-------------------- | :-------------------------------------------------------------------------------------- | :------------------------- |
|
|
45
|
+
| **One-off stdio run** | `HEVY_API_KEY=your_key npx -y hevy-mcp` or `HEVY_API_KEY=your_key bunx hevy-mcp@latest` | Node.js ≥ 20, Hevy API key |
|
|
46
|
+
| **Docker stdio run** | `docker run -i --rm -e HEVY_API_KEY ghcr.io/chrisdoc/hevy-mcp:latest` | Docker, Hevy API key |
|
|
47
|
+
| **Local development** | `npm install && npm run build && npm start` | `.env` with `HEVY_API_KEY` |
|
|
46
48
|
|
|
47
49
|
---
|
|
48
50
|
|
|
@@ -51,6 +53,7 @@ Pick the workflow that fits your setup:
|
|
|
51
53
|
- **Node.js**: v20 or higher (strongly recommended to use the exact version pinned in `.nvmrc`).
|
|
52
54
|
- **npm**: v10 or higher.
|
|
53
55
|
- **Bun** (optional): If you want to launch with `bunx`.
|
|
56
|
+
- **Docker** (optional): If you want an isolated container-based stdio setup.
|
|
54
57
|
- **Hevy API key**: Required for all operations (available with Hevy PRO).
|
|
55
58
|
|
|
56
59
|
---
|
|
@@ -70,25 +73,6 @@ HEVY_API_KEY=your_hevy_api_key_here npx -y hevy-mcp
|
|
|
70
73
|
HEVY_API_KEY=your_hevy_api_key_here bunx hevy-mcp@latest
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
### Prerelease channel
|
|
74
|
-
|
|
75
|
-
Install `hevy-mcp@beta` to opt into changes merged to `main` that have not yet
|
|
76
|
-
reached a stable release:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
npm install hevy-mcp@beta
|
|
80
|
-
|
|
81
|
-
# npx launcher
|
|
82
|
-
npx -y hevy-mcp@beta
|
|
83
|
-
|
|
84
|
-
# bun launcher
|
|
85
|
-
bunx hevy-mcp@beta
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Beta builds may be less stable and can change before their stable release.
|
|
89
|
-
`npm install hevy-mcp@latest` remains the stable channel. To switch back from
|
|
90
|
-
beta, install `hevy-mcp@latest` again.
|
|
91
|
-
|
|
92
76
|
### Manual Installation
|
|
93
77
|
|
|
94
78
|
```bash
|
|
@@ -104,6 +88,26 @@ cp .env.sample .env
|
|
|
104
88
|
# Edit .env and add your HEVY_API_KEY
|
|
105
89
|
```
|
|
106
90
|
|
|
91
|
+
### Run with Docker
|
|
92
|
+
|
|
93
|
+
Official multi-platform images are published to GitHub Container Registry for
|
|
94
|
+
`linux/amd64` and `linux/arm64`:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
export HEVY_API_KEY=your_hevy_api_key_here
|
|
98
|
+
docker run -i --rm -e HEVY_API_KEY ghcr.io/chrisdoc/hevy-mcp:latest
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The server uses stdio, so `-i` keeps standard input open for the MCP client.
|
|
102
|
+
`--rm` removes the stopped container automatically. The `-e HEVY_API_KEY`
|
|
103
|
+
form forwards the variable from the host environment without putting the key
|
|
104
|
+
in the command arguments.
|
|
105
|
+
|
|
106
|
+
Use `latest` to follow the newest stable release. For reproducible deployments,
|
|
107
|
+
pin the exact version shown on the release, using a tag such as
|
|
108
|
+
`ghcr.io/chrisdoc/hevy-mcp:X.Y.Z`. Major (`:X`) and major.minor (`:X.Y`) tags
|
|
109
|
+
are also published for controlled automatic updates.
|
|
110
|
+
|
|
107
111
|
---
|
|
108
112
|
|
|
109
113
|
## 🔗 Integration
|
|
@@ -138,6 +142,41 @@ If you prefer Bun, swap the launcher fields:
|
|
|
138
142
|
}
|
|
139
143
|
```
|
|
140
144
|
|
|
145
|
+
To run Claude Desktop through Docker instead, first create an environment file
|
|
146
|
+
outside the repository containing your real key:
|
|
147
|
+
|
|
148
|
+
```dotenv
|
|
149
|
+
HEVY_API_KEY=replace_with_your_real_key
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Restrict access to that file where supported (for example,
|
|
153
|
+
`chmod 600 /absolute/path/to/hevy-mcp.env`), then use its absolute path in the
|
|
154
|
+
Claude Desktop configuration:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"mcpServers": {
|
|
159
|
+
"hevy-mcp": {
|
|
160
|
+
"command": "docker",
|
|
161
|
+
"args": [
|
|
162
|
+
"run",
|
|
163
|
+
"-i",
|
|
164
|
+
"--rm",
|
|
165
|
+
"--env-file",
|
|
166
|
+
"/absolute/path/to/hevy-mcp.env",
|
|
167
|
+
"ghcr.io/chrisdoc/hevy-mcp:latest"
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
This configuration runs the same stdio server inside the container; it does
|
|
175
|
+
not expose an HTTP port or start a detached service. Docker reads the key from
|
|
176
|
+
the environment file, so the Claude configuration does not replace an
|
|
177
|
+
inherited key with a placeholder. Replace `latest` with an exact version tag if
|
|
178
|
+
you want Claude Desktop to stay on a pinned release.
|
|
179
|
+
|
|
141
180
|
### Cursor Configuration
|
|
142
181
|
|
|
143
182
|
Add this server under `"mcpServers"` in `~/.cursor/mcp.json`:
|
|
@@ -241,10 +280,11 @@ paging behavior explicit and avoid cross-page invalidation complexity.
|
|
|
241
280
|
<details>
|
|
242
281
|
<summary><strong>⚠️ Migration Note (v1.18.0)</strong></summary>
|
|
243
282
|
|
|
244
|
-
As of **v1.18.0**, `hevy-mcp` removed
|
|
245
|
-
support.
|
|
283
|
+
As of **v1.18.0**, `hevy-mcp` removed HTTP/SSE transport and its previous
|
|
284
|
+
Docker packaging. Docker support is now available again for the stdio server.
|
|
246
285
|
|
|
247
|
-
|
|
286
|
+
Both `npx hevy-mcp` and the official container image use stdio; HTTP ports and
|
|
287
|
+
detached-container deployment are not supported.
|
|
248
288
|
|
|
249
289
|
</details>
|
|
250
290
|
|
package/dist/cli.mjs
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
(function() {
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
|
-
e.SENTRY_RELEASE = { id: "hevy-mcp@
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@2.0.0" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
9
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "03cf150f-6466-4ca3-9cf1-e423cc0e3cd2", e._sentryDebugIdIdentifier = "sentry-dbid-03cf150f-6466-4ca3-9cf1-e423cc0e3cd2");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
-
import { r as runServer } from "./src-
|
|
12
|
+
import { r as runServer } from "./src-c3mB-R0m.mjs";
|
|
13
13
|
//#region src/cli.ts
|
|
14
14
|
runServer().catch((error) => {
|
|
15
15
|
console.error("Fatal error in main():", error);
|
package/dist/index.d.mts
CHANGED
|
@@ -14,7 +14,7 @@ declare function createServer({
|
|
|
14
14
|
config
|
|
15
15
|
}: {
|
|
16
16
|
config: ServerConfig;
|
|
17
|
-
}): McpServer
|
|
17
|
+
}): Promise<McpServer>;
|
|
18
18
|
declare function runServer(): Promise<void>;
|
|
19
19
|
//#endregion
|
|
20
20
|
export { configSchema, createServer, createServer as default, runServer };
|
package/dist/index.mjs
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
(function() {
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
|
-
e.SENTRY_RELEASE = { id: "hevy-mcp@
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@2.0.0" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
9
|
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "5b077b94-9ef8-4f24-a0b0-8dcfbf491be1", e._sentryDebugIdIdentifier = "sentry-dbid-5b077b94-9ef8-4f24-a0b0-8dcfbf491be1");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
|
-
import { n as createServer, r as runServer, t as configSchema } from "./src-
|
|
12
|
+
import { n as createServer, r as runServer, t as configSchema } from "./src-c3mB-R0m.mjs";
|
|
13
13
|
export { configSchema, createServer, createServer as default, runServer };
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
(function() {
|
|
5
5
|
try {
|
|
6
6
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {};
|
|
7
|
-
e.SENTRY_RELEASE = { id: "hevy-mcp@
|
|
7
|
+
e.SENTRY_RELEASE = { id: "hevy-mcp@2.0.0" };
|
|
8
8
|
var n = new e.Error().stack;
|
|
9
|
-
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "
|
|
9
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "17d5086b-9850-447d-9372-27bb2ce5dcc5", e._sentryDebugIdIdentifier = "sentry-dbid-17d5086b-9850-447d-9372-27bb2ce5dcc5");
|
|
10
10
|
} catch (e) {}
|
|
11
11
|
})();
|
|
12
12
|
import * as Sentry from "@sentry/node";
|
|
@@ -41,10 +41,10 @@ import semver from "semver";
|
|
|
41
41
|
* OTel Collector → Honeycomb: performance traces, metrics
|
|
42
42
|
*/
|
|
43
43
|
const name$1 = "hevy-mcp";
|
|
44
|
-
const version$1 = "
|
|
44
|
+
const version$1 = "2.0.0";
|
|
45
45
|
const collectorToken = "NH9vOela-HYreQxAbJa68cjEmORoEKM57EvneUDVcOo";
|
|
46
46
|
const COLLECTOR_ENDPOINT = "https://otel.chrisdoc.dev/v1";
|
|
47
|
-
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@
|
|
47
|
+
const sentryRelease = process.env.SENTRY_RELEASE ?? `hevy-mcp@2.0.0`;
|
|
48
48
|
const resource = resourceFromAttributes({
|
|
49
49
|
"service.name": name$1,
|
|
50
50
|
"service.version": version$1
|
|
@@ -2871,6 +2871,15 @@ function getApiTimeoutMs() {
|
|
|
2871
2871
|
if (!Number.isFinite(parsed) || parsed <= 0) return DEFAULT_API_TIMEOUT_MS;
|
|
2872
2872
|
return Math.trunc(parsed);
|
|
2873
2873
|
}
|
|
2874
|
+
function normalizeMaxGetRetries(value) {
|
|
2875
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) return 3;
|
|
2876
|
+
return Math.floor(value);
|
|
2877
|
+
}
|
|
2878
|
+
function normalizeTimeoutMs(value) {
|
|
2879
|
+
if (value === void 0 || !Number.isFinite(value) || value <= 0) return getApiTimeoutMs();
|
|
2880
|
+
const normalizedValue = Math.floor(value);
|
|
2881
|
+
return normalizedValue > 0 ? normalizedValue : getApiTimeoutMs();
|
|
2882
|
+
}
|
|
2874
2883
|
function sleep(ms) {
|
|
2875
2884
|
return new Promise((resolve) => {
|
|
2876
2885
|
setTimeout(resolve, ms);
|
|
@@ -2958,7 +2967,7 @@ function markRetryExhausted(error, retryCount) {
|
|
|
2958
2967
|
if (retryError.code) retryError.hevyRetryOriginalCode = retryError.code;
|
|
2959
2968
|
retryError.code = HEVY_RETRY_EXHAUSTED_ERROR_CODE;
|
|
2960
2969
|
}
|
|
2961
|
-
async function requestWithRetries(axiosInstance, config, logger) {
|
|
2970
|
+
async function requestWithRetries(axiosInstance, config, maxGetRetries, logger) {
|
|
2962
2971
|
let retryCount = 0;
|
|
2963
2972
|
while (true) try {
|
|
2964
2973
|
return await axiosInstance.request(config);
|
|
@@ -2980,7 +2989,7 @@ async function requestWithRetries(axiosInstance, config, logger) {
|
|
|
2980
2989
|
});
|
|
2981
2990
|
throw error;
|
|
2982
2991
|
}
|
|
2983
|
-
if (retryCount >=
|
|
2992
|
+
if (retryCount >= maxGetRetries) {
|
|
2984
2993
|
emitClientLog(logger, {
|
|
2985
2994
|
level: status === 429 ? "warning" : "error",
|
|
2986
2995
|
logger: "hevy-api",
|
|
@@ -2988,7 +2997,7 @@ async function requestWithRetries(axiosInstance, config, logger) {
|
|
|
2988
2997
|
message: "Hevy API request failed after retries",
|
|
2989
2998
|
status,
|
|
2990
2999
|
attempt: retryCount + 1,
|
|
2991
|
-
maxAttempts:
|
|
3000
|
+
maxAttempts: maxGetRetries + 1,
|
|
2992
3001
|
method,
|
|
2993
3002
|
endpoint
|
|
2994
3003
|
}
|
|
@@ -3006,7 +3015,7 @@ async function requestWithRetries(axiosInstance, config, logger) {
|
|
|
3006
3015
|
message: status === 429 ? "Hevy API rate limit; retrying request" : "Retrying Hevy API request",
|
|
3007
3016
|
status,
|
|
3008
3017
|
attempt: retryCount + 1,
|
|
3009
|
-
maxAttempts:
|
|
3018
|
+
maxAttempts: maxGetRetries + 1,
|
|
3010
3019
|
delayMs: retryDelayMs,
|
|
3011
3020
|
...status === 429 ? { retryAfterMs: retryAfterMs ?? null } : {},
|
|
3012
3021
|
method,
|
|
@@ -3016,10 +3025,10 @@ async function requestWithRetries(axiosInstance, config, logger) {
|
|
|
3016
3025
|
await sleep(retryDelayMs);
|
|
3017
3026
|
}
|
|
3018
3027
|
}
|
|
3019
|
-
function createResilientClient(axiosInstance, logger) {
|
|
3028
|
+
function createResilientClient(axiosInstance, maxGetRetries, logger) {
|
|
3020
3029
|
let clientConfig = { baseURL: axiosInstance.defaults.baseURL };
|
|
3021
3030
|
const resilientClient = (async (config) => {
|
|
3022
|
-
return requestWithRetries(axiosInstance, config, logger);
|
|
3031
|
+
return requestWithRetries(axiosInstance, config, maxGetRetries, logger);
|
|
3023
3032
|
});
|
|
3024
3033
|
resilientClient.getConfig = () => ({ ...clientConfig });
|
|
3025
3034
|
resilientClient.setConfig = (config) => {
|
|
@@ -3075,9 +3084,11 @@ function finalizeRequestTrace(opts) {
|
|
|
3075
3084
|
}
|
|
3076
3085
|
function createClient$1(apiKey, baseUrl = "https://api.hevyapp.com", options = {}) {
|
|
3077
3086
|
const { logger } = options;
|
|
3087
|
+
const maxGetRetries = normalizeMaxGetRetries(options.maxGetRetries);
|
|
3088
|
+
const timeoutMs = normalizeTimeoutMs(options.timeoutMs);
|
|
3078
3089
|
const axiosInstance = axios.create({
|
|
3079
3090
|
baseURL: baseUrl,
|
|
3080
|
-
timeout:
|
|
3091
|
+
timeout: timeoutMs,
|
|
3081
3092
|
headers: { "api-key": apiKey }
|
|
3082
3093
|
});
|
|
3083
3094
|
axiosInstance.interceptors.request.use((config) => {
|
|
@@ -3085,11 +3096,13 @@ function createClient$1(apiKey, baseUrl = "https://api.hevyapp.com", options = {
|
|
|
3085
3096
|
const method = (config.method ?? "get").toUpperCase();
|
|
3086
3097
|
const url = config.url ?? "";
|
|
3087
3098
|
const endpoint = url.split("?")[0] ?? url;
|
|
3099
|
+
const userId = getCurrentUserId();
|
|
3088
3100
|
tracedConfig._span = tracer.startSpan(`hevy.api.${method}`, { attributes: {
|
|
3089
3101
|
"http.method": method,
|
|
3090
3102
|
"http.url": url,
|
|
3091
3103
|
"http.base_url": config.baseURL ?? "",
|
|
3092
|
-
"hevy.api.endpoint": endpoint
|
|
3104
|
+
"hevy.api.endpoint": endpoint,
|
|
3105
|
+
...userId ? { "user.id": userId } : {}
|
|
3093
3106
|
} });
|
|
3094
3107
|
tracedConfig._startTime = Date.now();
|
|
3095
3108
|
return config;
|
|
@@ -3141,7 +3154,7 @@ function createClient$1(apiKey, baseUrl = "https://api.hevyapp.com", options = {
|
|
|
3141
3154
|
throw error;
|
|
3142
3155
|
});
|
|
3143
3156
|
const headers = { "api-key": apiKey };
|
|
3144
|
-
const client = createResilientClient(axiosInstance, logger);
|
|
3157
|
+
const client = createResilientClient(axiosInstance, maxGetRetries, logger);
|
|
3145
3158
|
return {
|
|
3146
3159
|
getWorkouts: (params) => wrapApi(getV1Workouts)(headers, params, { client }),
|
|
3147
3160
|
getWorkout: (workoutId) => wrapApi(getV1WorkoutsWorkoutid)(workoutId, headers, { client }),
|
|
@@ -3561,6 +3574,21 @@ function getCliAction(args) {
|
|
|
3561
3574
|
return "start";
|
|
3562
3575
|
}
|
|
3563
3576
|
const HEVY_API_BASEURL = "https://api.hevyapp.com";
|
|
3577
|
+
const STARTUP_PROBE_TIMEOUT_MS = 5e3;
|
|
3578
|
+
const INVALID_API_KEY_MESSAGE = "HEVY_API_KEY is invalid or expired. Please check your API key in the Hevy app under Settings > API Key.";
|
|
3579
|
+
const API_KEY_VALIDATION_WARNING = "Warning: HEVY_API_KEY could not be validated during startup. Startup will continue; check your network connection and Hevy API availability.";
|
|
3580
|
+
const SAFE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3581
|
+
"EAI_AGAIN",
|
|
3582
|
+
"ECONNABORTED",
|
|
3583
|
+
"ECONNREFUSED",
|
|
3584
|
+
"ECONNRESET",
|
|
3585
|
+
"ENETUNREACH",
|
|
3586
|
+
"ENOTFOUND",
|
|
3587
|
+
"ERR_NETWORK",
|
|
3588
|
+
"ERR_SOCKET_TIMEOUT",
|
|
3589
|
+
"ETIMEDOUT",
|
|
3590
|
+
"HEVY_RETRY_EXHAUSTED"
|
|
3591
|
+
]);
|
|
3564
3592
|
const SENTRY_USER_ID_CONTEXT = "hevy-mcp:sentry-user-id:v1";
|
|
3565
3593
|
function fingerprintApiKey(apiKey) {
|
|
3566
3594
|
return createHmac("sha256", apiKey).update(SENTRY_USER_ID_CONTEXT).digest("hex").slice(0, 10);
|
|
@@ -3589,6 +3617,33 @@ function createToolCountingServer(server) {
|
|
|
3589
3617
|
getCount: () => count
|
|
3590
3618
|
};
|
|
3591
3619
|
}
|
|
3620
|
+
function getHttpStatus(error) {
|
|
3621
|
+
if (!error || typeof error !== "object" || !("response" in error)) return;
|
|
3622
|
+
const response = error.response;
|
|
3623
|
+
if (!response || typeof response !== "object" || !("status" in response)) return;
|
|
3624
|
+
return typeof response.status === "number" && Number.isInteger(response.status) && response.status >= 100 && response.status <= 599 ? response.status : void 0;
|
|
3625
|
+
}
|
|
3626
|
+
function getSafeValidationDiagnostic(error) {
|
|
3627
|
+
const status = getHttpStatus(error);
|
|
3628
|
+
if (status !== void 0) return `HTTP ${status}`;
|
|
3629
|
+
if (!error || typeof error !== "object" || !("code" in error)) return;
|
|
3630
|
+
const code = error.code;
|
|
3631
|
+
return typeof code === "string" && SAFE_NETWORK_ERROR_CODES.has(code) ? code : void 0;
|
|
3632
|
+
}
|
|
3633
|
+
async function validateApiKey(apiKey) {
|
|
3634
|
+
const startupProbeClient = createClient(apiKey, HEVY_API_BASEURL, {
|
|
3635
|
+
maxGetRetries: 0,
|
|
3636
|
+
timeoutMs: STARTUP_PROBE_TIMEOUT_MS
|
|
3637
|
+
});
|
|
3638
|
+
try {
|
|
3639
|
+
await startupProbeClient.getUserInfo();
|
|
3640
|
+
} catch (error) {
|
|
3641
|
+
const status = getHttpStatus(error);
|
|
3642
|
+
if (status === 401 || status === 403) throw new Error(INVALID_API_KEY_MESSAGE);
|
|
3643
|
+
const diagnostic = getSafeValidationDiagnostic(error);
|
|
3644
|
+
console.error(diagnostic ? `${API_KEY_VALIDATION_WARNING} Diagnostic: ${diagnostic}.` : API_KEY_VALIDATION_WARNING);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3592
3647
|
function buildServer(apiKey) {
|
|
3593
3648
|
const userId = fingerprintApiKey(apiKey);
|
|
3594
3649
|
return tracer.startActiveSpan("mcp.server.build", { attributes: {
|
|
@@ -3649,8 +3704,9 @@ function buildServer(apiKey) {
|
|
|
3649
3704
|
}
|
|
3650
3705
|
});
|
|
3651
3706
|
}
|
|
3652
|
-
function createServer({ config }) {
|
|
3707
|
+
async function createServer({ config }) {
|
|
3653
3708
|
const { apiKey } = serverConfigSchema.parse(config);
|
|
3709
|
+
await validateApiKey(apiKey);
|
|
3654
3710
|
return buildServer(apiKey);
|
|
3655
3711
|
}
|
|
3656
3712
|
async function runServer() {
|
|
@@ -3669,7 +3725,7 @@ async function runServer() {
|
|
|
3669
3725
|
try {
|
|
3670
3726
|
const apiKey = parseConfig(args, process.env).apiKey;
|
|
3671
3727
|
assertApiKey(apiKey);
|
|
3672
|
-
const server =
|
|
3728
|
+
const server = await createServer({ config: { apiKey } });
|
|
3673
3729
|
console.error("Starting MCP server in stdio mode");
|
|
3674
3730
|
const transport = createInstrumentedStdioTransport(new StdioServerTransport());
|
|
3675
3731
|
await tracer.startActiveSpan("mcp.server.connect", { attributes: { "mcp.transport": "stdio" } }, async (connectSpan) => {
|
|
@@ -3700,4 +3756,4 @@ async function runServer() {
|
|
|
3700
3756
|
//#endregion
|
|
3701
3757
|
export { createServer as n, runServer as r, configSchema as t };
|
|
3702
3758
|
|
|
3703
|
-
//# sourceMappingURL=src-
|
|
3759
|
+
//# sourceMappingURL=src-c3mB-R0m.mjs.map
|