ostacky 0.9.3 → 0.9.5
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 +27 -25
- package/assets/agents/ostacky.md +5 -4
- package/assets/commands/install-stack.md +2 -2
- package/assets/mcp/ostacky-controller/bun.lock +20 -0
- package/assets/mcp/ostacky-controller/index.js +185 -29
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-B2Q9_Vxp.d.cts → auth--n_Yzytt.d.cts} +14 -9
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-CVhIKulL.d.mts.map → auth--n_Yzytt.d.cts.map} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-CfDMXiII.cjs → auth-4-zilcqg.cjs} +3 -2
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/auth-4-zilcqg.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-CUe6YdwF.mjs → auth-CGP0BDVq.mjs} +3 -2
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/auth-CGP0BDVq.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-CVhIKulL.d.mts → auth-YUQV3RRv.d.mts} +14 -9
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/{auth-B2Q9_Vxp.d.cts.map → auth-YUQV3RRv.d.mts.map} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/index.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/index.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/index.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/index.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/internal.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/internal.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/internal.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/internal.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/package.json +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/README.md +3 -3
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-CplOkyLC.mjs → ajvProvider-CEoC__sr.mjs} +483 -38
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CEoC__sr.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-BdSo9BII.d.mts → ajvProvider-CgI-5L6O.d.mts} +25 -8
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-BdSo9BII.d.mts.map → ajvProvider-CgI-5L6O.d.mts.map} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-B_4czhCS.d.cts → ajvProvider-FOQRM7up.d.cts} +24 -7
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-B_4czhCS.d.cts.map → ajvProvider-FOQRM7up.d.cts.map} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{ajvProvider-Brn-Q2J_.cjs → ajvProvider-ZaoO9afR.cjs} +483 -38
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/ajvProvider-ZaoO9afR.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{cfWorkerProvider-ojcZaap3.cjs → cfWorkerProvider-BwbPzsdI.cjs} +25 -15
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-BwbPzsdI.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{cfWorkerProvider-BYRW5af5.d.mts → cfWorkerProvider-C03CSigr.d.mts} +21 -6
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-C03CSigr.d.mts.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{cfWorkerProvider-D9GAttn8.d.cts → cfWorkerProvider-doTkZbTr.d.cts} +20 -5
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-doTkZbTr.d.cts.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{cfWorkerProvider-Bd-iTHAF.mjs → cfWorkerProvider-p3WaZPqB.mjs} +26 -15
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-p3WaZPqB.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{createMcpHandler-DzBzpE4_.d.cts → createMcpHandler-BLVe3qmU.d.cts} +137 -32
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-BLVe3qmU.d.cts.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{createMcpHandler-CEckaSEs.d.mts → createMcpHandler-Bt6U_Fqb.d.mts} +138 -33
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-Bt6U_Fqb.d.mts.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/dialects-D8eXzoGv.cjs +46 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/dialects-D8eXzoGv.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs +34 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.cjs +209 -257
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.cjs.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.d.cts +45 -3
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.d.cts.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.d.mts +46 -4
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.d.mts.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.mjs +201 -252
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/index.mjs.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{mcp-DM1iHYFo.cjs → mcp-DUcCQSTW.cjs} +458 -35
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/mcp-DUcCQSTW.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{mcp-IJurDZVN.mjs → mcp-Dw2OlZ1f.mjs} +389 -32
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/mcp-Dw2OlZ1f.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsNode.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsNode.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsNode.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.cjs +2 -2
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.mjs +2 -2
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{src-BX_fm-dB.cjs → src-CgFsfg3E.cjs} +161 -48
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/src-CgFsfg3E.cjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{src-D86MbS1I.mjs → src-D-y6h4N7.mjs} +161 -48
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/src-D-y6h4N7.mjs.map +1 -0
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.cjs +30 -3
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.cjs.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.d.cts +9 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.d.cts.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.d.mts +9 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.d.mts.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.mjs +30 -3
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/stdio.mjs.map +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{types-mS0yxCL0.d.mts → types-DUs7mGBv.d.mts} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/{types-mS0yxCL0.d.mts.map → types-DUs7mGBv.d.mts.map} +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/ajv.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/ajv.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/ajv.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/ajv.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.cjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.d.cts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.d.mts +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.mjs +1 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/package.json +4 -4
- package/assets/mcp/ostacky-controller/package.json +1 -1
- package/assets/plugins/ostacky-controller/index.ts +53 -11
- package/dist/cli.js +93 -53
- package/manifest.json +28 -28
- package/package.json +5 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/auth-CUe6YdwF.mjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/core/dist/auth-CfDMXiII.cjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/ajvProvider-Brn-Q2J_.cjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CplOkyLC.mjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-BYRW5af5.d.mts.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-Bd-iTHAF.mjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-D9GAttn8.d.cts.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-ojcZaap3.cjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-CEckaSEs.d.mts.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-DzBzpE4_.d.cts.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/mcp-DM1iHYFo.cjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/mcp-IJurDZVN.mjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/src-BX_fm-dB.cjs.map +0 -1
- package/assets/mcp/ostacky-controller/node_modules/@modelcontextprotocol/server/dist/src-D86MbS1I.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as promptArgumentsFromStandardSchema, At as LATEST_PROTOCOL_VERSION, B as scanXMcpHeaderDeclarations, C as REQUEST_STATE_ONLY_LEG_PACING_MS, Ct as CLIENT_CAPABILITIES_META_KEY, E as sleep, H as assertCompleteRequestPrompt, Ht as requiredClientCapabilitiesForInputRequest, It as SERVER_INFO_META_KEY, Kt as SdkError, Lt as SUBSCRIPTION_ID_META_KEY, M as validateStandardSchema, N as parseSchema, T as linkedRoundAbort, U as assertCompleteRequestResourceTemplate, Vt as missingClientCapabilities, _ as mergeCapabilities, _t as normalizeContentlessToolResult, a as UriTemplate, b as withRequestStateValue, bt as legacyProtocolVersions, ct as codecForVersion, dt as ResourceNotFoundError, g as Protocol, gt as attachCacheHintFallback, ht as assertValidCacheHint, j as standardSchemaToJsonSchema, jt as LOG_LEVEL_META_KEY, lt as MissingRequiredClientCapabilityError, mt as ProtocolErrorCode, nt as LoggingLevelSchema, q as isInputRequiredResult, qt as SdkErrorCode, r as normalizeRawShapeSchema, s as validateAndWarnToolName, st as MODERN_WIRE_REVISION, ut as ProtocolError, v as requestStateAccessor, w as inputRequiredRoundsExceededMessage, xt as modernProtocolVersions, yt as isModernProtocolVersion } from "./src-
|
|
1
|
+
import { A as promptArgumentsFromStandardSchema, At as LATEST_PROTOCOL_VERSION, B as scanXMcpHeaderDeclarations, C as REQUEST_STATE_ONLY_LEG_PACING_MS, Ct as CLIENT_CAPABILITIES_META_KEY, E as sleep, H as assertCompleteRequestPrompt, Ht as requiredClientCapabilitiesForInputRequest, It as SERVER_INFO_META_KEY, Kt as SdkError, Lt as SUBSCRIPTION_ID_META_KEY, M as validateStandardSchema, N as parseSchema, T as linkedRoundAbort, U as assertCompleteRequestResourceTemplate, Vt as missingClientCapabilities, Xt as OAuthErrorCode, Yt as OAuthError, _ as mergeCapabilities, _t as normalizeContentlessToolResult, a as UriTemplate, b as withRequestStateValue, bt as legacyProtocolVersions, ct as codecForVersion, dt as ResourceNotFoundError, g as Protocol, gt as attachCacheHintFallback, ht as assertValidCacheHint, j as standardSchemaToJsonSchema, jt as LOG_LEVEL_META_KEY, lt as MissingRequiredClientCapabilityError, mt as ProtocolErrorCode, nt as LoggingLevelSchema, q as isInputRequiredResult, qt as SdkErrorCode, r as normalizeRawShapeSchema, s as validateAndWarnToolName, st as MODERN_WIRE_REVISION, ut as ProtocolError, v as requestStateAccessor, w as inputRequiredRoundsExceededMessage, xt as modernProtocolVersions, yt as isModernProtocolVersion } from "./src-D-y6h4N7.mjs";
|
|
2
2
|
import { DefaultJsonSchemaValidator } from "@modelcontextprotocol/server/_shims";
|
|
3
3
|
|
|
4
4
|
//#region src/server/completable.ts
|
|
@@ -56,6 +56,19 @@ function getCompleter(schema) {
|
|
|
56
56
|
return schema[COMPLETABLE_SYMBOL]?.complete;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/server/sseKeepAlive.ts
|
|
61
|
+
/** Default interval between SSE keep-alive comment frames. */
|
|
62
|
+
const DEFAULT_SSE_KEEP_ALIVE_MS = 15e3;
|
|
63
|
+
const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
64
|
+
/** Arms an unref'd timer, or disables keep-alive for invalid delays. */
|
|
65
|
+
function armSseKeepAlive(intervalMs, onTick) {
|
|
66
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 1) return;
|
|
67
|
+
const timer = setInterval(onTick, Math.min(intervalMs, MAX_TIMER_DELAY_MS));
|
|
68
|
+
timer.unref?.();
|
|
69
|
+
return timer;
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
//#endregion
|
|
60
73
|
//#region src/server/serverEventBus.ts
|
|
61
74
|
/**
|
|
@@ -168,8 +181,6 @@ function serverEventToNotification(event) {
|
|
|
168
181
|
|
|
169
182
|
//#endregion
|
|
170
183
|
//#region src/server/listenRouter.ts
|
|
171
|
-
/** Default SSE comment-frame keepalive interval for listen streams. */
|
|
172
|
-
const DEFAULT_LISTEN_KEEPALIVE_MS = 15e3;
|
|
173
184
|
/** Default capacity guard: refuse a new subscription when this many are already open. */
|
|
174
185
|
const DEFAULT_MAX_SUBSCRIPTIONS = 1024;
|
|
175
186
|
function jsonRpcError(id, code, message) {
|
|
@@ -208,7 +219,7 @@ function parseListenFilter(message) {
|
|
|
208
219
|
function createListenRouter(options) {
|
|
209
220
|
const { bus, onerror } = options;
|
|
210
221
|
const maxSubscriptions = options.maxSubscriptions ?? DEFAULT_MAX_SUBSCRIPTIONS;
|
|
211
|
-
const keepAliveMs = options.keepAliveMs ??
|
|
222
|
+
const keepAliveMs = options.keepAliveMs ?? DEFAULT_SSE_KEEP_ALIVE_MS;
|
|
212
223
|
const open = /* @__PURE__ */ new Set();
|
|
213
224
|
function serve(message, signal, capabilities, serverInfo) {
|
|
214
225
|
if (open.size >= maxSubscriptions) {
|
|
@@ -254,7 +265,11 @@ function createListenRouter(options) {
|
|
|
254
265
|
}
|
|
255
266
|
})}\n\n`);
|
|
256
267
|
closed = true;
|
|
257
|
-
|
|
268
|
+
try {
|
|
269
|
+
unsubscribe?.();
|
|
270
|
+
} catch (error) {
|
|
271
|
+
onerror?.(error instanceof Error ? error : new Error(String(error)));
|
|
272
|
+
}
|
|
258
273
|
if (keepAliveTimer !== void 0) clearInterval(keepAliveTimer);
|
|
259
274
|
abortCleanup?.();
|
|
260
275
|
open.delete(teardown);
|
|
@@ -275,10 +290,7 @@ function createListenRouter(options) {
|
|
|
275
290
|
const note = stampSubscriptionId(serverEventToNotification(event), subscriptionId);
|
|
276
291
|
writeNotification(note.method, note.params);
|
|
277
292
|
});
|
|
278
|
-
|
|
279
|
-
keepAliveTimer = setInterval(() => writeFrame(": keepalive\n\n"), keepAliveMs);
|
|
280
|
-
keepAliveTimer.unref?.();
|
|
281
|
-
}
|
|
293
|
+
keepAliveTimer = armSseKeepAlive(keepAliveMs, () => writeFrame(": keepalive\n\n"));
|
|
282
294
|
open.add(teardown);
|
|
283
295
|
},
|
|
284
296
|
cancel() {
|
|
@@ -295,7 +307,7 @@ function createListenRouter(options) {
|
|
|
295
307
|
status: 200,
|
|
296
308
|
headers: {
|
|
297
309
|
"Content-Type": "text/event-stream",
|
|
298
|
-
"Cache-Control": "no-cache",
|
|
310
|
+
"Cache-Control": "no-cache, no-transform",
|
|
299
311
|
Connection: "keep-alive",
|
|
300
312
|
"X-Accel-Buffering": "no"
|
|
301
313
|
}
|
|
@@ -462,6 +474,310 @@ function notificationToServerEvent(method, uri) {
|
|
|
462
474
|
}
|
|
463
475
|
}
|
|
464
476
|
|
|
477
|
+
//#endregion
|
|
478
|
+
//#region src/server/middleware/bearerAuth.ts
|
|
479
|
+
function headerQuotedValue(value) {
|
|
480
|
+
return value.replaceAll(/[\\"]/g, String.raw`\$&`).replaceAll(/[^\u0020-\u007E]/g, " ");
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Build a `WWW-Authenticate: Bearer …` challenge header value (RFC 6750).
|
|
484
|
+
*
|
|
485
|
+
* The single formatter behind every challenge this package emits — the
|
|
486
|
+
* bearer-auth 401/403 answers and the per-operation scope-challenge 403 — so
|
|
487
|
+
* all challenges from one server agree on parameter order and quoting. Every
|
|
488
|
+
* parameter value is emitted as an HTTP quoted-string with `\` and `"`
|
|
489
|
+
* escaped and non-printable characters replaced.
|
|
490
|
+
*/
|
|
491
|
+
function buildWwwAuthenticateHeader(errorCode, description, requiredScopes, resourceMetadataUrl) {
|
|
492
|
+
let header = `Bearer error="${headerQuotedValue(errorCode)}", error_description="${headerQuotedValue(description)}"`;
|
|
493
|
+
if (requiredScopes.length > 0) header += `, scope="${headerQuotedValue(requiredScopes.join(" "))}"`;
|
|
494
|
+
if (resourceMetadataUrl) header += `, resource_metadata="${headerQuotedValue(resourceMetadataUrl)}"`;
|
|
495
|
+
return header;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Validate a raw `Authorization` header value as a Bearer token and return
|
|
499
|
+
* the verified {@link AuthInfo}.
|
|
500
|
+
*
|
|
501
|
+
* The runtime-neutral core of Bearer authentication: it parses the header,
|
|
502
|
+
* runs the verifier, enforces `requiredScopes`, and rejects tokens without an
|
|
503
|
+
* expiration or past it. On any failure it throws an {@link OAuthError} —
|
|
504
|
+
* pass that to {@link bearerAuthChallengeResponse} for the matching HTTP
|
|
505
|
+
* answer, or use {@link requireBearerAuth} to get both steps as one call.
|
|
506
|
+
*
|
|
507
|
+
* Framework adapters build on this: `requireBearerAuth` from
|
|
508
|
+
* `@modelcontextprotocol/express` feeds it `req.headers.authorization`.
|
|
509
|
+
*/
|
|
510
|
+
async function verifyBearerToken(authorizationHeader, options) {
|
|
511
|
+
const { verifier, requiredScopes = [] } = options;
|
|
512
|
+
if (!authorizationHeader) throw new OAuthError(OAuthErrorCode.InvalidToken, "Missing Authorization header");
|
|
513
|
+
const [type, token] = authorizationHeader.split(" ");
|
|
514
|
+
if (type?.toLowerCase() !== "bearer" || !token) throw new OAuthError(OAuthErrorCode.InvalidToken, "Invalid Authorization header format, expected 'Bearer TOKEN'");
|
|
515
|
+
const authInfo = await verifier.verifyAccessToken(token);
|
|
516
|
+
if (requiredScopes.length > 0) {
|
|
517
|
+
if (!requiredScopes.every((scope) => authInfo.scopes.includes(scope))) throw new OAuthError(OAuthErrorCode.InsufficientScope, "Insufficient scope");
|
|
518
|
+
}
|
|
519
|
+
if (typeof authInfo.expiresAt !== "number" || Number.isNaN(authInfo.expiresAt)) throw new OAuthError(OAuthErrorCode.InvalidToken, "Token has no expiration time");
|
|
520
|
+
else if (authInfo.expiresAt < Date.now() / 1e3) throw new OAuthError(OAuthErrorCode.InvalidToken, "Token has expired");
|
|
521
|
+
if (options.resourceMetadataUrl !== void 0 && authInfo.resourceMetadataUrl === void 0) return {
|
|
522
|
+
...authInfo,
|
|
523
|
+
resourceMetadataUrl: options.resourceMetadataUrl
|
|
524
|
+
};
|
|
525
|
+
return authInfo;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Build the HTTP answer for a Bearer authentication failure.
|
|
529
|
+
*
|
|
530
|
+
* Maps an {@link OAuthError} to its status — `401` for `invalid_token` and
|
|
531
|
+
* `403` for `insufficient_scope` (both carrying the `WWW-Authenticate: Bearer …`
|
|
532
|
+
* challenge, with `resource_metadata` when configured so clients can discover
|
|
533
|
+
* the Authorization Server), `500` for `server_error`, `400` for anything
|
|
534
|
+
* else. A non-`OAuthError` value answers `500 server_error`. The body is the
|
|
535
|
+
* OAuth error JSON.
|
|
536
|
+
*/
|
|
537
|
+
function bearerAuthChallengeResponse(error, options) {
|
|
538
|
+
const { requiredScopes = [], resourceMetadataUrl } = options ?? {};
|
|
539
|
+
if (!(error instanceof OAuthError)) {
|
|
540
|
+
const serverError = new OAuthError(OAuthErrorCode.ServerError, "Internal Server Error");
|
|
541
|
+
return Response.json(serverError.toResponseObject(), { status: 500 });
|
|
542
|
+
}
|
|
543
|
+
switch (error.code) {
|
|
544
|
+
case OAuthErrorCode.InvalidToken: {
|
|
545
|
+
const challenge = buildWwwAuthenticateHeader(error.code, error.message, requiredScopes, resourceMetadataUrl);
|
|
546
|
+
return Response.json(error.toResponseObject(), {
|
|
547
|
+
status: 401,
|
|
548
|
+
headers: { "WWW-Authenticate": challenge }
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
case OAuthErrorCode.InsufficientScope: {
|
|
552
|
+
const challenge = buildWwwAuthenticateHeader(error.code, error.message, requiredScopes, resourceMetadataUrl);
|
|
553
|
+
return Response.json(error.toResponseObject(), {
|
|
554
|
+
status: 403,
|
|
555
|
+
headers: { "WWW-Authenticate": challenge }
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
case OAuthErrorCode.ServerError: return Response.json(error.toResponseObject(), { status: 500 });
|
|
559
|
+
default: return Response.json(error.toResponseObject(), { status: 400 });
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Require a valid Bearer token on web-standard requests.
|
|
564
|
+
*
|
|
565
|
+
* The framework-free counterpart of `requireBearerAuth` from
|
|
566
|
+
* `@modelcontextprotocol/express`, for hosts whose HTTP surface is a
|
|
567
|
+
* `fetch(request)` handler — Cloudflare Workers, Deno, Bun, Hono. The
|
|
568
|
+
* returned gate resolves to the verified {@link AuthInfo}, or to the
|
|
569
|
+
* ready-to-return challenge `Response` when the request must be refused.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* ```ts source="./bearerAuth.examples.ts#requireBearerAuth_fetchGate"
|
|
573
|
+
* const gate = requireBearerAuth({ verifier, requiredScopes: ['mcp'] });
|
|
574
|
+
*
|
|
575
|
+
* async function fetchHandler(request: Request): Promise<Response> {
|
|
576
|
+
* const auth: AuthInfo | Response = await gate(request);
|
|
577
|
+
* if (auth instanceof Response) return auth;
|
|
578
|
+
* return handler.fetch(request, { authInfo: auth });
|
|
579
|
+
* }
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
function requireBearerAuth(options) {
|
|
583
|
+
const { verifier, requiredScopes = [], resourceMetadataUrl } = options;
|
|
584
|
+
const resolved = {
|
|
585
|
+
verifier,
|
|
586
|
+
requiredScopes,
|
|
587
|
+
resourceMetadataUrl
|
|
588
|
+
};
|
|
589
|
+
return async (request) => {
|
|
590
|
+
const [authorizationHeader] = (request.headers.get("authorization") ?? "").split(",");
|
|
591
|
+
try {
|
|
592
|
+
return await verifyBearerToken(authorizationHeader || void 0, resolved);
|
|
593
|
+
} catch (error) {
|
|
594
|
+
return bearerAuthChallengeResponse(error, resolved);
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/server/middleware/oauthMetadata.ts
|
|
601
|
+
function checkIssuerUrl(issuer, allowInsecure) {
|
|
602
|
+
if (issuer.protocol !== "https:" && issuer.hostname !== "localhost" && issuer.hostname !== "127.0.0.1" && !allowInsecure) throw new Error("Issuer URL must be HTTPS");
|
|
603
|
+
if (issuer.hash) throw new Error(`Issuer URL must not have a fragment: ${issuer}`);
|
|
604
|
+
if (issuer.search) throw new Error(`Issuer URL must not have a query string: ${issuer}`);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Derive the RFC 9728 Protected Resource Metadata document from
|
|
608
|
+
* {@link AuthMetadataOptions}, validating the Authorization Server issuer URL
|
|
609
|
+
* (HTTPS required outside localhost) in the process.
|
|
610
|
+
*
|
|
611
|
+
* `oauthMetadataResponse` and the Express `mcpAuthMetadataRouter` both build
|
|
612
|
+
* on this; use it directly when serving the document through your own
|
|
613
|
+
* routing — or call it once at startup to fail fast on a misconfigured
|
|
614
|
+
* issuer before any request arrives.
|
|
615
|
+
*/
|
|
616
|
+
function buildOAuthProtectedResourceMetadata(options) {
|
|
617
|
+
checkIssuerUrl(new URL(options.oauthMetadata.issuer), options.dangerouslyAllowInsecureIssuerUrl);
|
|
618
|
+
return {
|
|
619
|
+
resource: options.resourceServerUrl.href,
|
|
620
|
+
authorization_servers: [options.oauthMetadata.issuer],
|
|
621
|
+
scopes_supported: options.scopesSupported,
|
|
622
|
+
resource_name: options.resourceName,
|
|
623
|
+
resource_documentation: options.serviceDocumentationUrl?.href
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Builds the RFC 9728 Protected Resource Metadata URL for a given MCP server
|
|
628
|
+
* URL by inserting `/.well-known/oauth-protected-resource` ahead of the path.
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* ```ts
|
|
632
|
+
* getOAuthProtectedResourceMetadataUrl(new URL('https://api.example.com/mcp'))
|
|
633
|
+
* // → 'https://api.example.com/.well-known/oauth-protected-resource/mcp'
|
|
634
|
+
* ```
|
|
635
|
+
*/
|
|
636
|
+
function getOAuthProtectedResourceMetadataUrl(serverUrl) {
|
|
637
|
+
const metadataUrl = new URL(serverUrl);
|
|
638
|
+
metadataUrl.pathname = protectedResourceMetadataPath(serverUrl);
|
|
639
|
+
metadataUrl.hash = "";
|
|
640
|
+
return metadataUrl.href;
|
|
641
|
+
}
|
|
642
|
+
/** The RFC 9728 path-aware well-known path for a resource URL. */
|
|
643
|
+
function protectedResourceMetadataPath(resourceServerUrl) {
|
|
644
|
+
const rsPath = stripTrailingSlash(resourceServerUrl.pathname);
|
|
645
|
+
return `/.well-known/oauth-protected-resource${rsPath === "/" ? "" : rsPath}`;
|
|
646
|
+
}
|
|
647
|
+
function stripTrailingSlash(path) {
|
|
648
|
+
return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
|
|
649
|
+
}
|
|
650
|
+
const ALLOWED_METHODS = "GET, HEAD, OPTIONS";
|
|
651
|
+
function metadataDocumentResponse(request, metadata) {
|
|
652
|
+
if (request.method === "OPTIONS") {
|
|
653
|
+
const requestedHeaders = request.headers.get("access-control-request-headers");
|
|
654
|
+
return new Response(null, {
|
|
655
|
+
status: 204,
|
|
656
|
+
headers: {
|
|
657
|
+
"Access-Control-Allow-Origin": "*",
|
|
658
|
+
"Access-Control-Allow-Methods": ALLOWED_METHODS,
|
|
659
|
+
...requestedHeaders === null ? {} : {
|
|
660
|
+
"Access-Control-Allow-Headers": requestedHeaders,
|
|
661
|
+
Vary: "Access-Control-Request-Headers"
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
667
|
+
const error = new OAuthError(OAuthErrorCode.MethodNotAllowed, `The method ${request.method} is not allowed for this endpoint`);
|
|
668
|
+
return Response.json(error.toResponseObject(), {
|
|
669
|
+
status: 405,
|
|
670
|
+
headers: {
|
|
671
|
+
Allow: ALLOWED_METHODS,
|
|
672
|
+
"Access-Control-Allow-Origin": "*"
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
const response = Response.json(metadata, { headers: { "Access-Control-Allow-Origin": "*" } });
|
|
677
|
+
return request.method === "HEAD" ? new Response(null, {
|
|
678
|
+
status: response.status,
|
|
679
|
+
headers: response.headers
|
|
680
|
+
}) : response;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Serve the two OAuth discovery documents an MCP server acting as a Resource
|
|
684
|
+
* Server exposes, from a web-standard `fetch(request)` handler:
|
|
685
|
+
*
|
|
686
|
+
* - `/.well-known/oauth-protected-resource[/<path>]` — RFC 9728 Protected
|
|
687
|
+
* Resource Metadata, derived from the supplied options (path-aware: the
|
|
688
|
+
* resource URL's path is reflected in the route).
|
|
689
|
+
* - `/.well-known/oauth-authorization-server` — RFC 8414 Authorization
|
|
690
|
+
* Server Metadata, passed through verbatim.
|
|
691
|
+
*
|
|
692
|
+
* Returns the matched document `Response` (JSON with permissive CORS, `405`
|
|
693
|
+
* with an `Allow` header for non-GET methods, `204` for CORS preflight), or
|
|
694
|
+
* `undefined` when the request path is neither well-known route — fall
|
|
695
|
+
* through to your own routing. The framework-free counterpart of
|
|
696
|
+
* `mcpAuthMetadataRouter` from `@modelcontextprotocol/express`; pair it with
|
|
697
|
+
* `requireBearerAuth` and `getOAuthProtectedResourceMetadataUrl` so
|
|
698
|
+
* unauthenticated clients can discover the AS from the `401` challenge.
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```ts source="./oauthMetadata.examples.ts#oauthMetadataResponse_fetchHandler"
|
|
702
|
+
* async function fetchHandler(request: Request): Promise<Response> {
|
|
703
|
+
* return oauthMetadataResponse(request, options) ?? serveMcp(request);
|
|
704
|
+
* }
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
function oauthMetadataResponse(request, options) {
|
|
708
|
+
const requestPath = stripTrailingSlash(new URL(request.url).pathname);
|
|
709
|
+
if (requestPath === protectedResourceMetadataPath(options.resourceServerUrl)) return metadataDocumentResponse(request, buildOAuthProtectedResourceMetadata(options));
|
|
710
|
+
if (requestPath === "/.well-known/oauth-authorization-server") {
|
|
711
|
+
buildOAuthProtectedResourceMetadata(options);
|
|
712
|
+
return metadataDocumentResponse(request, options.oauthMetadata);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/server/scopeChallenge.ts
|
|
718
|
+
/** @internal */
|
|
719
|
+
function supportsScopeChallengeResolver(transport) {
|
|
720
|
+
return typeof transport === "object" && transport !== null && "setScopeChallengeResolver" in transport && typeof transport.setScopeChallengeResolver === "function";
|
|
721
|
+
}
|
|
722
|
+
function assertScope(scope, location) {
|
|
723
|
+
if (typeof scope !== "string" || !/^[\u0021\u0023-\u005B\u005D-\u007E]+$/.test(scope)) throw new TypeError(`${location} must satisfy the OAuth scope-token grammar`);
|
|
724
|
+
}
|
|
725
|
+
function validateScopeChallenge(challenge) {
|
|
726
|
+
if (challenge === null || typeof challenge !== "object" || !Array.isArray(challenge.scopes) || challenge.scopes.length === 0) throw new TypeError("scope challenge must contain at least one scope");
|
|
727
|
+
for (const [index, scope] of challenge.scopes.entries()) assertScope(scope, `scope challenge scopes[${index}]`);
|
|
728
|
+
if (challenge.errorDescription !== void 0 && typeof challenge.errorDescription !== "string") throw new TypeError("scope challenge errorDescription must be a string");
|
|
729
|
+
if (challenge.errorDescription !== void 0 && !/^[\u0020-\u0021\u0023-\u005B\u005D-\u007E]+$/.test(challenge.errorDescription)) throw new TypeError("scope challenge errorDescription must satisfy the RFC 6750 error-description grammar");
|
|
730
|
+
return challenge;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Creates a handler that requires every supplied scope exactly.
|
|
734
|
+
*
|
|
735
|
+
* Requests without authentication are left to the server's authentication gate.
|
|
736
|
+
*/
|
|
737
|
+
function requireScopes(...scopes) {
|
|
738
|
+
if (scopes.length === 0) throw new TypeError("requireScopes must contain at least one scope");
|
|
739
|
+
for (const [index, scope] of scopes.entries()) assertScope(scope, `requireScopes scope[${index}]`);
|
|
740
|
+
const requiredScopes = [...scopes];
|
|
741
|
+
return ({ authInfo }) => {
|
|
742
|
+
if (authInfo === void 0) return;
|
|
743
|
+
const activeScopes = new Set(authInfo.scopes);
|
|
744
|
+
if (requiredScopes.every((scope) => activeScopes.has(scope))) return;
|
|
745
|
+
return { scopes: requiredScopes };
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
/** @internal */
|
|
749
|
+
async function findScopeChallenge(requests, authInfo, resolve) {
|
|
750
|
+
for (const request of requests) {
|
|
751
|
+
const challenge = await resolve({
|
|
752
|
+
request,
|
|
753
|
+
...authInfo !== void 0 && { authInfo }
|
|
754
|
+
});
|
|
755
|
+
if (challenge !== void 0) return validateScopeChallenge(challenge);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* The RFC 9728 Protected Resource Metadata URL to advertise on a scope
|
|
760
|
+
* challenge, derived from the verified {@link AuthInfo}: the URL the
|
|
761
|
+
* authentication gate stamped (`authInfo.resourceMetadataUrl`, set by the
|
|
762
|
+
* bearer-auth helpers from their `resourceMetadataUrl` option), falling back
|
|
763
|
+
* to the well-known location for an HTTP(S) RFC 8707 `resource` identifier, or
|
|
764
|
+
* `undefined` when neither is available (the `resource_metadata` parameter is
|
|
765
|
+
* then omitted, matching the bearer-auth challenges).
|
|
766
|
+
*
|
|
767
|
+
* @internal
|
|
768
|
+
*/
|
|
769
|
+
function scopeChallengeResourceMetadataUrl(authInfo) {
|
|
770
|
+
if (authInfo?.resourceMetadataUrl !== void 0) return authInfo.resourceMetadataUrl;
|
|
771
|
+
if (authInfo?.resource?.protocol === "https:" || authInfo?.resource?.protocol === "http:") return getOAuthProtectedResourceMetadataUrl(authInfo.resource);
|
|
772
|
+
}
|
|
773
|
+
/** @internal */
|
|
774
|
+
function createScopeChallengeResponse(challenge, resourceMetadataUrl) {
|
|
775
|
+
return bearerAuthChallengeResponse(new OAuthError(OAuthErrorCode.InsufficientScope, challenge.errorDescription ?? "Insufficient scope"), {
|
|
776
|
+
requiredScopes: [...challenge.scopes],
|
|
777
|
+
resourceMetadataUrl
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
|
|
465
781
|
//#endregion
|
|
466
782
|
//#region src/server/legacyInputRequiredShim.ts
|
|
467
783
|
/**
|
|
@@ -1203,7 +1519,7 @@ var Server = class extends Protocol {
|
|
|
1203
1519
|
* notification for the specified elicitation ID.
|
|
1204
1520
|
*
|
|
1205
1521
|
* The notification (and the `elicitationId` it references) exists only on protocol revision
|
|
1206
|
-
* 2025-11-25 — the 2026-07-28
|
|
1522
|
+
* 2025-11-25 — the 2026-07-28 revision removed both. On a connection negotiated at 2026-07-28 the
|
|
1207
1523
|
* returned callback rejects with a typed local error before anything reaches the transport
|
|
1208
1524
|
* (the method is not part of that revision's wire registry).
|
|
1209
1525
|
*
|
|
@@ -1351,6 +1667,7 @@ var McpServer = class {
|
|
|
1351
1667
|
* ```
|
|
1352
1668
|
*/
|
|
1353
1669
|
async connect(transport) {
|
|
1670
|
+
if (supportsScopeChallengeResolver(transport)) transport.setScopeChallengeResolver((context) => this.resolveScopeChallenge(context));
|
|
1354
1671
|
return await this.server.connect(transport);
|
|
1355
1672
|
}
|
|
1356
1673
|
/**
|
|
@@ -1359,6 +1676,40 @@ var McpServer = class {
|
|
|
1359
1676
|
async close() {
|
|
1360
1677
|
await this.server.close();
|
|
1361
1678
|
}
|
|
1679
|
+
/** @internal */
|
|
1680
|
+
resolveScopeChallenge = (context) => {
|
|
1681
|
+
switch (context.request.method) {
|
|
1682
|
+
case "tools/call": {
|
|
1683
|
+
const toolName = context.request.params?.name;
|
|
1684
|
+
if (typeof toolName !== "string") return;
|
|
1685
|
+
const tool = this._registeredTools[toolName];
|
|
1686
|
+
if (tool === void 0 || !tool.enabled) return;
|
|
1687
|
+
return tool.scopeChallenge?.(context);
|
|
1688
|
+
}
|
|
1689
|
+
case "resources/read": {
|
|
1690
|
+
const resourceUri = context.request.params?.uri;
|
|
1691
|
+
if (typeof resourceUri !== "string") return;
|
|
1692
|
+
let uri;
|
|
1693
|
+
try {
|
|
1694
|
+
uri = new URL(resourceUri);
|
|
1695
|
+
} catch {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
const resource = this._registeredResources[uri.toString()];
|
|
1699
|
+
if (resource !== void 0) return resource.enabled ? resource.scopeChallenge?.(context) : void 0;
|
|
1700
|
+
for (const template of Object.values(this._registeredResourceTemplates)) if (template.resourceTemplate.uriTemplate.match(uri.toString())) return template.enabled ? template.scopeChallenge?.(context) : void 0;
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
case "prompts/get": {
|
|
1704
|
+
const promptName = context.request.params?.name;
|
|
1705
|
+
if (typeof promptName !== "string") return;
|
|
1706
|
+
const prompt = this._registeredPrompts[promptName];
|
|
1707
|
+
if (prompt === void 0 || !prompt.enabled) return;
|
|
1708
|
+
return prompt.scopeChallenge?.(context);
|
|
1709
|
+
}
|
|
1710
|
+
default: return;
|
|
1711
|
+
}
|
|
1712
|
+
};
|
|
1362
1713
|
_toolHandlersInitialized = false;
|
|
1363
1714
|
setToolRequestHandlers() {
|
|
1364
1715
|
if (this._toolHandlersInitialized) return;
|
|
@@ -1524,7 +1875,10 @@ var McpServer = class {
|
|
|
1524
1875
|
}
|
|
1525
1876
|
for (const template of Object.values(this._registeredResourceTemplates)) {
|
|
1526
1877
|
const variables = template.resourceTemplate.uriTemplate.match(uri.toString());
|
|
1527
|
-
if (variables)
|
|
1878
|
+
if (variables) {
|
|
1879
|
+
if (!template.enabled) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource template ${template.resourceTemplate.uriTemplate} disabled`);
|
|
1880
|
+
return attachCacheHintFallback(await template.readCallback(uri, variables, ctx), template.cacheHint);
|
|
1881
|
+
}
|
|
1528
1882
|
}
|
|
1529
1883
|
throw new ResourceNotFoundError(request.params.uri);
|
|
1530
1884
|
});
|
|
@@ -1555,36 +1909,32 @@ var McpServer = class {
|
|
|
1555
1909
|
this._promptHandlersInitialized = true;
|
|
1556
1910
|
}
|
|
1557
1911
|
registerResource(name, uriOrTemplate, config, readCallback) {
|
|
1558
|
-
const cacheHint = config
|
|
1559
|
-
|
|
1560
|
-
if (cacheHint !== void 0) {
|
|
1561
|
-
assertValidCacheHint(cacheHint, `resource ${name}`);
|
|
1562
|
-
const rest = { ...config };
|
|
1563
|
-
delete rest.cacheHint;
|
|
1564
|
-
metadata = rest;
|
|
1565
|
-
}
|
|
1912
|
+
const { cacheHint, scopeChallenge, ...resourceMetadata } = config;
|
|
1913
|
+
const metadata = resourceMetadata;
|
|
1914
|
+
if (cacheHint !== void 0) assertValidCacheHint(cacheHint, `resource ${name}`);
|
|
1566
1915
|
if (typeof uriOrTemplate === "string") {
|
|
1567
1916
|
if (this._registeredResources[uriOrTemplate]) throw new Error(`Resource ${uriOrTemplate} is already registered`);
|
|
1568
|
-
const registeredResource = this._createRegisteredResource(name, config.title, uriOrTemplate, metadata, readCallback);
|
|
1917
|
+
const registeredResource = this._createRegisteredResource(name, config.title, uriOrTemplate, metadata, scopeChallenge, readCallback);
|
|
1569
1918
|
if (cacheHint !== void 0) registeredResource.cacheHint = cacheHint;
|
|
1570
1919
|
this.setResourceRequestHandlers();
|
|
1571
1920
|
this.sendResourceListChanged();
|
|
1572
1921
|
return registeredResource;
|
|
1573
1922
|
} else {
|
|
1574
1923
|
if (this._registeredResourceTemplates[name]) throw new Error(`Resource template ${name} is already registered`);
|
|
1575
|
-
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, config.title, uriOrTemplate, metadata, readCallback);
|
|
1924
|
+
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name, config.title, uriOrTemplate, metadata, scopeChallenge, readCallback);
|
|
1576
1925
|
if (cacheHint !== void 0) registeredResourceTemplate.cacheHint = cacheHint;
|
|
1577
1926
|
this.setResourceRequestHandlers();
|
|
1578
1927
|
this.sendResourceListChanged();
|
|
1579
1928
|
return registeredResourceTemplate;
|
|
1580
1929
|
}
|
|
1581
1930
|
}
|
|
1582
|
-
_createRegisteredResource(name, title, uri, metadata, readCallback) {
|
|
1931
|
+
_createRegisteredResource(name, title, uri, metadata, scopeChallenge, readCallback) {
|
|
1583
1932
|
const registeredResource = {
|
|
1584
1933
|
name,
|
|
1585
1934
|
title,
|
|
1586
1935
|
metadata,
|
|
1587
1936
|
readCallback,
|
|
1937
|
+
scopeChallenge,
|
|
1588
1938
|
enabled: true,
|
|
1589
1939
|
disable: () => registeredResource.update({ enabled: false }),
|
|
1590
1940
|
enable: () => registeredResource.update({ enabled: true }),
|
|
@@ -1598,6 +1948,7 @@ var McpServer = class {
|
|
|
1598
1948
|
if (updates.title !== void 0) registeredResource.title = updates.title;
|
|
1599
1949
|
if (updates.metadata !== void 0) registeredResource.metadata = updates.metadata;
|
|
1600
1950
|
if (updates.callback !== void 0) registeredResource.readCallback = updates.callback;
|
|
1951
|
+
if (updates.scopeChallenge !== void 0) registeredResource.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
1601
1952
|
if (updates.enabled !== void 0) registeredResource.enabled = updates.enabled;
|
|
1602
1953
|
this.sendResourceListChanged();
|
|
1603
1954
|
}
|
|
@@ -1605,12 +1956,13 @@ var McpServer = class {
|
|
|
1605
1956
|
this._registeredResources[uri] = registeredResource;
|
|
1606
1957
|
return registeredResource;
|
|
1607
1958
|
}
|
|
1608
|
-
_createRegisteredResourceTemplate(name, title, template, metadata, readCallback) {
|
|
1959
|
+
_createRegisteredResourceTemplate(name, title, template, metadata, scopeChallenge, readCallback) {
|
|
1609
1960
|
const registeredResourceTemplate = {
|
|
1610
1961
|
resourceTemplate: template,
|
|
1611
1962
|
title,
|
|
1612
1963
|
metadata,
|
|
1613
1964
|
readCallback,
|
|
1965
|
+
scopeChallenge,
|
|
1614
1966
|
enabled: true,
|
|
1615
1967
|
disable: () => registeredResourceTemplate.update({ enabled: false }),
|
|
1616
1968
|
enable: () => registeredResourceTemplate.update({ enabled: true }),
|
|
@@ -1624,6 +1976,7 @@ var McpServer = class {
|
|
|
1624
1976
|
if (updates.template !== void 0) registeredResourceTemplate.resourceTemplate = updates.template;
|
|
1625
1977
|
if (updates.metadata !== void 0) registeredResourceTemplate.metadata = updates.metadata;
|
|
1626
1978
|
if (updates.callback !== void 0) registeredResourceTemplate.readCallback = updates.callback;
|
|
1979
|
+
if (updates.scopeChallenge !== void 0) registeredResourceTemplate.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
1627
1980
|
if (updates.enabled !== void 0) registeredResourceTemplate.enabled = updates.enabled;
|
|
1628
1981
|
this.sendResourceListChanged();
|
|
1629
1982
|
}
|
|
@@ -1633,7 +1986,7 @@ var McpServer = class {
|
|
|
1633
1986
|
if (Array.isArray(variableNames) && variableNames.some((v) => !!template.completeCallback(v))) this.setCompletionRequestHandler();
|
|
1634
1987
|
return registeredResourceTemplate;
|
|
1635
1988
|
}
|
|
1636
|
-
_createRegisteredPrompt(name, title, description, argsSchema, callback, icons, _meta) {
|
|
1989
|
+
_createRegisteredPrompt(name, title, description, argsSchema, callback, icons, scopeChallenge, _meta) {
|
|
1637
1990
|
let currentArgsSchema = argsSchema;
|
|
1638
1991
|
let currentCallback = callback;
|
|
1639
1992
|
const registeredPrompt = {
|
|
@@ -1641,6 +1994,7 @@ var McpServer = class {
|
|
|
1641
1994
|
description,
|
|
1642
1995
|
argsSchema,
|
|
1643
1996
|
icons,
|
|
1997
|
+
scopeChallenge,
|
|
1644
1998
|
_meta,
|
|
1645
1999
|
handler: createPromptHandler(name, argsSchema, callback),
|
|
1646
2000
|
enabled: true,
|
|
@@ -1655,6 +2009,7 @@ var McpServer = class {
|
|
|
1655
2009
|
if (updates.title !== void 0) registeredPrompt.title = updates.title;
|
|
1656
2010
|
if (updates.description !== void 0) registeredPrompt.description = updates.description;
|
|
1657
2011
|
if (updates.icons !== void 0) registeredPrompt.icons = updates.icons;
|
|
2012
|
+
if (updates.scopeChallenge !== void 0) registeredPrompt.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
1658
2013
|
if (updates._meta !== void 0) registeredPrompt._meta = updates._meta;
|
|
1659
2014
|
let needsHandlerRegen = false;
|
|
1660
2015
|
if (updates.argsSchema !== void 0) {
|
|
@@ -1682,7 +2037,7 @@ var McpServer = class {
|
|
|
1682
2037
|
}
|
|
1683
2038
|
return registeredPrompt;
|
|
1684
2039
|
}
|
|
1685
|
-
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, _meta, handler) {
|
|
2040
|
+
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
1686
2041
|
validateAndWarnToolName(name);
|
|
1687
2042
|
if (inputSchema !== void 0) try {
|
|
1688
2043
|
const json = standardSchemaToJsonSchema(inputSchema, "input");
|
|
@@ -1700,6 +2055,7 @@ var McpServer = class {
|
|
|
1700
2055
|
annotations,
|
|
1701
2056
|
icons,
|
|
1702
2057
|
execution,
|
|
2058
|
+
scopeChallenge,
|
|
1703
2059
|
_meta,
|
|
1704
2060
|
handler,
|
|
1705
2061
|
executor: createToolExecutor(inputSchema, handler),
|
|
@@ -1738,6 +2094,7 @@ var McpServer = class {
|
|
|
1738
2094
|
}
|
|
1739
2095
|
if (updates.annotations !== void 0) registeredTool.annotations = updates.annotations;
|
|
1740
2096
|
if (updates.icons !== void 0) registeredTool.icons = updates.icons;
|
|
2097
|
+
if (updates.scopeChallenge !== void 0) registeredTool.scopeChallenge = updates.scopeChallenge === null ? void 0 : updates.scopeChallenge;
|
|
1741
2098
|
if (updates._meta !== void 0) registeredTool._meta = updates._meta;
|
|
1742
2099
|
if (updates.enabled !== void 0) registeredTool.enabled = updates.enabled;
|
|
1743
2100
|
this.sendToolListChanged();
|
|
@@ -1750,13 +2107,13 @@ var McpServer = class {
|
|
|
1750
2107
|
}
|
|
1751
2108
|
registerTool(name, config, cb) {
|
|
1752
2109
|
if (this._registeredTools[name]) throw new Error(`Tool ${name} is already registered`);
|
|
1753
|
-
const { title, description, inputSchema, outputSchema, annotations, icons, _meta } = config;
|
|
1754
|
-
return this._createRegisteredTool(name, title, description, normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, icons, void 0, _meta, cb);
|
|
2110
|
+
const { title, description, inputSchema, outputSchema, annotations, icons, scopeChallenge, _meta } = config;
|
|
2111
|
+
return this._createRegisteredTool(name, title, description, normalizeRawShapeSchema(inputSchema), normalizeRawShapeSchema(outputSchema), annotations, icons, void 0, scopeChallenge, _meta, cb);
|
|
1755
2112
|
}
|
|
1756
2113
|
registerPrompt(name, config, cb) {
|
|
1757
2114
|
if (this._registeredPrompts[name]) throw new Error(`Prompt ${name} is already registered`);
|
|
1758
|
-
const { title, description, argsSchema, icons, _meta } = config;
|
|
1759
|
-
const registeredPrompt = this._createRegisteredPrompt(name, title, description, normalizeRawShapeSchema(argsSchema), cb, icons, _meta);
|
|
2115
|
+
const { title, description, argsSchema, icons, scopeChallenge, _meta } = config;
|
|
2116
|
+
const registeredPrompt = this._createRegisteredPrompt(name, title, description, normalizeRawShapeSchema(argsSchema), cb, icons, scopeChallenge, _meta);
|
|
1760
2117
|
this.setPromptRequestHandlers();
|
|
1761
2118
|
this.sendPromptListChanged();
|
|
1762
2119
|
return registeredPrompt;
|
|
@@ -1915,5 +2272,5 @@ function unwrapOptionalSchema(schema) {
|
|
|
1915
2272
|
}
|
|
1916
2273
|
|
|
1917
2274
|
//#endregion
|
|
1918
|
-
export { seedClientIdentityFromEnvelope as a,
|
|
1919
|
-
//# sourceMappingURL=mcp-
|
|
2275
|
+
export { armSseKeepAlive as C, DEFAULT_SSE_KEEP_ALIVE_MS as S, isCompletable as T, DEFAULT_MAX_SUBSCRIPTIONS as _, seedClientIdentityFromEnvelope as a, InMemoryServerEventBus as b, findScopeChallenge as c, buildOAuthProtectedResourceMetadata as d, getOAuthProtectedResourceMetadataUrl as f, verifyBearerToken as g, requireBearerAuth as h, installModernOnlyHandlers as i, requireScopes as l, bearerAuthChallengeResponse as m, ResourceTemplate as n, serverIdentityOf as o, oauthMetadataResponse as p, Server as r, createScopeChallengeResponse as s, McpServer as t, scopeChallengeResourceMetadataUrl as u, StdioListenRouter as v, completable as w, createServerNotifier as x, createListenRouter as y };
|
|
2276
|
+
//# sourceMappingURL=mcp-Dw2OlZ1f.mjs.map
|