@burdenoff/mcp-libs 2026.511.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +76 -0
  2. package/dist/chunk-4GBVJ4OY.js +847 -0
  3. package/dist/chunk-4GBVJ4OY.js.map +1 -0
  4. package/dist/chunk-H2OYWLOA.js +919 -0
  5. package/dist/chunk-H2OYWLOA.js.map +1 -0
  6. package/dist/chunk-JFEQYSWM.js +174 -0
  7. package/dist/chunk-JFEQYSWM.js.map +1 -0
  8. package/dist/chunk-WWFVD7BO.js +273 -0
  9. package/dist/chunk-WWFVD7BO.js.map +1 -0
  10. package/dist/context-1jV4NsLv.d.cts +138 -0
  11. package/dist/context-1jV4NsLv.d.ts +138 -0
  12. package/dist/core/index.cjs +953 -0
  13. package/dist/core/index.cjs.map +1 -0
  14. package/dist/core/index.d.cts +59 -0
  15. package/dist/core/index.d.ts +59 -0
  16. package/dist/core/index.js +3 -0
  17. package/dist/core/index.js.map +1 -0
  18. package/dist/http-BP4c721D.d.cts +22 -0
  19. package/dist/http-DXTeCD5r.d.ts +22 -0
  20. package/dist/index.cjs +1013 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +7 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.js +4 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/module-DBcfA-i3.d.ts +67 -0
  27. package/dist/module-DFQBZNK6.d.cts +67 -0
  28. package/dist/modules/auth/index.cjs +533 -0
  29. package/dist/modules/auth/index.cjs.map +1 -0
  30. package/dist/modules/auth/index.d.cts +51 -0
  31. package/dist/modules/auth/index.d.ts +51 -0
  32. package/dist/modules/auth/index.js +159 -0
  33. package/dist/modules/auth/index.js.map +1 -0
  34. package/dist/modules/billing/index.cjs +655 -0
  35. package/dist/modules/billing/index.cjs.map +1 -0
  36. package/dist/modules/billing/index.d.cts +8 -0
  37. package/dist/modules/billing/index.d.ts +8 -0
  38. package/dist/modules/billing/index.js +606 -0
  39. package/dist/modules/billing/index.js.map +1 -0
  40. package/dist/modules/channels/index.cjs +443 -0
  41. package/dist/modules/channels/index.cjs.map +1 -0
  42. package/dist/modules/channels/index.d.cts +8 -0
  43. package/dist/modules/channels/index.d.ts +8 -0
  44. package/dist/modules/channels/index.js +394 -0
  45. package/dist/modules/channels/index.js.map +1 -0
  46. package/dist/modules/conversations/index.cjs +288 -0
  47. package/dist/modules/conversations/index.cjs.map +1 -0
  48. package/dist/modules/conversations/index.d.cts +8 -0
  49. package/dist/modules/conversations/index.d.ts +8 -0
  50. package/dist/modules/conversations/index.js +239 -0
  51. package/dist/modules/conversations/index.js.map +1 -0
  52. package/dist/modules/devportal/index.cjs +796 -0
  53. package/dist/modules/devportal/index.cjs.map +1 -0
  54. package/dist/modules/devportal/index.d.cts +8 -0
  55. package/dist/modules/devportal/index.d.ts +8 -0
  56. package/dist/modules/devportal/index.js +747 -0
  57. package/dist/modules/devportal/index.js.map +1 -0
  58. package/dist/modules/export/index.cjs +333 -0
  59. package/dist/modules/export/index.cjs.map +1 -0
  60. package/dist/modules/export/index.d.cts +8 -0
  61. package/dist/modules/export/index.d.ts +8 -0
  62. package/dist/modules/export/index.js +284 -0
  63. package/dist/modules/export/index.js.map +1 -0
  64. package/dist/modules/files/index.cjs +278 -0
  65. package/dist/modules/files/index.cjs.map +1 -0
  66. package/dist/modules/files/index.d.cts +8 -0
  67. package/dist/modules/files/index.d.ts +8 -0
  68. package/dist/modules/files/index.js +229 -0
  69. package/dist/modules/files/index.js.map +1 -0
  70. package/dist/modules/groups/index.cjs +451 -0
  71. package/dist/modules/groups/index.cjs.map +1 -0
  72. package/dist/modules/groups/index.d.cts +8 -0
  73. package/dist/modules/groups/index.d.ts +8 -0
  74. package/dist/modules/groups/index.js +402 -0
  75. package/dist/modules/groups/index.js.map +1 -0
  76. package/dist/modules/health/index.cjs +159 -0
  77. package/dist/modules/health/index.cjs.map +1 -0
  78. package/dist/modules/health/index.d.cts +8 -0
  79. package/dist/modules/health/index.d.ts +8 -0
  80. package/dist/modules/health/index.js +36 -0
  81. package/dist/modules/health/index.js.map +1 -0
  82. package/dist/modules/integrations/index.cjs +316 -0
  83. package/dist/modules/integrations/index.cjs.map +1 -0
  84. package/dist/modules/integrations/index.d.cts +8 -0
  85. package/dist/modules/integrations/index.d.ts +8 -0
  86. package/dist/modules/integrations/index.js +267 -0
  87. package/dist/modules/integrations/index.js.map +1 -0
  88. package/dist/modules/notifications/index.cjs +222 -0
  89. package/dist/modules/notifications/index.cjs.map +1 -0
  90. package/dist/modules/notifications/index.d.cts +8 -0
  91. package/dist/modules/notifications/index.d.ts +8 -0
  92. package/dist/modules/notifications/index.js +173 -0
  93. package/dist/modules/notifications/index.js.map +1 -0
  94. package/dist/modules/organizations/index.cjs +267 -0
  95. package/dist/modules/organizations/index.cjs.map +1 -0
  96. package/dist/modules/organizations/index.d.cts +8 -0
  97. package/dist/modules/organizations/index.d.ts +8 -0
  98. package/dist/modules/organizations/index.js +218 -0
  99. package/dist/modules/organizations/index.js.map +1 -0
  100. package/dist/modules/products/index.cjs +736 -0
  101. package/dist/modules/products/index.cjs.map +1 -0
  102. package/dist/modules/products/index.d.cts +8 -0
  103. package/dist/modules/products/index.d.ts +8 -0
  104. package/dist/modules/products/index.js +687 -0
  105. package/dist/modules/products/index.js.map +1 -0
  106. package/dist/modules/rbac/index.cjs +378 -0
  107. package/dist/modules/rbac/index.cjs.map +1 -0
  108. package/dist/modules/rbac/index.d.cts +8 -0
  109. package/dist/modules/rbac/index.d.ts +8 -0
  110. package/dist/modules/rbac/index.js +329 -0
  111. package/dist/modules/rbac/index.js.map +1 -0
  112. package/dist/modules/sandbox/index.cjs +318 -0
  113. package/dist/modules/sandbox/index.cjs.map +1 -0
  114. package/dist/modules/sandbox/index.d.cts +8 -0
  115. package/dist/modules/sandbox/index.d.ts +8 -0
  116. package/dist/modules/sandbox/index.js +225 -0
  117. package/dist/modules/sandbox/index.js.map +1 -0
  118. package/dist/modules/scheduler/index.cjs +267 -0
  119. package/dist/modules/scheduler/index.cjs.map +1 -0
  120. package/dist/modules/scheduler/index.d.cts +8 -0
  121. package/dist/modules/scheduler/index.d.ts +8 -0
  122. package/dist/modules/scheduler/index.js +218 -0
  123. package/dist/modules/scheduler/index.js.map +1 -0
  124. package/dist/modules/security/index.cjs +529 -0
  125. package/dist/modules/security/index.cjs.map +1 -0
  126. package/dist/modules/security/index.d.cts +8 -0
  127. package/dist/modules/security/index.d.ts +8 -0
  128. package/dist/modules/security/index.js +480 -0
  129. package/dist/modules/security/index.js.map +1 -0
  130. package/dist/modules/store/index.cjs +450 -0
  131. package/dist/modules/store/index.cjs.map +1 -0
  132. package/dist/modules/store/index.d.cts +8 -0
  133. package/dist/modules/store/index.d.ts +8 -0
  134. package/dist/modules/store/index.js +401 -0
  135. package/dist/modules/store/index.js.map +1 -0
  136. package/dist/modules/support/index.cjs +285 -0
  137. package/dist/modules/support/index.cjs.map +1 -0
  138. package/dist/modules/support/index.d.cts +8 -0
  139. package/dist/modules/support/index.d.ts +8 -0
  140. package/dist/modules/support/index.js +236 -0
  141. package/dist/modules/support/index.js.map +1 -0
  142. package/dist/modules/tags/index.cjs +421 -0
  143. package/dist/modules/tags/index.cjs.map +1 -0
  144. package/dist/modules/tags/index.d.cts +8 -0
  145. package/dist/modules/tags/index.d.ts +8 -0
  146. package/dist/modules/tags/index.js +372 -0
  147. package/dist/modules/tags/index.js.map +1 -0
  148. package/dist/modules/tours/index.cjs +225 -0
  149. package/dist/modules/tours/index.cjs.map +1 -0
  150. package/dist/modules/tours/index.d.cts +8 -0
  151. package/dist/modules/tours/index.d.ts +8 -0
  152. package/dist/modules/tours/index.js +176 -0
  153. package/dist/modules/tours/index.js.map +1 -0
  154. package/dist/modules/vibecontrols/index.cjs +5551 -0
  155. package/dist/modules/vibecontrols/index.cjs.map +1 -0
  156. package/dist/modules/vibecontrols/index.d.cts +8 -0
  157. package/dist/modules/vibecontrols/index.d.ts +8 -0
  158. package/dist/modules/vibecontrols/index.js +4380 -0
  159. package/dist/modules/vibecontrols/index.js.map +1 -0
  160. package/dist/modules/workspaces/index.cjs +552 -0
  161. package/dist/modules/workspaces/index.cjs.map +1 -0
  162. package/dist/modules/workspaces/index.d.cts +8 -0
  163. package/dist/modules/workspaces/index.d.ts +8 -0
  164. package/dist/modules/workspaces/index.js +503 -0
  165. package/dist/modules/workspaces/index.js.map +1 -0
  166. package/dist/tool-name-CQf_IqAj.d.cts +47 -0
  167. package/dist/tool-name-DlnrBsZ6.d.ts +47 -0
  168. package/dist/transports/index.cjs +183 -0
  169. package/dist/transports/index.cjs.map +1 -0
  170. package/dist/transports/index.d.cts +13 -0
  171. package/dist/transports/index.d.ts +13 -0
  172. package/dist/transports/index.js +3 -0
  173. package/dist/transports/index.js.map +1 -0
  174. package/package.json +125 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,1013 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var os = require('os');
6
+ var graphqlRequest = require('graphql-request');
7
+ var fetch = require('cross-fetch');
8
+ var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
9
+ var types_js = require('@modelcontextprotocol/sdk/types.js');
10
+ var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
11
+ var crypto = require('crypto');
12
+ var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ var fetch__default = /*#__PURE__*/_interopDefault(fetch);
17
+
18
+ // src/core/auth/store.ts
19
+ var TOKEN_BUFFER_MS = 5 * 60 * 1e3;
20
+ function createAuthStore(configDir, authFileName2 = "auth.json") {
21
+ const authFile = path.join(configDir, authFileName2);
22
+ function ensureConfigDir() {
23
+ if (!fs.existsSync(configDir)) {
24
+ fs.mkdirSync(configDir, { recursive: true, mode: 448 });
25
+ }
26
+ }
27
+ function read() {
28
+ try {
29
+ if (!fs.existsSync(authFile)) return null;
30
+ const raw = fs.readFileSync(authFile, "utf8");
31
+ return JSON.parse(raw);
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+ function write(auth) {
37
+ ensureConfigDir();
38
+ fs.writeFileSync(authFile, JSON.stringify(auth, null, 2), { encoding: "utf8", mode: 384 });
39
+ try {
40
+ fs.chmodSync(authFile, 384);
41
+ } catch {
42
+ }
43
+ }
44
+ function clear() {
45
+ try {
46
+ if (fs.existsSync(authFile)) fs.unlinkSync(authFile);
47
+ } catch {
48
+ }
49
+ }
50
+ function isTokenExpired() {
51
+ const auth = read();
52
+ if (!auth?.expiresAt) return false;
53
+ return Date.now() >= auth.expiresAt;
54
+ }
55
+ function isTokenExpiringSoon() {
56
+ const auth = read();
57
+ if (!auth?.expiresAt) return false;
58
+ return Date.now() + TOKEN_BUFFER_MS >= auth.expiresAt;
59
+ }
60
+ function isWorkspaceTokenExpired() {
61
+ const auth = read();
62
+ if (!auth?.workspaceTokenExpiresAt) return false;
63
+ return Date.now() >= auth.workspaceTokenExpiresAt;
64
+ }
65
+ function isWorkspaceTokenExpiringSoon() {
66
+ const auth = read();
67
+ if (!auth?.workspaceTokenExpiresAt) return false;
68
+ return Date.now() + TOKEN_BUFFER_MS >= auth.workspaceTokenExpiresAt;
69
+ }
70
+ function isAuthenticated() {
71
+ const auth = read();
72
+ if (auth?.apiKey) return true;
73
+ if (!auth?.accessToken) return false;
74
+ return !isTokenExpired();
75
+ }
76
+ return {
77
+ read,
78
+ write,
79
+ clear,
80
+ isTokenExpired,
81
+ isTokenExpiringSoon,
82
+ isWorkspaceTokenExpired,
83
+ isWorkspaceTokenExpiringSoon,
84
+ isAuthenticated
85
+ };
86
+ }
87
+ function envOr(prefix, key, fallback) {
88
+ if (prefix) {
89
+ const prefixed = process.env[`${prefix}_${key}`];
90
+ if (prefixed !== void 0 && prefixed !== "") return prefixed;
91
+ }
92
+ const direct = process.env[key];
93
+ if (direct !== void 0 && direct !== "") return direct;
94
+ return fallback;
95
+ }
96
+ function createConfigStore(defaults) {
97
+ const configDir = path.join(os.homedir(), ".config", defaults.configDirName);
98
+ const configFile = path.join(configDir, "config.json");
99
+ const envPrefix = defaults.envPrefix ?? defaults.configDirName.toUpperCase().replace(/-/g, "_");
100
+ function ensureConfigDir() {
101
+ if (!fs.existsSync(configDir)) {
102
+ fs.mkdirSync(configDir, { recursive: true, mode: 448 });
103
+ }
104
+ }
105
+ function readPersisted() {
106
+ try {
107
+ if (!fs.existsSync(configFile)) return {};
108
+ const raw = fs.readFileSync(configFile, "utf8");
109
+ return JSON.parse(raw);
110
+ } catch {
111
+ return {};
112
+ }
113
+ }
114
+ function read() {
115
+ const persisted = readPersisted();
116
+ const workspaceEndpoint = envOr(envPrefix, "WORKSPACE_ENDPOINT") ?? persisted.workspaceEndpoint ?? defaults.workspaceEndpointDefault;
117
+ const globalEndpoint = envOr(envPrefix, "GLOBAL_ENDPOINT") ?? persisted.globalEndpoint ?? defaults.globalEndpointDefault;
118
+ const httpPortRaw = envOr(envPrefix, "HTTP_PORT") ?? envOr(void 0, "PORT") ?? String(defaults.httpPortDefault ?? 3e3);
119
+ const logLevelRaw = envOr(void 0, "LOG_LEVEL") ?? persisted.logLevel ?? "info";
120
+ const logFormatRaw = envOr(void 0, "LOG_FORMAT") ?? persisted.logFormat ?? "json";
121
+ return {
122
+ workspaceEndpoint,
123
+ globalEndpoint,
124
+ oidcIssuer: envOr(envPrefix, "OIDC_ISSUER") ?? persisted.oidcIssuer,
125
+ clientId: envOr(envPrefix, "CLIENT_ID") ?? persisted.clientId,
126
+ accessToken: envOr(envPrefix, "ACCESS_TOKEN"),
127
+ refreshToken: envOr(envPrefix, "REFRESH_TOKEN"),
128
+ workspaceToken: envOr(envPrefix, "WORKSPACE_TOKEN"),
129
+ apiKey: envOr(envPrefix, "API_KEY") ?? envOr(void 0, "MCP_API_KEY"),
130
+ workspaceId: envOr(envPrefix, "WORKSPACE_ID"),
131
+ organizationId: envOr(envPrefix, "ORGANIZATION_ID"),
132
+ host: envOr(void 0, "HOST") ?? envOr(void 0, "MCP_HOST") ?? defaults.hostDefault ?? "127.0.0.1",
133
+ httpPort: parseInt(httpPortRaw, 10) || (defaults.httpPortDefault ?? 3e3),
134
+ corsOrigins: envOr(void 0, "CORS_ORIGINS") ?? persisted.corsOrigins ?? "http://127.0.0.1,http://localhost",
135
+ allowedHosts: envOr(void 0, "ALLOWED_HOSTS") ?? persisted.allowedHosts ?? "127.0.0.1,localhost",
136
+ logLevel: ["error", "warn", "info", "debug"].includes(logLevelRaw) ? logLevelRaw : "info",
137
+ logFormat: logFormatRaw === "text" ? "text" : "json"
138
+ };
139
+ }
140
+ function write(patch) {
141
+ ensureConfigDir();
142
+ const merged = { ...readPersisted(), ...patch };
143
+ fs.writeFileSync(configFile, JSON.stringify(merged, null, 2), { encoding: "utf8" });
144
+ try {
145
+ fs.chmodSync(configFile, 384);
146
+ } catch {
147
+ }
148
+ }
149
+ function resolveOIDC() {
150
+ const config = read();
151
+ const clientId = config.clientId || defaults.oidcClientId;
152
+ let oidcIssuer = config.oidcIssuer;
153
+ if (!oidcIssuer) {
154
+ const globalEndpoint = config.globalEndpoint;
155
+ if (globalEndpoint.includes("localhost") || globalEndpoint.includes("127.0.0.1")) {
156
+ oidcIssuer = globalEndpoint.replace(/\/graphql$/, "").replace(/\/global\/graphql$/, "/global");
157
+ } else {
158
+ oidcIssuer = defaults.oidcIssuerProd ?? "https://graphql.burdenoff.com/global";
159
+ }
160
+ }
161
+ return { oidcIssuer, clientId };
162
+ }
163
+ return {
164
+ read,
165
+ write,
166
+ path: () => configFile,
167
+ dir: () => configDir,
168
+ resolveOIDC
169
+ };
170
+ }
171
+ async function clientCredentialsFlow(globalEndpoint, clientId, clientSecret, scopes) {
172
+ const query = `
173
+ mutation AuthenticateApp($input: AuthenticateAppInput!) {
174
+ authenticateApp(input: $input) {
175
+ accessToken tokenType expiresIn scopes
176
+ }
177
+ }
178
+ `;
179
+ const response = await fetch__default.default(globalEndpoint, {
180
+ method: "POST",
181
+ headers: { "Content-Type": "application/json" },
182
+ body: JSON.stringify({
183
+ query,
184
+ variables: { input: { clientId, clientSecret, scopes } }
185
+ })
186
+ });
187
+ if (!response.ok) {
188
+ const text = await response.text().catch(() => "Unknown error");
189
+ throw new Error(`App authentication failed (${response.status}): ${text}`);
190
+ }
191
+ const data = await response.json();
192
+ if (data.errors?.length) {
193
+ throw new Error(`App authentication failed: ${data.errors[0]?.message ?? "unknown error"}`);
194
+ }
195
+ if (!data.data?.authenticateApp?.accessToken) {
196
+ throw new Error("App authentication failed: no access token returned");
197
+ }
198
+ return data.data.authenticateApp;
199
+ }
200
+ async function issueWorkspaceToken(workspaceEndpoint, authToken, workspaceId, organizationId) {
201
+ const query = `
202
+ mutation IssueWorkspaceToken($input: IssueWorkspaceTokenInput!) {
203
+ issueWorkspaceToken(input: $input) {
204
+ success token expiresAt scopes
205
+ error { code message }
206
+ }
207
+ }
208
+ `;
209
+ const response = await fetch__default.default(workspaceEndpoint, {
210
+ method: "POST",
211
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${authToken}` },
212
+ body: JSON.stringify({ query, variables: { input: { workspaceId, organizationId } } })
213
+ });
214
+ if (!response.ok) {
215
+ const text = await response.text().catch(() => "Unknown error");
216
+ throw new Error(`Workspace token request failed (${response.status}): ${text}`);
217
+ }
218
+ const data = await response.json();
219
+ if (data.errors?.length) {
220
+ throw new Error(`Workspace token failed: ${data.errors[0]?.message ?? "unknown error"}`);
221
+ }
222
+ const result = data.data?.issueWorkspaceToken;
223
+ if (!result?.success || !result.token) {
224
+ throw new Error(`Workspace token failed: ${result?.error?.message ?? "Unknown error"}`);
225
+ }
226
+ return { token: result.token, expiresAt: result.expiresAt ?? "", scopes: result.scopes ?? [] };
227
+ }
228
+
229
+ // src/core/gql/client.ts
230
+ var DEFAULT_TIMEOUT = 3e4;
231
+ var MAX_RETRIES = 3;
232
+ var INITIAL_RETRY_DELAY_MS = 1e3;
233
+ function sleep(ms) {
234
+ return new Promise((resolve) => setTimeout(resolve, ms));
235
+ }
236
+ function isNetworkOrServerError(error) {
237
+ if (error instanceof TypeError) return true;
238
+ if (error && typeof error === "object" && "response" in error) {
239
+ const resp = error.response;
240
+ if (resp && typeof resp.status === "number" && resp.status >= 500) return true;
241
+ }
242
+ return false;
243
+ }
244
+ function extractGqlErrorMessage(error) {
245
+ if (error && typeof error === "object" && "response" in error) {
246
+ const resp = error;
247
+ const firstError = resp.response?.errors?.[0];
248
+ if (firstError?.message) return firstError.message;
249
+ if (resp.message) return resp.message;
250
+ }
251
+ if (error instanceof Error) return error.message;
252
+ return String(error);
253
+ }
254
+ function getHeaders(auth) {
255
+ const headers = {};
256
+ if (auth?.apiKey) headers["X-API-Key"] = auth.apiKey;
257
+ if (auth?.accessToken) headers["Authorization"] = `Bearer ${auth.accessToken}`;
258
+ if (auth?.organizationId) headers["x-org-id"] = auth.organizationId;
259
+ return headers;
260
+ }
261
+ function getWorkspaceHeaders(auth) {
262
+ const headers = getHeaders(auth);
263
+ if (auth?.workspaceToken) {
264
+ headers["X-Workspace-Authorization"] = `Bearer ${auth.workspaceToken}`;
265
+ }
266
+ if (auth?.workspaceId) headers["x-workspace-id"] = auth.workspaceId;
267
+ return headers;
268
+ }
269
+ async function executeWithRetry(client, document, variables) {
270
+ let lastError;
271
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
272
+ try {
273
+ const controller = new AbortController();
274
+ const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
275
+ try {
276
+ return await client.request({ document, variables, signal: controller.signal });
277
+ } finally {
278
+ clearTimeout(timer);
279
+ }
280
+ } catch (error) {
281
+ lastError = error;
282
+ if (error && typeof error === "object" && "response" in error) {
283
+ const resp = error.response;
284
+ if (resp && typeof resp.status === "number" && resp.status >= 400 && resp.status < 500) {
285
+ break;
286
+ }
287
+ }
288
+ if (isNetworkOrServerError(error) && attempt < MAX_RETRIES - 1) {
289
+ const delay = INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt);
290
+ await sleep(delay);
291
+ continue;
292
+ }
293
+ break;
294
+ }
295
+ }
296
+ throw new Error(extractGqlErrorMessage(lastError));
297
+ }
298
+ function createGqlClients(config, authStore) {
299
+ let workspaceClient = null;
300
+ let globalClient = null;
301
+ function init() {
302
+ const cfg = config.read();
303
+ const auth = authStore.read();
304
+ workspaceClient = new graphqlRequest.GraphQLClient(cfg.workspaceEndpoint);
305
+ workspaceClient.setHeaders(getWorkspaceHeaders(auth));
306
+ globalClient = new graphqlRequest.GraphQLClient(cfg.globalEndpoint);
307
+ globalClient.setHeaders(getHeaders(auth));
308
+ return { workspace: workspaceClient, global: globalClient };
309
+ }
310
+ async function refreshPlatformToken() {
311
+ const auth = authStore.read();
312
+ if (!auth) return;
313
+ if (auth.authMethod === "client_credentials" && auth.clientId && auth.clientSecret) {
314
+ const cfg2 = config.read();
315
+ try {
316
+ const result = await clientCredentialsFlow(
317
+ cfg2.globalEndpoint,
318
+ auth.clientId,
319
+ auth.clientSecret
320
+ );
321
+ authStore.write({
322
+ ...auth,
323
+ accessToken: result.accessToken,
324
+ expiresAt: Date.now() + result.expiresIn * 1e3
325
+ });
326
+ workspaceClient = null;
327
+ globalClient = null;
328
+ } catch {
329
+ }
330
+ return;
331
+ }
332
+ if (!auth.refreshToken) return;
333
+ const cfg = config.read();
334
+ const client = new graphqlRequest.GraphQLClient(cfg.globalEndpoint);
335
+ client.setHeaders({ Authorization: `Bearer ${auth.accessToken}` });
336
+ const REFRESH_MUTATION = `
337
+ mutation RefreshToken($token: String!) {
338
+ refreshToken(token: $token) { accessToken refreshToken expiresIn }
339
+ }
340
+ `;
341
+ try {
342
+ const data = await client.request(REFRESH_MUTATION, {
343
+ token: auth.refreshToken
344
+ });
345
+ authStore.write({
346
+ ...auth,
347
+ accessToken: data.refreshToken.accessToken,
348
+ refreshToken: data.refreshToken.refreshToken,
349
+ expiresAt: Date.now() + data.refreshToken.expiresIn * 1e3
350
+ });
351
+ workspaceClient = null;
352
+ globalClient = null;
353
+ } catch {
354
+ }
355
+ }
356
+ async function refreshWorkspaceToken() {
357
+ const auth = authStore.read();
358
+ if (!auth?.accessToken || !auth.workspaceId || !auth.organizationId) return;
359
+ const cfg = config.read();
360
+ try {
361
+ const result = await issueWorkspaceToken(
362
+ cfg.workspaceEndpoint,
363
+ auth.accessToken,
364
+ auth.workspaceId,
365
+ auth.organizationId
366
+ );
367
+ authStore.write({
368
+ ...auth,
369
+ workspaceToken: result.token,
370
+ workspaceTokenExpiresAt: new Date(result.expiresAt).getTime()
371
+ });
372
+ workspaceClient = null;
373
+ } catch {
374
+ }
375
+ }
376
+ async function ensureFreshTokens() {
377
+ const initial = authStore.read();
378
+ if (initial?.apiKey) return;
379
+ if (authStore.isTokenExpiringSoon()) {
380
+ await refreshPlatformToken();
381
+ }
382
+ if (authStore.isWorkspaceTokenExpiringSoon()) {
383
+ await refreshWorkspaceToken();
384
+ }
385
+ }
386
+ const workspace = {
387
+ async request(document, variables) {
388
+ await ensureFreshTokens();
389
+ const { workspace: ws } = workspaceClient ? { workspace: workspaceClient } : init();
390
+ ws.setHeaders(getWorkspaceHeaders(authStore.read()));
391
+ return executeWithRetry(ws, document, variables);
392
+ }
393
+ };
394
+ const global = {
395
+ async request(document, variables) {
396
+ const { global: g } = globalClient ? { global: globalClient } : init();
397
+ g.setHeaders(getHeaders(authStore.read()));
398
+ return executeWithRetry(g, document, variables);
399
+ }
400
+ };
401
+ const workspaceAuthOnly = {
402
+ async request(document, variables) {
403
+ const cfg = config.read();
404
+ const auth = authStore.read();
405
+ const client = new graphqlRequest.GraphQLClient(cfg.workspaceEndpoint);
406
+ client.setHeaders(getHeaders(auth));
407
+ return executeWithRetry(client, document, variables);
408
+ }
409
+ };
410
+ return {
411
+ workspace,
412
+ global,
413
+ workspaceAuthOnly,
414
+ reset() {
415
+ workspaceClient = null;
416
+ globalClient = null;
417
+ }
418
+ };
419
+ }
420
+
421
+ // src/core/logger.ts
422
+ var LEVEL_RANK = {
423
+ error: 0,
424
+ warn: 1,
425
+ info: 2,
426
+ debug: 3
427
+ };
428
+ function createLogger(opts = {}) {
429
+ let level = opts.level ?? process.env.LOG_LEVEL ?? "info";
430
+ const format = opts.format ?? process.env.LOG_FORMAT ?? "json";
431
+ function shouldLog(target) {
432
+ return LEVEL_RANK[target] <= LEVEL_RANK[level];
433
+ }
434
+ function formatMessage(target, message, context) {
435
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
436
+ if (format === "json") {
437
+ return JSON.stringify({ timestamp, level: target, message, ...context });
438
+ }
439
+ const contextStr = context ? ` ${JSON.stringify(context)}` : "";
440
+ return `[${timestamp}] ${target.toUpperCase()}: ${message}${contextStr}`;
441
+ }
442
+ function emit(target, message, context) {
443
+ if (!shouldLog(target)) return;
444
+ process.stderr.write(formatMessage(target, message, context) + "\n");
445
+ }
446
+ return {
447
+ error(message, context) {
448
+ emit("error", message, context);
449
+ },
450
+ warn(message, context) {
451
+ emit("warn", message, context);
452
+ },
453
+ info(message, context) {
454
+ emit("info", message, context);
455
+ },
456
+ debug(message, context) {
457
+ emit("debug", message, context);
458
+ },
459
+ setLevel(newLevel) {
460
+ level = newLevel;
461
+ },
462
+ getLevel() {
463
+ return level;
464
+ }
465
+ };
466
+ }
467
+
468
+ // src/core/progress.ts
469
+ function createProgress(serverRef) {
470
+ return (token, current, total, message) => {
471
+ if (token === void 0 || token === null) return;
472
+ const server = serverRef.current;
473
+ if (!server) return;
474
+ try {
475
+ const params = { progressToken: token, progress: current };
476
+ if (total !== void 0) params.total = total;
477
+ if (message !== void 0) params.message = message;
478
+ const inner = server.server ?? server;
479
+ inner.notification?.({ method: "notifications/progress", params });
480
+ } catch {
481
+ }
482
+ };
483
+ }
484
+
485
+ // src/core/context.ts
486
+ function inferEnv(workspaceEndpoint) {
487
+ if (workspaceEndpoint.includes("localhost") || workspaceEndpoint.includes("127.0.0.1")) {
488
+ return "local";
489
+ }
490
+ if (workspaceEndpoint.includes("alpha")) return "alpha";
491
+ return "prod";
492
+ }
493
+ function isLogger(value) {
494
+ return !!value && typeof value.debug === "function" && typeof value.info === "function";
495
+ }
496
+ function buildContext(opts) {
497
+ const config = createConfigStore(opts.defaults);
498
+ const cfg = config.read();
499
+ const logger = isLogger(opts.logger) ? opts.logger : createLogger({
500
+ ...opts.logger,
501
+ level: cfg.logLevel,
502
+ format: cfg.logFormat
503
+ });
504
+ const auth = createAuthStore(
505
+ opts.tokenStorePath ? dirOf(opts.tokenStorePath) : config.dir(),
506
+ authFileName(opts.tokenStorePath)
507
+ );
508
+ const existing = auth.read();
509
+ if (!existing && (cfg.accessToken || cfg.apiKey)) {
510
+ auth.write({
511
+ accessToken: cfg.accessToken ?? "",
512
+ refreshToken: cfg.refreshToken ?? "",
513
+ ...cfg.workspaceToken ? { workspaceToken: cfg.workspaceToken } : {},
514
+ ...cfg.workspaceId ? { workspaceId: cfg.workspaceId } : {},
515
+ ...cfg.organizationId ? { organizationId: cfg.organizationId } : {},
516
+ ...cfg.apiKey ? { apiKey: cfg.apiKey, authMethod: "api_key" } : {}
517
+ });
518
+ }
519
+ const gql = createGqlClients(config, auth);
520
+ const env = opts.env ?? inferEnv(cfg.workspaceEndpoint);
521
+ const serverRef = { current: null };
522
+ const progress = createProgress(serverRef);
523
+ return {
524
+ productName: opts.productName,
525
+ productVersion: opts.productVersion,
526
+ serverName: opts.serverName,
527
+ serverVersion: opts.serverVersion,
528
+ defaults: opts.defaults,
529
+ config,
530
+ auth,
531
+ gql,
532
+ logger,
533
+ progress,
534
+ env,
535
+ _internal: { serverRef }
536
+ };
537
+ }
538
+ function dirOf(p) {
539
+ const lastSlash = p.lastIndexOf("/");
540
+ return lastSlash > 0 ? p.slice(0, lastSlash) : p;
541
+ }
542
+ function authFileName(p) {
543
+ if (!p) return void 0;
544
+ const lastSlash = p.lastIndexOf("/");
545
+ return lastSlash >= 0 ? p.slice(lastSlash + 1) : p;
546
+ }
547
+
548
+ // src/core/errors.ts
549
+ var McpUserError = class extends Error {
550
+ hint;
551
+ constructor(message, opts) {
552
+ super(message);
553
+ this.name = "McpUserError";
554
+ this.hint = opts?.hint;
555
+ }
556
+ };
557
+ var McpAuthError = class extends McpUserError {
558
+ constructor(message, opts) {
559
+ super(message, {
560
+ hint: opts?.hint ?? "Run the auth_login tool to authenticate."
561
+ });
562
+ this.name = "McpAuthError";
563
+ }
564
+ };
565
+ var McpInternalError = class extends Error {
566
+ cause;
567
+ constructor(message, cause) {
568
+ super(message);
569
+ this.name = "McpInternalError";
570
+ this.cause = cause;
571
+ }
572
+ };
573
+
574
+ // src/core/module.ts
575
+ var MissingDependencyError = class extends McpInternalError {
576
+ constructor(moduleId, missingDep) {
577
+ super(
578
+ `Module '${moduleId}' declares dependency on '${missingDep}', but '${missingDep}' is not in the module list.`
579
+ );
580
+ this.name = "MissingDependencyError";
581
+ }
582
+ };
583
+ var CircularDependencyError = class extends McpInternalError {
584
+ constructor(cycle) {
585
+ super(`Circular dependency detected among modules: ${cycle.join(" -> ")}`);
586
+ this.name = "CircularDependencyError";
587
+ }
588
+ };
589
+ function sortModules(modules) {
590
+ const byId = /* @__PURE__ */ new Map();
591
+ for (const m of modules) {
592
+ if (byId.has(m.id)) {
593
+ throw new McpInternalError(`Duplicate module id: '${m.id}'`);
594
+ }
595
+ byId.set(m.id, m);
596
+ }
597
+ for (const m of modules) {
598
+ for (const dep of m.dependsOn ?? []) {
599
+ if (!byId.has(dep)) {
600
+ throw new MissingDependencyError(m.id, dep);
601
+ }
602
+ }
603
+ }
604
+ const sorted = [];
605
+ const visiting = /* @__PURE__ */ new Set();
606
+ const visited = /* @__PURE__ */ new Set();
607
+ function visit(m, path) {
608
+ if (visited.has(m.id)) return;
609
+ if (visiting.has(m.id)) {
610
+ throw new CircularDependencyError([...path, m.id]);
611
+ }
612
+ visiting.add(m.id);
613
+ for (const dep of m.dependsOn ?? []) {
614
+ const depModule = byId.get(dep);
615
+ if (depModule) visit(depModule, [...path, m.id]);
616
+ }
617
+ visiting.delete(m.id);
618
+ visited.add(m.id);
619
+ sorted.push(m);
620
+ }
621
+ for (const m of modules) {
622
+ visit(m, []);
623
+ }
624
+ return sorted;
625
+ }
626
+
627
+ // src/core/capabilities.ts
628
+ function unionCapabilities(caps) {
629
+ const out = {};
630
+ for (const cap of caps) {
631
+ if (!cap) continue;
632
+ if (cap.resources) {
633
+ out.resources ??= {};
634
+ if (cap.resources.subscribe) out.resources.subscribe = true;
635
+ if (cap.resources.listChanged) out.resources.listChanged = true;
636
+ }
637
+ if (cap.prompts) {
638
+ out.prompts ??= {};
639
+ if (cap.prompts.listChanged) out.prompts.listChanged = true;
640
+ }
641
+ if (cap.tools) {
642
+ out.tools ??= {};
643
+ if (cap.tools.listChanged) out.tools.listChanged = true;
644
+ }
645
+ if (cap.logging) out.logging = true;
646
+ if (cap.completions) out.completions = true;
647
+ }
648
+ return out;
649
+ }
650
+ function toServerCapabilities(caps) {
651
+ const out = {};
652
+ if (caps.tools) out.tools = caps.tools;
653
+ if (caps.resources) out.resources = caps.resources;
654
+ if (caps.prompts) out.prompts = caps.prompts;
655
+ if (caps.logging) out.logging = {};
656
+ if (caps.completions) out.completions = {};
657
+ return out;
658
+ }
659
+
660
+ // src/core/server.ts
661
+ var MCP_TO_LOGGER_LEVEL = {
662
+ debug: "debug",
663
+ info: "info",
664
+ notice: "info",
665
+ warning: "warn",
666
+ error: "error",
667
+ critical: "error",
668
+ alert: "error",
669
+ emergency: "error"
670
+ };
671
+ function createMcpServer(ctx, modules, opts) {
672
+ const sorted = sortModules(modules);
673
+ const baseCapabilities = { logging: true };
674
+ const capabilities = unionCapabilities([
675
+ baseCapabilities,
676
+ ...sorted.map((m) => m.capabilities),
677
+ opts.extraCapabilities
678
+ ]);
679
+ const server = new mcp_js.McpServer(
680
+ { name: opts.name, version: opts.version },
681
+ { capabilities: toServerCapabilities(capabilities) }
682
+ );
683
+ ctx._internal.serverRef.current = server;
684
+ const inner = server.server ?? server;
685
+ if (typeof inner.setRequestHandler === "function") {
686
+ inner.setRequestHandler(
687
+ types_js.SetLevelRequestSchema,
688
+ async (req) => {
689
+ const target = MCP_TO_LOGGER_LEVEL[req.params.level] ?? "info";
690
+ ctx.logger.setLevel(target);
691
+ ctx.logger.info("MCP logging level set", { level: req.params.level, mapped: target });
692
+ return {};
693
+ }
694
+ );
695
+ }
696
+ const tools = [];
697
+ const resources = [];
698
+ const prompts = [];
699
+ const moduleManifest = [];
700
+ for (const mod of sorted) {
701
+ try {
702
+ const reg = mod.register(server, ctx);
703
+ tools.push(...reg.tools);
704
+ resources.push(...reg.resources);
705
+ prompts.push(...reg.prompts);
706
+ moduleManifest.push({ id: mod.id, version: mod.version });
707
+ ctx.logger.debug(`Registered module: ${mod.id}`, {
708
+ tools: reg.tools.length,
709
+ resources: reg.resources.length,
710
+ prompts: reg.prompts.length
711
+ });
712
+ } catch (error) {
713
+ ctx.logger.error(`Failed to register module: ${mod.id}`, {
714
+ error: error instanceof Error ? error.message : String(error)
715
+ });
716
+ throw error;
717
+ }
718
+ }
719
+ const manifest = {
720
+ modules: moduleManifest,
721
+ tools,
722
+ resources,
723
+ prompts
724
+ };
725
+ ctx.logger.info(`MCP server ready: ${opts.name}@${opts.version}`, {
726
+ modules: manifest.modules.length,
727
+ tools: manifest.tools.length,
728
+ resources: manifest.resources.length,
729
+ prompts: manifest.prompts.length
730
+ });
731
+ return { server, manifest };
732
+ }
733
+
734
+ // src/core/result.ts
735
+ function jsonResult(data, structured) {
736
+ const result = {
737
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
738
+ };
739
+ if (structured !== void 0) {
740
+ result.structuredContent = structured;
741
+ }
742
+ return result;
743
+ }
744
+ function textResult(text) {
745
+ return { content: [{ type: "text", text }] };
746
+ }
747
+ function errorResult(message, hint) {
748
+ const text = hint ? `${message}
749
+
750
+ Hint: ${hint}` : message;
751
+ return { content: [{ type: "text", text }], isError: true };
752
+ }
753
+ function registerTool(server, ctx, name, metadata, handler) {
754
+ const sdkConfig = {
755
+ title: metadata.title,
756
+ description: metadata.description,
757
+ ...metadata.inputSchema ? { inputSchema: metadata.inputSchema } : {}
758
+ };
759
+ const wrapped = async (...callbackArgs) => {
760
+ const hasArgs = callbackArgs.length === 2;
761
+ const args = hasArgs ? callbackArgs[0] : {};
762
+ const extra = hasArgs ? callbackArgs[1] : callbackArgs[0];
763
+ const progressToken = extra?._meta?.progressToken;
764
+ const meta = progressToken !== void 0 ? { progressToken } : {};
765
+ try {
766
+ const result = await handler(args, ctx, meta);
767
+ if (isToolResult(result)) return result;
768
+ if (result === void 0) return textResult("OK");
769
+ return jsonResult(result);
770
+ } catch (error) {
771
+ return mapErrorToResult(error, ctx, name);
772
+ }
773
+ };
774
+ server.registerTool(name, sdkConfig, wrapped);
775
+ }
776
+ function isToolResult(value) {
777
+ return !!value && typeof value === "object" && "content" in value && Array.isArray(value.content);
778
+ }
779
+ function mapErrorToResult(error, ctx, toolName) {
780
+ if (error instanceof McpAuthError) {
781
+ ctx.logger.warn(`${toolName}: auth required`, { message: error.message });
782
+ return errorResult(error.message, error.hint);
783
+ }
784
+ if (error instanceof McpUserError) {
785
+ ctx.logger.info(`${toolName}: user error`, { message: error.message });
786
+ return errorResult(error.message, error.hint);
787
+ }
788
+ if (error instanceof McpInternalError) {
789
+ ctx.logger.error(`${toolName}: internal error`, {
790
+ message: error.message,
791
+ cause: stringifyCause(error.cause)
792
+ });
793
+ return errorResult(`Internal error in ${toolName}.`);
794
+ }
795
+ const message = error instanceof Error ? error.message : String(error);
796
+ ctx.logger.error(`${toolName}: unhandled error`, { message });
797
+ return errorResult(`${toolName}: ${message}`);
798
+ }
799
+ function stringifyCause(cause) {
800
+ if (cause === void 0 || cause === null) return void 0;
801
+ if (cause instanceof Error) return cause.message;
802
+ try {
803
+ return JSON.stringify(cause);
804
+ } catch {
805
+ return String(cause);
806
+ }
807
+ }
808
+
809
+ // src/core/tool-name.ts
810
+ var MAX_TOOL_NAME_LENGTH = 63;
811
+ function assertSafeName(name, kind) {
812
+ if (name.length > MAX_TOOL_NAME_LENGTH) {
813
+ throw new McpInternalError(
814
+ `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`
815
+ );
816
+ }
817
+ return name;
818
+ }
819
+ function mcpToolName(productName, ...parts) {
820
+ if (!productName) {
821
+ throw new McpInternalError("mcpToolName: productName is required");
822
+ }
823
+ const name = [productName, ...parts].filter(Boolean).join("_");
824
+ return assertSafeName(name);
825
+ }
826
+ function mcpResourceUri(productName, ...parts) {
827
+ if (!productName) {
828
+ throw new McpInternalError("mcpResourceUri: productName is required");
829
+ }
830
+ return `${productName}://${parts.filter(Boolean).join("/")}`;
831
+ }
832
+ function mcpPromptName(productName, ...parts) {
833
+ if (!productName) {
834
+ throw new McpInternalError("mcpPromptName: productName is required");
835
+ }
836
+ return [productName, ...parts].filter(Boolean).join("-");
837
+ }
838
+ async function startStdioServer(server, ctx, _opts = {}) {
839
+ ctx.logger.info("Starting MCP server with stdio transport", {
840
+ name: ctx.serverName,
841
+ version: ctx.serverVersion
842
+ });
843
+ const transport = new stdio_js.StdioServerTransport();
844
+ await server.connect(transport);
845
+ ctx.logger.info("MCP stdio server started");
846
+ }
847
+
848
+ // src/transports/security.ts
849
+ var SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
850
+ function parseCorsOrigins(origins) {
851
+ if (Array.isArray(origins)) return origins;
852
+ const value = origins?.trim();
853
+ if (!value || value === "*") {
854
+ return ["http://127.0.0.1", "http://localhost"];
855
+ }
856
+ return value.split(",").map((origin) => origin.trim()).filter(Boolean);
857
+ }
858
+ function isAuthorizedRequest(req, apiKey) {
859
+ return req.headers.authorization === `Bearer ${apiKey}` || req.headers["x-api-key"] === apiKey;
860
+ }
861
+ function requireAuthorizedRequest(req, res, apiKey) {
862
+ if (!apiKey) {
863
+ res.status(503).json({ error: "Transport authentication is not configured" });
864
+ return false;
865
+ }
866
+ if (!isAuthorizedRequest(req, apiKey)) {
867
+ res.status(401).json({ error: "Unauthorized" });
868
+ return false;
869
+ }
870
+ return true;
871
+ }
872
+ function isValidSessionId(sessionId) {
873
+ return SESSION_ID_PATTERN.test(sessionId);
874
+ }
875
+
876
+ // src/transports/http.ts
877
+ async function createHttpApp(ctx, createServerFn, options = {}) {
878
+ const expressMod = await import('express');
879
+ const corsMod = await import('cors');
880
+ const express = expressMod.default ?? expressMod;
881
+ const cors = corsMod.default ?? corsMod;
882
+ const cfg = ctx.config.read();
883
+ const app = express();
884
+ app.use(express.json());
885
+ if (options.enableCors !== false) {
886
+ const corsOrigins = options.corsOrigins ?? cfg.corsOrigins;
887
+ app.use(
888
+ cors({
889
+ origin: parseCorsOrigins(corsOrigins),
890
+ exposedHeaders: ["Mcp-Session-Id"],
891
+ allowedHeaders: ["Content-Type", "Authorization", "X-API-Key", "mcp-session-id"]
892
+ })
893
+ );
894
+ }
895
+ const transports = {};
896
+ const apiKey = options.apiKey ?? cfg.apiKey;
897
+ app.post("/mcp", async (req, res) => {
898
+ if (!requireAuthorizedRequest(req, res, apiKey)) return;
899
+ try {
900
+ const sessionId = req.headers["mcp-session-id"];
901
+ let transport;
902
+ if (sessionId && !isValidSessionId(sessionId)) {
903
+ res.status(400).json({
904
+ jsonrpc: "2.0",
905
+ error: { code: -32e3, message: "Bad Request: Invalid session ID provided" },
906
+ id: null
907
+ });
908
+ return;
909
+ }
910
+ if (sessionId && transports[sessionId]) {
911
+ transport = transports[sessionId];
912
+ } else if (!sessionId && types_js.isInitializeRequest(req.body)) {
913
+ transport = new streamableHttp_js.StreamableHTTPServerTransport({
914
+ sessionIdGenerator: () => crypto.randomUUID(),
915
+ onsessioninitialized: (sid) => {
916
+ transports[sid] = transport;
917
+ ctx.logger.info("New MCP session initialized", { sessionId: sid });
918
+ },
919
+ enableDnsRebindingProtection: options.enableDnsRebindingProtection ?? true,
920
+ allowedHosts: options.allowedHosts ?? cfg.allowedHosts.split(",")
921
+ });
922
+ transport.onclose = () => {
923
+ if (transport.sessionId) {
924
+ delete transports[transport.sessionId];
925
+ ctx.logger.info("MCP session closed", { sessionId: transport.sessionId });
926
+ }
927
+ };
928
+ const server = createServerFn();
929
+ await server.connect(transport);
930
+ } else {
931
+ res.status(400).json({
932
+ jsonrpc: "2.0",
933
+ error: { code: -32e3, message: "Bad Request: No valid session ID provided" },
934
+ id: null
935
+ });
936
+ return;
937
+ }
938
+ await transport.handleRequest(req, res, req.body);
939
+ } catch (error) {
940
+ ctx.logger.error("Error handling MCP request", {
941
+ error: error instanceof Error ? error.message : String(error)
942
+ });
943
+ if (!res.headersSent) {
944
+ res.status(500).json({
945
+ jsonrpc: "2.0",
946
+ error: { code: -32603, message: "Internal server error" },
947
+ id: null
948
+ });
949
+ }
950
+ }
951
+ });
952
+ const handleSessionRequest = async (req, res) => {
953
+ if (!requireAuthorizedRequest(req, res, apiKey)) return;
954
+ const sessionId = req.headers["mcp-session-id"];
955
+ if (!sessionId || !isValidSessionId(sessionId) || !transports[sessionId]) {
956
+ res.status(400).send("Invalid or missing session ID");
957
+ return;
958
+ }
959
+ await transports[sessionId].handleRequest(req, res);
960
+ };
961
+ app.get("/mcp", handleSessionRequest);
962
+ app.delete("/mcp", handleSessionRequest);
963
+ app.get("/health", (_req, res) => {
964
+ res.json({
965
+ status: "healthy",
966
+ server: ctx.serverName,
967
+ version: ctx.serverVersion,
968
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
969
+ uptime: process.uptime(),
970
+ activeSessions: Object.keys(transports).length
971
+ });
972
+ });
973
+ return app;
974
+ }
975
+ async function startHttpServer(ctx, createServerFn, options = {}) {
976
+ const cfg = ctx.config.read();
977
+ const port = options.port ?? cfg.httpPort;
978
+ const host = options.host ?? cfg.host;
979
+ ctx.logger.info("Starting MCP server with HTTP transport", {
980
+ port,
981
+ host,
982
+ name: ctx.serverName,
983
+ version: ctx.serverVersion
984
+ });
985
+ const app = await createHttpApp(ctx, createServerFn, options);
986
+ await new Promise((resolve, reject) => {
987
+ const server = app.listen(port, host, (err) => {
988
+ if (err) reject(err);
989
+ else {
990
+ ctx.logger.info("MCP HTTP server started", { port, host });
991
+ resolve();
992
+ }
993
+ });
994
+ server.on("error", reject);
995
+ });
996
+ }
997
+
998
+ exports.McpAuthError = McpAuthError;
999
+ exports.McpInternalError = McpInternalError;
1000
+ exports.McpUserError = McpUserError;
1001
+ exports.buildContext = buildContext;
1002
+ exports.createMcpServer = createMcpServer;
1003
+ exports.errorResult = errorResult;
1004
+ exports.jsonResult = jsonResult;
1005
+ exports.mcpPromptName = mcpPromptName;
1006
+ exports.mcpResourceUri = mcpResourceUri;
1007
+ exports.mcpToolName = mcpToolName;
1008
+ exports.registerTool = registerTool;
1009
+ exports.startHttpServer = startHttpServer;
1010
+ exports.startStdioServer = startStdioServer;
1011
+ exports.textResult = textResult;
1012
+ //# sourceMappingURL=index.cjs.map
1013
+ //# sourceMappingURL=index.cjs.map