@frontmcp/sdk 1.4.0 → 1.5.0-rc.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.
- package/auth/flows/oauth.authorize.flow.d.ts.map +1 -1
- package/auth/flows/oauth.token.flow.d.ts.map +1 -1
- package/auth/flows/session.verify.flow.d.ts.map +1 -1
- package/auth/instances/instance.local-primary-auth.d.ts.map +1 -1
- package/common/decorators/app.decorator.d.ts +13 -1
- package/common/decorators/app.decorator.d.ts.map +1 -1
- package/common/decorators/front-mcp.decorator.d.ts.map +1 -1
- package/common/metadata/front-mcp.metadata.d.ts +24 -0
- package/common/metadata/front-mcp.metadata.d.ts.map +1 -1
- package/common/schemas/http-output.schema.d.ts +17 -0
- package/common/schemas/http-output.schema.d.ts.map +1 -1
- package/common/tokens/server.tokens.d.ts +3 -0
- package/common/tokens/server.tokens.d.ts.map +1 -1
- package/common/types/options/skills-http/interfaces.d.ts +15 -1
- package/common/types/options/skills-http/interfaces.d.ts.map +1 -1
- package/common/types/options/skills-http/schema.d.ts +4 -0
- package/common/types/options/skills-http/schema.d.ts.map +1 -1
- package/common/utils/path.utils.d.ts +15 -0
- package/common/utils/path.utils.d.ts.map +1 -1
- package/esm/index.mjs +1190 -295
- package/esm-loader/esm-cache.d.ts +10 -0
- package/esm-loader/esm-cache.d.ts.map +1 -1
- package/esm-loader/esm-module-loader.d.ts.map +1 -1
- package/flows/flow.instance.d.ts +14 -0
- package/flows/flow.instance.d.ts.map +1 -1
- package/flows/flow.registry.d.ts +9 -1
- package/flows/flow.registry.d.ts.map +1 -1
- package/front-mcp/front-mcp.d.ts +14 -0
- package/front-mcp/front-mcp.d.ts.map +1 -1
- package/front-mcp/front-mcp.providers.d.ts +4 -0
- package/front-mcp/front-mcp.providers.d.ts.map +1 -1
- package/index.d.ts +9 -5
- package/index.d.ts.map +1 -1
- package/index.js +1423 -522
- package/logger/instances/instance.file-logger.d.ts.map +1 -1
- package/package.json +29 -29
- package/scope/flows/http.request.flow.d.ts +17 -1
- package/scope/flows/http.request.flow.d.ts.map +1 -1
- package/scope/optional-dependency.util.d.ts +25 -0
- package/scope/optional-dependency.util.d.ts.map +1 -1
- package/scope/scope.instance.d.ts +9 -1
- package/scope/scope.instance.d.ts.map +1 -1
- package/server/server.instance.d.ts.map +1 -1
- package/server/server.validation.d.ts.map +1 -1
- package/skill/index.d.ts +1 -0
- package/skill/index.d.ts.map +1 -1
- package/skill/providers/memory-skill.provider.d.ts +61 -1
- package/skill/providers/memory-skill.provider.d.ts.map +1 -1
- package/skill/skill-index-cache.interface.d.ts +33 -0
- package/skill/skill-index-cache.interface.d.ts.map +1 -0
- package/skill/skill-instructions.helper.d.ts +13 -0
- package/skill/skill-instructions.helper.d.ts.map +1 -1
- package/skill/skill-storage.interface.d.ts +13 -0
- package/skill/skill-storage.interface.d.ts.map +1 -1
- package/skill/skill.registry.d.ts +27 -0
- package/skill/skill.registry.d.ts.map +1 -1
- package/transport/build-scoped-server-options.d.ts +35 -0
- package/transport/build-scoped-server-options.d.ts.map +1 -0
- package/transport/in-memory-server.d.ts.map +1 -1
- package/transport/index.d.ts +17 -0
- package/transport/index.d.ts.map +1 -1
- package/transport/web-fetch-handler.d.ts +106 -0
- package/transport/web-fetch-handler.d.ts.map +1 -0
- package/transport/web-response.renderer.d.ts +13 -0
- package/transport/web-response.renderer.d.ts.map +1 -0
- package/transport/web-standard-mcp.d.ts +63 -0
- package/transport/web-standard-mcp.d.ts.map +1 -0
package/index.js
CHANGED
|
@@ -6,11 +6,20 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
8
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
11
16
|
};
|
|
12
17
|
var __commonJS = (cb, mod) => function __require() {
|
|
13
|
-
|
|
18
|
+
try {
|
|
19
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
20
|
+
} catch (e) {
|
|
21
|
+
throw mod = 0, e;
|
|
22
|
+
}
|
|
14
23
|
};
|
|
15
24
|
var __export = (target, all) => {
|
|
16
25
|
for (var name41 in all)
|
|
@@ -671,7 +680,10 @@ var init_server_tokens = __esm({
|
|
|
671
680
|
intent: tokenFactory.meta("intent"),
|
|
672
681
|
auth: tokenFactory.meta("auth"),
|
|
673
682
|
sessionId: tokenFactory.meta("sessionId"),
|
|
674
|
-
reinitialize: tokenFactory.meta("reinitialize")
|
|
683
|
+
reinitialize: tokenFactory.meta("reinitialize"),
|
|
684
|
+
webRequest: tokenFactory.meta("webRequest"),
|
|
685
|
+
webCtx: tokenFactory.meta("webCtx"),
|
|
686
|
+
webTransport: tokenFactory.meta("webTransport")
|
|
675
687
|
};
|
|
676
688
|
}
|
|
677
689
|
});
|
|
@@ -1372,7 +1384,7 @@ var init_annotated_class_schema = __esm({
|
|
|
1372
1384
|
});
|
|
1373
1385
|
|
|
1374
1386
|
// libs/sdk/src/common/schemas/http-output.schema.ts
|
|
1375
|
-
var import_lazy_zod2, import_protocol, import_utils2, JSON_RPC, REDIRECTS, NO_BODY_STATUSES, zNumUnion, HttpStatus, HttpRedirectStatus, HttpEmptyStatus, HttpHeaders, HttpCookieSchema, HttpCookies, HttpMeta, statusAllowsBody, HttpRedirectSchema, HttpJsonSchema, HttpNextSchema, HttpConsumedSchema, HttpTextSchema, HttpHtmlSchema, HttpBinarySchema, HttpImageSchema, isHttpReadableLike, HttpStreamSchema, HttpSseSchema, HttpJsonRpcSchema, HttpProblemSchema, HttpEmptySchema, httpOutputSchema, httpRespond;
|
|
1387
|
+
var import_lazy_zod2, import_protocol, import_utils2, JSON_RPC, REDIRECTS, NO_BODY_STATUSES, zNumUnion, HttpStatus, HttpRedirectStatus, HttpEmptyStatus, HttpHeaders, HttpCookieSchema, HttpCookies, HttpMeta, statusAllowsBody, HttpRedirectSchema, HttpJsonSchema, HttpNextSchema, HttpConsumedSchema, HttpWebResponseSchema, HttpTextSchema, HttpHtmlSchema, HttpBinarySchema, HttpImageSchema, isHttpReadableLike, HttpStreamSchema, HttpSseSchema, HttpJsonRpcSchema, HttpProblemSchema, HttpEmptySchema, httpOutputSchema, httpRespond;
|
|
1376
1388
|
var init_http_output_schema = __esm({
|
|
1377
1389
|
"libs/sdk/src/common/schemas/http-output.schema.ts"() {
|
|
1378
1390
|
"use strict";
|
|
@@ -1427,6 +1439,13 @@ var init_http_output_schema = __esm({
|
|
|
1427
1439
|
kind: import_lazy_zod2.z.literal("next")
|
|
1428
1440
|
}).passthrough();
|
|
1429
1441
|
HttpConsumedSchema = import_lazy_zod2.z.object({ kind: import_lazy_zod2.z.literal("consumed") });
|
|
1442
|
+
HttpWebResponseSchema = import_lazy_zod2.z.object({
|
|
1443
|
+
kind: import_lazy_zod2.z.literal("web-response"),
|
|
1444
|
+
response: import_lazy_zod2.z.custom(
|
|
1445
|
+
(v) => typeof Response !== "undefined" && v instanceof Response,
|
|
1446
|
+
"must be a Web Response"
|
|
1447
|
+
)
|
|
1448
|
+
});
|
|
1430
1449
|
HttpTextSchema = import_lazy_zod2.z.object({
|
|
1431
1450
|
kind: import_lazy_zod2.z.literal("text"),
|
|
1432
1451
|
status: HttpStatus.refine((s) => statusAllowsBody(s) && !REDIRECTS.includes(s), {
|
|
@@ -1519,7 +1538,8 @@ var init_http_output_schema = __esm({
|
|
|
1519
1538
|
HttpProblemSchema,
|
|
1520
1539
|
HttpEmptySchema,
|
|
1521
1540
|
HttpNextSchema,
|
|
1522
|
-
HttpConsumedSchema
|
|
1541
|
+
HttpConsumedSchema,
|
|
1542
|
+
HttpWebResponseSchema
|
|
1523
1543
|
]);
|
|
1524
1544
|
httpRespond = {
|
|
1525
1545
|
json: (body, extra = {}) => {
|
|
@@ -1619,6 +1639,9 @@ var init_http_output_schema = __esm({
|
|
|
1619
1639
|
consumed() {
|
|
1620
1640
|
return { kind: "consumed" };
|
|
1621
1641
|
},
|
|
1642
|
+
webResponse(response) {
|
|
1643
|
+
return { kind: "web-response", response };
|
|
1644
|
+
},
|
|
1622
1645
|
empty(status = 204, headers) {
|
|
1623
1646
|
return { kind: "empty", status, headers };
|
|
1624
1647
|
},
|
|
@@ -2138,6 +2161,18 @@ var init_sqlite = __esm({
|
|
|
2138
2161
|
});
|
|
2139
2162
|
|
|
2140
2163
|
// libs/sdk/src/common/types/options/transport/schema.ts
|
|
2164
|
+
var schema_exports = {};
|
|
2165
|
+
__export(schema_exports, {
|
|
2166
|
+
PROTOCOL_PRESETS: () => PROTOCOL_PRESETS,
|
|
2167
|
+
eventStoreConfigSchema: () => eventStoreConfigSchema,
|
|
2168
|
+
expandProtocolConfig: () => expandProtocolConfig,
|
|
2169
|
+
expandTransportConfig: () => expandTransportConfig,
|
|
2170
|
+
isDistributedMode: () => isDistributedMode,
|
|
2171
|
+
persistenceConfigSchema: () => persistenceConfigSchema,
|
|
2172
|
+
shouldCacheProviders: () => shouldCacheProviders,
|
|
2173
|
+
toLegacyProtocolFlags: () => toLegacyProtocolFlags,
|
|
2174
|
+
transportOptionsSchema: () => transportOptionsSchema
|
|
2175
|
+
});
|
|
2141
2176
|
function expandProtocolConfig(protocol) {
|
|
2142
2177
|
if (!protocol) {
|
|
2143
2178
|
return { ...PROTOCOL_PRESETS.legacy };
|
|
@@ -2457,7 +2492,8 @@ var init_schema10 = __esm({
|
|
|
2457
2492
|
sep2640InInstructions: import_lazy_zod15.z.boolean().optional().default(false),
|
|
2458
2493
|
cache: skillsConfigCacheOptionsSchema.optional(),
|
|
2459
2494
|
audit: skillsConfigAuditOptionsSchema.optional(),
|
|
2460
|
-
injectInstructions: import_lazy_zod15.z.enum(["off", "append", "prepend", "replace"]).optional().default("append")
|
|
2495
|
+
injectInstructions: import_lazy_zod15.z.enum(["off", "append", "prepend", "replace"]).optional().default("append"),
|
|
2496
|
+
scoring: import_lazy_zod15.z.enum(["cosine", "bm25"]).optional()
|
|
2461
2497
|
});
|
|
2462
2498
|
}
|
|
2463
2499
|
});
|
|
@@ -4671,6 +4707,12 @@ var init_elicitation_error = __esm({
|
|
|
4671
4707
|
this.toolInput = toolInput;
|
|
4672
4708
|
this.ttl = ttl;
|
|
4673
4709
|
}
|
|
4710
|
+
elicitId;
|
|
4711
|
+
elicitMessage;
|
|
4712
|
+
schema;
|
|
4713
|
+
toolName;
|
|
4714
|
+
toolInput;
|
|
4715
|
+
ttl;
|
|
4674
4716
|
getPublicMessage() {
|
|
4675
4717
|
return this.elicitMessage;
|
|
4676
4718
|
}
|
|
@@ -6129,30 +6171,30 @@ var require_dist = __commonJS({
|
|
|
6129
6171
|
sqliteStorageOptionsSchema: () => sqliteStorageOptionsSchema
|
|
6130
6172
|
});
|
|
6131
6173
|
module2.exports = __toCommonJS2(index_exports2);
|
|
6132
|
-
var
|
|
6174
|
+
var import_utils103 = require("@frontmcp/utils");
|
|
6133
6175
|
var HKDF_SALT = new TextEncoder().encode("frontmcp-sqlite-storage-v1");
|
|
6134
6176
|
var HKDF_INFO = new TextEncoder().encode("aes-256-gcm-value-encryption");
|
|
6135
6177
|
var KEY_LENGTH = 32;
|
|
6136
6178
|
function deriveEncryptionKey(secret) {
|
|
6137
6179
|
const ikm = new TextEncoder().encode(secret);
|
|
6138
|
-
return (0,
|
|
6180
|
+
return (0, import_utils103.hkdfSha256)(ikm, HKDF_SALT, HKDF_INFO, KEY_LENGTH);
|
|
6139
6181
|
}
|
|
6140
6182
|
var SEPARATOR = ":";
|
|
6141
6183
|
function encryptValue(key, plaintext) {
|
|
6142
|
-
const iv = (0,
|
|
6184
|
+
const iv = (0, import_utils103.randomBytes)(12);
|
|
6143
6185
|
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
6144
|
-
const { ciphertext, tag } = (0,
|
|
6145
|
-
return [(0,
|
|
6186
|
+
const { ciphertext, tag } = (0, import_utils103.encryptAesGcm)(key, plaintextBytes, iv);
|
|
6187
|
+
return [(0, import_utils103.base64urlEncode)(iv), (0, import_utils103.base64urlEncode)(tag), (0, import_utils103.base64urlEncode)(ciphertext)].join(SEPARATOR);
|
|
6146
6188
|
}
|
|
6147
6189
|
function decryptValue(key, encrypted) {
|
|
6148
6190
|
const parts = encrypted.split(SEPARATOR);
|
|
6149
6191
|
if (parts.length !== 3) {
|
|
6150
6192
|
throw new Error("Invalid encrypted value format");
|
|
6151
6193
|
}
|
|
6152
|
-
const iv = (0,
|
|
6153
|
-
const tag = (0,
|
|
6154
|
-
const ciphertext = (0,
|
|
6155
|
-
const plaintext = (0,
|
|
6194
|
+
const iv = (0, import_utils103.base64urlDecode)(parts[0]);
|
|
6195
|
+
const tag = (0, import_utils103.base64urlDecode)(parts[1]);
|
|
6196
|
+
const ciphertext = (0, import_utils103.base64urlDecode)(parts[2]);
|
|
6197
|
+
const plaintext = (0, import_utils103.decryptAesGcm)(key, ciphertext, iv, tag);
|
|
6156
6198
|
return new TextDecoder().decode(plaintext);
|
|
6157
6199
|
}
|
|
6158
6200
|
var import_utils210 = require("@frontmcp/utils");
|
|
@@ -7273,6 +7315,8 @@ var init_task_notifier = __esm({
|
|
|
7273
7315
|
this.notifications = notifications;
|
|
7274
7316
|
this.logger = logger;
|
|
7275
7317
|
}
|
|
7318
|
+
notifications;
|
|
7319
|
+
logger;
|
|
7276
7320
|
sendStatus(record) {
|
|
7277
7321
|
const params = {
|
|
7278
7322
|
...toWireShape(record)
|
|
@@ -7429,6 +7473,7 @@ var init_in_process_task_runner = __esm({
|
|
|
7429
7473
|
constructor(deps) {
|
|
7430
7474
|
this.deps = deps;
|
|
7431
7475
|
}
|
|
7476
|
+
deps;
|
|
7432
7477
|
kind = "in-process";
|
|
7433
7478
|
async run(record, context) {
|
|
7434
7479
|
await this.deps.store.update(record.taskId, record.sessionId, {
|
|
@@ -7483,6 +7528,7 @@ var init_cli_task_runner = __esm({
|
|
|
7483
7528
|
constructor(deps) {
|
|
7484
7529
|
this.deps = deps;
|
|
7485
7530
|
}
|
|
7531
|
+
deps;
|
|
7486
7532
|
kind = "cli";
|
|
7487
7533
|
async run(record, _context) {
|
|
7488
7534
|
const { exe, args } = this.resolveCommand();
|
|
@@ -7837,6 +7883,9 @@ var init_tasks_result_flow = __esm({
|
|
|
7837
7883
|
this.taskId = taskId;
|
|
7838
7884
|
this.name = "JsonRpcReplayError";
|
|
7839
7885
|
}
|
|
7886
|
+
code;
|
|
7887
|
+
data;
|
|
7888
|
+
taskId;
|
|
7840
7889
|
toJsonRpcError() {
|
|
7841
7890
|
const out = {
|
|
7842
7891
|
code: this.code,
|
|
@@ -8060,6 +8109,72 @@ var init_task = __esm({
|
|
|
8060
8109
|
}
|
|
8061
8110
|
});
|
|
8062
8111
|
|
|
8112
|
+
// libs/sdk/src/transport/build-scoped-server-options.ts
|
|
8113
|
+
var build_scoped_server_options_exports = {};
|
|
8114
|
+
__export(build_scoped_server_options_exports, {
|
|
8115
|
+
buildScopedServerOptions: () => buildScopedServerOptions
|
|
8116
|
+
});
|
|
8117
|
+
function buildScopedServerOptions(scope, instructions = "") {
|
|
8118
|
+
const hasRemoteApps = scope.apps?.getApps().some((app) => app.isRemote) ?? false;
|
|
8119
|
+
const hasPrompts = scope.prompts.hasAny() || hasRemoteApps;
|
|
8120
|
+
const hasResources = scope.resources.hasAny() || hasRemoteApps;
|
|
8121
|
+
const completionsCapability = hasPrompts || hasResources ? { completions: {} } : {};
|
|
8122
|
+
const remoteCapabilities = hasRemoteApps ? {
|
|
8123
|
+
tools: { listChanged: true },
|
|
8124
|
+
resources: { subscribe: true, listChanged: true },
|
|
8125
|
+
prompts: { listChanged: true }
|
|
8126
|
+
} : {};
|
|
8127
|
+
const skillsCapabilities = scope.skills?.getCapabilities() ?? {};
|
|
8128
|
+
const toolsCapabilities = scope.tools.getCapabilities();
|
|
8129
|
+
const resourcesCapabilities = scope.resources.getCapabilities();
|
|
8130
|
+
const promptsCapabilities = scope.prompts.getCapabilities();
|
|
8131
|
+
const agentsCapabilities = scope.agents.getCapabilities();
|
|
8132
|
+
const taskCapabilities = computeTaskCapabilities(scope);
|
|
8133
|
+
const fragments = [
|
|
8134
|
+
remoteCapabilities,
|
|
8135
|
+
toolsCapabilities,
|
|
8136
|
+
resourcesCapabilities,
|
|
8137
|
+
promptsCapabilities,
|
|
8138
|
+
agentsCapabilities,
|
|
8139
|
+
skillsCapabilities,
|
|
8140
|
+
completionsCapability,
|
|
8141
|
+
taskCapabilities
|
|
8142
|
+
];
|
|
8143
|
+
const experimental = {};
|
|
8144
|
+
const extensions = {};
|
|
8145
|
+
for (const cap2 of fragments) {
|
|
8146
|
+
if (cap2["experimental"] && typeof cap2["experimental"] === "object") {
|
|
8147
|
+
Object.assign(experimental, cap2["experimental"]);
|
|
8148
|
+
}
|
|
8149
|
+
if (cap2["extensions"] && typeof cap2["extensions"] === "object") {
|
|
8150
|
+
Object.assign(extensions, cap2["extensions"]);
|
|
8151
|
+
}
|
|
8152
|
+
}
|
|
8153
|
+
const baseCapabilities = {
|
|
8154
|
+
...remoteCapabilities,
|
|
8155
|
+
...toolsCapabilities,
|
|
8156
|
+
...resourcesCapabilities,
|
|
8157
|
+
...promptsCapabilities,
|
|
8158
|
+
...agentsCapabilities,
|
|
8159
|
+
...completionsCapability,
|
|
8160
|
+
...taskCapabilities,
|
|
8161
|
+
logging: {}
|
|
8162
|
+
};
|
|
8163
|
+
if (Object.keys(experimental).length > 0) baseCapabilities["experimental"] = experimental;
|
|
8164
|
+
if (Object.keys(extensions).length > 0) baseCapabilities["extensions"] = extensions;
|
|
8165
|
+
return {
|
|
8166
|
+
instructions,
|
|
8167
|
+
capabilities: baseCapabilities,
|
|
8168
|
+
serverInfo: scope.metadata.info
|
|
8169
|
+
};
|
|
8170
|
+
}
|
|
8171
|
+
var init_build_scoped_server_options = __esm({
|
|
8172
|
+
"libs/sdk/src/transport/build-scoped-server-options.ts"() {
|
|
8173
|
+
"use strict";
|
|
8174
|
+
init_task();
|
|
8175
|
+
}
|
|
8176
|
+
});
|
|
8177
|
+
|
|
8063
8178
|
// libs/sdk/src/transport/mcp-handlers/mcp-error.utils.ts
|
|
8064
8179
|
function toSdkMcpError(err) {
|
|
8065
8180
|
if (err && typeof err === "object") {
|
|
@@ -8328,6 +8443,8 @@ var init_notification_service = __esm({
|
|
|
8328
8443
|
this.options = options;
|
|
8329
8444
|
this.logger = scope.logger.child("NotificationService");
|
|
8330
8445
|
}
|
|
8446
|
+
scope;
|
|
8447
|
+
options;
|
|
8331
8448
|
logger;
|
|
8332
8449
|
servers = /* @__PURE__ */ new Map();
|
|
8333
8450
|
unsubscribers = [];
|
|
@@ -10748,58 +10865,7 @@ async function createInMemoryServer(scope, options) {
|
|
|
10748
10865
|
const sessionId = options?.sessionId ?? `in-memory:${(0, import_utils21.randomUUID)()}`;
|
|
10749
10866
|
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
10750
10867
|
let currentAuthInfo = options?.authInfo ?? {};
|
|
10751
|
-
const
|
|
10752
|
-
const hasPrompts = scope.prompts.hasAny() || hasRemoteApps;
|
|
10753
|
-
const hasResources = scope.resources.hasAny() || hasRemoteApps;
|
|
10754
|
-
const completionsCapability = hasPrompts || hasResources ? { completions: {} } : {};
|
|
10755
|
-
const remoteCapabilities = hasRemoteApps ? {
|
|
10756
|
-
tools: { listChanged: true },
|
|
10757
|
-
resources: { subscribe: true, listChanged: true },
|
|
10758
|
-
prompts: { listChanged: true }
|
|
10759
|
-
} : {};
|
|
10760
|
-
const skillsCapabilities = scope.skills?.getCapabilities() ?? {};
|
|
10761
|
-
const toolsCapabilities = scope.tools.getCapabilities();
|
|
10762
|
-
const resourcesCapabilities = scope.resources.getCapabilities();
|
|
10763
|
-
const promptsCapabilities = scope.prompts.getCapabilities();
|
|
10764
|
-
const agentsCapabilities = scope.agents.getCapabilities();
|
|
10765
|
-
const taskCapabilities = computeTaskCapabilities(scope);
|
|
10766
|
-
const fragments = [
|
|
10767
|
-
remoteCapabilities,
|
|
10768
|
-
toolsCapabilities,
|
|
10769
|
-
resourcesCapabilities,
|
|
10770
|
-
promptsCapabilities,
|
|
10771
|
-
agentsCapabilities,
|
|
10772
|
-
skillsCapabilities,
|
|
10773
|
-
completionsCapability,
|
|
10774
|
-
taskCapabilities
|
|
10775
|
-
];
|
|
10776
|
-
const experimental = {};
|
|
10777
|
-
const extensions = {};
|
|
10778
|
-
for (const cap2 of fragments) {
|
|
10779
|
-
if (cap2["experimental"] && typeof cap2["experimental"] === "object") {
|
|
10780
|
-
Object.assign(experimental, cap2["experimental"]);
|
|
10781
|
-
}
|
|
10782
|
-
if (cap2["extensions"] && typeof cap2["extensions"] === "object") {
|
|
10783
|
-
Object.assign(extensions, cap2["extensions"]);
|
|
10784
|
-
}
|
|
10785
|
-
}
|
|
10786
|
-
const baseCapabilities = {
|
|
10787
|
-
...remoteCapabilities,
|
|
10788
|
-
...toolsCapabilities,
|
|
10789
|
-
...resourcesCapabilities,
|
|
10790
|
-
...promptsCapabilities,
|
|
10791
|
-
...agentsCapabilities,
|
|
10792
|
-
...completionsCapability,
|
|
10793
|
-
...taskCapabilities,
|
|
10794
|
-
logging: {}
|
|
10795
|
-
};
|
|
10796
|
-
if (Object.keys(experimental).length > 0) baseCapabilities["experimental"] = experimental;
|
|
10797
|
-
if (Object.keys(extensions).length > 0) baseCapabilities["extensions"] = extensions;
|
|
10798
|
-
const serverOptions = {
|
|
10799
|
-
instructions: "",
|
|
10800
|
-
capabilities: baseCapabilities,
|
|
10801
|
-
serverInfo: scope.metadata.info
|
|
10802
|
-
};
|
|
10868
|
+
const serverOptions = buildScopedServerOptions(scope);
|
|
10803
10869
|
const mcpServer = new McpServer2(scope.metadata.info, serverOptions);
|
|
10804
10870
|
const handlers = createMcpHandlers2({ scope, serverOptions });
|
|
10805
10871
|
for (const handler of handlers) {
|
|
@@ -10834,7 +10900,7 @@ var init_in_memory_server = __esm({
|
|
|
10834
10900
|
"libs/sdk/src/transport/in-memory-server.ts"() {
|
|
10835
10901
|
"use strict";
|
|
10836
10902
|
import_utils21 = require("@frontmcp/utils");
|
|
10837
|
-
|
|
10903
|
+
init_build_scoped_server_options();
|
|
10838
10904
|
}
|
|
10839
10905
|
});
|
|
10840
10906
|
|
|
@@ -10844,29 +10910,29 @@ __export(direct_client_exports, {
|
|
|
10844
10910
|
DirectClientImpl: () => DirectClientImpl
|
|
10845
10911
|
});
|
|
10846
10912
|
function findFileFromRoot(root, relativePath) {
|
|
10847
|
-
const
|
|
10913
|
+
const fs = require("fs");
|
|
10848
10914
|
const path3 = require("path");
|
|
10849
10915
|
const cleanRelative = relativePath.replace(/^\.\//, "");
|
|
10850
10916
|
const searchDirs = ["src", "."];
|
|
10851
10917
|
for (const srcDir of searchDirs) {
|
|
10852
10918
|
const srcRoot = path3.join(root, srcDir);
|
|
10853
|
-
if (!
|
|
10854
|
-
const found = walkForFile(srcRoot, cleanRelative,
|
|
10919
|
+
if (!fs.existsSync(srcRoot)) continue;
|
|
10920
|
+
const found = walkForFile(srcRoot, cleanRelative, fs, path3);
|
|
10855
10921
|
if (found) return found;
|
|
10856
10922
|
}
|
|
10857
10923
|
return void 0;
|
|
10858
10924
|
}
|
|
10859
|
-
function walkForFile(dir, targetRelative,
|
|
10925
|
+
function walkForFile(dir, targetRelative, fs, path3, maxDepth = 10) {
|
|
10860
10926
|
const candidate = path3.join(dir, targetRelative);
|
|
10861
|
-
if (
|
|
10927
|
+
if (fs.existsSync(candidate)) {
|
|
10862
10928
|
return { absolute: candidate, baseDir: dir };
|
|
10863
10929
|
}
|
|
10864
10930
|
if (maxDepth <= 0) return void 0;
|
|
10865
10931
|
try {
|
|
10866
|
-
const entries =
|
|
10932
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
10867
10933
|
for (const entry of entries) {
|
|
10868
10934
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules" && entry.name !== "dist") {
|
|
10869
|
-
const result = walkForFile(path3.join(dir, entry.name), targetRelative,
|
|
10935
|
+
const result = walkForFile(path3.join(dir, entry.name), targetRelative, fs, path3, maxDepth - 1);
|
|
10870
10936
|
if (result) return result;
|
|
10871
10937
|
}
|
|
10872
10938
|
}
|
|
@@ -12049,14 +12115,16 @@ var init_health2 = __esm({
|
|
|
12049
12115
|
});
|
|
12050
12116
|
|
|
12051
12117
|
// libs/sdk/src/logger/instances/instance.file-logger.ts
|
|
12118
|
+
function getFs() {
|
|
12119
|
+
return _fs ??= require("fs");
|
|
12120
|
+
}
|
|
12052
12121
|
function stripAnsi(str) {
|
|
12053
12122
|
return str.split(ESC).map((s) => s.replace(/\[[0-9;]*m/, "")).join("");
|
|
12054
12123
|
}
|
|
12055
|
-
var
|
|
12124
|
+
var os, path2, _fs, LOG_LEVEL_LABELS, ESC, DEFAULT_LOGS_MAX, FileLogTransportInstance;
|
|
12056
12125
|
var init_instance_file_logger = __esm({
|
|
12057
12126
|
"libs/sdk/src/logger/instances/instance.file-logger.ts"() {
|
|
12058
12127
|
"use strict";
|
|
12059
|
-
fs = __toESM(require("fs"));
|
|
12060
12128
|
os = __toESM(require("os"));
|
|
12061
12129
|
path2 = __toESM(require("path"));
|
|
12062
12130
|
init_common();
|
|
@@ -12086,10 +12154,10 @@ var init_instance_file_logger = __esm({
|
|
|
12086
12154
|
return;
|
|
12087
12155
|
}
|
|
12088
12156
|
try {
|
|
12089
|
-
|
|
12157
|
+
getFs().mkdirSync(this.logDir, { recursive: true });
|
|
12090
12158
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "_");
|
|
12091
12159
|
const filePath = path2.join(this.logDir, `${this.appName}-${ts}.log`);
|
|
12092
|
-
this.fd =
|
|
12160
|
+
this.fd = getFs().openSync(filePath, "a");
|
|
12093
12161
|
this.rotate(isNaN(logsMax) ? DEFAULT_LOGS_MAX : logsMax);
|
|
12094
12162
|
} catch {
|
|
12095
12163
|
this.fd = void 0;
|
|
@@ -12099,7 +12167,7 @@ var init_instance_file_logger = __esm({
|
|
|
12099
12167
|
close() {
|
|
12100
12168
|
if (this.fd !== void 0) {
|
|
12101
12169
|
try {
|
|
12102
|
-
|
|
12170
|
+
getFs().closeSync(this.fd);
|
|
12103
12171
|
} catch {
|
|
12104
12172
|
}
|
|
12105
12173
|
this.fd = void 0;
|
|
@@ -12114,7 +12182,7 @@ var init_instance_file_logger = __esm({
|
|
|
12114
12182
|
const line = `[${ts}] ${level}${prefix} ${message}
|
|
12115
12183
|
`;
|
|
12116
12184
|
try {
|
|
12117
|
-
|
|
12185
|
+
getFs().writeSync(this.fd, line);
|
|
12118
12186
|
} catch {
|
|
12119
12187
|
}
|
|
12120
12188
|
}
|
|
@@ -12122,12 +12190,12 @@ var init_instance_file_logger = __esm({
|
|
|
12122
12190
|
rotate(maxFiles) {
|
|
12123
12191
|
try {
|
|
12124
12192
|
const prefix = `${this.appName}-`;
|
|
12125
|
-
const files =
|
|
12193
|
+
const files = getFs().readdirSync(this.logDir).filter((f) => f.startsWith(prefix) && f.endsWith(".log")).sort();
|
|
12126
12194
|
const excess = files.length - maxFiles;
|
|
12127
12195
|
if (excess <= 0) return;
|
|
12128
12196
|
for (let i = 0; i < excess; i++) {
|
|
12129
12197
|
try {
|
|
12130
|
-
|
|
12198
|
+
getFs().unlinkSync(path2.join(this.logDir, files[i]));
|
|
12131
12199
|
} catch {
|
|
12132
12200
|
}
|
|
12133
12201
|
}
|
|
@@ -12285,6 +12353,8 @@ var init_instance_logger = __esm({
|
|
|
12285
12353
|
this.transports = transports;
|
|
12286
12354
|
this.consoleTransport = consoleTransport;
|
|
12287
12355
|
}
|
|
12356
|
+
config;
|
|
12357
|
+
getTransports;
|
|
12288
12358
|
level;
|
|
12289
12359
|
prefix;
|
|
12290
12360
|
transports;
|
|
@@ -15188,6 +15258,7 @@ var init_tool_instance = __esm({
|
|
|
15188
15258
|
super(args);
|
|
15189
15259
|
this.record = record;
|
|
15190
15260
|
}
|
|
15261
|
+
record;
|
|
15191
15262
|
execute(input) {
|
|
15192
15263
|
return this.record.provide(input, this);
|
|
15193
15264
|
}
|
|
@@ -15294,6 +15365,10 @@ var init_base_adapter = __esm({
|
|
|
15294
15365
|
this.raw = raw;
|
|
15295
15366
|
this.name = "LlmAdapterError";
|
|
15296
15367
|
}
|
|
15368
|
+
provider;
|
|
15369
|
+
code;
|
|
15370
|
+
statusCode;
|
|
15371
|
+
raw;
|
|
15297
15372
|
};
|
|
15298
15373
|
}
|
|
15299
15374
|
});
|
|
@@ -16244,6 +16319,7 @@ var init_providers = __esm({
|
|
|
16244
16319
|
constructor(options) {
|
|
16245
16320
|
this.options = options;
|
|
16246
16321
|
}
|
|
16322
|
+
options;
|
|
16247
16323
|
adapter = null;
|
|
16248
16324
|
getAdapter() {
|
|
16249
16325
|
if (this.adapter) {
|
|
@@ -16528,6 +16604,8 @@ var init_flow_context_providers = __esm({
|
|
|
16528
16604
|
this.baseProviders = baseProviders;
|
|
16529
16605
|
this.contextDeps = contextDeps;
|
|
16530
16606
|
}
|
|
16607
|
+
baseProviders;
|
|
16608
|
+
contextDeps;
|
|
16531
16609
|
get(token) {
|
|
16532
16610
|
if (this.contextDeps.has(token)) {
|
|
16533
16611
|
return this.contextDeps.get(token);
|
|
@@ -17279,6 +17357,7 @@ var init_prompt_instance = __esm({
|
|
|
17279
17357
|
super(args);
|
|
17280
17358
|
this.record = record;
|
|
17281
17359
|
}
|
|
17360
|
+
record;
|
|
17282
17361
|
execute(args) {
|
|
17283
17362
|
return this.record.provide(args, this);
|
|
17284
17363
|
}
|
|
@@ -19446,6 +19525,7 @@ var init_resource_instance = __esm({
|
|
|
19446
19525
|
super(args);
|
|
19447
19526
|
this.record = record;
|
|
19448
19527
|
}
|
|
19528
|
+
record;
|
|
19449
19529
|
execute(uri, params) {
|
|
19450
19530
|
return this.record.provide(uri, params, this);
|
|
19451
19531
|
}
|
|
@@ -23080,6 +23160,8 @@ var init_flow_interface = __esm({
|
|
|
23080
23160
|
this.type = type;
|
|
23081
23161
|
this.output = output;
|
|
23082
23162
|
}
|
|
23163
|
+
type;
|
|
23164
|
+
output;
|
|
23083
23165
|
static respond(output) {
|
|
23084
23166
|
throw new _FlowControl("respond", output);
|
|
23085
23167
|
}
|
|
@@ -23108,6 +23190,11 @@ var init_flow_interface = __esm({
|
|
|
23108
23190
|
this.input = metadata.inputSchema?.parse?.(rawInput);
|
|
23109
23191
|
this.scopeLogger = scope.logger;
|
|
23110
23192
|
}
|
|
23193
|
+
metadata;
|
|
23194
|
+
rawInput;
|
|
23195
|
+
scope;
|
|
23196
|
+
appendContextHooks;
|
|
23197
|
+
deps;
|
|
23111
23198
|
input;
|
|
23112
23199
|
state = FlowState.create({});
|
|
23113
23200
|
scopeLogger;
|
|
@@ -23760,6 +23847,18 @@ async function writeHttpResponse(res, value) {
|
|
|
23760
23847
|
res.status(out.status).end();
|
|
23761
23848
|
return;
|
|
23762
23849
|
}
|
|
23850
|
+
case "web-response": {
|
|
23851
|
+
const r = out.response;
|
|
23852
|
+
r.headers.forEach((v, k) => res.setHeader(k, v));
|
|
23853
|
+
res.status(r.status);
|
|
23854
|
+
if (r.body) {
|
|
23855
|
+
for await (const chunk of r.body) {
|
|
23856
|
+
res.write(chunk);
|
|
23857
|
+
}
|
|
23858
|
+
}
|
|
23859
|
+
res.end();
|
|
23860
|
+
return;
|
|
23861
|
+
}
|
|
23763
23862
|
}
|
|
23764
23863
|
}
|
|
23765
23864
|
var import_utils50;
|
|
@@ -23978,6 +24077,34 @@ var init_flow_instance = __esm({
|
|
|
23978
24077
|
const results = await Promise.all(canActivate.map((m) => m(request, this.scope)));
|
|
23979
24078
|
return results.every((r) => r);
|
|
23980
24079
|
}
|
|
24080
|
+
/**
|
|
24081
|
+
* Express-equivalent HTTP match for runtimes that have NO middleware server
|
|
24082
|
+
* (the Cloudflare Worker / web-fetch handler, where `registerMiddleware` is a
|
|
24083
|
+
* no-op so flows never mount as routes). It mirrors how Express dispatches:
|
|
24084
|
+
* method + `middleware.path` (mounted as a prefix) + `canActivate`.
|
|
24085
|
+
*
|
|
24086
|
+
* Only flows with a SPECIFIC matcher qualify — a `middleware.path` (e.g.
|
|
24087
|
+
* `/oauth/token`) and/or a `canActivate` (static class method or
|
|
24088
|
+
* `middleware.canActivate`, e.g. the well-known PRM path set). A bare
|
|
24089
|
+
* `{ method }` middleware is too broad to safely claim an arbitrary request,
|
|
24090
|
+
* so it returns false. Used by the web-fetch handler to serve auth/well-known/
|
|
24091
|
+
* oauth endpoints through the real flow pipeline.
|
|
24092
|
+
*/
|
|
24093
|
+
async matchHttp(request) {
|
|
24094
|
+
const mw = this.metadata.middleware;
|
|
24095
|
+
if (!mw) return false;
|
|
24096
|
+
const path3 = typeof mw.path === "string" ? mw.path : "";
|
|
24097
|
+
const hasStaticCanActivate = typeof this.FlowClass.canActivate === "function";
|
|
24098
|
+
const hasMwCanActivate = (mw.canActivate?.length ?? 0) > 0;
|
|
24099
|
+
if (!path3 && !hasStaticCanActivate && !hasMwCanActivate) return false;
|
|
24100
|
+
if (this.method && request.method !== this.method) return false;
|
|
24101
|
+
if (path3) {
|
|
24102
|
+
const reqPath = request.path;
|
|
24103
|
+
const prefix = path3.endsWith("/") ? path3 : `${path3}/`;
|
|
24104
|
+
if (reqPath !== path3 && !reqPath.startsWith(prefix)) return false;
|
|
24105
|
+
}
|
|
24106
|
+
return this.canActivate(request);
|
|
24107
|
+
}
|
|
23981
24108
|
/**
|
|
23982
24109
|
* Get FrontMcpContextStorage from providers (with fallback).
|
|
23983
24110
|
* Returns undefined if not available (backward compatibility).
|
|
@@ -24380,6 +24507,21 @@ var init_flow_registry = __esm({
|
|
|
24380
24507
|
)
|
|
24381
24508
|
);
|
|
24382
24509
|
}
|
|
24510
|
+
/**
|
|
24511
|
+
* Find the name of the first registered flow whose HTTP matcher claims this
|
|
24512
|
+
* request (method + `middleware.path` prefix + `canActivate`). For runtimes
|
|
24513
|
+
* with no middleware server (the web-fetch/Worker handler), this replaces
|
|
24514
|
+
* Express's route dispatch so auth/well-known/oauth flows still run. Returns
|
|
24515
|
+
* `undefined` when no flow matches.
|
|
24516
|
+
*/
|
|
24517
|
+
async findHttpFlowName(request, exclude = /* @__PURE__ */ new Set()) {
|
|
24518
|
+
for (const instance of this.instances.values()) {
|
|
24519
|
+
const name41 = instance.name;
|
|
24520
|
+
if (exclude.has(name41)) continue;
|
|
24521
|
+
if (await instance.matchHttp(request)) return name41;
|
|
24522
|
+
}
|
|
24523
|
+
return void 0;
|
|
24524
|
+
}
|
|
24383
24525
|
/**
|
|
24384
24526
|
* Get FrontMcpContextStorage from providers (with fallback).
|
|
24385
24527
|
* Returns undefined if not available (backward compatibility).
|
|
@@ -24969,12 +25111,51 @@ var init_skill_validation_error = __esm({
|
|
|
24969
25111
|
}
|
|
24970
25112
|
});
|
|
24971
25113
|
|
|
25114
|
+
// libs/sdk/src/scope/optional-dependency.util.ts
|
|
25115
|
+
function probeOptionalDependency(moduleName, loadError, resolve) {
|
|
25116
|
+
let resolvedPath;
|
|
25117
|
+
try {
|
|
25118
|
+
resolvedPath = resolve(moduleName);
|
|
25119
|
+
} catch {
|
|
25120
|
+
resolvedPath = void 0;
|
|
25121
|
+
}
|
|
25122
|
+
const error = loadError instanceof Error ? loadError.message : String(loadError);
|
|
25123
|
+
return resolvedPath ? { status: "load-failed", resolvedPath, error } : { status: "not-installed", error };
|
|
25124
|
+
}
|
|
25125
|
+
async function importOptionalPeer(moduleName, importer, resolve, feature) {
|
|
25126
|
+
try {
|
|
25127
|
+
return await importer();
|
|
25128
|
+
} catch (cause) {
|
|
25129
|
+
const probe = probeOptionalDependency(moduleName, cause, resolve);
|
|
25130
|
+
if (probe.status === "not-installed") {
|
|
25131
|
+
throw new Error(
|
|
25132
|
+
`@frontmcp/sdk ${feature} needs the optional peer dependency '${moduleName}'. Install it in your project (e.g. \`npm i ${moduleName}\`).`,
|
|
25133
|
+
{ cause }
|
|
25134
|
+
);
|
|
25135
|
+
}
|
|
25136
|
+
throw new Error(
|
|
25137
|
+
`@frontmcp/sdk ${feature} found '${moduleName}' at ${probe.resolvedPath} but it failed to load \u2014 reinstalling will not help. This is usually an export-condition, transpile, or transitive-peer mismatch. Original error: ${probe.error}`,
|
|
25138
|
+
{ cause }
|
|
25139
|
+
);
|
|
25140
|
+
}
|
|
25141
|
+
}
|
|
25142
|
+
var init_optional_dependency_util = __esm({
|
|
25143
|
+
"libs/sdk/src/scope/optional-dependency.util.ts"() {
|
|
25144
|
+
"use strict";
|
|
25145
|
+
}
|
|
25146
|
+
});
|
|
25147
|
+
|
|
24972
25148
|
// libs/sdk/src/skill/providers/memory-skill.provider.ts
|
|
24973
|
-
|
|
25149
|
+
function isSnapshotCapable(db) {
|
|
25150
|
+
const d = db;
|
|
25151
|
+
return typeof d.toSnapshot === "function" && typeof d.loadSnapshot === "function";
|
|
25152
|
+
}
|
|
25153
|
+
var import_utils53, STOP_WORDS, MemorySkillProvider;
|
|
24974
25154
|
var init_memory_skill_provider = __esm({
|
|
24975
25155
|
"libs/sdk/src/skill/providers/memory-skill.provider.ts"() {
|
|
24976
25156
|
"use strict";
|
|
24977
|
-
|
|
25157
|
+
import_utils53 = require("@frontmcp/utils");
|
|
25158
|
+
init_optional_dependency_util();
|
|
24978
25159
|
STOP_WORDS = /* @__PURE__ */ new Set([
|
|
24979
25160
|
// Articles & Determiners
|
|
24980
25161
|
"the",
|
|
@@ -25050,19 +25231,118 @@ var init_memory_skill_provider = __esm({
|
|
|
25050
25231
|
MemorySkillProvider = class {
|
|
25051
25232
|
type = "memory";
|
|
25052
25233
|
vectorDB;
|
|
25234
|
+
vectorDBReady;
|
|
25053
25235
|
skills = /* @__PURE__ */ new Map();
|
|
25054
25236
|
defaultTopK;
|
|
25055
25237
|
defaultMinScore;
|
|
25056
25238
|
toolValidator;
|
|
25057
25239
|
initialized = false;
|
|
25240
|
+
/** Ranking mode passed to the vector DB (cosine | bm25). */
|
|
25241
|
+
scoring;
|
|
25242
|
+
/** Optional snapshot cache for fast cold-start (e.g. KV-backed on the edge). */
|
|
25243
|
+
indexCache;
|
|
25244
|
+
/**
|
|
25245
|
+
* Whether the vector index reflects the current document set. Adds/removes
|
|
25246
|
+
* mark it stale; the FIRST search after a mutation builds (or restores) it
|
|
25247
|
+
* exactly once. This defers the expensive IDF/embedding pass off the
|
|
25248
|
+
* registration hot-path — registering N skills no longer triggers N reindexes.
|
|
25249
|
+
*/
|
|
25250
|
+
indexReady = false;
|
|
25058
25251
|
constructor(options = {}) {
|
|
25059
25252
|
this.defaultTopK = options.defaultTopK ?? 10;
|
|
25060
25253
|
this.defaultMinScore = options.defaultMinScore ?? 0.1;
|
|
25061
25254
|
this.toolValidator = options.toolValidator;
|
|
25062
|
-
this.
|
|
25255
|
+
this.scoring = options.scoring ?? "cosine";
|
|
25256
|
+
this.indexCache = options.indexCache;
|
|
25257
|
+
this.vectorDBReady = this.initVectorDB();
|
|
25258
|
+
this.vectorDBReady.catch(() => void 0);
|
|
25259
|
+
}
|
|
25260
|
+
async initVectorDB() {
|
|
25261
|
+
const mod = await importOptionalPeer(
|
|
25262
|
+
"vectoriadb",
|
|
25263
|
+
() => import("vectoriadb"),
|
|
25264
|
+
require.resolve,
|
|
25265
|
+
"skill storage"
|
|
25266
|
+
);
|
|
25267
|
+
const dbConfig = {
|
|
25063
25268
|
defaultTopK: this.defaultTopK,
|
|
25064
25269
|
defaultSimilarityThreshold: this.defaultMinScore
|
|
25065
|
-
}
|
|
25270
|
+
};
|
|
25271
|
+
if (this.scoring !== "cosine") dbConfig.scoring = this.scoring;
|
|
25272
|
+
this.vectorDB = new mod.TFIDFVectoria(dbConfig);
|
|
25273
|
+
}
|
|
25274
|
+
/**
|
|
25275
|
+
* Attach (or replace) the snapshot cache after construction — useful when the
|
|
25276
|
+
* cache binding only exists at request time (e.g. a Cloudflare KV namespace on
|
|
25277
|
+
* `env`). Marks the index stale so the next search consults the new cache.
|
|
25278
|
+
*/
|
|
25279
|
+
setIndexCache(cache2) {
|
|
25280
|
+
this.indexCache = cache2;
|
|
25281
|
+
this.indexReady = false;
|
|
25282
|
+
}
|
|
25283
|
+
/**
|
|
25284
|
+
* Ensure the vector index reflects the current document set, building it AT
|
|
25285
|
+
* MOST once per mutation batch. When a snapshot cache is configured and the
|
|
25286
|
+
* vector DB supports snapshots, a content-hash hit restores the index without
|
|
25287
|
+
* recomputing IDF/embeddings (the cold-start fast path); a miss rebuilds and
|
|
25288
|
+
* persists the snapshot for next time. Cache failures degrade to a local
|
|
25289
|
+
* rebuild — they never block search.
|
|
25290
|
+
*/
|
|
25291
|
+
async ensureIndexed() {
|
|
25292
|
+
if (this.indexReady) return;
|
|
25293
|
+
const db = await this.db();
|
|
25294
|
+
if (this.indexCache && isSnapshotCapable(db)) {
|
|
25295
|
+
const key = await this.computeIndexKey();
|
|
25296
|
+
try {
|
|
25297
|
+
const snapshot = await this.indexCache.get(key);
|
|
25298
|
+
if (snapshot !== void 0 && snapshot !== null) {
|
|
25299
|
+
db.loadSnapshot(snapshot);
|
|
25300
|
+
this.indexReady = true;
|
|
25301
|
+
return;
|
|
25302
|
+
}
|
|
25303
|
+
} catch {
|
|
25304
|
+
}
|
|
25305
|
+
this.reindexNow(db);
|
|
25306
|
+
this.indexReady = true;
|
|
25307
|
+
try {
|
|
25308
|
+
await this.indexCache.set(key, db.toSnapshot());
|
|
25309
|
+
} catch {
|
|
25310
|
+
}
|
|
25311
|
+
return;
|
|
25312
|
+
}
|
|
25313
|
+
this.reindexNow(db);
|
|
25314
|
+
this.indexReady = true;
|
|
25315
|
+
}
|
|
25316
|
+
/**
|
|
25317
|
+
* Eagerly build (or restore from cache) the search index now, rather than on
|
|
25318
|
+
* the first search. A host calls this after registration completes to move the
|
|
25319
|
+
* one-time index build off the first request's critical path (e.g. the edge
|
|
25320
|
+
* does this right after attaching the KV cache).
|
|
25321
|
+
*/
|
|
25322
|
+
async warm() {
|
|
25323
|
+
await this.ensureIndexed();
|
|
25324
|
+
}
|
|
25325
|
+
/** Force the vector DB to (re)compute its index now. */
|
|
25326
|
+
reindexNow(db) {
|
|
25327
|
+
db.reindex();
|
|
25328
|
+
}
|
|
25329
|
+
/**
|
|
25330
|
+
* Stable content hash of the indexed skill set + scoring mode. Changing any
|
|
25331
|
+
* skill's searchable text, the set of skills, or the scoring mode changes the
|
|
25332
|
+
* key, so a stale snapshot is never restored.
|
|
25333
|
+
*/
|
|
25334
|
+
async computeIndexKey() {
|
|
25335
|
+
const parts = Array.from(this.skills.values()).map((s) => `${s.id}\0${this.buildSearchableText(s)}`).sort();
|
|
25336
|
+
const canonical = `frontmcp-skill-index:v1|${this.scoring}|${this.skills.size}|${parts.join("")}`;
|
|
25337
|
+
return (0, import_utils53.sha256Hex)(canonical);
|
|
25338
|
+
}
|
|
25339
|
+
/** Await the lazy vectoriadb load (throws the clear install hint if absent). */
|
|
25340
|
+
async db() {
|
|
25341
|
+
await this.vectorDBReady;
|
|
25342
|
+
if (!this.vectorDB) {
|
|
25343
|
+
throw new Error("Vector DB not initialized; await this.vectorDBReady before use.");
|
|
25344
|
+
}
|
|
25345
|
+
return this.vectorDB;
|
|
25066
25346
|
}
|
|
25067
25347
|
/**
|
|
25068
25348
|
* Set the tool validator after construction.
|
|
@@ -25072,9 +25352,13 @@ var init_memory_skill_provider = __esm({
|
|
|
25072
25352
|
this.toolValidator = validator;
|
|
25073
25353
|
}
|
|
25074
25354
|
async initialize() {
|
|
25355
|
+
await this.vectorDBReady;
|
|
25075
25356
|
this.initialized = true;
|
|
25076
25357
|
}
|
|
25077
25358
|
async search(query, options = {}) {
|
|
25359
|
+
if (query.trim().length === 0) {
|
|
25360
|
+
return [];
|
|
25361
|
+
}
|
|
25078
25362
|
const {
|
|
25079
25363
|
topK = this.defaultTopK,
|
|
25080
25364
|
tags,
|
|
@@ -25105,10 +25389,16 @@ var init_memory_skill_provider = __esm({
|
|
|
25105
25389
|
}
|
|
25106
25390
|
return true;
|
|
25107
25391
|
};
|
|
25108
|
-
|
|
25392
|
+
const db = await this.db();
|
|
25393
|
+
await this.ensureIndexed();
|
|
25394
|
+
let results = await db.search(query, {
|
|
25109
25395
|
topK,
|
|
25110
25396
|
threshold: minScore,
|
|
25111
|
-
filter
|
|
25397
|
+
filter,
|
|
25398
|
+
// `negativeQuery` (anti-query demotion) is honored by newer vectoriadb
|
|
25399
|
+
// versions; older ones ignore the extra field.
|
|
25400
|
+
...options.negativeQuery !== void 0 ? { negativeQuery: options.negativeQuery } : {},
|
|
25401
|
+
...options.negativeWeight !== void 0 ? { negativeWeight: options.negativeWeight } : {}
|
|
25112
25402
|
});
|
|
25113
25403
|
if (results.length === 0 && query.trim().length > 0 && this.skills.size > 0) {
|
|
25114
25404
|
results = this.fallbackTextSearch(query, topK, filter);
|
|
@@ -25216,29 +25506,35 @@ var init_memory_skill_provider = __esm({
|
|
|
25216
25506
|
}
|
|
25217
25507
|
async add(skill) {
|
|
25218
25508
|
this.skills.set(skill.id, skill);
|
|
25219
|
-
this.indexSkill(skill);
|
|
25509
|
+
await this.indexSkill(skill);
|
|
25220
25510
|
}
|
|
25221
25511
|
async update(skillId, skill) {
|
|
25222
25512
|
const normalizedSkill = skill.id !== skillId ? { ...skill, id: skillId } : skill;
|
|
25223
|
-
|
|
25224
|
-
|
|
25513
|
+
const db = await this.db();
|
|
25514
|
+
if (db.hasDocument(skillId)) {
|
|
25515
|
+
db.removeDocument(skillId);
|
|
25225
25516
|
}
|
|
25226
25517
|
this.skills.set(skillId, normalizedSkill);
|
|
25227
|
-
this.indexSkill(normalizedSkill);
|
|
25518
|
+
await this.indexSkill(normalizedSkill);
|
|
25228
25519
|
}
|
|
25229
25520
|
async remove(skillId) {
|
|
25230
25521
|
this.skills.delete(skillId);
|
|
25231
|
-
|
|
25232
|
-
|
|
25522
|
+
const db = await this.db();
|
|
25523
|
+
if (db.hasDocument(skillId)) {
|
|
25524
|
+
db.removeDocument(skillId);
|
|
25233
25525
|
}
|
|
25526
|
+
this.indexReady = false;
|
|
25234
25527
|
}
|
|
25235
25528
|
async clear() {
|
|
25236
25529
|
this.skills.clear();
|
|
25237
|
-
this.
|
|
25530
|
+
const db = await this.db().catch(() => void 0);
|
|
25531
|
+
db?.clear();
|
|
25532
|
+
this.indexReady = false;
|
|
25238
25533
|
}
|
|
25239
25534
|
async dispose() {
|
|
25240
25535
|
this.skills.clear();
|
|
25241
|
-
this.
|
|
25536
|
+
const db = await this.db().catch(() => void 0);
|
|
25537
|
+
db?.clear();
|
|
25242
25538
|
this.initialized = false;
|
|
25243
25539
|
}
|
|
25244
25540
|
/**
|
|
@@ -25257,13 +25553,14 @@ var init_memory_skill_provider = __esm({
|
|
|
25257
25553
|
}
|
|
25258
25554
|
};
|
|
25259
25555
|
});
|
|
25260
|
-
this.
|
|
25261
|
-
|
|
25556
|
+
const db = await this.db();
|
|
25557
|
+
db.addDocuments(documents);
|
|
25558
|
+
this.indexReady = false;
|
|
25262
25559
|
}
|
|
25263
25560
|
/**
|
|
25264
25561
|
* Index a single skill in the vector database.
|
|
25265
25562
|
*/
|
|
25266
|
-
indexSkill(skill) {
|
|
25563
|
+
async indexSkill(skill) {
|
|
25267
25564
|
const document = {
|
|
25268
25565
|
id: skill.id,
|
|
25269
25566
|
text: this.buildSearchableText(skill),
|
|
@@ -25273,8 +25570,9 @@ var init_memory_skill_provider = __esm({
|
|
|
25273
25570
|
skill
|
|
25274
25571
|
}
|
|
25275
25572
|
};
|
|
25276
|
-
this.
|
|
25277
|
-
|
|
25573
|
+
const db = await this.db();
|
|
25574
|
+
db.addDocuments([document]);
|
|
25575
|
+
this.indexReady = false;
|
|
25278
25576
|
}
|
|
25279
25577
|
/**
|
|
25280
25578
|
* Build searchable text for TF-IDF indexing.
|
|
@@ -25688,7 +25986,7 @@ function createSkillInstance(record, providers, owner) {
|
|
|
25688
25986
|
}
|
|
25689
25987
|
function getSkillManifestMainDir() {
|
|
25690
25988
|
try {
|
|
25691
|
-
const cwd = (0,
|
|
25989
|
+
const cwd = (0, import_utils54.getCwd)();
|
|
25692
25990
|
return cwd && cwd.length > 0 ? cwd : void 0;
|
|
25693
25991
|
} catch {
|
|
25694
25992
|
return void 0;
|
|
@@ -25696,7 +25994,7 @@ function getSkillManifestMainDir() {
|
|
|
25696
25994
|
}
|
|
25697
25995
|
async function loadResourceWithManifestFallback(resourcePath, baseDir, skillName, resourceType, loader) {
|
|
25698
25996
|
if (!resourcePath) return void 0;
|
|
25699
|
-
let dir = resourcePath.startsWith("/") ? resourcePath : baseDir ? (0,
|
|
25997
|
+
let dir = resourcePath.startsWith("/") ? resourcePath : baseDir ? (0, import_utils54.pathResolve)(baseDir, resourcePath) : void 0;
|
|
25700
25998
|
if (dir) {
|
|
25701
25999
|
try {
|
|
25702
26000
|
return await loader(dir);
|
|
@@ -25720,9 +26018,9 @@ async function resolveFromSkillManifest(skillName) {
|
|
|
25720
26018
|
return void 0;
|
|
25721
26019
|
}
|
|
25722
26020
|
try {
|
|
25723
|
-
const manifestPath = (0,
|
|
25724
|
-
if (await (0,
|
|
25725
|
-
skillManifestCache = await (0,
|
|
26021
|
+
const manifestPath = (0, import_utils54.pathJoin)(mainDir2, "_skills", "manifest.json");
|
|
26022
|
+
if (await (0, import_utils54.fileExists)(manifestPath)) {
|
|
26023
|
+
skillManifestCache = await (0, import_utils54.readJSON)(manifestPath);
|
|
25726
26024
|
} else {
|
|
25727
26025
|
skillManifestCache = null;
|
|
25728
26026
|
return void 0;
|
|
@@ -25740,7 +26038,7 @@ async function resolveFromSkillManifest(skillName) {
|
|
|
25740
26038
|
if (!entry?.instructions) return void 0;
|
|
25741
26039
|
const mainDir = getSkillManifestMainDir();
|
|
25742
26040
|
if (!mainDir) return void 0;
|
|
25743
|
-
return (0,
|
|
26041
|
+
return (0, import_utils54.pathResolve)(mainDir, entry.instructions);
|
|
25744
26042
|
}
|
|
25745
26043
|
async function resolveResourceFromManifest(skillName, resourceType) {
|
|
25746
26044
|
await resolveFromSkillManifest(skillName);
|
|
@@ -25750,13 +26048,13 @@ async function resolveResourceFromManifest(skillName, resourceType) {
|
|
|
25750
26048
|
if (!relPath) return void 0;
|
|
25751
26049
|
const mainDir = getSkillManifestMainDir();
|
|
25752
26050
|
if (!mainDir) return void 0;
|
|
25753
|
-
return (0,
|
|
26051
|
+
return (0, import_utils54.pathResolve)(mainDir, relPath);
|
|
25754
26052
|
}
|
|
25755
|
-
var
|
|
26053
|
+
var import_utils54, SkillInstance, skillManifestCache;
|
|
25756
26054
|
var init_skill_instance = __esm({
|
|
25757
26055
|
"libs/sdk/src/skill/skill.instance.ts"() {
|
|
25758
26056
|
"use strict";
|
|
25759
|
-
|
|
26057
|
+
import_utils54 = require("@frontmcp/utils");
|
|
25760
26058
|
init_common();
|
|
25761
26059
|
init_skill_utils();
|
|
25762
26060
|
SkillInstance = class extends SkillEntry {
|
|
@@ -25839,7 +26137,7 @@ var init_skill_instance = __esm({
|
|
|
25839
26137
|
*/
|
|
25840
26138
|
getBaseDir() {
|
|
25841
26139
|
if (this.record.kind === "FILE" /* FILE */) {
|
|
25842
|
-
return (0,
|
|
26140
|
+
return (0, import_utils54.dirname)(this.record.filePath) || void 0;
|
|
25843
26141
|
}
|
|
25844
26142
|
if ((this.record.kind === "VALUE" /* VALUE */ || this.record.kind === "CLASS_TOKEN" /* CLASS_TOKEN */) && this.record.callerDir) {
|
|
25845
26143
|
return this.record.callerDir;
|
|
@@ -25942,12 +26240,12 @@ var init_skill_instance = __esm({
|
|
|
25942
26240
|
});
|
|
25943
26241
|
|
|
25944
26242
|
// libs/sdk/src/skill/skill.registry.ts
|
|
25945
|
-
var import_di22,
|
|
26243
|
+
var import_di22, import_utils55, SkillRegistry;
|
|
25946
26244
|
var init_skill_registry = __esm({
|
|
25947
26245
|
"libs/sdk/src/skill/skill.registry.ts"() {
|
|
25948
26246
|
"use strict";
|
|
25949
26247
|
import_di22 = require("@frontmcp/di");
|
|
25950
|
-
|
|
26248
|
+
import_utils55 = require("@frontmcp/utils");
|
|
25951
26249
|
init_availability();
|
|
25952
26250
|
init_errors();
|
|
25953
26251
|
init_regsitry();
|
|
@@ -26012,7 +26310,9 @@ var init_skill_registry = __esm({
|
|
|
26012
26310
|
this.options = options ?? {};
|
|
26013
26311
|
this.storageProvider = new MemorySkillProvider({
|
|
26014
26312
|
defaultTopK: 10,
|
|
26015
|
-
defaultMinScore: 0.1
|
|
26313
|
+
defaultMinScore: 0.1,
|
|
26314
|
+
...this.options.scoring ? { scoring: this.options.scoring } : {},
|
|
26315
|
+
...this.options.indexCache ? { indexCache: this.options.indexCache } : {}
|
|
26016
26316
|
});
|
|
26017
26317
|
this.buildGraph();
|
|
26018
26318
|
this.ready = this.initialize();
|
|
@@ -26150,8 +26450,8 @@ var init_skill_registry = __esm({
|
|
|
26150
26450
|
return skillVis === visibility;
|
|
26151
26451
|
});
|
|
26152
26452
|
}
|
|
26153
|
-
const ctx = (0,
|
|
26154
|
-
skills = skills.filter((s) => (0,
|
|
26453
|
+
const ctx = (0, import_utils55.getRuntimeContext)();
|
|
26454
|
+
skills = skills.filter((s) => (0, import_utils55.isEntryAvailable)(s.metadata.availableWhen, ctx));
|
|
26155
26455
|
return skills;
|
|
26156
26456
|
}
|
|
26157
26457
|
/**
|
|
@@ -26172,8 +26472,8 @@ var init_skill_registry = __esm({
|
|
|
26172
26472
|
getAlwaysLoadedSkills() {
|
|
26173
26473
|
let skills = this.listAllIndexed().map((r) => r.instance);
|
|
26174
26474
|
skills = skills.filter((s) => s.isAlwaysLoaded());
|
|
26175
|
-
const ctx = (0,
|
|
26176
|
-
skills = skills.filter((s) => (0,
|
|
26475
|
+
const ctx = (0, import_utils55.getRuntimeContext)();
|
|
26476
|
+
skills = skills.filter((s) => (0, import_utils55.isEntryAvailable)(s.metadata.availableWhen, ctx));
|
|
26177
26477
|
return skills;
|
|
26178
26478
|
}
|
|
26179
26479
|
/**
|
|
@@ -26222,6 +26522,31 @@ var init_skill_registry = __esm({
|
|
|
26222
26522
|
* provider update lagged or failed) would mask the newer dynamic content.
|
|
26223
26523
|
* Provider-only rows pass through unchanged; overlay-only rows are appended.
|
|
26224
26524
|
*/
|
|
26525
|
+
/**
|
|
26526
|
+
* Attach (or replace) the snapshot cache used to persist/restore the search
|
|
26527
|
+
* index — for runtimes where the cache binding only exists at request time
|
|
26528
|
+
* (e.g. a Cloudflare KV namespace on `env`). No-op if the storage provider
|
|
26529
|
+
* doesn't support index caching. Pair with {@link warmIndex} to build/restore
|
|
26530
|
+
* the index off the first request's critical path.
|
|
26531
|
+
*/
|
|
26532
|
+
setIndexCache(cache2) {
|
|
26533
|
+
const provider = this.storageProvider;
|
|
26534
|
+
if (typeof provider.setIndexCache === "function") {
|
|
26535
|
+
provider.setIndexCache(cache2);
|
|
26536
|
+
}
|
|
26537
|
+
}
|
|
26538
|
+
/**
|
|
26539
|
+
* Eagerly build (or restore from the cache) the search index now. Called by a
|
|
26540
|
+
* host after registration so the one-time index build (or a KV restore) is
|
|
26541
|
+
* paid here rather than inside the first `search`. No-op if unsupported.
|
|
26542
|
+
*/
|
|
26543
|
+
async warmIndex() {
|
|
26544
|
+
await this.ready;
|
|
26545
|
+
const provider = this.storageProvider;
|
|
26546
|
+
if (typeof provider.warm === "function") {
|
|
26547
|
+
await provider.warm();
|
|
26548
|
+
}
|
|
26549
|
+
}
|
|
26225
26550
|
async search(query, options) {
|
|
26226
26551
|
const baseResults = await this.storageProvider.search(query, options);
|
|
26227
26552
|
if (this.dynamicContents.size === 0) return baseResults;
|
|
@@ -26272,8 +26597,8 @@ var init_skill_registry = __esm({
|
|
|
26272
26597
|
}
|
|
26273
26598
|
}
|
|
26274
26599
|
if (localSkill) {
|
|
26275
|
-
const ctx = (0,
|
|
26276
|
-
if (!(0,
|
|
26600
|
+
const ctx = (0, import_utils55.getRuntimeContext)();
|
|
26601
|
+
if (!(0, import_utils55.isEntryAvailable)(localSkill.metadata.availableWhen, ctx)) {
|
|
26277
26602
|
return void 0;
|
|
26278
26603
|
}
|
|
26279
26604
|
const dynamicResolved = this.dynamicContents.get(localSkill.metadata.id ?? localSkill.metadata.name);
|
|
@@ -27272,6 +27597,7 @@ var init_agent_scope = __esm({
|
|
|
27272
27597
|
};
|
|
27273
27598
|
this.ready = this.initialize();
|
|
27274
27599
|
}
|
|
27600
|
+
metadata;
|
|
27275
27601
|
id;
|
|
27276
27602
|
entryPath;
|
|
27277
27603
|
routeBase;
|
|
@@ -27441,6 +27767,7 @@ var init_agent_scope = __esm({
|
|
|
27441
27767
|
this.fullPath = agentScope.fullPath;
|
|
27442
27768
|
this.logger = agentScope.logger;
|
|
27443
27769
|
}
|
|
27770
|
+
agentScope;
|
|
27444
27771
|
id;
|
|
27445
27772
|
entryPath;
|
|
27446
27773
|
routeBase;
|
|
@@ -28173,6 +28500,7 @@ var init_agent_instance = __esm({
|
|
|
28173
28500
|
super(args);
|
|
28174
28501
|
this.record = record;
|
|
28175
28502
|
}
|
|
28503
|
+
record;
|
|
28176
28504
|
async execute(input) {
|
|
28177
28505
|
return this.record.provide(input, this);
|
|
28178
28506
|
}
|
|
@@ -28196,12 +28524,12 @@ function dedupLineage4(l) {
|
|
|
28196
28524
|
}
|
|
28197
28525
|
return out;
|
|
28198
28526
|
}
|
|
28199
|
-
var import_di26,
|
|
28527
|
+
var import_di26, import_utils56, AgentRegistry;
|
|
28200
28528
|
var init_agent_registry = __esm({
|
|
28201
28529
|
"libs/sdk/src/agent/agent.registry.ts"() {
|
|
28202
28530
|
"use strict";
|
|
28203
28531
|
import_di26 = require("@frontmcp/di");
|
|
28204
|
-
|
|
28532
|
+
import_utils56 = require("@frontmcp/utils");
|
|
28205
28533
|
init_availability();
|
|
28206
28534
|
init_mcp_error();
|
|
28207
28535
|
init_regsitry();
|
|
@@ -28396,11 +28724,11 @@ var init_agent_registry = __esm({
|
|
|
28396
28724
|
*/
|
|
28397
28725
|
// NOTE: `any` is intentional - heterogeneous agent collections
|
|
28398
28726
|
getAgents(includeHidden = false) {
|
|
28399
|
-
const ctx = (0,
|
|
28727
|
+
const ctx = (0, import_utils56.getRuntimeContext)();
|
|
28400
28728
|
const local = [...this.localRows].map((a) => a.instance);
|
|
28401
28729
|
const adopted = [...this.adopted.values()].flat().map((a) => a.instance);
|
|
28402
28730
|
return [...local, ...adopted].filter((a) => {
|
|
28403
|
-
if (!(0,
|
|
28731
|
+
if (!(0, import_utils56.isEntryAvailable)(a.metadata.availableWhen, ctx)) return false;
|
|
28404
28732
|
if (!includeHidden && a.metadata.hideFromDiscovery === true) return false;
|
|
28405
28733
|
return true;
|
|
28406
28734
|
});
|
|
@@ -28429,8 +28757,8 @@ var init_agent_registry = __esm({
|
|
|
28429
28757
|
* Used by discovery/listing APIs to enforce registry-level constraints.
|
|
28430
28758
|
*/
|
|
28431
28759
|
getAvailableInstances() {
|
|
28432
|
-
const ctx = (0,
|
|
28433
|
-
return [...this.listAllInstances()].filter((a) => (0,
|
|
28760
|
+
const ctx = (0, import_utils56.getRuntimeContext)();
|
|
28761
|
+
return [...this.listAllInstances()].filter((a) => (0, import_utils56.isEntryAvailable)(a.metadata.availableWhen, ctx));
|
|
28434
28762
|
}
|
|
28435
28763
|
/**
|
|
28436
28764
|
* Find an agent by ID.
|
|
@@ -29060,7 +29388,7 @@ function isRemoteAppConfig(item) {
|
|
|
29060
29388
|
return true;
|
|
29061
29389
|
}
|
|
29062
29390
|
if (obj["urlType"] === "url" || obj["urlType"] === "worker") {
|
|
29063
|
-
return (0,
|
|
29391
|
+
return (0, import_utils57.isValidMcpUri)(obj["url"]);
|
|
29064
29392
|
}
|
|
29065
29393
|
return false;
|
|
29066
29394
|
}
|
|
@@ -29108,23 +29436,23 @@ function appDiscoveryDeps(rec) {
|
|
|
29108
29436
|
return (0, import_di27.depsOfClass)(rec.provide, "discovery");
|
|
29109
29437
|
}
|
|
29110
29438
|
}
|
|
29111
|
-
var import_di27,
|
|
29439
|
+
var import_di27, import_utils57;
|
|
29112
29440
|
var init_app_utils = __esm({
|
|
29113
29441
|
"libs/sdk/src/app/app.utils.ts"() {
|
|
29114
29442
|
"use strict";
|
|
29115
29443
|
import_di27 = require("@frontmcp/di");
|
|
29116
|
-
|
|
29444
|
+
import_utils57 = require("@frontmcp/utils");
|
|
29117
29445
|
init_common();
|
|
29118
29446
|
init_errors();
|
|
29119
29447
|
}
|
|
29120
29448
|
});
|
|
29121
29449
|
|
|
29122
29450
|
// libs/sdk/src/app/instances/app.local.instance.ts
|
|
29123
|
-
var
|
|
29451
|
+
var import_utils58, AppLocalInstance;
|
|
29124
29452
|
var init_app_local_instance = __esm({
|
|
29125
29453
|
"libs/sdk/src/app/instances/app.local.instance.ts"() {
|
|
29126
29454
|
"use strict";
|
|
29127
|
-
|
|
29455
|
+
import_utils58 = require("@frontmcp/utils");
|
|
29128
29456
|
init_adapter_registry();
|
|
29129
29457
|
init_agent_registry();
|
|
29130
29458
|
init_common();
|
|
@@ -29149,7 +29477,7 @@ var init_app_local_instance = __esm({
|
|
|
29149
29477
|
constructor(record, scopeProviders) {
|
|
29150
29478
|
super(record);
|
|
29151
29479
|
this.scopeProviders = scopeProviders;
|
|
29152
|
-
this.id = this.metadata.id ?? (0,
|
|
29480
|
+
this.id = this.metadata.id ?? (0, import_utils58.idFromString)(this.metadata.name);
|
|
29153
29481
|
try {
|
|
29154
29482
|
this.logger = scopeProviders.get(FrontMcpLogger)?.child("AppLocalInstance");
|
|
29155
29483
|
} catch {
|
|
@@ -30851,11 +31179,11 @@ var init_remote_mcp = __esm({
|
|
|
30851
31179
|
});
|
|
30852
31180
|
|
|
30853
31181
|
// libs/sdk/src/app/instances/app.remote.instance.ts
|
|
30854
|
-
var
|
|
31182
|
+
var import_utils59, EmptyPluginRegistry, EmptyAdapterRegistry, EmptySkillRegistry, AppRemoteInstance;
|
|
30855
31183
|
var init_app_remote_instance = __esm({
|
|
30856
31184
|
"libs/sdk/src/app/instances/app.remote.instance.ts"() {
|
|
30857
31185
|
"use strict";
|
|
30858
|
-
|
|
31186
|
+
import_utils59 = require("@frontmcp/utils");
|
|
30859
31187
|
init_common();
|
|
30860
31188
|
init_errors();
|
|
30861
31189
|
init_prompt_registry();
|
|
@@ -30970,7 +31298,7 @@ var init_app_remote_instance = __esm({
|
|
|
30970
31298
|
_unsubscribeCapability;
|
|
30971
31299
|
constructor(record, scopeProviders) {
|
|
30972
31300
|
super(record);
|
|
30973
|
-
this.id = this.metadata.id ?? (0,
|
|
31301
|
+
this.id = this.metadata.id ?? (0, import_utils59.idFromString)(this.metadata.name);
|
|
30974
31302
|
this.scopeProviders = scopeProviders;
|
|
30975
31303
|
this.appOwner = {
|
|
30976
31304
|
kind: "app",
|
|
@@ -31356,8 +31684,8 @@ function getDefaultCacheDir() {
|
|
|
31356
31684
|
const path3 = require("node:path");
|
|
31357
31685
|
try {
|
|
31358
31686
|
const nodeModulesDir = path3.join(process.cwd(), "node_modules");
|
|
31359
|
-
const
|
|
31360
|
-
if (
|
|
31687
|
+
const fs = require("node:fs");
|
|
31688
|
+
if (fs.existsSync(nodeModulesDir)) {
|
|
31361
31689
|
return path3.join(nodeModulesDir, ".cache", "frontmcp-esm");
|
|
31362
31690
|
}
|
|
31363
31691
|
} catch {
|
|
@@ -31372,20 +31700,31 @@ function getDefaultCacheDir() {
|
|
|
31372
31700
|
return "";
|
|
31373
31701
|
}
|
|
31374
31702
|
}
|
|
31375
|
-
var
|
|
31703
|
+
var import_utils60, DEFAULT_CACHE_DIR, DEFAULT_MAX_AGE_MS, DEFAULT_MAX_ENTRIES, EsmCacheManager;
|
|
31376
31704
|
var init_esm_cache = __esm({
|
|
31377
31705
|
"libs/sdk/src/esm-loader/esm-cache.ts"() {
|
|
31378
31706
|
"use strict";
|
|
31379
|
-
|
|
31707
|
+
import_utils60 = require("@frontmcp/utils");
|
|
31380
31708
|
DEFAULT_CACHE_DIR = getDefaultCacheDir();
|
|
31381
31709
|
DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
31710
|
+
DEFAULT_MAX_ENTRIES = 100;
|
|
31382
31711
|
EsmCacheManager = class {
|
|
31383
31712
|
cacheDir;
|
|
31384
31713
|
maxAgeMs;
|
|
31714
|
+
maxEntries;
|
|
31385
31715
|
memoryStore = /* @__PURE__ */ new Map();
|
|
31386
31716
|
constructor(options) {
|
|
31387
31717
|
this.cacheDir = options?.cacheDir ?? DEFAULT_CACHE_DIR;
|
|
31388
31718
|
this.maxAgeMs = options?.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
31719
|
+
this.maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
31720
|
+
}
|
|
31721
|
+
/** Evict oldest in-memory entries (FIFO via Map insertion order) past the cap. */
|
|
31722
|
+
evictIfNeeded() {
|
|
31723
|
+
while (this.memoryStore.size > this.maxEntries) {
|
|
31724
|
+
const oldest = this.memoryStore.keys().next().value;
|
|
31725
|
+
if (oldest === void 0) break;
|
|
31726
|
+
this.memoryStore.delete(oldest);
|
|
31727
|
+
}
|
|
31389
31728
|
}
|
|
31390
31729
|
/**
|
|
31391
31730
|
* Get a cached ESM bundle entry if it exists and is not expired.
|
|
@@ -31419,6 +31758,7 @@ var init_esm_cache = __esm({
|
|
|
31419
31758
|
return void 0;
|
|
31420
31759
|
}
|
|
31421
31760
|
this.memoryStore.set(memKey, meta);
|
|
31761
|
+
this.evictIfNeeded();
|
|
31422
31762
|
return meta;
|
|
31423
31763
|
} catch {
|
|
31424
31764
|
return void 0;
|
|
@@ -31428,7 +31768,7 @@ var init_esm_cache = __esm({
|
|
|
31428
31768
|
* Store an ESM bundle in the cache.
|
|
31429
31769
|
*/
|
|
31430
31770
|
async put(packageName, version, bundleContent, packageUrl, etag) {
|
|
31431
|
-
if (!(0,
|
|
31771
|
+
if (!(0, import_utils60.isValidMcpUri)(packageUrl)) {
|
|
31432
31772
|
throw new Error("URI must have a valid scheme (e.g., file://, https://, custom://)");
|
|
31433
31773
|
}
|
|
31434
31774
|
const memKey = `${packageName}@${version}`;
|
|
@@ -31465,6 +31805,7 @@ var init_esm_cache = __esm({
|
|
|
31465
31805
|
bundleContent
|
|
31466
31806
|
};
|
|
31467
31807
|
this.memoryStore.set(memKey, entry);
|
|
31808
|
+
this.evictIfNeeded();
|
|
31468
31809
|
return entry;
|
|
31469
31810
|
}
|
|
31470
31811
|
/**
|
|
@@ -31558,7 +31899,7 @@ var init_esm_cache = __esm({
|
|
|
31558
31899
|
*/
|
|
31559
31900
|
getEntryDir(packageName, version) {
|
|
31560
31901
|
const path3 = require("node:path");
|
|
31561
|
-
const hash = (0,
|
|
31902
|
+
const hash = (0, import_utils60.sha256Hex)(`${packageName}@${version}`);
|
|
31562
31903
|
return path3.join(this.cacheDir, hash);
|
|
31563
31904
|
}
|
|
31564
31905
|
};
|
|
@@ -31609,7 +31950,7 @@ function normalizeResourceFromEsmExport(raw) {
|
|
|
31609
31950
|
const obj = raw;
|
|
31610
31951
|
if (typeof obj["read"] === "function" && typeof obj["name"] === "string" && typeof obj["uri"] === "string") {
|
|
31611
31952
|
const uri = obj["uri"];
|
|
31612
|
-
if (!(0,
|
|
31953
|
+
if (!(0, import_utils61.isValidMcpUri)(uri)) return void 0;
|
|
31613
31954
|
const description = obj["description"];
|
|
31614
31955
|
const mimeType = obj["mimeType"];
|
|
31615
31956
|
return {
|
|
@@ -31637,12 +31978,12 @@ function normalizePromptFromEsmExport(raw) {
|
|
|
31637
31978
|
}
|
|
31638
31979
|
return void 0;
|
|
31639
31980
|
}
|
|
31640
|
-
var import_di28,
|
|
31981
|
+
var import_di28, import_utils61;
|
|
31641
31982
|
var init_esm_normalize_utils = __esm({
|
|
31642
31983
|
"libs/sdk/src/app/instances/esm-normalize.utils.ts"() {
|
|
31643
31984
|
"use strict";
|
|
31644
31985
|
import_di28 = require("@frontmcp/di");
|
|
31645
|
-
|
|
31986
|
+
import_utils61 = require("@frontmcp/utils");
|
|
31646
31987
|
init_tokens();
|
|
31647
31988
|
}
|
|
31648
31989
|
});
|
|
@@ -31911,6 +32252,13 @@ var init_version_resolver = __esm({
|
|
|
31911
32252
|
});
|
|
31912
32253
|
|
|
31913
32254
|
// libs/sdk/src/esm-loader/esm-module-loader.ts
|
|
32255
|
+
function importComputed(specifier) {
|
|
32256
|
+
return import(
|
|
32257
|
+
/* webpackIgnore: true */
|
|
32258
|
+
/* @vite-ignore */
|
|
32259
|
+
specifier
|
|
32260
|
+
);
|
|
32261
|
+
}
|
|
31914
32262
|
var EsmModuleLoader;
|
|
31915
32263
|
var init_esm_module_loader = __esm({
|
|
31916
32264
|
"libs/sdk/src/esm-loader/esm-module-loader.ts"() {
|
|
@@ -32042,9 +32390,7 @@ var init_esm_module_loader = __esm({
|
|
|
32042
32390
|
*/
|
|
32043
32391
|
async importFromPath(filePath) {
|
|
32044
32392
|
const { pathToFileURL } = await import("node:url");
|
|
32045
|
-
|
|
32046
|
-
const bustUrl = `${fileUrl}?t=${Date.now()}`;
|
|
32047
|
-
return import(bustUrl);
|
|
32393
|
+
return importComputed(pathToFileURL(filePath).href);
|
|
32048
32394
|
}
|
|
32049
32395
|
/**
|
|
32050
32396
|
* Import a bundle from its source text.
|
|
@@ -32073,27 +32419,22 @@ var init_esm_module_loader = __esm({
|
|
|
32073
32419
|
const blob = new Blob([bundleContent], { type: "text/javascript" });
|
|
32074
32420
|
const url = URL.createObjectURL(blob);
|
|
32075
32421
|
try {
|
|
32076
|
-
return await
|
|
32077
|
-
/* webpackIgnore: true */
|
|
32078
|
-
url
|
|
32079
|
-
);
|
|
32422
|
+
return await importComputed(url);
|
|
32080
32423
|
} finally {
|
|
32081
32424
|
URL.revokeObjectURL(url);
|
|
32082
32425
|
}
|
|
32083
32426
|
}
|
|
32084
|
-
const {
|
|
32427
|
+
const { ensureDir, fileExists: fileExists9, sha256Hex: sha256Hex9, writeFile } = await import("@frontmcp/utils");
|
|
32085
32428
|
const nodePath = await import("node:path");
|
|
32086
32429
|
const nodeOs = await import("node:os");
|
|
32087
32430
|
const { pathToFileURL } = await import("node:url");
|
|
32088
|
-
const
|
|
32089
|
-
|
|
32090
|
-
|
|
32431
|
+
const dir = nodePath.join(nodeOs.tmpdir(), "frontmcp-esm-modules");
|
|
32432
|
+
await ensureDir(dir);
|
|
32433
|
+
const tempPath = nodePath.join(dir, `${sha256Hex9(bundleContent)}.mjs`);
|
|
32434
|
+
if (!await fileExists9(tempPath)) {
|
|
32091
32435
|
await writeFile(tempPath, bundleContent);
|
|
32092
|
-
return await import(pathToFileURL(tempPath).href + `?t=${Date.now()}`);
|
|
32093
|
-
} finally {
|
|
32094
|
-
await rm(tempDir, { recursive: true, force: true }).catch(() => {
|
|
32095
|
-
});
|
|
32096
32436
|
}
|
|
32437
|
+
return importComputed(pathToFileURL(tempPath).href);
|
|
32097
32438
|
}
|
|
32098
32439
|
};
|
|
32099
32440
|
}
|
|
@@ -32414,11 +32755,11 @@ var init_esm_loader = __esm({
|
|
|
32414
32755
|
});
|
|
32415
32756
|
|
|
32416
32757
|
// libs/sdk/src/app/instances/app.esm.instance.ts
|
|
32417
|
-
var
|
|
32758
|
+
var import_utils62, EmptyPluginRegistry2, EmptyAdapterRegistry2, EmptySkillRegistry2, AppEsmInstance;
|
|
32418
32759
|
var init_app_esm_instance = __esm({
|
|
32419
32760
|
"libs/sdk/src/app/instances/app.esm.instance.ts"() {
|
|
32420
32761
|
"use strict";
|
|
32421
|
-
|
|
32762
|
+
import_utils62 = require("@frontmcp/utils");
|
|
32422
32763
|
init_common();
|
|
32423
32764
|
init_errors();
|
|
32424
32765
|
init_esm_loader();
|
|
@@ -32533,7 +32874,7 @@ var init_app_esm_instance = __esm({
|
|
|
32533
32874
|
_skills;
|
|
32534
32875
|
constructor(record, scopeProviders) {
|
|
32535
32876
|
super(record);
|
|
32536
|
-
this.id = this.metadata.id ?? (0,
|
|
32877
|
+
this.id = this.metadata.id ?? (0, import_utils62.idFromString)(this.metadata.name);
|
|
32537
32878
|
this.scopeProviders = scopeProviders;
|
|
32538
32879
|
this.appOwner = {
|
|
32539
32880
|
kind: "app",
|
|
@@ -32881,11 +33222,11 @@ function timingSafeEqualStr(a, b) {
|
|
|
32881
33222
|
}
|
|
32882
33223
|
return diff === 0;
|
|
32883
33224
|
}
|
|
32884
|
-
var
|
|
33225
|
+
var import_utils63, ALL_SLOTS, PENDING_UI_TTL_MS, AuthUiRegistry;
|
|
32885
33226
|
var init_auth_ui_registry = __esm({
|
|
32886
33227
|
"libs/sdk/src/auth/auth-ui/auth-ui.registry.ts"() {
|
|
32887
33228
|
"use strict";
|
|
32888
|
-
|
|
33229
|
+
import_utils63 = require("@frontmcp/utils");
|
|
32889
33230
|
ALL_SLOTS = ["login", "consent", "incremental", "federated", "error"];
|
|
32890
33231
|
PENDING_UI_TTL_MS = 10 * 60 * 1e3;
|
|
32891
33232
|
AuthUiRegistry = class {
|
|
@@ -32916,7 +33257,7 @@ var init_auth_ui_registry = __esm({
|
|
|
32916
33257
|
throw new Error(`auth.ui slot "${slot}" is not one of: ${ALL_SLOTS.join(", ")}.`);
|
|
32917
33258
|
}
|
|
32918
33259
|
if (typeof rawPath !== "string" || rawPath.length === 0) continue;
|
|
32919
|
-
const file = (0,
|
|
33260
|
+
const file = (0, import_utils63.isAbsolute)(rawPath) ? rawPath : (0, import_utils63.pathResolve)(sourceDir, rawPath);
|
|
32920
33261
|
this.slots.set(slot, { file });
|
|
32921
33262
|
this.logger?.verbose(`Registered auth.ui slot "${slot}" \u2192 ${file}`);
|
|
32922
33263
|
}
|
|
@@ -33002,7 +33343,7 @@ var init_auth_ui_registry = __esm({
|
|
|
33002
33343
|
mintCsrf(pendingAuthId) {
|
|
33003
33344
|
const existing = this.pending.get(pendingAuthId);
|
|
33004
33345
|
if (existing) return existing.csrf;
|
|
33005
|
-
const csrf = (0,
|
|
33346
|
+
const csrf = (0, import_utils63.sha256Hex)((0, import_utils63.randomBytes)(32)).slice(0, 43);
|
|
33006
33347
|
this.pending.set(pendingAuthId, { csrf, addedItems: {}, createdAt: Date.now() });
|
|
33007
33348
|
this.pruneExpired();
|
|
33008
33349
|
return csrf;
|
|
@@ -33055,7 +33396,7 @@ var init_auth_ui_registry = __esm({
|
|
|
33055
33396
|
ensurePending(pendingAuthId) {
|
|
33056
33397
|
let state = this.pending.get(pendingAuthId);
|
|
33057
33398
|
if (!state) {
|
|
33058
|
-
state = { csrf: (0,
|
|
33399
|
+
state = { csrf: (0, import_utils63.sha256Hex)((0, import_utils63.randomBytes)(32)).slice(0, 43), addedItems: {}, createdAt: Date.now() };
|
|
33059
33400
|
this.pending.set(pendingAuthId, state);
|
|
33060
33401
|
this.pruneExpired();
|
|
33061
33402
|
}
|
|
@@ -33640,13 +33981,13 @@ function getConfiguredProviders(auth) {
|
|
|
33640
33981
|
function getConfiguredProviderIds(auth) {
|
|
33641
33982
|
return getConfiguredProviders(auth).map((p) => p.id);
|
|
33642
33983
|
}
|
|
33643
|
-
var import_auth21, import_lazy_zod64,
|
|
33984
|
+
var import_auth21, import_lazy_zod64, import_utils64, pkceChallengeSchema, codeChallengeMethodSchema, responseTypeSchema, safeRedirectUriSchema, oauthAuthorizeRequestSchema, anonymousAuthorizeRequestSchema, inputSchema16, stateSchema15, outputSchema15, plan15, name15, Stage15, OauthAuthorizeFlow;
|
|
33644
33985
|
var init_oauth_authorize_flow = __esm({
|
|
33645
33986
|
"libs/sdk/src/auth/flows/oauth.authorize.flow.ts"() {
|
|
33646
33987
|
"use strict";
|
|
33647
33988
|
import_auth21 = require("@frontmcp/auth");
|
|
33648
33989
|
import_lazy_zod64 = require("@frontmcp/lazy-zod");
|
|
33649
|
-
|
|
33990
|
+
import_utils64 = require("@frontmcp/utils");
|
|
33650
33991
|
init_common();
|
|
33651
33992
|
init_auth_ui();
|
|
33652
33993
|
init_cimd();
|
|
@@ -33877,6 +34218,15 @@ var init_oauth_authorize_flow = __esm({
|
|
|
33877
34218
|
return;
|
|
33878
34219
|
}
|
|
33879
34220
|
}
|
|
34221
|
+
if (!isCimdClientId2) {
|
|
34222
|
+
const registry = this.scope.auth.dcrClientRegistry;
|
|
34223
|
+
const registered = registry?.get?.(client_id);
|
|
34224
|
+
if (registered && !registered.redirect_uris.includes(redirect_uri)) {
|
|
34225
|
+
this.logger.warn(`OAuth authorize: redirect_uri "${redirect_uri}" not registered for client "${client_id}"`);
|
|
34226
|
+
this.respondWithError(["redirect_uri is not registered for this client"], void 0, rawState);
|
|
34227
|
+
return;
|
|
34228
|
+
}
|
|
34229
|
+
}
|
|
33880
34230
|
}
|
|
33881
34231
|
async checkIfAuthorized() {
|
|
33882
34232
|
}
|
|
@@ -34141,7 +34491,7 @@ var init_oauth_authorize_flow = __esm({
|
|
|
34141
34491
|
}
|
|
34142
34492
|
const state = buildState({
|
|
34143
34493
|
pendingAuthId,
|
|
34144
|
-
submitUrl:
|
|
34494
|
+
submitUrl: "/oauth/callback",
|
|
34145
34495
|
extraUrl: authUiExtraPath(this.scope.fullPath),
|
|
34146
34496
|
csrfToken,
|
|
34147
34497
|
addedItems: authUi.getAddedItems(pendingAuthId)
|
|
@@ -34194,10 +34544,10 @@ var init_oauth_authorize_flow = __esm({
|
|
|
34194
34544
|
frontmcpPkce: { challenge: validatedRequest.code_challenge, method: "S256" },
|
|
34195
34545
|
providerIds: [providerId]
|
|
34196
34546
|
});
|
|
34197
|
-
const verifier = (0,
|
|
34198
|
-
const challenge = (0,
|
|
34547
|
+
const verifier = (0, import_utils64.generateCodeVerifier)();
|
|
34548
|
+
const challenge = (0, import_utils64.sha256Base64url)(verifier);
|
|
34199
34549
|
const pkce = { verifier, challenge, method: "S256" };
|
|
34200
|
-
const providerState = `federated:${session.id}:${(0,
|
|
34550
|
+
const providerState = `federated:${session.id}:${(0, import_utils64.randomUUID)()}`;
|
|
34201
34551
|
(0, import_auth21.startNextProvider)(session, pkce, providerState);
|
|
34202
34552
|
await localAuth.federatedSessionStore.store(session);
|
|
34203
34553
|
const redirectUrl = await localAuth.buildProviderAuthorizeUrl(providerId, {
|
|
@@ -34287,7 +34637,7 @@ var init_oauth_authorize_flow = __esm({
|
|
|
34287
34637
|
*/
|
|
34288
34638
|
renderLoginPage(params) {
|
|
34289
34639
|
const { pendingAuthId, clientId, clientName, scope, logoUri } = params;
|
|
34290
|
-
const callbackPath =
|
|
34640
|
+
const callbackPath = "/oauth/callback";
|
|
34291
34641
|
const auth = this.scope.metadata.auth;
|
|
34292
34642
|
const login = auth && auth.mode === "local" ? auth.login : void 0;
|
|
34293
34643
|
const ctx = {
|
|
@@ -34306,7 +34656,7 @@ var init_oauth_authorize_flow = __esm({
|
|
|
34306
34656
|
*/
|
|
34307
34657
|
renderIncrementalAuthPage(params) {
|
|
34308
34658
|
const { pendingAuthId, appId, appName, appDescription, toolId } = params;
|
|
34309
|
-
const callbackPath =
|
|
34659
|
+
const callbackPath = "/oauth/callback";
|
|
34310
34660
|
const app = {
|
|
34311
34661
|
appId,
|
|
34312
34662
|
appName,
|
|
@@ -34324,7 +34674,7 @@ var init_oauth_authorize_flow = __esm({
|
|
|
34324
34674
|
*/
|
|
34325
34675
|
renderFederatedLoginPage(params) {
|
|
34326
34676
|
const { pendingAuthId, detection, clientId } = params;
|
|
34327
|
-
const callbackPath =
|
|
34677
|
+
const callbackPath = "/oauth/callback";
|
|
34328
34678
|
const providers = [...detection.providers.values()].map((provider) => ({
|
|
34329
34679
|
providerId: provider.id,
|
|
34330
34680
|
providerName: provider.id,
|
|
@@ -34428,13 +34778,13 @@ function timingSafeEqualStr3(a, b) {
|
|
|
34428
34778
|
}
|
|
34429
34779
|
return diff === 0;
|
|
34430
34780
|
}
|
|
34431
|
-
var import_auth22, import_lazy_zod65,
|
|
34781
|
+
var import_auth22, import_lazy_zod65, import_utils65, inputSchema17, stateSchema16, outputSchema16, plan16, name16, Stage16, OauthCallbackFlow;
|
|
34432
34782
|
var init_oauth_callback_flow = __esm({
|
|
34433
34783
|
"libs/sdk/src/auth/flows/oauth.callback.flow.ts"() {
|
|
34434
34784
|
"use strict";
|
|
34435
34785
|
import_auth22 = require("@frontmcp/auth");
|
|
34436
34786
|
import_lazy_zod65 = require("@frontmcp/lazy-zod");
|
|
34437
|
-
|
|
34787
|
+
import_utils65 = require("@frontmcp/utils");
|
|
34438
34788
|
init_common();
|
|
34439
34789
|
init_auth_ui();
|
|
34440
34790
|
init_consent_tools_helper();
|
|
@@ -34855,7 +35205,7 @@ var init_oauth_callback_flow = __esm({
|
|
|
34855
35205
|
return;
|
|
34856
35206
|
}
|
|
34857
35207
|
const federatedSession = (0, import_auth22.createFederatedAuthSession)({
|
|
34858
|
-
pendingAuthId: this.state.required.pendingAuthId || (0,
|
|
35208
|
+
pendingAuthId: this.state.required.pendingAuthId || (0, import_utils65.randomUUID)(),
|
|
34859
35209
|
clientId,
|
|
34860
35210
|
redirectUri,
|
|
34861
35211
|
scopes: scopes ?? [],
|
|
@@ -34875,14 +35225,14 @@ var init_oauth_callback_flow = __esm({
|
|
|
34875
35225
|
await sessionStore.store(federatedSession);
|
|
34876
35226
|
this.logger.info(`Created federated session: ${federatedSession.id}`);
|
|
34877
35227
|
const firstProviderId = selectedProviders[0];
|
|
34878
|
-
const verifier = (0,
|
|
34879
|
-
const challenge = (0,
|
|
35228
|
+
const verifier = (0, import_utils65.generateCodeVerifier)();
|
|
35229
|
+
const challenge = (0, import_utils65.sha256Base64url)(verifier);
|
|
34880
35230
|
const pkce = {
|
|
34881
35231
|
verifier,
|
|
34882
35232
|
challenge,
|
|
34883
35233
|
method: "S256"
|
|
34884
35234
|
};
|
|
34885
|
-
const providerState = `federated:${federatedSession.id}:${(0,
|
|
35235
|
+
const providerState = `federated:${federatedSession.id}:${(0, import_utils65.randomUUID)()}`;
|
|
34886
35236
|
(0, import_auth22.startNextProvider)(federatedSession, pkce, providerState);
|
|
34887
35237
|
await sessionStore.update(federatedSession);
|
|
34888
35238
|
const providerConfig = localAuth.getProviderConfig(firstProviderId);
|
|
@@ -35148,7 +35498,7 @@ var init_oauth_callback_flow = __esm({
|
|
|
35148
35498
|
* preserved on the form so the user does not have to re-enter everything.
|
|
35149
35499
|
*/
|
|
35150
35500
|
renderLoginRetryPage(pendingAuth, login, fields, failure) {
|
|
35151
|
-
const callbackPath =
|
|
35501
|
+
const callbackPath = "/oauth/callback";
|
|
35152
35502
|
const ctx = {
|
|
35153
35503
|
clientId: pendingAuth.clientId,
|
|
35154
35504
|
clientName: pendingAuth.clientId,
|
|
@@ -35214,7 +35564,7 @@ var init_oauth_callback_flow = __esm({
|
|
|
35214
35564
|
const state = buildConsentState(
|
|
35215
35565
|
{
|
|
35216
35566
|
pendingAuthId: pendingAuth.id,
|
|
35217
|
-
submitUrl:
|
|
35567
|
+
submitUrl: "/oauth/callback",
|
|
35218
35568
|
extraUrl: authUiExtraPath(this.scope.fullPath),
|
|
35219
35569
|
csrfToken,
|
|
35220
35570
|
addedItems: authUi.getAddedItems(pendingAuth.id)
|
|
@@ -35241,7 +35591,7 @@ var init_oauth_callback_flow = __esm({
|
|
|
35241
35591
|
* (used for an empty `requireSelection` submit).
|
|
35242
35592
|
*/
|
|
35243
35593
|
renderConsentScreen(pendingAuth, consentConfig, identity, error, preSelectedTools) {
|
|
35244
|
-
const callbackPath =
|
|
35594
|
+
const callbackPath = "/oauth/callback";
|
|
35245
35595
|
const { toolCards } = projectConsentTools(this.scope, consentConfig?.excludedTools);
|
|
35246
35596
|
const hiddenFields = [];
|
|
35247
35597
|
if (identity.email) hiddenFields.push({ name: "email", value: identity.email });
|
|
@@ -35280,7 +35630,7 @@ var init_oauth_callback_flow = __esm({
|
|
|
35280
35630
|
* In production, this would be the user's ID from the database
|
|
35281
35631
|
*/
|
|
35282
35632
|
generateUserSub(email) {
|
|
35283
|
-
const hash = (0,
|
|
35633
|
+
const hash = (0, import_utils65.sha256Hex)(email.toLowerCase());
|
|
35284
35634
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
|
|
35285
35635
|
}
|
|
35286
35636
|
/**
|
|
@@ -35664,13 +36014,13 @@ var init_oauth_connect_flow = __esm({
|
|
|
35664
36014
|
});
|
|
35665
36015
|
|
|
35666
36016
|
// libs/sdk/src/auth/flows/oauth.provider-callback.flow.ts
|
|
35667
|
-
var import_auth24, import_lazy_zod67,
|
|
36017
|
+
var import_auth24, import_lazy_zod67, import_utils66, inputSchema19, stateSchema18, outputSchema18, plan18, name18, Stage18, OauthProviderCallbackFlow;
|
|
35668
36018
|
var init_oauth_provider_callback_flow = __esm({
|
|
35669
36019
|
"libs/sdk/src/auth/flows/oauth.provider-callback.flow.ts"() {
|
|
35670
36020
|
"use strict";
|
|
35671
36021
|
import_auth24 = require("@frontmcp/auth");
|
|
35672
36022
|
import_lazy_zod67 = require("@frontmcp/lazy-zod");
|
|
35673
|
-
|
|
36023
|
+
import_utils66 = require("@frontmcp/utils");
|
|
35674
36024
|
init_common();
|
|
35675
36025
|
init_errors();
|
|
35676
36026
|
init_consent_tools_helper();
|
|
@@ -35983,14 +36333,14 @@ var init_oauth_provider_callback_flow = __esm({
|
|
|
35983
36333
|
if (!nextProviderId) {
|
|
35984
36334
|
return this.completeFederatedAuth(session);
|
|
35985
36335
|
}
|
|
35986
|
-
const verifier = (0,
|
|
35987
|
-
const challenge = (0,
|
|
36336
|
+
const verifier = (0, import_utils66.generateCodeVerifier)();
|
|
36337
|
+
const challenge = (0, import_utils66.sha256Base64url)(verifier);
|
|
35988
36338
|
const pkce = {
|
|
35989
36339
|
verifier,
|
|
35990
36340
|
challenge,
|
|
35991
36341
|
method: "S256"
|
|
35992
36342
|
};
|
|
35993
|
-
const providerState = `federated:${session.id}:${(0,
|
|
36343
|
+
const providerState = `federated:${session.id}:${(0, import_utils66.randomUUID)()}`;
|
|
35994
36344
|
(0, import_auth24.startNextProvider)(session, pkce, providerState);
|
|
35995
36345
|
const sessionStore = localAuth.federatedSessionStore;
|
|
35996
36346
|
if (sessionStore) {
|
|
@@ -36181,9 +36531,9 @@ var init_oauth_provider_callback_flow = __esm({
|
|
|
36181
36531
|
*/
|
|
36182
36532
|
generateUserSub(email) {
|
|
36183
36533
|
if (!email) {
|
|
36184
|
-
return `anon:${(0,
|
|
36534
|
+
return `anon:${(0, import_utils66.randomUUID)()}`;
|
|
36185
36535
|
}
|
|
36186
|
-
const hash = (0,
|
|
36536
|
+
const hash = (0, import_utils66.sha256Base64url)(email.toLowerCase());
|
|
36187
36537
|
return `user:${hash.substring(0, 16)}`;
|
|
36188
36538
|
}
|
|
36189
36539
|
/**
|
|
@@ -36292,12 +36642,12 @@ function extractBearer(headers) {
|
|
|
36292
36642
|
const match = /^Bearer\s+(.+)$/i.exec(raw.trim());
|
|
36293
36643
|
return match ? match[1].trim() : void 0;
|
|
36294
36644
|
}
|
|
36295
|
-
var import_lazy_zod68,
|
|
36645
|
+
var import_lazy_zod68, import_utils67, inputSchema20, outputSchema19, registrationRequestSchema, stateSchema19, plan19, name19, Stage19, OauthRegisterFlow;
|
|
36296
36646
|
var init_oauth_register_flow = __esm({
|
|
36297
36647
|
"libs/sdk/src/auth/flows/oauth.register.flow.ts"() {
|
|
36298
36648
|
"use strict";
|
|
36299
36649
|
import_lazy_zod68 = require("@frontmcp/lazy-zod");
|
|
36300
|
-
|
|
36650
|
+
import_utils67 = require("@frontmcp/utils");
|
|
36301
36651
|
init_common();
|
|
36302
36652
|
inputSchema20 = httpInputSchema;
|
|
36303
36653
|
outputSchema19 = HttpJsonSchema;
|
|
@@ -36450,10 +36800,10 @@ var init_oauth_register_flow = __esm({
|
|
|
36450
36800
|
async registerClient() {
|
|
36451
36801
|
const now = Math.floor(Date.now() / 1e3);
|
|
36452
36802
|
const { token_endpoint_auth_method, grant_types, response_types, redirect_uris, client_name, scope } = this.state.required.body;
|
|
36453
|
-
const client_id = (0,
|
|
36803
|
+
const client_id = (0, import_utils67.randomUUID)();
|
|
36454
36804
|
let client_secret;
|
|
36455
36805
|
if (token_endpoint_auth_method === "client_secret_post" || token_endpoint_auth_method === "client_secret_basic") {
|
|
36456
|
-
client_secret = (0,
|
|
36806
|
+
client_secret = (0, import_utils67.base64urlEncode)((0, import_utils67.randomBytes)(24));
|
|
36457
36807
|
}
|
|
36458
36808
|
this.registered = {
|
|
36459
36809
|
client_id,
|
|
@@ -36560,12 +36910,12 @@ function parseRawTokenBody(raw) {
|
|
|
36560
36910
|
}
|
|
36561
36911
|
return {};
|
|
36562
36912
|
}
|
|
36563
|
-
var import_lazy_zod69,
|
|
36913
|
+
var import_lazy_zod69, import_utils68, inputSchema21, pkceVerifierRegex, authorizationCodeGrant, refreshTokenGrant, anonymousGrant, tokenRequestSchema, stateSchema20, outputSchema20, plan20, name20, Stage20, OauthTokenFlow;
|
|
36564
36914
|
var init_oauth_token_flow = __esm({
|
|
36565
36915
|
"libs/sdk/src/auth/flows/oauth.token.flow.ts"() {
|
|
36566
36916
|
"use strict";
|
|
36567
36917
|
import_lazy_zod69 = require("@frontmcp/lazy-zod");
|
|
36568
|
-
|
|
36918
|
+
import_utils68 = require("@frontmcp/utils");
|
|
36569
36919
|
init_common();
|
|
36570
36920
|
inputSchema21 = httpInputSchema;
|
|
36571
36921
|
pkceVerifierRegex = /^[A-Za-z0-9_.~-]{43,128}$/;
|
|
@@ -36669,14 +37019,15 @@ var init_oauth_token_flow = __esm({
|
|
|
36669
37019
|
async handleAuthorizationCodeGrant() {
|
|
36670
37020
|
const { body, isDefaultAuthProvider } = this.state.required;
|
|
36671
37021
|
if (body?.grant_type !== "authorization_code") return;
|
|
36672
|
-
|
|
37022
|
+
const authOptions = this.scope.auth?.options;
|
|
37023
|
+
if (isDefaultAuthProvider && body.code === "anonymous" && !!authOptions && (0, import_auth10.allowsPublicAccess)(authOptions)) {
|
|
36673
37024
|
const localAuth2 = this.scope.auth;
|
|
36674
37025
|
const accessToken = await localAuth2.signAnonymousJwt();
|
|
36675
37026
|
this.state.set("tokenResponse", {
|
|
36676
37027
|
access_token: accessToken,
|
|
36677
37028
|
token_type: "Bearer",
|
|
36678
37029
|
expires_in: 86400,
|
|
36679
|
-
refresh_token: (0,
|
|
37030
|
+
refresh_token: (0, import_utils68.randomUUID)()
|
|
36680
37031
|
});
|
|
36681
37032
|
return;
|
|
36682
37033
|
}
|
|
@@ -36707,13 +37058,23 @@ var init_oauth_token_flow = __esm({
|
|
|
36707
37058
|
const { body, isDefaultAuthProvider } = this.state.required;
|
|
36708
37059
|
if (body?.grant_type !== "refresh_token") return;
|
|
36709
37060
|
if (isDefaultAuthProvider) {
|
|
37061
|
+
const authOptions = this.scope.auth?.options;
|
|
37062
|
+
if (!authOptions || !(0, import_auth10.allowsPublicAccess)(authOptions)) {
|
|
37063
|
+
this.respond(
|
|
37064
|
+
httpRespond.json(
|
|
37065
|
+
{ error: "invalid_grant", error_description: "Refresh requires re-authentication on this server" },
|
|
37066
|
+
{ status: 400 }
|
|
37067
|
+
)
|
|
37068
|
+
);
|
|
37069
|
+
return;
|
|
37070
|
+
}
|
|
36710
37071
|
const localAuth2 = this.scope.auth;
|
|
36711
37072
|
const accessToken = await localAuth2.signAnonymousJwt();
|
|
36712
37073
|
this.state.set("tokenResponse", {
|
|
36713
37074
|
access_token: accessToken,
|
|
36714
37075
|
token_type: "Bearer",
|
|
36715
37076
|
expires_in: 86400,
|
|
36716
|
-
refresh_token: (0,
|
|
37077
|
+
refresh_token: (0, import_utils68.randomUUID)()
|
|
36717
37078
|
});
|
|
36718
37079
|
return;
|
|
36719
37080
|
}
|
|
@@ -36742,6 +37103,19 @@ var init_oauth_token_flow = __esm({
|
|
|
36742
37103
|
}
|
|
36743
37104
|
async handleAnonymousGrant() {
|
|
36744
37105
|
const { body } = this.state.required;
|
|
37106
|
+
const authOptions = this.scope.auth?.options;
|
|
37107
|
+
if (!authOptions || !(0, import_auth10.allowsPublicAccess)(authOptions)) {
|
|
37108
|
+
this.respond(
|
|
37109
|
+
httpRespond.json(
|
|
37110
|
+
{
|
|
37111
|
+
error: "unsupported_grant_type",
|
|
37112
|
+
error_description: "Anonymous access is not enabled on this server"
|
|
37113
|
+
},
|
|
37114
|
+
{ status: 400 }
|
|
37115
|
+
)
|
|
37116
|
+
);
|
|
37117
|
+
return;
|
|
37118
|
+
}
|
|
36745
37119
|
if (body?.grant_type === "anonymous" && body.resource) {
|
|
36746
37120
|
const { request } = this.rawInput;
|
|
36747
37121
|
const canonicalResource = computeResource(request, this.scope.entryPath, this.scope.routeBase);
|
|
@@ -36765,7 +37139,7 @@ var init_oauth_token_flow = __esm({
|
|
|
36765
37139
|
access_token: accessToken,
|
|
36766
37140
|
token_type: "Bearer",
|
|
36767
37141
|
expires_in: 86400,
|
|
36768
|
-
refresh_token: (0,
|
|
37142
|
+
refresh_token: (0, import_utils68.randomUUID)()
|
|
36769
37143
|
});
|
|
36770
37144
|
}
|
|
36771
37145
|
async buildTokenResponse() {
|
|
@@ -36928,7 +37302,7 @@ var init_oauth_userinfo_flow = __esm({
|
|
|
36928
37302
|
});
|
|
36929
37303
|
|
|
36930
37304
|
// libs/sdk/src/auth/flows/session.verify.flow.ts
|
|
36931
|
-
var import_reflect_metadata17, import_auth26, import_lazy_zod71,
|
|
37305
|
+
var import_reflect_metadata17, import_auth26, import_lazy_zod71, import_utils69, inputSchema23, stateSchema22, UnauthorizedSchema, AuthorizedSchema, ForbiddenSchema, sessionVerifyOutputSchema, plan22, name22, Stage22, SessionVerifyFlow;
|
|
36932
37306
|
var init_session_verify_flow = __esm({
|
|
36933
37307
|
"libs/sdk/src/auth/flows/session.verify.flow.ts"() {
|
|
36934
37308
|
"use strict";
|
|
@@ -36936,7 +37310,7 @@ var init_session_verify_flow = __esm({
|
|
|
36936
37310
|
import_reflect_metadata17 = require("reflect-metadata");
|
|
36937
37311
|
import_auth26 = require("@frontmcp/auth");
|
|
36938
37312
|
import_lazy_zod71 = require("@frontmcp/lazy-zod");
|
|
36939
|
-
|
|
37313
|
+
import_utils69 = require("@frontmcp/utils");
|
|
36940
37314
|
init_notification_service();
|
|
36941
37315
|
init_session_id_utils();
|
|
36942
37316
|
inputSchema23 = httpRequestInputSchema;
|
|
@@ -36991,10 +37365,10 @@ var init_session_verify_flow = __esm({
|
|
|
36991
37365
|
createAnonymousSession(options) {
|
|
36992
37366
|
const { authMode, issuer, scopes = ["anonymous"], sessionIdHeader } = options;
|
|
36993
37367
|
this.logger.verbose("createAnonymousSession", { authMode, hasExistingSession: !!sessionIdHeader });
|
|
36994
|
-
const machineId = (0,
|
|
37368
|
+
const machineId = (0, import_utils69.getMachineId)();
|
|
36995
37369
|
if (sessionIdHeader) {
|
|
36996
37370
|
const existingPayload = decryptPublicSession(sessionIdHeader);
|
|
36997
|
-
const user2 = existingPayload ? { sub: `anon:${existingPayload.iat * 1e3}`, iss: issuer, name: "Anonymous", scope: scopes.join(" ") } : { sub: `anon:${(0,
|
|
37371
|
+
const user2 = existingPayload ? { sub: `anon:${existingPayload.iat * 1e3}`, iss: issuer, name: "Anonymous", scope: scopes.join(" ") } : { sub: `anon:${(0, import_utils69.randomUUID)()}`, iss: issuer, name: "Anonymous", scope: scopes.join(" ") };
|
|
36998
37372
|
const finalPayload = existingPayload && existingPayload.nodeId === machineId ? existingPayload : void 0;
|
|
36999
37373
|
this.respond({
|
|
37000
37374
|
kind: "authorized",
|
|
@@ -37011,12 +37385,12 @@ var init_session_verify_flow = __esm({
|
|
|
37011
37385
|
}
|
|
37012
37386
|
const now = Date.now();
|
|
37013
37387
|
const user = {
|
|
37014
|
-
sub: `anon:${(0,
|
|
37388
|
+
sub: `anon:${(0, import_utils69.randomUUID)()}`,
|
|
37015
37389
|
iss: issuer,
|
|
37016
37390
|
name: "Anonymous",
|
|
37017
37391
|
scope: scopes.join(" ")
|
|
37018
37392
|
};
|
|
37019
|
-
const uuid = (0,
|
|
37393
|
+
const uuid = (0, import_utils69.randomUUID)();
|
|
37020
37394
|
const platformDetectionConfig = this.scope.metadata.transport?.platformDetection;
|
|
37021
37395
|
const platformType = detectPlatformFromUserAgent(this.state.userAgent, platformDetectionConfig);
|
|
37022
37396
|
const payload = {
|
|
@@ -37052,7 +37426,7 @@ var init_session_verify_flow = __esm({
|
|
|
37052
37426
|
const token = (0, import_auth26.extractBearerToken)(authorizationHeader);
|
|
37053
37427
|
const userAgent = request.headers?.["user-agent"] ?? void 0;
|
|
37054
37428
|
const prmMetadataPath = `/.well-known/oauth-protected-resource${entryPath}${routeBase}`;
|
|
37055
|
-
const prmUrl = `${
|
|
37429
|
+
const prmUrl = `${getRequestBaseUrl(request)}${prmMetadataPath}`;
|
|
37056
37430
|
const prmMetadataHeader = (0, import_auth26.buildUnauthorizedHeader)(prmUrl);
|
|
37057
37431
|
this.logger.verbose("parseInput", {
|
|
37058
37432
|
hasAuthHeader: !!authorizationHeader,
|
|
@@ -37359,15 +37733,15 @@ function resolveDcrEnabled(auth) {
|
|
|
37359
37733
|
return dcr.enabled;
|
|
37360
37734
|
}
|
|
37361
37735
|
}
|
|
37362
|
-
return !(0,
|
|
37736
|
+
return !(0, import_utils70.isProduction)();
|
|
37363
37737
|
}
|
|
37364
|
-
var import_reflect_metadata19, import_lazy_zod73,
|
|
37738
|
+
var import_reflect_metadata19, import_lazy_zod73, import_utils70, inputSchema25, AuthServerMetadataSchema, outputSchema23, wellKnownAsStateSchema, wellKnownAsPlan, name24, Stage24, WellKnownAsFlow;
|
|
37365
37739
|
var init_well_known_oauth_authorization_server_flow = __esm({
|
|
37366
37740
|
"libs/sdk/src/auth/flows/well-known.oauth-authorization-server.flow.ts"() {
|
|
37367
37741
|
"use strict";
|
|
37368
37742
|
import_reflect_metadata19 = require("reflect-metadata");
|
|
37369
37743
|
import_lazy_zod73 = require("@frontmcp/lazy-zod");
|
|
37370
|
-
|
|
37744
|
+
import_utils70 = require("@frontmcp/utils");
|
|
37371
37745
|
init_common();
|
|
37372
37746
|
init_sdk_errors();
|
|
37373
37747
|
inputSchema25 = httpInputSchema;
|
|
@@ -37667,13 +38041,19 @@ var init_secure_store = __esm({
|
|
|
37667
38041
|
});
|
|
37668
38042
|
|
|
37669
38043
|
// libs/sdk/src/auth/instances/instance.local-primary-auth.ts
|
|
37670
|
-
|
|
38044
|
+
function getDefaultNoAuthSecret() {
|
|
38045
|
+
if (!defaultNoAuthSecret) {
|
|
38046
|
+
defaultNoAuthSecret = (0, import_utils71.randomBytes)(32);
|
|
38047
|
+
}
|
|
38048
|
+
return defaultNoAuthSecret;
|
|
38049
|
+
}
|
|
38050
|
+
var import_jose, import_auth30, import_utils71, defaultNoAuthSecret, RESERVED_JWT_CLAIMS, LocalPrimaryAuth;
|
|
37671
38051
|
var init_instance_local_primary_auth = __esm({
|
|
37672
38052
|
"libs/sdk/src/auth/instances/instance.local-primary-auth.ts"() {
|
|
37673
38053
|
"use strict";
|
|
37674
38054
|
import_jose = require("jose");
|
|
37675
38055
|
import_auth30 = require("@frontmcp/auth");
|
|
37676
|
-
|
|
38056
|
+
import_utils71 = require("@frontmcp/utils");
|
|
37677
38057
|
init_common();
|
|
37678
38058
|
init_auth2();
|
|
37679
38059
|
init_context_extension();
|
|
@@ -37694,7 +38074,6 @@ var init_instance_local_primary_auth = __esm({
|
|
|
37694
38074
|
init_well_known_prm_flow();
|
|
37695
38075
|
init_secure_store();
|
|
37696
38076
|
init_secure_store_context_extension();
|
|
37697
|
-
DEFAULT_NO_AUTH_SECRET = (0, import_utils70.randomBytes)(32);
|
|
37698
38077
|
RESERVED_JWT_CLAIMS = /* @__PURE__ */ new Set([
|
|
37699
38078
|
"sub",
|
|
37700
38079
|
"iss",
|
|
@@ -37719,14 +38098,14 @@ var init_instance_local_primary_auth = __esm({
|
|
|
37719
38098
|
this.providers = providers;
|
|
37720
38099
|
this.logger = this.providers.getActiveScope().logger.child("LocalPrimaryAuth");
|
|
37721
38100
|
this.port = this.providers.getActiveScope().metadata.http?.port ?? 3001;
|
|
37722
|
-
this.host = (0,
|
|
38101
|
+
this.host = (0, import_utils71.getEnv)("FRONTMCP_PUBLIC_HOST")?.trim() || "localhost";
|
|
37723
38102
|
this.issuer = this.deriveIssuer(options);
|
|
37724
|
-
const jwtSecret = (0,
|
|
38103
|
+
const jwtSecret = (0, import_utils71.getEnv)("JWT_SECRET");
|
|
37725
38104
|
if (jwtSecret) {
|
|
37726
38105
|
this.secret = new TextEncoder().encode(jwtSecret);
|
|
37727
38106
|
} else {
|
|
37728
38107
|
this.logger.warn("JWT_SECRET is not set, using default secret");
|
|
37729
|
-
this.secret =
|
|
38108
|
+
this.secret = getDefaultNoAuthSecret();
|
|
37730
38109
|
}
|
|
37731
38110
|
this.tokenStorage = this.readTokenStorage(options);
|
|
37732
38111
|
this.authorizationStoreImpl = new import_auth30.InMemoryAuthorizationStore();
|
|
@@ -37743,6 +38122,8 @@ var init_instance_local_primary_auth = __esm({
|
|
|
37743
38122
|
}
|
|
37744
38123
|
this.ready = this.initialize();
|
|
37745
38124
|
}
|
|
38125
|
+
scope;
|
|
38126
|
+
providers;
|
|
37746
38127
|
host;
|
|
37747
38128
|
port;
|
|
37748
38129
|
issuer;
|
|
@@ -37848,7 +38229,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
37848
38229
|
if (dcr && typeof dcr.enabled === "boolean") {
|
|
37849
38230
|
return dcr.enabled;
|
|
37850
38231
|
}
|
|
37851
|
-
return !(0,
|
|
38232
|
+
return !(0, import_utils71.isProduction)();
|
|
37852
38233
|
}
|
|
37853
38234
|
/** Provider configurations (indexed by provider ID) */
|
|
37854
38235
|
providerConfigs = /* @__PURE__ */ new Map();
|
|
@@ -37955,11 +38336,11 @@ var init_instance_local_primary_auth = __esm({
|
|
|
37955
38336
|
if (this.storageAdapter) {
|
|
37956
38337
|
storage = this.storageAdapter;
|
|
37957
38338
|
} else {
|
|
37958
|
-
const memory = new
|
|
38339
|
+
const memory = new import_utils71.MemoryStorageAdapter();
|
|
37959
38340
|
await memory.connect();
|
|
37960
38341
|
storage = memory;
|
|
37961
38342
|
}
|
|
37962
|
-
const pepper = (0,
|
|
38343
|
+
const pepper = (0, import_utils71.getEnv)("VAULT_SECRET") ?? (0, import_utils71.getEnv)("JWT_SECRET") ?? void 0;
|
|
37963
38344
|
this.credentialVaultImpl = new import_auth30.SessionCredentialVault({
|
|
37964
38345
|
storage,
|
|
37965
38346
|
pepper,
|
|
@@ -38010,7 +38391,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
38010
38391
|
}
|
|
38011
38392
|
const config = this.readSecureStoreConfig();
|
|
38012
38393
|
const reuseAdapter = this.storageAdapter && this.secureStoreSharesTokenStorage(config) ? this.storageAdapter : void 0;
|
|
38013
|
-
const pepper = (0,
|
|
38394
|
+
const pepper = (0, import_utils71.getEnv)("VAULT_SECRET") ?? (0, import_utils71.getEnv)("JWT_SECRET") ?? new TextDecoder().decode(this.secret);
|
|
38014
38395
|
const resolved = await (0, import_auth30.createSecureStore)({
|
|
38015
38396
|
config,
|
|
38016
38397
|
pepper,
|
|
@@ -38043,7 +38424,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
38043
38424
|
return false;
|
|
38044
38425
|
}
|
|
38045
38426
|
async signAnonymousJwt() {
|
|
38046
|
-
const sub = (0,
|
|
38427
|
+
const sub = (0, import_utils71.randomUUID)();
|
|
38047
38428
|
return new import_jose.SignJWT({ sub, role: "user", anonymous: true }).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setIssuer(this.issuer).setExpirationTime("1d").sign(this.secret);
|
|
38048
38429
|
}
|
|
38049
38430
|
/**
|
|
@@ -38116,7 +38497,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
38116
38497
|
}
|
|
38117
38498
|
}
|
|
38118
38499
|
}
|
|
38119
|
-
const jwt = new import_jose.SignJWT(claims).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setIssuer(this.issuer).setExpirationTime(`${this.accessTokenTtlSeconds}s`).setJti((0,
|
|
38500
|
+
const jwt = new import_jose.SignJWT(claims).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setIssuer(this.issuer).setExpirationTime(`${this.accessTokenTtlSeconds}s`).setJti((0, import_utils71.randomUUID)());
|
|
38120
38501
|
if (audience) {
|
|
38121
38502
|
jwt.setAudience(audience);
|
|
38122
38503
|
}
|
|
@@ -38186,7 +38567,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
38186
38567
|
const pendingAuthId = `pending:${codeRecord.pendingAuthId}`;
|
|
38187
38568
|
const parts = accessToken.split(".");
|
|
38188
38569
|
const signature = parts[2] || accessToken;
|
|
38189
|
-
const newAuthId = (0,
|
|
38570
|
+
const newAuthId = (0, import_utils71.sha256Hex)(signature).substring(0, 16);
|
|
38190
38571
|
await this.orchestratedTokenStore.migrateTokens(pendingAuthId, newAuthId);
|
|
38191
38572
|
this.logger.info(`Migrated tokens from ${pendingAuthId} to ${newAuthId}`);
|
|
38192
38573
|
} catch (err) {
|
|
@@ -38533,7 +38914,7 @@ var init_instance_local_primary_auth = __esm({
|
|
|
38533
38914
|
if (idToken) {
|
|
38534
38915
|
try {
|
|
38535
38916
|
const [, payloadB64] = idToken.split(".");
|
|
38536
|
-
const payload = JSON.parse(new TextDecoder().decode((0,
|
|
38917
|
+
const payload = JSON.parse(new TextDecoder().decode((0, import_utils71.base64urlDecode)(payloadB64)));
|
|
38537
38918
|
return {
|
|
38538
38919
|
sub: payload["sub"],
|
|
38539
38920
|
email: payload["email"],
|
|
@@ -38636,6 +39017,8 @@ var init_instance_remote_primary_auth = __esm({
|
|
|
38636
39017
|
this.providers = providers;
|
|
38637
39018
|
this.ready = this.initialize();
|
|
38638
39019
|
}
|
|
39020
|
+
scope;
|
|
39021
|
+
providers;
|
|
38639
39022
|
ready;
|
|
38640
39023
|
jwks = new import_auth32.JwksService();
|
|
38641
39024
|
fetch(input, init) {
|
|
@@ -38890,6 +39273,7 @@ var init_channel_notification_service = __esm({
|
|
|
38890
39273
|
this.logger = logger.child("ChannelNotificationService");
|
|
38891
39274
|
this.defaultMeta = defaultMeta ?? {};
|
|
38892
39275
|
}
|
|
39276
|
+
notificationService;
|
|
38893
39277
|
logger;
|
|
38894
39278
|
defaultMeta;
|
|
38895
39279
|
/**
|
|
@@ -40189,12 +40573,12 @@ var init_complete_flow = __esm({
|
|
|
40189
40573
|
});
|
|
40190
40574
|
|
|
40191
40575
|
// libs/sdk/src/elicitation/store/storage-elicitation.store.ts
|
|
40192
|
-
var
|
|
40576
|
+
var import_utils72, import_utils73, RESOLVED_RESULT_TTL_SECONDS, RESULT_CHANNEL_PREFIX, FALLBACK_RESULT_CHANNEL_PREFIX, StorageElicitationStore;
|
|
40193
40577
|
var init_storage_elicitation_store = __esm({
|
|
40194
40578
|
"libs/sdk/src/elicitation/store/storage-elicitation.store.ts"() {
|
|
40195
40579
|
"use strict";
|
|
40196
|
-
import_utils71 = require("@frontmcp/utils");
|
|
40197
40580
|
import_utils72 = require("@frontmcp/utils");
|
|
40581
|
+
import_utils73 = require("@frontmcp/utils");
|
|
40198
40582
|
RESOLVED_RESULT_TTL_SECONDS = 300;
|
|
40199
40583
|
RESULT_CHANNEL_PREFIX = "result:";
|
|
40200
40584
|
FALLBACK_RESULT_CHANNEL_PREFIX = "fallback-result:";
|
|
@@ -40219,9 +40603,9 @@ var init_storage_elicitation_store = __esm({
|
|
|
40219
40603
|
constructor(storage, logger) {
|
|
40220
40604
|
this.storage = storage;
|
|
40221
40605
|
this.logger = logger;
|
|
40222
|
-
this.pending = new
|
|
40223
|
-
this.fallback = new
|
|
40224
|
-
this.resolved = new
|
|
40606
|
+
this.pending = new import_utils72.TypedStorage(storage.namespace("pending"));
|
|
40607
|
+
this.fallback = new import_utils72.TypedStorage(storage.namespace("fallback"));
|
|
40608
|
+
this.resolved = new import_utils72.TypedStorage(storage.namespace("resolved"));
|
|
40225
40609
|
}
|
|
40226
40610
|
// ============================================
|
|
40227
40611
|
// Pending Elicitation Methods
|
|
@@ -40231,7 +40615,7 @@ var init_storage_elicitation_store = __esm({
|
|
|
40231
40615
|
*/
|
|
40232
40616
|
async setPending(record) {
|
|
40233
40617
|
const { sessionId, expiresAt } = record;
|
|
40234
|
-
const ttlSeconds = (0,
|
|
40618
|
+
const ttlSeconds = (0, import_utils73.expiresAtToTTL)(expiresAt);
|
|
40235
40619
|
if (ttlSeconds <= 0) {
|
|
40236
40620
|
this.logger?.warn("[StorageElicitationStore] Record already expired, not storing", {
|
|
40237
40621
|
sessionId,
|
|
@@ -40409,7 +40793,7 @@ var init_storage_elicitation_store = __esm({
|
|
|
40409
40793
|
*/
|
|
40410
40794
|
async setPendingFallback(record) {
|
|
40411
40795
|
const { elicitId, expiresAt } = record;
|
|
40412
|
-
const ttlSeconds = (0,
|
|
40796
|
+
const ttlSeconds = (0, import_utils73.expiresAtToTTL)(expiresAt);
|
|
40413
40797
|
if (ttlSeconds <= 0) {
|
|
40414
40798
|
this.logger?.warn("[StorageElicitationStore] Fallback record already expired, not storing", { elicitId });
|
|
40415
40799
|
return;
|
|
@@ -40664,7 +41048,7 @@ var init_storage_elicitation_store = __esm({
|
|
|
40664
41048
|
|
|
40665
41049
|
// libs/sdk/src/elicitation/store/elicitation-encryption.ts
|
|
40666
41050
|
function getElicitationSecret() {
|
|
40667
|
-
return (0,
|
|
41051
|
+
return (0, import_utils74.getEnv)("MCP_ELICITATION_SECRET") || (0, import_utils74.getEnv)("MCP_SESSION_SECRET") || (0, import_utils74.getEnv)("MCP_SERVER_SECRET") || null;
|
|
40668
41052
|
}
|
|
40669
41053
|
function isElicitationEncryptionAvailable() {
|
|
40670
41054
|
return getElicitationSecret() !== null;
|
|
@@ -40677,27 +41061,27 @@ async function deriveElicitationKey(sessionId, secret) {
|
|
|
40677
41061
|
const ikm = textEncoder.encode(serverSecret + sessionId);
|
|
40678
41062
|
const salt = textEncoder.encode(ELICITATION_SALT);
|
|
40679
41063
|
const info = textEncoder.encode(`elicit:${sessionId}`);
|
|
40680
|
-
return (0,
|
|
41064
|
+
return (0, import_utils74.hkdfSha256)(ikm, salt, info, 32);
|
|
40681
41065
|
}
|
|
40682
41066
|
async function encryptElicitationData(data, sessionId, secret) {
|
|
40683
41067
|
const key = await deriveElicitationKey(sessionId, secret);
|
|
40684
41068
|
const plaintext = textEncoder.encode(JSON.stringify(data));
|
|
40685
|
-
const iv = (0,
|
|
40686
|
-
const { ciphertext, tag } = (0,
|
|
41069
|
+
const iv = (0, import_utils74.randomBytes)(12);
|
|
41070
|
+
const { ciphertext, tag } = (0, import_utils74.encryptAesGcm)(key, plaintext, iv);
|
|
40687
41071
|
return {
|
|
40688
41072
|
alg: "A256GCM",
|
|
40689
|
-
iv: (0,
|
|
40690
|
-
tag: (0,
|
|
40691
|
-
data: (0,
|
|
41073
|
+
iv: (0, import_utils74.base64urlEncode)(iv),
|
|
41074
|
+
tag: (0, import_utils74.base64urlEncode)(tag),
|
|
41075
|
+
data: (0, import_utils74.base64urlEncode)(ciphertext)
|
|
40692
41076
|
};
|
|
40693
41077
|
}
|
|
40694
41078
|
async function decryptElicitationData(blob, sessionId, secret) {
|
|
40695
41079
|
try {
|
|
40696
41080
|
const key = await deriveElicitationKey(sessionId, secret);
|
|
40697
|
-
const iv = (0,
|
|
40698
|
-
const tag = (0,
|
|
40699
|
-
const ciphertext = (0,
|
|
40700
|
-
const decrypted = (0,
|
|
41081
|
+
const iv = (0, import_utils74.base64urlDecode)(blob.iv);
|
|
41082
|
+
const tag = (0, import_utils74.base64urlDecode)(blob.tag);
|
|
41083
|
+
const ciphertext = (0, import_utils74.base64urlDecode)(blob.data);
|
|
41084
|
+
const decrypted = (0, import_utils74.decryptAesGcm)(key, ciphertext, iv, tag);
|
|
40701
41085
|
return JSON.parse(textDecoder.decode(decrypted));
|
|
40702
41086
|
} catch {
|
|
40703
41087
|
return null;
|
|
@@ -40737,11 +41121,11 @@ async function tryDecryptStoredValue(value, sessionId, secret) {
|
|
|
40737
41121
|
}
|
|
40738
41122
|
return decryptElicitationData(value, sessionId, secret);
|
|
40739
41123
|
}
|
|
40740
|
-
var
|
|
41124
|
+
var import_utils74, ELICITATION_SALT, textEncoder, textDecoder;
|
|
40741
41125
|
var init_elicitation_encryption = __esm({
|
|
40742
41126
|
"libs/sdk/src/elicitation/store/elicitation-encryption.ts"() {
|
|
40743
41127
|
"use strict";
|
|
40744
|
-
|
|
41128
|
+
import_utils74 = require("@frontmcp/utils");
|
|
40745
41129
|
init_auth_internal_errors();
|
|
40746
41130
|
ELICITATION_SALT = "elicitation-store-v1";
|
|
40747
41131
|
textEncoder = new TextEncoder();
|
|
@@ -41143,10 +41527,10 @@ var init_encrypted_elicitation_store = __esm({
|
|
|
41143
41527
|
|
|
41144
41528
|
// libs/sdk/src/elicitation/store/elicitation-store.factory.ts
|
|
41145
41529
|
function detectStorageType2(storage) {
|
|
41146
|
-
if ((0,
|
|
41530
|
+
if ((0, import_utils75.getEnv)("UPSTASH_REDIS_REST_URL")) {
|
|
41147
41531
|
return "upstash";
|
|
41148
41532
|
}
|
|
41149
|
-
if ((0,
|
|
41533
|
+
if ((0, import_utils75.getEnv)("REDIS_URL") || (0, import_utils75.getEnv)("REDIS_HOST")) {
|
|
41150
41534
|
return "redis";
|
|
41151
41535
|
}
|
|
41152
41536
|
return "memory";
|
|
@@ -41232,7 +41616,7 @@ async function createElicitationStore(options = {}) {
|
|
|
41232
41616
|
});
|
|
41233
41617
|
}
|
|
41234
41618
|
}
|
|
41235
|
-
if (finalStorageConfig?.type === "vercel-kv" || (0,
|
|
41619
|
+
if (finalStorageConfig?.type === "vercel-kv" || (0, import_utils75.getEnv)("KV_REST_API_URL")) {
|
|
41236
41620
|
throw new ElicitationNotSupportedError(
|
|
41237
41621
|
"Vercel KV is not supported for elicitation stores. Elicitation requires pub/sub for cross-node result routing, which Vercel KV does not support. Use Redis or Upstash instead."
|
|
41238
41622
|
);
|
|
@@ -41242,7 +41626,7 @@ async function createElicitationStore(options = {}) {
|
|
|
41242
41626
|
"Elicitation requires distributed storage when running on Edge runtime. Edge functions are stateless and cannot use in-memory elicitation. Configure Redis or Upstash storage."
|
|
41243
41627
|
);
|
|
41244
41628
|
}
|
|
41245
|
-
const storage = await (0,
|
|
41629
|
+
const storage = await (0, import_utils75.createStorage)({
|
|
41246
41630
|
...finalStorageConfig,
|
|
41247
41631
|
prefix: keyPrefix,
|
|
41248
41632
|
fallback: isEdgeRuntime2 ? "error" : "memory"
|
|
@@ -41280,7 +41664,7 @@ async function createElicitationStore(options = {}) {
|
|
|
41280
41664
|
}
|
|
41281
41665
|
function createMemoryElicitationStore(options = {}) {
|
|
41282
41666
|
const { keyPrefix = "mcp:elicit:", logger, encryption } = options;
|
|
41283
|
-
const storage = (0,
|
|
41667
|
+
const storage = (0, import_utils75.createMemoryStorage)({ prefix: keyPrefix });
|
|
41284
41668
|
let store = new StorageElicitationStore(storage, logger);
|
|
41285
41669
|
const encryptionEnabled = encryption?.enabled ?? "auto";
|
|
41286
41670
|
const encryptionSecret = encryption?.secret;
|
|
@@ -41336,11 +41720,11 @@ function createSqliteElicitationStore(sqliteConfig, storeOptions = {}) {
|
|
|
41336
41720
|
keyPrefix
|
|
41337
41721
|
});
|
|
41338
41722
|
}
|
|
41339
|
-
var
|
|
41723
|
+
var import_utils75;
|
|
41340
41724
|
var init_elicitation_store_factory = __esm({
|
|
41341
41725
|
"libs/sdk/src/elicitation/store/elicitation-store.factory.ts"() {
|
|
41342
41726
|
"use strict";
|
|
41343
|
-
|
|
41727
|
+
import_utils75 = require("@frontmcp/utils");
|
|
41344
41728
|
init_elicitation_error();
|
|
41345
41729
|
init_elicitation_encryption();
|
|
41346
41730
|
init_encrypted_elicitation_store();
|
|
@@ -41371,12 +41755,12 @@ var init_elicitation2 = __esm({
|
|
|
41371
41755
|
});
|
|
41372
41756
|
|
|
41373
41757
|
// libs/sdk/src/elicitation/flows/elicitation-request.flow.ts
|
|
41374
|
-
var import_lazy_zod79,
|
|
41758
|
+
var import_lazy_zod79, import_utils76, inputSchema30, outputSchema28, stateSchema28, plan28, name29, Stage29, ElicitationRequestFlow;
|
|
41375
41759
|
var init_elicitation_request_flow = __esm({
|
|
41376
41760
|
"libs/sdk/src/elicitation/flows/elicitation-request.flow.ts"() {
|
|
41377
41761
|
"use strict";
|
|
41378
41762
|
import_lazy_zod79 = require("@frontmcp/lazy-zod");
|
|
41379
|
-
|
|
41763
|
+
import_utils76 = require("@frontmcp/utils");
|
|
41380
41764
|
init_common();
|
|
41381
41765
|
init_errors();
|
|
41382
41766
|
init_elicitation_types();
|
|
@@ -41459,7 +41843,7 @@ var init_elicitation_request_flow = __esm({
|
|
|
41459
41843
|
async generateElicitId() {
|
|
41460
41844
|
this.logger.verbose("generateElicitId:start");
|
|
41461
41845
|
const { elicitationId, ttl } = this.state;
|
|
41462
|
-
const elicitId = elicitationId ?? `elicit-${(0,
|
|
41846
|
+
const elicitId = elicitationId ?? `elicit-${(0, import_utils76.randomUUID)()}`;
|
|
41463
41847
|
const expiresAt = Date.now() + (ttl ?? DEFAULT_ELICIT_TTL);
|
|
41464
41848
|
this.state.set({ elicitId, expiresAt });
|
|
41465
41849
|
this.logger.verbose("generateElicitId:done", { elicitId });
|
|
@@ -41776,6 +42160,8 @@ var init_heartbeat_service = __esm({
|
|
|
41776
42160
|
this.intervalMs = config?.heartbeatIntervalMs ?? DEFAULT_HA_CONFIG.heartbeatIntervalMs;
|
|
41777
42161
|
this.ttlMs = config?.heartbeatTtlMs ?? DEFAULT_HA_CONFIG.heartbeatTtlMs;
|
|
41778
42162
|
}
|
|
42163
|
+
redis;
|
|
42164
|
+
nodeId;
|
|
41779
42165
|
timer;
|
|
41780
42166
|
startedAt;
|
|
41781
42167
|
keyPrefix;
|
|
@@ -41855,6 +42241,9 @@ var init_notification_relay = __esm({
|
|
|
41855
42241
|
this.keyPrefix = config?.redisKeyPrefix ?? DEFAULT_HA_CONFIG.redisKeyPrefix;
|
|
41856
42242
|
this.channel = `${this.keyPrefix}notify:${nodeId}`;
|
|
41857
42243
|
}
|
|
42244
|
+
subscriber;
|
|
42245
|
+
publisher;
|
|
42246
|
+
nodeId;
|
|
41858
42247
|
handler;
|
|
41859
42248
|
channel;
|
|
41860
42249
|
keyPrefix;
|
|
@@ -41964,6 +42353,8 @@ var init_ha_manager = __esm({
|
|
|
41964
42353
|
this.relay = new NotificationRelay(options.pubsubSubscriber, options.pubsubPublisher, nodeId, this.config);
|
|
41965
42354
|
}
|
|
41966
42355
|
}
|
|
42356
|
+
redis;
|
|
42357
|
+
nodeId;
|
|
41967
42358
|
heartbeat;
|
|
41968
42359
|
relay;
|
|
41969
42360
|
config;
|
|
@@ -43001,11 +43392,11 @@ var init_workflow_engine = __esm({
|
|
|
43001
43392
|
});
|
|
43002
43393
|
|
|
43003
43394
|
// libs/sdk/src/job/execution/job-execution.manager.ts
|
|
43004
|
-
var
|
|
43395
|
+
var import_utils77, JobExecutionManager;
|
|
43005
43396
|
var init_job_execution_manager = __esm({
|
|
43006
43397
|
"libs/sdk/src/job/execution/job-execution.manager.ts"() {
|
|
43007
43398
|
"use strict";
|
|
43008
|
-
|
|
43399
|
+
import_utils77 = require("@frontmcp/utils");
|
|
43009
43400
|
init_workflow_engine();
|
|
43010
43401
|
JobExecutionManager = class {
|
|
43011
43402
|
stateStore;
|
|
@@ -43020,7 +43411,7 @@ var init_job_execution_manager = __esm({
|
|
|
43020
43411
|
* Execute a job inline (synchronous) or in background.
|
|
43021
43412
|
*/
|
|
43022
43413
|
async executeJob(job, input, opts = {}) {
|
|
43023
|
-
const runId = (0,
|
|
43414
|
+
const runId = (0, import_utils77.randomUUID)();
|
|
43024
43415
|
const retryConfig = job.metadata.retry ?? {};
|
|
43025
43416
|
const maxAttempts = retryConfig.maxAttempts ?? 1;
|
|
43026
43417
|
const runRecord = {
|
|
@@ -43058,7 +43449,7 @@ var init_job_execution_manager = __esm({
|
|
|
43058
43449
|
* Execute a workflow inline or in background.
|
|
43059
43450
|
*/
|
|
43060
43451
|
async executeWorkflow(workflow, jobRegistry, opts = {}) {
|
|
43061
|
-
const runId = (0,
|
|
43452
|
+
const runId = (0, import_utils77.randomUUID)();
|
|
43062
43453
|
const runRecord = {
|
|
43063
43454
|
runId,
|
|
43064
43455
|
jobId: workflow.metadata.id ?? workflow.name,
|
|
@@ -43466,6 +43857,7 @@ var init_job_instance = __esm({
|
|
|
43466
43857
|
super(args);
|
|
43467
43858
|
this.record = record;
|
|
43468
43859
|
}
|
|
43860
|
+
record;
|
|
43469
43861
|
execute(input) {
|
|
43470
43862
|
return this.record.provide(input, this);
|
|
43471
43863
|
}
|
|
@@ -44634,6 +45026,9 @@ var init_custom_routes_helper = __esm({
|
|
|
44634
45026
|
this.reserved = reserved;
|
|
44635
45027
|
this.name = "ReservedRouteCollisionError";
|
|
44636
45028
|
}
|
|
45029
|
+
method;
|
|
45030
|
+
path;
|
|
45031
|
+
reserved;
|
|
44637
45032
|
};
|
|
44638
45033
|
}
|
|
44639
45034
|
});
|
|
@@ -44878,15 +45273,15 @@ var init_skill_session_types = __esm({
|
|
|
44878
45273
|
});
|
|
44879
45274
|
|
|
44880
45275
|
// libs/sdk/src/skill/session/skill-session.manager.ts
|
|
44881
|
-
var
|
|
45276
|
+
var import_utils78, SkillSessionManager;
|
|
44882
45277
|
var init_skill_session_manager = __esm({
|
|
44883
45278
|
"libs/sdk/src/skill/session/skill-session.manager.ts"() {
|
|
44884
45279
|
"use strict";
|
|
44885
|
-
|
|
45280
|
+
import_utils78 = require("@frontmcp/utils");
|
|
44886
45281
|
init_errors();
|
|
44887
45282
|
init_skill_session_types();
|
|
44888
|
-
SkillSessionManager = class extends
|
|
44889
|
-
storage = new
|
|
45283
|
+
SkillSessionManager = class extends import_utils78.EventEmitter {
|
|
45284
|
+
storage = new import_utils78.AsyncLocalStorage();
|
|
44890
45285
|
options;
|
|
44891
45286
|
logger;
|
|
44892
45287
|
store;
|
|
@@ -46022,11 +46417,11 @@ function createSkillHttpAuthValidator(skillsConfig, logger) {
|
|
|
46022
46417
|
}
|
|
46023
46418
|
return new SkillHttpAuthValidator({ skillsConfig, logger });
|
|
46024
46419
|
}
|
|
46025
|
-
var
|
|
46420
|
+
var import_utils79, SkillHttpAuthValidator;
|
|
46026
46421
|
var init_skill_http_auth = __esm({
|
|
46027
46422
|
"libs/sdk/src/skill/auth/skill-http-auth.ts"() {
|
|
46028
46423
|
"use strict";
|
|
46029
|
-
|
|
46424
|
+
import_utils79 = require("@frontmcp/utils");
|
|
46030
46425
|
SkillHttpAuthValidator = class {
|
|
46031
46426
|
skillsConfig;
|
|
46032
46427
|
logger;
|
|
@@ -46096,14 +46491,14 @@ var init_skill_http_auth = __esm({
|
|
|
46096
46491
|
* This prevents timing attacks that could reveal information about valid API keys.
|
|
46097
46492
|
*/
|
|
46098
46493
|
timingSafeIncludes(keys, candidate) {
|
|
46099
|
-
const
|
|
46100
|
-
const candidateBytes =
|
|
46494
|
+
const encoder2 = new TextEncoder();
|
|
46495
|
+
const candidateBytes = encoder2.encode(candidate);
|
|
46101
46496
|
let found = false;
|
|
46102
46497
|
for (const key of keys) {
|
|
46103
|
-
const keyBytes =
|
|
46498
|
+
const keyBytes = encoder2.encode(key);
|
|
46104
46499
|
if (keyBytes.length === candidateBytes.length) {
|
|
46105
46500
|
try {
|
|
46106
|
-
if ((0,
|
|
46501
|
+
if ((0, import_utils79.timingSafeEqual)(keyBytes, candidateBytes)) {
|
|
46107
46502
|
found = true;
|
|
46108
46503
|
}
|
|
46109
46504
|
} catch {
|
|
@@ -48034,6 +48429,7 @@ var init_agent_execution_loop = __esm({
|
|
|
48034
48429
|
this.maxIterations = maxIterations;
|
|
48035
48430
|
this.name = "AgentMaxIterationsError";
|
|
48036
48431
|
}
|
|
48432
|
+
maxIterations;
|
|
48037
48433
|
};
|
|
48038
48434
|
}
|
|
48039
48435
|
});
|
|
@@ -49016,14 +49412,30 @@ var init_decide_request_intent_utils = __esm({
|
|
|
49016
49412
|
|
|
49017
49413
|
// libs/sdk/src/common/utils/path.utils.ts
|
|
49018
49414
|
function normalizeEntryPrefix(entryPath) {
|
|
49019
|
-
const t = (0,
|
|
49415
|
+
const t = (0, import_utils80.trimSlashes)(entryPath ?? "");
|
|
49020
49416
|
return t ? `/${t}` : "";
|
|
49021
49417
|
}
|
|
49022
49418
|
function normalizeScopeBase(scopeBase) {
|
|
49023
|
-
const t = (0,
|
|
49419
|
+
const t = (0, import_utils80.trimSlashes)(scopeBase ?? "");
|
|
49024
49420
|
return t ? `/${t}` : "";
|
|
49025
49421
|
}
|
|
49422
|
+
function readPublicUrlPin() {
|
|
49423
|
+
try {
|
|
49424
|
+
if (typeof process !== "undefined" && process.env) {
|
|
49425
|
+
const v = process.env["FRONTMCP_PUBLIC_URL"];
|
|
49426
|
+
if (typeof v === "string" && v.trim()) {
|
|
49427
|
+
return v.trim().replace(/\/+$/, "");
|
|
49428
|
+
}
|
|
49429
|
+
}
|
|
49430
|
+
} catch {
|
|
49431
|
+
}
|
|
49432
|
+
return void 0;
|
|
49433
|
+
}
|
|
49026
49434
|
function getRequestBaseUrl(req, entryPath) {
|
|
49435
|
+
const pin = readPublicUrlPin();
|
|
49436
|
+
if (pin) {
|
|
49437
|
+
return `${pin}${entryPath ?? ""}`;
|
|
49438
|
+
}
|
|
49027
49439
|
const proto = req.headers["x-forwarded-proto"] || req.protocol || "http";
|
|
49028
49440
|
const host = req.headers["x-forwarded-host"] || req.headers["host"];
|
|
49029
49441
|
return `${proto}://${host}${entryPath ?? ""}`;
|
|
@@ -49062,22 +49474,22 @@ function resourceUriMatches(provided, canonical) {
|
|
|
49062
49474
|
function urlToSafeId(url) {
|
|
49063
49475
|
const u = new URL(url);
|
|
49064
49476
|
const raw = (u.host + (u.pathname && u.pathname !== "/" ? u.pathname : "")).replace(/\/+$/, "");
|
|
49065
|
-
return (0,
|
|
49477
|
+
return (0, import_utils80.trimSlashes)(raw).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
49066
49478
|
}
|
|
49067
49479
|
function makeWellKnownPaths(name41, entryPrefix, scopeBase = "") {
|
|
49068
49480
|
const prefix = normalizeEntryPrefix(entryPrefix);
|
|
49069
49481
|
const scope = normalizeScopeBase(scopeBase);
|
|
49070
|
-
const reversed = (0,
|
|
49071
|
-
const inPrefixRoot = `${prefix}${(0,
|
|
49072
|
-
const inPrefixScope = `${prefix}${scope}${(0,
|
|
49482
|
+
const reversed = (0, import_utils80.joinPath)(".well-known", name41) + `${prefix}${scope}`;
|
|
49483
|
+
const inPrefixRoot = `${prefix}${(0, import_utils80.joinPath)(".well-known", name41)}${scope}`;
|
|
49484
|
+
const inPrefixScope = `${prefix}${scope}${(0, import_utils80.joinPath)(".well-known", name41)}`;
|
|
49073
49485
|
return /* @__PURE__ */ new Set([reversed, inPrefixRoot, inPrefixScope]);
|
|
49074
49486
|
}
|
|
49075
|
-
var
|
|
49487
|
+
var import_utils80, import_utils81;
|
|
49076
49488
|
var init_path_utils = __esm({
|
|
49077
49489
|
"libs/sdk/src/common/utils/path.utils.ts"() {
|
|
49078
49490
|
"use strict";
|
|
49079
|
-
import_utils79 = require("@frontmcp/utils");
|
|
49080
49491
|
import_utils80 = require("@frontmcp/utils");
|
|
49492
|
+
import_utils81 = require("@frontmcp/utils");
|
|
49081
49493
|
}
|
|
49082
49494
|
});
|
|
49083
49495
|
|
|
@@ -49357,15 +49769,15 @@ async function readSkillFileByPath(instance, filePath) {
|
|
|
49357
49769
|
let candidatePath;
|
|
49358
49770
|
for (const [subdir, configured] of candidateDirs) {
|
|
49359
49771
|
if (segments[0] !== subdir) continue;
|
|
49360
|
-
const dir = configured ? (0,
|
|
49361
|
-
candidatePath = (0,
|
|
49772
|
+
const dir = configured ? (0, import_utils83.isAbsolute)(configured) ? configured : (0, import_utils83.pathResolve)(baseDir, configured) : (0, import_utils83.joinPath)(baseDir, subdir);
|
|
49773
|
+
candidatePath = (0, import_utils83.pathResolve)(dir, ...segments.slice(1));
|
|
49362
49774
|
if (!isInside(candidatePath, dir)) {
|
|
49363
49775
|
throw new PublicMcpError(`Invalid file path "${filePath}".`, "INVALID_PARAMS", 400);
|
|
49364
49776
|
}
|
|
49365
49777
|
break;
|
|
49366
49778
|
}
|
|
49367
49779
|
if (!candidatePath) {
|
|
49368
|
-
candidatePath = (0,
|
|
49780
|
+
candidatePath = (0, import_utils83.pathResolve)(baseDir, ...segments);
|
|
49369
49781
|
if (!isInside(candidatePath, baseDir)) {
|
|
49370
49782
|
throw new PublicMcpError(`Invalid file path "${filePath}".`, "INVALID_PARAMS", 400);
|
|
49371
49783
|
}
|
|
@@ -49373,7 +49785,7 @@ async function readSkillFileByPath(instance, filePath) {
|
|
|
49373
49785
|
const mimeType = guessMimeType(filePath);
|
|
49374
49786
|
let buffer;
|
|
49375
49787
|
try {
|
|
49376
|
-
buffer = await (0,
|
|
49788
|
+
buffer = await (0, import_utils83.readFileBuffer)(candidatePath);
|
|
49377
49789
|
} catch (err) {
|
|
49378
49790
|
if (isFileMissingError(err)) {
|
|
49379
49791
|
throw new ResourceNotFoundError(`skill://${instance.getSkillPath()}/${filePath}`);
|
|
@@ -49416,7 +49828,7 @@ async function tryResolvedSubFile(instance, kind, tail) {
|
|
|
49416
49828
|
const resolvedPath = resolveEntryPath(instance, kind, absolutePath, filename);
|
|
49417
49829
|
if (!resolvedPath) continue;
|
|
49418
49830
|
try {
|
|
49419
|
-
const buf = await (0,
|
|
49831
|
+
const buf = await (0, import_utils83.readFileBuffer)(resolvedPath);
|
|
49420
49832
|
const text = (Buffer.isBuffer(buf) ? buf : Buffer.from(buf)).toString("utf-8");
|
|
49421
49833
|
return parseSkillMdFrontmatter(text).body;
|
|
49422
49834
|
} catch (err) {
|
|
@@ -49429,18 +49841,18 @@ async function tryResolvedSubFile(instance, kind, tail) {
|
|
|
49429
49841
|
return void 0;
|
|
49430
49842
|
}
|
|
49431
49843
|
function resolveEntryPath(instance, kind, absolutePath, filename) {
|
|
49432
|
-
if (absolutePath && (0,
|
|
49844
|
+
if (absolutePath && (0, import_utils83.isAbsolute)(absolutePath)) return absolutePath;
|
|
49433
49845
|
if (!filename) return void 0;
|
|
49434
49846
|
const baseDir = instance.getBaseDir();
|
|
49435
49847
|
const configured = instance.getResources()?.[kind];
|
|
49436
49848
|
let dir;
|
|
49437
|
-
if (configured && (0,
|
|
49849
|
+
if (configured && (0, import_utils83.isAbsolute)(configured)) {
|
|
49438
49850
|
dir = configured;
|
|
49439
49851
|
} else if (baseDir) {
|
|
49440
|
-
dir = configured ? (0,
|
|
49852
|
+
dir = configured ? (0, import_utils83.pathResolve)(baseDir, configured) : (0, import_utils83.joinPath)(baseDir, kind);
|
|
49441
49853
|
}
|
|
49442
49854
|
if (!dir) return void 0;
|
|
49443
|
-
const resolved = (0,
|
|
49855
|
+
const resolved = (0, import_utils83.pathResolve)(dir, filename);
|
|
49444
49856
|
if (!isInside(resolved, dir)) return void 0;
|
|
49445
49857
|
return resolved;
|
|
49446
49858
|
}
|
|
@@ -49472,11 +49884,11 @@ function isInside(child, parent) {
|
|
|
49472
49884
|
const parentPrefix = normParent.endsWith("/") ? normParent : `${normParent}/`;
|
|
49473
49885
|
return normChild === normParent || normChild.startsWith(parentPrefix);
|
|
49474
49886
|
}
|
|
49475
|
-
var
|
|
49887
|
+
var import_utils83;
|
|
49476
49888
|
var init_sep_2640_resource_helpers = __esm({
|
|
49477
49889
|
"libs/sdk/src/skill/sep-2640/sep-2640.resource-helpers.ts"() {
|
|
49478
49890
|
"use strict";
|
|
49479
|
-
|
|
49891
|
+
import_utils83 = require("@frontmcp/utils");
|
|
49480
49892
|
init_errors();
|
|
49481
49893
|
init_skill_md_parser();
|
|
49482
49894
|
}
|
|
@@ -49676,17 +50088,17 @@ async function resolveLastModifiedForSkill(skill) {
|
|
|
49676
50088
|
return void 0;
|
|
49677
50089
|
}
|
|
49678
50090
|
try {
|
|
49679
|
-
const s = await (0,
|
|
50091
|
+
const s = await (0, import_utils84.stat)(record.filePath);
|
|
49680
50092
|
return s.mtime instanceof Date ? s.mtime.toISOString() : void 0;
|
|
49681
50093
|
} catch {
|
|
49682
50094
|
return void 0;
|
|
49683
50095
|
}
|
|
49684
50096
|
}
|
|
49685
|
-
var
|
|
50097
|
+
var import_utils84;
|
|
49686
50098
|
var init_sep_2640_last_modified = __esm({
|
|
49687
50099
|
"libs/sdk/src/skill/sep-2640/sep-2640.last-modified.ts"() {
|
|
49688
50100
|
"use strict";
|
|
49689
|
-
|
|
50101
|
+
import_utils84 = require("@frontmcp/utils");
|
|
49690
50102
|
}
|
|
49691
50103
|
});
|
|
49692
50104
|
|
|
@@ -49833,7 +50245,7 @@ function createDefaultSigner(mod, logger) {
|
|
|
49833
50245
|
"[skill-audit] refusing to use the default HS256 signer in production. Configure skillsConfig.audit.signer with a host-managed key (e.g. RS256 pointing at the same key registry your bundle signing uses)."
|
|
49834
50246
|
);
|
|
49835
50247
|
}
|
|
49836
|
-
const bytes = (0,
|
|
50248
|
+
const bytes = (0, import_utils85.randomBytes)(32);
|
|
49837
50249
|
logger.warn(
|
|
49838
50250
|
"[skill-audit] no audit signer configured \u2014 using process-local HS256 with a CSPRNG-generated secret. Records signed by this instance cannot be verified after restart. Configure skillsConfig.audit.signer for production."
|
|
49839
50251
|
);
|
|
@@ -49845,12 +50257,12 @@ function createDefaultStore(mod, logger) {
|
|
|
49845
50257
|
);
|
|
49846
50258
|
return new mod.MemoryAuditStore();
|
|
49847
50259
|
}
|
|
49848
|
-
var import_di38,
|
|
50260
|
+
var import_di38, import_utils85, injectedFactory;
|
|
49849
50261
|
var init_skill_audit_helper = __esm({
|
|
49850
50262
|
"libs/sdk/src/skill/skill-audit.helper.ts"() {
|
|
49851
50263
|
"use strict";
|
|
49852
50264
|
import_di38 = require("@frontmcp/di");
|
|
49853
|
-
|
|
50265
|
+
import_utils85 = require("@frontmcp/utils");
|
|
49854
50266
|
}
|
|
49855
50267
|
});
|
|
49856
50268
|
|
|
@@ -49933,6 +50345,8 @@ return 0
|
|
|
49933
50345
|
this.haKeyPrefix = options?.haKeyPrefix ?? "mcp:ha:";
|
|
49934
50346
|
this.logger = options?.logger;
|
|
49935
50347
|
}
|
|
50348
|
+
redis;
|
|
50349
|
+
machineId;
|
|
49936
50350
|
keyPrefix;
|
|
49937
50351
|
ttlSeconds;
|
|
49938
50352
|
haKeyPrefix;
|
|
@@ -50389,11 +50803,11 @@ function createSqliteSessionStore(options, logger) {
|
|
|
50389
50803
|
logger?.info("[SessionStoreFactory] Creating SQLite session store", { path: options.path });
|
|
50390
50804
|
return new SqliteSessionStore(options);
|
|
50391
50805
|
}
|
|
50392
|
-
var
|
|
50806
|
+
var import_utils86;
|
|
50393
50807
|
var init_session_store_factory = __esm({
|
|
50394
50808
|
"libs/sdk/src/auth/session/session-store.factory.ts"() {
|
|
50395
50809
|
"use strict";
|
|
50396
|
-
|
|
50810
|
+
import_utils86 = require("@frontmcp/utils");
|
|
50397
50811
|
init_common();
|
|
50398
50812
|
}
|
|
50399
50813
|
});
|
|
@@ -50426,12 +50840,12 @@ function getQuerySessionId2(urlPath) {
|
|
|
50426
50840
|
return void 0;
|
|
50427
50841
|
}
|
|
50428
50842
|
}
|
|
50429
|
-
var import_lazy_zod100,
|
|
50843
|
+
var import_lazy_zod100, import_utils87, plan36, stateSessionSchema, stateSchema36, name37, Stage37, HandleSseFlow;
|
|
50430
50844
|
var init_handle_sse_flow = __esm({
|
|
50431
50845
|
"libs/sdk/src/transport/flows/handle.sse.flow.ts"() {
|
|
50432
50846
|
"use strict";
|
|
50433
50847
|
import_lazy_zod100 = require("@frontmcp/lazy-zod");
|
|
50434
|
-
|
|
50848
|
+
import_utils87 = require("@frontmcp/utils");
|
|
50435
50849
|
init_session_id_utils();
|
|
50436
50850
|
init_common();
|
|
50437
50851
|
init_errors();
|
|
@@ -50522,10 +50936,10 @@ var init_handle_sse_flow = __esm({
|
|
|
50522
50936
|
const { request, response } = this.rawInput;
|
|
50523
50937
|
const { token, session } = this.state.required;
|
|
50524
50938
|
const transport = await transportService.createTransporter("sse", token, session.id, response);
|
|
50525
|
-
if ((0,
|
|
50526
|
-
const nodeId = (0,
|
|
50939
|
+
if ((0, import_utils87.getRuntimeContext)().deployment === "distributed") {
|
|
50940
|
+
const nodeId = (0, import_utils87.getMachineId)();
|
|
50527
50941
|
response.setHeader(DEFAULT_FRONTMCP_MACHINE_ID_HEADER, nodeId);
|
|
50528
|
-
const cookie = (0,
|
|
50942
|
+
const cookie = (0, import_utils87.buildSetCookie)({ name: DEFAULT_FRONTMCP_NODE_COOKIE, value: nodeId }, request);
|
|
50529
50943
|
if (cookie) {
|
|
50530
50944
|
const existing = response.getHeader("Set-Cookie");
|
|
50531
50945
|
const existingArr = Array.isArray(existing) ? existing : existing ? [String(existing)] : [];
|
|
@@ -50547,12 +50961,12 @@ var init_handle_sse_flow = __esm({
|
|
|
50547
50961
|
const { request, response } = this.rawInput;
|
|
50548
50962
|
const { token, session } = this.state.required;
|
|
50549
50963
|
const transport = await transportService.getTransporter("sse", token, session.id);
|
|
50550
|
-
if (!transport && (0,
|
|
50964
|
+
if (!transport && (0, import_utils87.getRuntimeContext)().deployment === "distributed") {
|
|
50551
50965
|
const storedSession = await transportService.getStoredSession("sse", token, session.id);
|
|
50552
50966
|
if (storedSession) {
|
|
50553
50967
|
const haManager = this.scope.haManager;
|
|
50554
50968
|
const relay = haManager?.getRelay();
|
|
50555
|
-
if (relay && storedSession.session.nodeId && storedSession.session.nodeId !== (0,
|
|
50969
|
+
if (relay && storedSession.session.nodeId && storedSession.session.nodeId !== (0, import_utils87.getMachineId)()) {
|
|
50556
50970
|
const isAlive2 = await haManager.isNodeAlive(storedSession.session.nodeId);
|
|
50557
50971
|
if (isAlive2) {
|
|
50558
50972
|
try {
|
|
@@ -50777,11 +51191,11 @@ var init_ext_apps_types = __esm({
|
|
|
50777
51191
|
function createExtAppsMessageHandler(options) {
|
|
50778
51192
|
return new ExtAppsMessageHandler(options);
|
|
50779
51193
|
}
|
|
50780
|
-
var
|
|
51194
|
+
var import_utils88, ExtAppsMessageHandler, ExtAppsError, ExtAppsMethodNotFoundError, ExtAppsInvalidParamsError, ExtAppsNotSupportedError, ExtAppsToolNotFoundError;
|
|
50781
51195
|
var init_ext_apps_handler = __esm({
|
|
50782
51196
|
"libs/sdk/src/ext-apps/ext-apps.handler.ts"() {
|
|
50783
51197
|
"use strict";
|
|
50784
|
-
|
|
51198
|
+
import_utils88 = require("@frontmcp/utils");
|
|
50785
51199
|
init_ext_apps_types();
|
|
50786
51200
|
ExtAppsMessageHandler = class {
|
|
50787
51201
|
context;
|
|
@@ -50825,7 +51239,7 @@ var init_ext_apps_handler = __esm({
|
|
|
50825
51239
|
code: errorCode,
|
|
50826
51240
|
message: errorMessage,
|
|
50827
51241
|
// Only include stack traces in development to avoid leaking internals in production
|
|
50828
|
-
data: (0,
|
|
51242
|
+
data: (0, import_utils88.isDevelopment)() && error instanceof Error ? { stack: error.stack } : void 0
|
|
50829
51243
|
}
|
|
50830
51244
|
};
|
|
50831
51245
|
}
|
|
@@ -51187,13 +51601,13 @@ async function lookupStreamableHttpTransport(params) {
|
|
|
51187
51601
|
}
|
|
51188
51602
|
return { kind: "session-not-initialized", recreationError };
|
|
51189
51603
|
}
|
|
51190
|
-
var import_lazy_zod102, import_protocol46,
|
|
51604
|
+
var import_lazy_zod102, import_protocol46, import_utils89, plan38, stateSessionSchema2, stateSchema38, name39, Stage39, HandleStreamableHttpFlow;
|
|
51191
51605
|
var init_handle_streamable_http_flow = __esm({
|
|
51192
51606
|
"libs/sdk/src/transport/flows/handle.streamable-http.flow.ts"() {
|
|
51193
51607
|
"use strict";
|
|
51194
51608
|
import_lazy_zod102 = require("@frontmcp/lazy-zod");
|
|
51195
51609
|
import_protocol46 = require("@frontmcp/protocol");
|
|
51196
|
-
|
|
51610
|
+
import_utils89 = require("@frontmcp/utils");
|
|
51197
51611
|
init_session_id_utils();
|
|
51198
51612
|
init_common();
|
|
51199
51613
|
init_errors();
|
|
@@ -51325,10 +51739,10 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
51325
51739
|
return;
|
|
51326
51740
|
}
|
|
51327
51741
|
}
|
|
51328
|
-
if ((0,
|
|
51329
|
-
const nodeId = (0,
|
|
51742
|
+
if ((0, import_utils89.getRuntimeContext)().deployment === "distributed") {
|
|
51743
|
+
const nodeId = (0, import_utils89.getMachineId)();
|
|
51330
51744
|
response.setHeader(DEFAULT_FRONTMCP_MACHINE_ID_HEADER, nodeId);
|
|
51331
|
-
const cookie = (0,
|
|
51745
|
+
const cookie = (0, import_utils89.buildSetCookie)({ name: DEFAULT_FRONTMCP_NODE_COOKIE, value: nodeId }, request);
|
|
51332
51746
|
if (cookie) {
|
|
51333
51747
|
const existing = response.getHeader("Set-Cookie");
|
|
51334
51748
|
const existingArr = Array.isArray(existing) ? existing : existing ? [String(existing)] : [];
|
|
@@ -51646,21 +52060,21 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
51646
52060
|
});
|
|
51647
52061
|
|
|
51648
52062
|
// libs/sdk/src/transport/transport.error.ts
|
|
51649
|
-
var
|
|
52063
|
+
var import_utils90, JSON_RPC2, rpcError, rpcRequest;
|
|
51650
52064
|
var init_transport_error = __esm({
|
|
51651
52065
|
"libs/sdk/src/transport/transport.error.ts"() {
|
|
51652
52066
|
"use strict";
|
|
51653
|
-
|
|
52067
|
+
import_utils90 = require("@frontmcp/utils");
|
|
51654
52068
|
JSON_RPC2 = "2.0";
|
|
51655
52069
|
rpcError = (message, requestId) => ({
|
|
51656
52070
|
jsonrpc: JSON_RPC2,
|
|
51657
52071
|
error: { code: -32e3, message },
|
|
51658
|
-
id: requestId ?? (0,
|
|
52072
|
+
id: requestId ?? (0, import_utils90.randomUUID)()
|
|
51659
52073
|
// change it to request id + random
|
|
51660
52074
|
});
|
|
51661
52075
|
rpcRequest = (requestId, method, params) => ({
|
|
51662
52076
|
jsonrpc: JSON_RPC2,
|
|
51663
|
-
id: requestId ?? (0,
|
|
52077
|
+
id: requestId ?? (0, import_utils90.randomUUID)(),
|
|
51664
52078
|
method,
|
|
51665
52079
|
...params !== void 0 && { params }
|
|
51666
52080
|
});
|
|
@@ -51668,14 +52082,14 @@ var init_transport_error = __esm({
|
|
|
51668
52082
|
});
|
|
51669
52083
|
|
|
51670
52084
|
// libs/sdk/src/transport/adapters/base-sse-transport.ts
|
|
51671
|
-
var import_content_type, import_raw_body, import_protocol47,
|
|
52085
|
+
var import_content_type, import_raw_body, import_protocol47, import_utils91, MAXIMUM_MESSAGE_SIZE, SSEServerTransport;
|
|
51672
52086
|
var init_base_sse_transport = __esm({
|
|
51673
52087
|
"libs/sdk/src/transport/adapters/base-sse-transport.ts"() {
|
|
51674
52088
|
"use strict";
|
|
51675
52089
|
import_content_type = __toESM(require("content-type"));
|
|
51676
52090
|
import_raw_body = __toESM(require("raw-body"));
|
|
51677
52091
|
import_protocol47 = require("@frontmcp/protocol");
|
|
51678
|
-
|
|
52092
|
+
import_utils91 = require("@frontmcp/utils");
|
|
51679
52093
|
init_transport_errors();
|
|
51680
52094
|
MAXIMUM_MESSAGE_SIZE = "4mb";
|
|
51681
52095
|
SSEServerTransport = class {
|
|
@@ -51685,9 +52099,11 @@ var init_base_sse_transport = __esm({
|
|
|
51685
52099
|
constructor(_endpoint, res, options) {
|
|
51686
52100
|
this._endpoint = _endpoint;
|
|
51687
52101
|
this.res = res;
|
|
51688
|
-
this._sessionId = options?.sessionId ?? (0,
|
|
52102
|
+
this._sessionId = options?.sessionId ?? (0, import_utils91.randomUUID)();
|
|
51689
52103
|
this._options = options || { enableDnsRebindingProtection: false };
|
|
51690
52104
|
}
|
|
52105
|
+
_endpoint;
|
|
52106
|
+
res;
|
|
51691
52107
|
_sseResponse;
|
|
51692
52108
|
_sessionId;
|
|
51693
52109
|
_options;
|
|
@@ -51932,6 +52348,12 @@ function sanitizeDescription(raw) {
|
|
|
51932
52348
|
if (!raw) return "";
|
|
51933
52349
|
return raw.replace(/\r?\n/g, " ").replace(/\s+/g, " ").replace(/^\s*-{3,}\s*$/g, "").replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\*/g, "\\*").replace(/_/g, "\\_").replace(/\[/g, "\\[").trim();
|
|
51934
52350
|
}
|
|
52351
|
+
function sanitizeName(raw) {
|
|
52352
|
+
if (!raw) return "(unnamed)";
|
|
52353
|
+
const s = raw.replace(/\s+/g, " ").trim();
|
|
52354
|
+
if (!s) return "(unnamed)";
|
|
52355
|
+
return s.length > MAX_SKILL_NAME_CHARS ? `${s.slice(0, MAX_SKILL_NAME_CHARS)}\u2026` : s;
|
|
52356
|
+
}
|
|
51935
52357
|
function buildSkillsCatalogSummary(skillRegistry) {
|
|
51936
52358
|
if (!skillRegistry) return "";
|
|
51937
52359
|
const skills = skillRegistry.getSkills({ visibility: "mcp" });
|
|
@@ -51943,7 +52365,7 @@ function buildSkillsCatalogSummary(skillRegistry) {
|
|
|
51943
52365
|
const effectiveCap = MAX_SKILL_CATALOG_CHARS - TRUNCATION_FOOTER_RESERVE;
|
|
51944
52366
|
for (const skill of skills) {
|
|
51945
52367
|
const meta = skill.metadata;
|
|
51946
|
-
const name41 = meta.name;
|
|
52368
|
+
const name41 = sanitizeName(meta.name);
|
|
51947
52369
|
const description = sanitizeDescription(meta.description);
|
|
51948
52370
|
const line = description ? `- **${name41}**: ${description}` : `- **${name41}**`;
|
|
51949
52371
|
if (charCount + line.length + 1 > effectiveCap) {
|
|
@@ -51988,13 +52410,14 @@ function buildChannelInstructions(channels) {
|
|
|
51988
52410
|
function joinSections(sections) {
|
|
51989
52411
|
return sections.map((s) => (s ?? "").trim()).filter((s) => s.length > 0).join("\n\n---\n\n");
|
|
51990
52412
|
}
|
|
51991
|
-
var DEFAULT_POLICY, MAX_SKILL_CATALOG_CHARS, TRUNCATION_FOOTER_RESERVE, CATALOG_HEADER;
|
|
52413
|
+
var DEFAULT_POLICY, MAX_SKILL_CATALOG_CHARS, TRUNCATION_FOOTER_RESERVE, MAX_SKILL_NAME_CHARS, CATALOG_HEADER;
|
|
51992
52414
|
var init_skill_instructions_helper = __esm({
|
|
51993
52415
|
"libs/sdk/src/skill/skill-instructions.helper.ts"() {
|
|
51994
52416
|
"use strict";
|
|
51995
52417
|
DEFAULT_POLICY = "append";
|
|
51996
52418
|
MAX_SKILL_CATALOG_CHARS = 16e3;
|
|
51997
52419
|
TRUNCATION_FOOTER_RESERVE = 160;
|
|
52420
|
+
MAX_SKILL_NAME_CHARS = 80;
|
|
51998
52421
|
CATALOG_HEADER = "Available skills (read the `skills://catalog` resource to browse, or `skills://{name}/SKILL.md` for full content):";
|
|
51999
52422
|
}
|
|
52000
52423
|
});
|
|
@@ -52043,6 +52466,9 @@ var init_transport_local_adapter = __esm({
|
|
|
52043
52466
|
this.transport = this.createTransport(key.sessionId, res);
|
|
52044
52467
|
this.ready = this.connectServer();
|
|
52045
52468
|
}
|
|
52469
|
+
scope;
|
|
52470
|
+
key;
|
|
52471
|
+
onDispose;
|
|
52046
52472
|
logger;
|
|
52047
52473
|
transport;
|
|
52048
52474
|
/**
|
|
@@ -52963,6 +53389,7 @@ var init_transport_local = __esm({
|
|
|
52963
53389
|
throw new UnsupportedTransportTypeError(this.type);
|
|
52964
53390
|
}
|
|
52965
53391
|
}
|
|
53392
|
+
onDispose;
|
|
52966
53393
|
type;
|
|
52967
53394
|
tokenHash;
|
|
52968
53395
|
sessionId;
|
|
@@ -53032,6 +53459,8 @@ var init_transport_remote = __esm({
|
|
|
53032
53459
|
this.tokenHash = key.tokenHash;
|
|
53033
53460
|
this.sessionId = key.sessionId;
|
|
53034
53461
|
}
|
|
53462
|
+
key;
|
|
53463
|
+
bus;
|
|
53035
53464
|
type;
|
|
53036
53465
|
tokenHash;
|
|
53037
53466
|
sessionId;
|
|
@@ -53061,11 +53490,11 @@ var init_transport_remote = __esm({
|
|
|
53061
53490
|
});
|
|
53062
53491
|
|
|
53063
53492
|
// libs/sdk/src/transport/transport.registry.ts
|
|
53064
|
-
var
|
|
53493
|
+
var import_utils92, TransportService;
|
|
53065
53494
|
var init_transport_registry = __esm({
|
|
53066
53495
|
"libs/sdk/src/transport/transport.registry.ts"() {
|
|
53067
53496
|
"use strict";
|
|
53068
|
-
|
|
53497
|
+
import_utils92 = require("@frontmcp/utils");
|
|
53069
53498
|
init_session_store_factory();
|
|
53070
53499
|
init_transport_errors();
|
|
53071
53500
|
init_handle_sse_flow();
|
|
@@ -53350,7 +53779,7 @@ var init_transport_registry = __esm({
|
|
|
53350
53779
|
protocol: storedSession.session.protocol,
|
|
53351
53780
|
createdAt: storedSession.createdAt
|
|
53352
53781
|
});
|
|
53353
|
-
const currentNodeId = (0,
|
|
53782
|
+
const currentNodeId = (0, import_utils92.getMachineId)();
|
|
53354
53783
|
if (this.scope.haManager && storedSession.session.nodeId && storedSession.session.nodeId !== currentNodeId) {
|
|
53355
53784
|
const sessionKey = `${this.transportKeyPrefix}${sessionId}`;
|
|
53356
53785
|
const result = await this.scope.haManager.attemptTakeover(sessionKey, storedSession.session.nodeId);
|
|
@@ -53445,7 +53874,7 @@ var init_transport_registry = __esm({
|
|
|
53445
53874
|
authorizationId: key.tokenHash,
|
|
53446
53875
|
protocol: type === "sse" ? "sse" : "streamable-http",
|
|
53447
53876
|
createdAt: Date.now(),
|
|
53448
|
-
nodeId: (0,
|
|
53877
|
+
nodeId: (0, import_utils92.getMachineId)()
|
|
53449
53878
|
},
|
|
53450
53879
|
authorizationId: key.tokenHash,
|
|
53451
53880
|
createdAt: Date.now(),
|
|
@@ -53591,7 +54020,7 @@ var init_transport_registry = __esm({
|
|
|
53591
54020
|
}
|
|
53592
54021
|
/* --------------------------------- internals -------------------------------- */
|
|
53593
54022
|
sha256(value) {
|
|
53594
|
-
return (0,
|
|
54023
|
+
return (0, import_utils92.sha256Hex)(value);
|
|
53595
54024
|
}
|
|
53596
54025
|
/**
|
|
53597
54026
|
* Create a history key from components.
|
|
@@ -53697,14 +54126,83 @@ var init_transport_registry = __esm({
|
|
|
53697
54126
|
}
|
|
53698
54127
|
});
|
|
53699
54128
|
|
|
54129
|
+
// libs/sdk/src/transport/web-standard-mcp.ts
|
|
54130
|
+
var web_standard_mcp_exports = {};
|
|
54131
|
+
__export(web_standard_mcp_exports, {
|
|
54132
|
+
buildPersistentWebStandardMcp: () => buildPersistentWebStandardMcp,
|
|
54133
|
+
runWebStandardMcp: () => runWebStandardMcp
|
|
54134
|
+
});
|
|
54135
|
+
async function wireServer(scope, serverOptions, sessionId, sessionIdGenerator, enableJsonResponse) {
|
|
54136
|
+
const { McpServer: McpServer2, WebStandardStreamableHTTPServerTransport: WebStandardStreamableHTTPServerTransport2 } = await import("@frontmcp/protocol");
|
|
54137
|
+
const { createMcpHandlers: createMcpHandlers2 } = await Promise.resolve().then(() => (init_mcp_handlers(), mcp_handlers_exports));
|
|
54138
|
+
const mcpServer = new McpServer2(scope.metadata.info, serverOptions);
|
|
54139
|
+
for (const handler of createMcpHandlers2({ scope, serverOptions })) {
|
|
54140
|
+
const originalHandler = handler.handler;
|
|
54141
|
+
const wrappedHandler = async (req, ctx) => {
|
|
54142
|
+
const existingAuthInfo = ctx?.["authInfo"] ?? {};
|
|
54143
|
+
const enrichedCtx = { ...ctx, authInfo: { ...existingAuthInfo, sessionId } };
|
|
54144
|
+
return originalHandler(req, enrichedCtx);
|
|
54145
|
+
};
|
|
54146
|
+
mcpServer.setRequestHandler(handler.requestSchema, wrappedHandler);
|
|
54147
|
+
}
|
|
54148
|
+
const transport = new WebStandardStreamableHTTPServerTransport2({ sessionIdGenerator, enableJsonResponse });
|
|
54149
|
+
await mcpServer.connect(transport);
|
|
54150
|
+
return { mcpServer, transport };
|
|
54151
|
+
}
|
|
54152
|
+
async function buildPersistentWebStandardMcp(scope, options) {
|
|
54153
|
+
const serverOptions = buildScopedServerOptions(scope);
|
|
54154
|
+
return wireServer(scope, serverOptions, options.sessionId, () => options.sessionId, false);
|
|
54155
|
+
}
|
|
54156
|
+
async function runWebStandardMcp(scope, request, options) {
|
|
54157
|
+
if (options.persistent) {
|
|
54158
|
+
return options.persistent.transport.handleRequest(request, { authInfo: options.authInfo });
|
|
54159
|
+
}
|
|
54160
|
+
const sessionId = `web:${(0, import_utils93.randomUUID)()}`;
|
|
54161
|
+
const accept = request.headers.get("accept") ?? "";
|
|
54162
|
+
const wantsStream = request.method === "GET" || options.sse && accept.includes("text/event-stream");
|
|
54163
|
+
const { mcpServer, transport } = await wireServer(
|
|
54164
|
+
scope,
|
|
54165
|
+
options.serverOptions,
|
|
54166
|
+
sessionId,
|
|
54167
|
+
void 0,
|
|
54168
|
+
!wantsStream
|
|
54169
|
+
);
|
|
54170
|
+
const response = await transport.handleRequest(request, {
|
|
54171
|
+
authInfo: options.authInfo
|
|
54172
|
+
});
|
|
54173
|
+
if (response.headers.get("content-type")?.includes("text/event-stream")) {
|
|
54174
|
+
const closed = new Promise((resolve) => {
|
|
54175
|
+
const prev = transport.onclose;
|
|
54176
|
+
transport.onclose = () => {
|
|
54177
|
+
prev?.();
|
|
54178
|
+
resolve();
|
|
54179
|
+
};
|
|
54180
|
+
});
|
|
54181
|
+
const teardown = closed.then(() => mcpServer.close().catch(() => void 0));
|
|
54182
|
+
if (options.ctx?.waitUntil) options.ctx.waitUntil(teardown);
|
|
54183
|
+
else void teardown;
|
|
54184
|
+
} else {
|
|
54185
|
+
void mcpServer.close().catch(() => void 0);
|
|
54186
|
+
}
|
|
54187
|
+
return response;
|
|
54188
|
+
}
|
|
54189
|
+
var import_utils93;
|
|
54190
|
+
var init_web_standard_mcp = __esm({
|
|
54191
|
+
"libs/sdk/src/transport/web-standard-mcp.ts"() {
|
|
54192
|
+
"use strict";
|
|
54193
|
+
import_utils93 = require("@frontmcp/utils");
|
|
54194
|
+
init_build_scoped_server_options();
|
|
54195
|
+
}
|
|
54196
|
+
});
|
|
54197
|
+
|
|
53700
54198
|
// libs/sdk/src/scope/flows/http.request.flow.ts
|
|
53701
|
-
var import_auth38, import_lazy_zod105,
|
|
54199
|
+
var import_auth38, import_lazy_zod105, import_utils94, plan39, httpRequestStateSchema, name40, Stage40, HttpRequestFlow;
|
|
53702
54200
|
var init_http_request_flow = __esm({
|
|
53703
54201
|
"libs/sdk/src/scope/flows/http.request.flow.ts"() {
|
|
53704
54202
|
"use strict";
|
|
53705
54203
|
import_auth38 = require("@frontmcp/auth");
|
|
53706
54204
|
import_lazy_zod105 = require("@frontmcp/lazy-zod");
|
|
53707
|
-
|
|
54205
|
+
import_utils94 = require("@frontmcp/utils");
|
|
53708
54206
|
init_session_verify_flow();
|
|
53709
54207
|
init_common();
|
|
53710
54208
|
init_errors();
|
|
@@ -53720,6 +54218,11 @@ var init_http_request_flow = __esm({
|
|
|
53720
54218
|
"router"
|
|
53721
54219
|
],
|
|
53722
54220
|
execute: [
|
|
54221
|
+
// Web-fetch (V8-isolate / Cloudflare Worker) MCP handling. Runs FIRST and,
|
|
54222
|
+
// in web mode only, responds with a Web `Response` (short-circuiting the
|
|
54223
|
+
// Node handle stages below). On the Node/Express path it's a no-op and falls
|
|
54224
|
+
// through to the runtime-coupled stages.
|
|
54225
|
+
"handleWebFetch",
|
|
53723
54226
|
"handleLegacySse",
|
|
53724
54227
|
"handleSse",
|
|
53725
54228
|
"handleStreamableHttp",
|
|
@@ -53762,7 +54265,7 @@ var init_http_request_flow = __esm({
|
|
|
53762
54265
|
const { request } = this.rawInput;
|
|
53763
54266
|
this.requestStartTime = Date.now();
|
|
53764
54267
|
const ctx = this.tryGetContext();
|
|
53765
|
-
this.requestId = ctx?.requestId ?? `req-${(0,
|
|
54268
|
+
this.requestId = ctx?.requestId ?? `req-${(0, import_utils94.randomUUID)()}`;
|
|
53766
54269
|
const headers = request.headers ?? {};
|
|
53767
54270
|
const body = request.body;
|
|
53768
54271
|
const userAgent = headers["user-agent"];
|
|
@@ -53921,6 +54424,10 @@ var init_http_request_flow = __esm({
|
|
|
53921
54424
|
accept: request.headers?.["accept"]
|
|
53922
54425
|
});
|
|
53923
54426
|
const decision = decideIntent(request, { ...legacyFlags, tolerateMissingAccept: true });
|
|
54427
|
+
const isWebMode = !!request[ServerRequestTokens.webRequest];
|
|
54428
|
+
if (isWebMode && decision.intent === "unknown") {
|
|
54429
|
+
decision.intent = "stateless-http";
|
|
54430
|
+
}
|
|
53924
54431
|
this.logger.debug(`[${this.requestId}] decision result`, {
|
|
53925
54432
|
intent: decision.intent,
|
|
53926
54433
|
reasons: decision.reasons,
|
|
@@ -54047,6 +54554,47 @@ var init_http_request_flow = __esm({
|
|
|
54047
54554
|
throw error;
|
|
54048
54555
|
}
|
|
54049
54556
|
}
|
|
54557
|
+
async handleWebFetch() {
|
|
54558
|
+
const { request } = this.rawInput;
|
|
54559
|
+
const req = request;
|
|
54560
|
+
const webRequest = req[ServerRequestTokens.webRequest];
|
|
54561
|
+
if (!webRequest) return;
|
|
54562
|
+
try {
|
|
54563
|
+
const webCtx = req[ServerRequestTokens.webCtx];
|
|
54564
|
+
const { runWebStandardMcp: runWebStandardMcp2 } = await Promise.resolve().then(() => (init_web_standard_mcp(), web_standard_mcp_exports));
|
|
54565
|
+
const { buildScopedServerOptions: buildScopedServerOptions2 } = await Promise.resolve().then(() => (init_build_scoped_server_options(), build_scoped_server_options_exports));
|
|
54566
|
+
const { expandProtocolConfig: expandProtocolConfig2 } = await Promise.resolve().then(() => (init_schema7(), schema_exports));
|
|
54567
|
+
const scope = this.scope;
|
|
54568
|
+
const proto = expandProtocolConfig2(scope.metadata.transport?.protocol);
|
|
54569
|
+
const sse = proto.streamable && !proto.json;
|
|
54570
|
+
const authorization = req[ServerRequestTokens.auth];
|
|
54571
|
+
const authInfo = authorization ? {
|
|
54572
|
+
token: authorization.token,
|
|
54573
|
+
clientId: authorization.user?.sub,
|
|
54574
|
+
scopes: [],
|
|
54575
|
+
expiresAt: authorization.user?.exp ? authorization.user.exp * 1e3 : void 0,
|
|
54576
|
+
extra: {
|
|
54577
|
+
user: authorization.user,
|
|
54578
|
+
sessionId: authorization.session?.id,
|
|
54579
|
+
sessionPayload: authorization.session?.payload
|
|
54580
|
+
}
|
|
54581
|
+
} : void 0;
|
|
54582
|
+
const persistent = req[ServerRequestTokens.webTransport];
|
|
54583
|
+
const response = await runWebStandardMcp2(scope, webRequest, {
|
|
54584
|
+
serverOptions: buildScopedServerOptions2(scope),
|
|
54585
|
+
authInfo,
|
|
54586
|
+
sse,
|
|
54587
|
+
ctx: webCtx,
|
|
54588
|
+
persistent
|
|
54589
|
+
});
|
|
54590
|
+
this.respond(httpRespond.webResponse(response));
|
|
54591
|
+
} catch (error) {
|
|
54592
|
+
if (!(error instanceof FlowControl)) {
|
|
54593
|
+
this.logError(error, "handleWebFetch");
|
|
54594
|
+
}
|
|
54595
|
+
throw error;
|
|
54596
|
+
}
|
|
54597
|
+
}
|
|
54050
54598
|
async handleLegacySse() {
|
|
54051
54599
|
try {
|
|
54052
54600
|
const response = await this.scope.runFlow("handle:legacy-sse", this.rawInput);
|
|
@@ -54216,6 +54764,9 @@ var init_http_request_flow = __esm({
|
|
|
54216
54764
|
__decorateClass([
|
|
54217
54765
|
Stage40("router")
|
|
54218
54766
|
], HttpRequestFlow.prototype, "router", 1);
|
|
54767
|
+
__decorateClass([
|
|
54768
|
+
Stage40("handleWebFetch")
|
|
54769
|
+
], HttpRequestFlow.prototype, "handleWebFetch", 1);
|
|
54219
54770
|
__decorateClass([
|
|
54220
54771
|
Stage40("handleLegacySse", {
|
|
54221
54772
|
filter: ({
|
|
@@ -54288,31 +54839,14 @@ var init_http_request_flow = __esm({
|
|
|
54288
54839
|
}
|
|
54289
54840
|
});
|
|
54290
54841
|
|
|
54291
|
-
// libs/sdk/src/scope/optional-dependency.util.ts
|
|
54292
|
-
function probeOptionalDependency(moduleName, loadError, resolve) {
|
|
54293
|
-
let resolvedPath;
|
|
54294
|
-
try {
|
|
54295
|
-
resolvedPath = resolve(moduleName);
|
|
54296
|
-
} catch {
|
|
54297
|
-
resolvedPath = void 0;
|
|
54298
|
-
}
|
|
54299
|
-
const error = loadError instanceof Error ? loadError.message : String(loadError);
|
|
54300
|
-
return resolvedPath ? { status: "load-failed", resolvedPath, error } : { status: "not-installed", error };
|
|
54301
|
-
}
|
|
54302
|
-
var init_optional_dependency_util = __esm({
|
|
54303
|
-
"libs/sdk/src/scope/optional-dependency.util.ts"() {
|
|
54304
|
-
"use strict";
|
|
54305
|
-
}
|
|
54306
|
-
});
|
|
54307
|
-
|
|
54308
54842
|
// libs/sdk/src/scope/scope.instance.ts
|
|
54309
|
-
var import_reflect_metadata25, import_guard6,
|
|
54843
|
+
var import_reflect_metadata25, import_guard6, import_utils95, SCOPE_NON_DISPATCHABLE_FLOWS, Scope;
|
|
54310
54844
|
var init_scope_instance = __esm({
|
|
54311
54845
|
"libs/sdk/src/scope/scope.instance.ts"() {
|
|
54312
54846
|
"use strict";
|
|
54313
54847
|
import_reflect_metadata25 = require("reflect-metadata");
|
|
54314
54848
|
import_guard6 = require("@frontmcp/guard");
|
|
54315
|
-
|
|
54849
|
+
import_utils95 = require("@frontmcp/utils");
|
|
54316
54850
|
init_agent_registry();
|
|
54317
54851
|
init_call_agent_flow();
|
|
54318
54852
|
init_app_registry();
|
|
@@ -54355,6 +54889,7 @@ var init_scope_instance = __esm({
|
|
|
54355
54889
|
init_transport_registry();
|
|
54356
54890
|
init_http_request_flow();
|
|
54357
54891
|
init_optional_dependency_util();
|
|
54892
|
+
SCOPE_NON_DISPATCHABLE_FLOWS = /* @__PURE__ */ new Set(["http:request"]);
|
|
54358
54893
|
Scope = class _Scope extends ScopeEntry {
|
|
54359
54894
|
id;
|
|
54360
54895
|
globalProviders;
|
|
@@ -54440,7 +54975,7 @@ var init_scope_instance = __esm({
|
|
|
54440
54975
|
await this.scopeProviders.ready;
|
|
54441
54976
|
const scopeRef = { kind: "scope", id: this.id, ref: _Scope };
|
|
54442
54977
|
const scopeProviders = this.scopeProviders;
|
|
54443
|
-
const perf = (0,
|
|
54978
|
+
const perf = (0, import_utils95.getEnvFlag)("FRONTMCP_PERF");
|
|
54444
54979
|
const t0 = perf ? performance.now() : 0;
|
|
54445
54980
|
const mark = perf ? (label) => this.logger.info(`[PERF] ${label}: ${(performance.now() - t0).toFixed(1)}ms`) : () => {
|
|
54446
54981
|
};
|
|
@@ -54450,13 +54985,13 @@ var init_scope_instance = __esm({
|
|
|
54450
54985
|
this.scopeApps = new AppRegistry(this.scopeProviders, this.metadata.apps, scopeRef);
|
|
54451
54986
|
this.logger.info(`Initializing ${this.metadata.apps.length} app(s)...`);
|
|
54452
54987
|
const transportConfig = this.metadata.transport;
|
|
54453
|
-
const isDistributed = (0,
|
|
54988
|
+
const isDistributed = (0, import_utils95.getRuntimeContext)().deployment === "distributed";
|
|
54454
54989
|
if (isDistributed && this.metadata.redis && !this.cliMode) {
|
|
54455
54990
|
try {
|
|
54456
54991
|
const haRedis = this.metadata.redis;
|
|
54457
54992
|
this.haManager = HaManager.create({
|
|
54458
54993
|
redis: haRedis,
|
|
54459
|
-
nodeId: (0,
|
|
54994
|
+
nodeId: (0, import_utils95.getMachineId)(),
|
|
54460
54995
|
logger: this.logger
|
|
54461
54996
|
});
|
|
54462
54997
|
await this.haManager.start();
|
|
@@ -54467,7 +55002,7 @@ var init_scope_instance = __esm({
|
|
|
54467
55002
|
}
|
|
54468
55003
|
let transportBus;
|
|
54469
55004
|
if (this.haManager && isDistributed && this.metadata.redis) {
|
|
54470
|
-
transportBus = new RedisTransportBus(this.metadata.redis, (0,
|
|
55005
|
+
transportBus = new RedisTransportBus(this.metadata.redis, (0, import_utils95.getMachineId)(), {
|
|
54471
55006
|
logger: this.logger
|
|
54472
55007
|
});
|
|
54473
55008
|
this.logger.info("[HA] Transport bus created for distributed session routing");
|
|
@@ -54490,7 +55025,7 @@ var init_scope_instance = __esm({
|
|
|
54490
55025
|
}
|
|
54491
55026
|
});
|
|
54492
55027
|
}
|
|
54493
|
-
if ((0,
|
|
55028
|
+
if ((0, import_utils95.getRuntimeContext)().deployment === "serverless") {
|
|
54494
55029
|
const protocolCfg = transportConfig?.protocol;
|
|
54495
55030
|
const hasSSE = typeof protocolCfg === "string" ? protocolCfg !== "stateless-api" : protocolCfg?.sse === true;
|
|
54496
55031
|
if (hasSSE) {
|
|
@@ -54517,7 +55052,7 @@ var init_scope_instance = __esm({
|
|
|
54517
55052
|
sqlite: elicitationSqlite,
|
|
54518
55053
|
keyPrefix: elicitationRedis?.keyPrefix ?? "mcp:elicit:",
|
|
54519
55054
|
logger: this.logger,
|
|
54520
|
-
isEdgeRuntime: (0,
|
|
55055
|
+
isEdgeRuntime: (0, import_utils95.isEdgeRuntime)()
|
|
54521
55056
|
});
|
|
54522
55057
|
this._elicitationStore = elicitStore;
|
|
54523
55058
|
this.elicitationBackendType = elicitType;
|
|
@@ -54533,7 +55068,7 @@ var init_scope_instance = __esm({
|
|
|
54533
55068
|
const tasksPromise = shouldInitTasks ? (async () => {
|
|
54534
55069
|
const tasksRedis = tasksConfig?.redis ?? this.metadata.redis;
|
|
54535
55070
|
const tasksSqlite = tasksConfig?.sqlite ?? (tasksRedis ? void 0 : resolvedTopLevelSqlite);
|
|
54536
|
-
const onEdge = (0,
|
|
55071
|
+
const onEdge = (0, import_utils95.isEdgeRuntime)();
|
|
54537
55072
|
if (onEdge) {
|
|
54538
55073
|
const msg = "[tasks] Background tasks are enabled on an edge/serverless runtime. The in-process runner cannot continue past the HTTP response on this platform \u2014 task bodies will not execute. Run on a long-lived Node process, or set `tasks.enabled: false`.";
|
|
54539
55074
|
if (tasksConfig?.strict) {
|
|
@@ -54748,7 +55283,9 @@ var init_scope_instance = __esm({
|
|
|
54748
55283
|
this.scopeResources = new ResourceRegistry(this.scopeProviders, [], scopeRef);
|
|
54749
55284
|
this.scopePrompts = new PromptRegistry(this.scopeProviders, [], scopeRef);
|
|
54750
55285
|
this.scopeAgents = new AgentRegistry(this.scopeProviders, [], scopeRef);
|
|
54751
|
-
this.scopeSkills = new SkillRegistry(this.scopeProviders, this.metadata.skills ?? [], scopeRef
|
|
55286
|
+
this.scopeSkills = new SkillRegistry(this.scopeProviders, this.metadata.skills ?? [], scopeRef, {
|
|
55287
|
+
...this.metadata.skillsConfig?.scoring ? { scoring: this.metadata.skillsConfig.scoring } : {}
|
|
55288
|
+
});
|
|
54752
55289
|
await Promise.all([
|
|
54753
55290
|
this.scopeTools.ready,
|
|
54754
55291
|
this.scopeResources.ready,
|
|
@@ -55509,6 +56046,16 @@ var init_scope_instance = __esm({
|
|
|
55509
56046
|
runFlow(name41, input, deps) {
|
|
55510
56047
|
return this.scopeFlows.runFlow(name41, input, deps);
|
|
55511
56048
|
}
|
|
56049
|
+
/**
|
|
56050
|
+
* Find the registered flow that handles this HTTP request (by method +
|
|
56051
|
+
* `middleware.path` + `canActivate`), excluding `http:request` (which the
|
|
56052
|
+
* web-fetch handler runs directly for the MCP entry path). Lets the
|
|
56053
|
+
* Worker/web-fetch adapter dispatch auth/well-known/oauth flows the same way
|
|
56054
|
+
* the Express host routes them — without a middleware server.
|
|
56055
|
+
*/
|
|
56056
|
+
async findHttpFlowName(request) {
|
|
56057
|
+
return this.scopeFlows.findHttpFlowName(request, SCOPE_NON_DISPATCHABLE_FLOWS);
|
|
56058
|
+
}
|
|
55512
56059
|
async runFlowForOutput(name41, input, deps) {
|
|
55513
56060
|
const result = await this.scopeFlows.runFlow(name41, input, deps);
|
|
55514
56061
|
if (result) {
|
|
@@ -55585,6 +56132,7 @@ var init_provider_registry = __esm({
|
|
|
55585
56132
|
this.topoSort();
|
|
55586
56133
|
this.ready = this.initialize();
|
|
55587
56134
|
}
|
|
56135
|
+
parentProviders;
|
|
55588
56136
|
/** used to track which registry provided which token */
|
|
55589
56137
|
providedBy;
|
|
55590
56138
|
/** topo order (deps first) */
|
|
@@ -56538,6 +57086,292 @@ var init_scope_registry = __esm({
|
|
|
56538
57086
|
}
|
|
56539
57087
|
});
|
|
56540
57088
|
|
|
57089
|
+
// libs/sdk/src/transport/web-response.renderer.ts
|
|
57090
|
+
function toByteStream(streamLike) {
|
|
57091
|
+
const iter = streamLike[Symbol.asyncIterator];
|
|
57092
|
+
if (typeof iter !== "function") {
|
|
57093
|
+
return new ReadableStream({ start: (c) => c.close() });
|
|
57094
|
+
}
|
|
57095
|
+
const it = iter.call(streamLike);
|
|
57096
|
+
return new ReadableStream({
|
|
57097
|
+
async pull(controller) {
|
|
57098
|
+
const { value, done } = await it.next();
|
|
57099
|
+
if (done) {
|
|
57100
|
+
controller.close();
|
|
57101
|
+
return;
|
|
57102
|
+
}
|
|
57103
|
+
controller.enqueue(typeof value === "string" ? encoder.encode(value) : value);
|
|
57104
|
+
},
|
|
57105
|
+
async cancel() {
|
|
57106
|
+
await it.return?.(void 0);
|
|
57107
|
+
}
|
|
57108
|
+
});
|
|
57109
|
+
}
|
|
57110
|
+
function bytesFrom(body, encoding) {
|
|
57111
|
+
if (typeof body !== "string") return body;
|
|
57112
|
+
if (encoding === "base64") return Uint8Array.from(atob(body), (c) => c.charCodeAt(0));
|
|
57113
|
+
if (encoding === "hex") {
|
|
57114
|
+
if (body.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(body)) {
|
|
57115
|
+
throw new TypeError("Invalid hex-encoded body");
|
|
57116
|
+
}
|
|
57117
|
+
const out = new Uint8Array(body.length / 2);
|
|
57118
|
+
for (let i = 0; i < out.length; i++) out[i] = parseInt(body.slice(i * 2, i * 2 + 2), 16);
|
|
57119
|
+
return out;
|
|
57120
|
+
}
|
|
57121
|
+
return encoder.encode(body);
|
|
57122
|
+
}
|
|
57123
|
+
function buildHeaders(out, contentType2) {
|
|
57124
|
+
const headers = new Headers();
|
|
57125
|
+
if (contentType2) headers.set("Content-Type", contentType2);
|
|
57126
|
+
const extra = out["headers"];
|
|
57127
|
+
if (extra) for (const [k, v] of Object.entries(extra)) headers.set(k, v);
|
|
57128
|
+
const cookies = out["cookies"];
|
|
57129
|
+
if (Array.isArray(cookies)) for (const c of cookies) headers.append("Set-Cookie", c);
|
|
57130
|
+
return headers;
|
|
57131
|
+
}
|
|
57132
|
+
function renderHttpOutputToWebResponse(output) {
|
|
57133
|
+
const out = output;
|
|
57134
|
+
switch (out.kind) {
|
|
57135
|
+
// Already a Web Response (the MCP execute stage on a worker) — return verbatim.
|
|
57136
|
+
case "web-response":
|
|
57137
|
+
return out.response;
|
|
57138
|
+
// "no response" — let the adapter fall through (404 / next middleware).
|
|
57139
|
+
case "next":
|
|
57140
|
+
case "consumed":
|
|
57141
|
+
return void 0;
|
|
57142
|
+
case "redirect": {
|
|
57143
|
+
const headers = buildHeaders(out);
|
|
57144
|
+
headers.set("Location", out.location);
|
|
57145
|
+
return new Response(null, { status: out.status, headers });
|
|
57146
|
+
}
|
|
57147
|
+
case "json":
|
|
57148
|
+
case "jsonrpc":
|
|
57149
|
+
case "problem":
|
|
57150
|
+
return new Response(JSON.stringify(out.body), { status: out.status, headers: buildHeaders(out, out.contentType) });
|
|
57151
|
+
case "text":
|
|
57152
|
+
case "html":
|
|
57153
|
+
return new Response(out.body, { status: out.status, headers: buildHeaders(out, out.contentType) });
|
|
57154
|
+
case "binary":
|
|
57155
|
+
case "image": {
|
|
57156
|
+
const headers = buildHeaders(out, out.contentType);
|
|
57157
|
+
headers.set(
|
|
57158
|
+
"Content-Disposition",
|
|
57159
|
+
out.filename ? `${out.disposition}; filename="${out.filename}"` : out.disposition
|
|
57160
|
+
);
|
|
57161
|
+
return new Response(bytesFrom(out.body, out.encoding), { status: out.status, headers });
|
|
57162
|
+
}
|
|
57163
|
+
case "stream":
|
|
57164
|
+
case "sse": {
|
|
57165
|
+
const headers = buildHeaders(out, out.contentType);
|
|
57166
|
+
if (out.kind === "sse" && !headers.has("Cache-Control")) headers.set("Cache-Control", "no-cache");
|
|
57167
|
+
return new Response(toByteStream(out.stream), { status: out.status, headers });
|
|
57168
|
+
}
|
|
57169
|
+
case "empty":
|
|
57170
|
+
return new Response(null, { status: out.status, headers: buildHeaders(out) });
|
|
57171
|
+
default:
|
|
57172
|
+
return void 0;
|
|
57173
|
+
}
|
|
57174
|
+
}
|
|
57175
|
+
var encoder;
|
|
57176
|
+
var init_web_response_renderer = __esm({
|
|
57177
|
+
"libs/sdk/src/transport/web-response.renderer.ts"() {
|
|
57178
|
+
"use strict";
|
|
57179
|
+
encoder = new TextEncoder();
|
|
57180
|
+
}
|
|
57181
|
+
});
|
|
57182
|
+
|
|
57183
|
+
// libs/sdk/src/transport/web-fetch-handler.ts
|
|
57184
|
+
function mapHttpCors(httpCors, scope) {
|
|
57185
|
+
if (!httpCors) return void 0;
|
|
57186
|
+
const { origin, credentials, maxAge } = httpCors;
|
|
57187
|
+
if (typeof origin === "function") {
|
|
57188
|
+
scope.logger.warn(
|
|
57189
|
+
"[web-fetch] http.cors.origin is a function, which the worker adapter cannot replay \u2014 CORS left disabled. Use a static origin (true / string / string[])."
|
|
57190
|
+
);
|
|
57191
|
+
return void 0;
|
|
57192
|
+
}
|
|
57193
|
+
return { origin, credentials, maxAge };
|
|
57194
|
+
}
|
|
57195
|
+
function createWebFetchHandler(scope, options = {}) {
|
|
57196
|
+
const httpConfig = scope.metadata.http;
|
|
57197
|
+
const healthPaths = new Set(options.healthPaths ?? ["/healthz", "/readyz"]);
|
|
57198
|
+
const normalizePath = (p) => {
|
|
57199
|
+
const withSlash = p.startsWith("/") ? p : `/${p}`;
|
|
57200
|
+
let end = withSlash.length;
|
|
57201
|
+
while (end > 1 && withSlash.charCodeAt(end - 1) === 47) end--;
|
|
57202
|
+
return withSlash.slice(0, end);
|
|
57203
|
+
};
|
|
57204
|
+
const rawEntry = options.entryPath ?? (normalizeEntryPrefix(httpConfig?.entryPath) || "/");
|
|
57205
|
+
const entryPaths = new Set((Array.isArray(rawEntry) ? rawEntry : [rawEntry]).map(normalizePath));
|
|
57206
|
+
const cors2 = options.cors ?? mapHttpCors(httpConfig?.cors, scope);
|
|
57207
|
+
const corsEnabled = cors2?.origin !== void 0 && cors2.origin !== false;
|
|
57208
|
+
const corsHeadersFor = (request) => {
|
|
57209
|
+
if (!corsEnabled) return {};
|
|
57210
|
+
const reqOrigin = request.headers.get("origin") ?? "";
|
|
57211
|
+
let allowOrigin;
|
|
57212
|
+
if (cors2.origin === true) allowOrigin = reqOrigin || "*";
|
|
57213
|
+
else if (cors2.origin === "*" || cors2.origin === reqOrigin) allowOrigin = cors2.origin;
|
|
57214
|
+
else if (typeof cors2.origin === "string") allowOrigin = cors2.origin;
|
|
57215
|
+
else if (Array.isArray(cors2.origin)) allowOrigin = cors2.origin.includes(reqOrigin) ? reqOrigin : void 0;
|
|
57216
|
+
if (!allowOrigin) return {};
|
|
57217
|
+
const h2 = {
|
|
57218
|
+
"Access-Control-Allow-Origin": allowOrigin,
|
|
57219
|
+
"Access-Control-Allow-Methods": (cors2.methods ?? ["GET", "POST", "OPTIONS", "DELETE"]).join(", "),
|
|
57220
|
+
"Access-Control-Allow-Headers": (cors2.headers ?? [
|
|
57221
|
+
request.headers.get("access-control-request-headers") || "content-type, authorization, mcp-session-id, mcp-protocol-version, last-event-id"
|
|
57222
|
+
]).join(", "),
|
|
57223
|
+
"Access-Control-Expose-Headers": (cors2.exposeHeaders ?? ["Mcp-Session-Id", "WWW-Authenticate"]).join(", ")
|
|
57224
|
+
};
|
|
57225
|
+
if (cors2.credentials) h2["Access-Control-Allow-Credentials"] = "true";
|
|
57226
|
+
if (cors2.maxAge !== void 0) h2["Access-Control-Max-Age"] = String(cors2.maxAge);
|
|
57227
|
+
if (allowOrigin !== "*") h2["Vary"] = "Origin";
|
|
57228
|
+
return h2;
|
|
57229
|
+
};
|
|
57230
|
+
const withCors = (response, request) => {
|
|
57231
|
+
if (!corsEnabled) return response;
|
|
57232
|
+
const headers = new Headers(response.headers);
|
|
57233
|
+
for (const [k, v] of Object.entries(corsHeadersFor(request))) headers.set(k, v);
|
|
57234
|
+
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
|
|
57235
|
+
};
|
|
57236
|
+
return async function handle(request, ctx, env) {
|
|
57237
|
+
const url = new URL(request.url);
|
|
57238
|
+
if (corsEnabled && request.method === "OPTIONS") {
|
|
57239
|
+
return new Response(null, { status: 204, headers: corsHeadersFor(request) });
|
|
57240
|
+
}
|
|
57241
|
+
if (healthPaths.has(url.pathname)) {
|
|
57242
|
+
return withCors(
|
|
57243
|
+
Response.json(
|
|
57244
|
+
{ status: "ok", server: scope.metadata.info, transport: "web-fetch" },
|
|
57245
|
+
{ headers: { "Cache-Control": "no-store" } }
|
|
57246
|
+
),
|
|
57247
|
+
request
|
|
57248
|
+
);
|
|
57249
|
+
}
|
|
57250
|
+
if (!entryPaths.has(normalizePath(url.pathname))) {
|
|
57251
|
+
const authResponse = await runMatchingHttpFlowWeb(scope, request);
|
|
57252
|
+
if (authResponse) return withCors(authResponse, request);
|
|
57253
|
+
return withCors(Response.json({ error: "Not Found", entryPaths: [...entryPaths] }, { status: 404 }), request);
|
|
57254
|
+
}
|
|
57255
|
+
if (options.sessionRouter) {
|
|
57256
|
+
const routed = await options.sessionRouter(request, env, ctx);
|
|
57257
|
+
if (routed) return withCors(routed, request);
|
|
57258
|
+
}
|
|
57259
|
+
const rendered = await runHttpRequestFlowWeb(scope, request, { ctx });
|
|
57260
|
+
return withCors(rendered ?? Response.json({ error: "Not Found" }, { status: 404 }), request);
|
|
57261
|
+
};
|
|
57262
|
+
}
|
|
57263
|
+
async function runHttpRequestFlowWeb(scope, request, opts = {}) {
|
|
57264
|
+
const url = new URL(request.url);
|
|
57265
|
+
const serverRequest = await toServerRequest(request, url, opts.ctx, opts.persistent);
|
|
57266
|
+
let output;
|
|
57267
|
+
try {
|
|
57268
|
+
output = await scope.runFlow("http:request", {
|
|
57269
|
+
request: serverRequest,
|
|
57270
|
+
response: {}
|
|
57271
|
+
});
|
|
57272
|
+
} catch (error) {
|
|
57273
|
+
output = flowErrorToHttpOutput(error);
|
|
57274
|
+
}
|
|
57275
|
+
return output ? renderHttpOutputToWebResponse(output) : void 0;
|
|
57276
|
+
}
|
|
57277
|
+
async function runMatchingHttpFlowWeb(scope, request) {
|
|
57278
|
+
const url = new URL(request.url);
|
|
57279
|
+
const serverRequest = await toServerRequest(request, url);
|
|
57280
|
+
const flowName = await scope.findHttpFlowName(serverRequest);
|
|
57281
|
+
if (!flowName) return void 0;
|
|
57282
|
+
let output;
|
|
57283
|
+
try {
|
|
57284
|
+
output = await scope.runFlow(flowName, {
|
|
57285
|
+
request: serverRequest,
|
|
57286
|
+
response: {}
|
|
57287
|
+
});
|
|
57288
|
+
} catch (error) {
|
|
57289
|
+
output = flowErrorToHttpOutput(error);
|
|
57290
|
+
}
|
|
57291
|
+
return output ? renderHttpOutputToWebResponse(output) : void 0;
|
|
57292
|
+
}
|
|
57293
|
+
async function toServerRequest(request, url, ctx, persistent) {
|
|
57294
|
+
const headers = {};
|
|
57295
|
+
request.headers.forEach((v, k) => {
|
|
57296
|
+
headers[k] = v;
|
|
57297
|
+
});
|
|
57298
|
+
const query = {};
|
|
57299
|
+
url.searchParams.forEach((v, k) => {
|
|
57300
|
+
const existing = query[k];
|
|
57301
|
+
if (existing === void 0) query[k] = v;
|
|
57302
|
+
else if (Array.isArray(existing)) existing.push(v);
|
|
57303
|
+
else query[k] = [existing, v];
|
|
57304
|
+
});
|
|
57305
|
+
const method = request.method.toUpperCase();
|
|
57306
|
+
const hasBody = method !== "GET" && method !== "HEAD";
|
|
57307
|
+
let rawBody = "";
|
|
57308
|
+
if (hasBody) {
|
|
57309
|
+
try {
|
|
57310
|
+
rawBody = await request.text();
|
|
57311
|
+
} catch {
|
|
57312
|
+
rawBody = "";
|
|
57313
|
+
}
|
|
57314
|
+
}
|
|
57315
|
+
let body;
|
|
57316
|
+
if (rawBody) {
|
|
57317
|
+
try {
|
|
57318
|
+
body = JSON.parse(rawBody);
|
|
57319
|
+
} catch {
|
|
57320
|
+
body = rawBody;
|
|
57321
|
+
}
|
|
57322
|
+
}
|
|
57323
|
+
const init = { method: request.method, headers: request.headers };
|
|
57324
|
+
if (rawBody) init.body = rawBody;
|
|
57325
|
+
const webRequest = new Request(url.toString(), init);
|
|
57326
|
+
const serverRequest = {
|
|
57327
|
+
method,
|
|
57328
|
+
path: url.pathname,
|
|
57329
|
+
url: url.pathname + url.search,
|
|
57330
|
+
headers,
|
|
57331
|
+
query,
|
|
57332
|
+
body
|
|
57333
|
+
};
|
|
57334
|
+
const tokenized = serverRequest;
|
|
57335
|
+
tokenized[ServerRequestTokens.webRequest] = webRequest;
|
|
57336
|
+
tokenized[ServerRequestTokens.webCtx] = ctx;
|
|
57337
|
+
if (persistent) tokenized[ServerRequestTokens.webTransport] = persistent;
|
|
57338
|
+
return serverRequest;
|
|
57339
|
+
}
|
|
57340
|
+
function flowErrorToHttpOutput(error) {
|
|
57341
|
+
if (error instanceof FlowControl) {
|
|
57342
|
+
switch (error.type) {
|
|
57343
|
+
case "respond":
|
|
57344
|
+
return error.output;
|
|
57345
|
+
case "next":
|
|
57346
|
+
case "handled":
|
|
57347
|
+
return void 0;
|
|
57348
|
+
default:
|
|
57349
|
+
return { kind: "text", status: 500, body: "Internal Server Error", contentType: "text/plain; charset=utf-8" };
|
|
57350
|
+
}
|
|
57351
|
+
}
|
|
57352
|
+
if (error instanceof PublicMcpError) {
|
|
57353
|
+
const challenge = error.wwwAuthenticate;
|
|
57354
|
+
return {
|
|
57355
|
+
kind: "json",
|
|
57356
|
+
status: error.statusCode,
|
|
57357
|
+
contentType: "application/json; charset=utf-8",
|
|
57358
|
+
body: { error: error.getPublicMessage() },
|
|
57359
|
+
...typeof challenge === "string" && challenge.length > 0 ? { headers: { "WWW-Authenticate": challenge } } : {}
|
|
57360
|
+
};
|
|
57361
|
+
}
|
|
57362
|
+
return { kind: "text", status: 500, body: "Internal Server Error", contentType: "text/plain; charset=utf-8" };
|
|
57363
|
+
}
|
|
57364
|
+
var init_web_fetch_handler = __esm({
|
|
57365
|
+
"libs/sdk/src/transport/web-fetch-handler.ts"() {
|
|
57366
|
+
"use strict";
|
|
57367
|
+
init_common();
|
|
57368
|
+
init_server_tokens();
|
|
57369
|
+
init_path_utils();
|
|
57370
|
+
init_errors();
|
|
57371
|
+
init_web_response_renderer();
|
|
57372
|
+
}
|
|
57373
|
+
});
|
|
57374
|
+
|
|
56541
57375
|
// libs/sdk/src/server/noop-server.ts
|
|
56542
57376
|
var NoopFrontMcpServer;
|
|
56543
57377
|
var init_noop_server = __esm({
|
|
@@ -56563,6 +57397,122 @@ var init_noop_server = __esm({
|
|
|
56563
57397
|
}
|
|
56564
57398
|
});
|
|
56565
57399
|
|
|
57400
|
+
// libs/sdk/src/server/security/security-audit.ts
|
|
57401
|
+
function auditSecurityDefaults(config, isProduction5) {
|
|
57402
|
+
const findings = [];
|
|
57403
|
+
if (!isProduction5 && config.deploymentMode !== "distributed") {
|
|
57404
|
+
return findings;
|
|
57405
|
+
}
|
|
57406
|
+
const strict = config.security?.strict === true;
|
|
57407
|
+
if (config.cors === void 0 && !strict) {
|
|
57408
|
+
findings.push({
|
|
57409
|
+
level: "warn",
|
|
57410
|
+
code: "CORS_PERMISSIVE_DEFAULT",
|
|
57411
|
+
message: "CORS is using the permissive default (origin: true), which allows all origins.",
|
|
57412
|
+
recommendation: "Set explicit cors.origin to restrict allowed origins in production."
|
|
57413
|
+
});
|
|
57414
|
+
} else if (config.cors !== false && config.cors?.origin === true && !strict) {
|
|
57415
|
+
findings.push({
|
|
57416
|
+
level: "warn",
|
|
57417
|
+
code: "CORS_ORIGIN_TRUE",
|
|
57418
|
+
message: "CORS origin=true allows all origins to make cross-origin requests.",
|
|
57419
|
+
recommendation: "Set cors.origin to specific allowed origins."
|
|
57420
|
+
});
|
|
57421
|
+
} else if (config.cors === false) {
|
|
57422
|
+
findings.push({
|
|
57423
|
+
level: "info",
|
|
57424
|
+
code: "CORS_DISABLED",
|
|
57425
|
+
message: "CORS is disabled. Cross-origin requests will be blocked by browsers."
|
|
57426
|
+
});
|
|
57427
|
+
} else {
|
|
57428
|
+
findings.push({
|
|
57429
|
+
level: "info",
|
|
57430
|
+
code: "CORS_CONFIGURED",
|
|
57431
|
+
message: "CORS is explicitly configured."
|
|
57432
|
+
});
|
|
57433
|
+
}
|
|
57434
|
+
const bindAddress = config.resolvedBindAddress ?? "0.0.0.0";
|
|
57435
|
+
if (bindAddress === "0.0.0.0" || bindAddress === "::") {
|
|
57436
|
+
if (config.deploymentMode !== "distributed") {
|
|
57437
|
+
findings.push({
|
|
57438
|
+
level: "warn",
|
|
57439
|
+
code: "BIND_ALL_INTERFACES",
|
|
57440
|
+
message: `Server bound to ${bindAddress} \u2014 accessible from all network interfaces.`,
|
|
57441
|
+
recommendation: "Set security.bindAddress to 'loopback' or '127.0.0.1' for local-only access, or configure a reverse proxy. Distributed deployments require 'all' (0.0.0.0)."
|
|
57442
|
+
});
|
|
57443
|
+
} else {
|
|
57444
|
+
findings.push({
|
|
57445
|
+
level: "info",
|
|
57446
|
+
code: "BIND_ALL_INTERFACES_DISTRIBUTED",
|
|
57447
|
+
message: `Server bound to ${bindAddress} (expected for distributed deployment).`
|
|
57448
|
+
});
|
|
57449
|
+
}
|
|
57450
|
+
} else {
|
|
57451
|
+
findings.push({
|
|
57452
|
+
level: "info",
|
|
57453
|
+
code: "BIND_RESTRICTED",
|
|
57454
|
+
message: `Server bound to ${bindAddress}.`
|
|
57455
|
+
});
|
|
57456
|
+
}
|
|
57457
|
+
const dnsProtectionEnabled = config.security?.dnsRebindingProtection?.enabled ?? strict;
|
|
57458
|
+
if (!dnsProtectionEnabled) {
|
|
57459
|
+
findings.push({
|
|
57460
|
+
level: "warn",
|
|
57461
|
+
code: "DNS_REBINDING_UNPROTECTED",
|
|
57462
|
+
message: "DNS rebinding protection is disabled.",
|
|
57463
|
+
recommendation: "Enable security.dnsRebindingProtection with allowedHosts to prevent DNS rebinding attacks."
|
|
57464
|
+
});
|
|
57465
|
+
} else {
|
|
57466
|
+
findings.push({
|
|
57467
|
+
level: "info",
|
|
57468
|
+
code: "DNS_REBINDING_PROTECTED",
|
|
57469
|
+
message: "DNS rebinding protection is enabled."
|
|
57470
|
+
});
|
|
57471
|
+
}
|
|
57472
|
+
if (config.security?.strict) {
|
|
57473
|
+
findings.push({
|
|
57474
|
+
level: "info",
|
|
57475
|
+
code: "STRICT_MODE_ENABLED",
|
|
57476
|
+
message: "Strict security mode is enabled: loopback binding, restrictive CORS, DNS rebinding protection."
|
|
57477
|
+
});
|
|
57478
|
+
} else {
|
|
57479
|
+
findings.push({
|
|
57480
|
+
level: "info",
|
|
57481
|
+
code: "STRICT_MODE_HINT",
|
|
57482
|
+
message: "To enable strict security defaults, set security.strict = true in HttpOptions."
|
|
57483
|
+
});
|
|
57484
|
+
}
|
|
57485
|
+
return findings;
|
|
57486
|
+
}
|
|
57487
|
+
function logSecurityFindings(findings, logger) {
|
|
57488
|
+
if (findings.length === 0) return;
|
|
57489
|
+
for (const finding of findings) {
|
|
57490
|
+
const prefix = `[Security] ${finding.code}:`;
|
|
57491
|
+
const message = finding.recommendation ? `${prefix} ${finding.message} ${finding.recommendation}` : `${prefix} ${finding.message}`;
|
|
57492
|
+
if (finding.level === "warn") {
|
|
57493
|
+
logger.warn(message);
|
|
57494
|
+
} else {
|
|
57495
|
+
logger.info(message);
|
|
57496
|
+
}
|
|
57497
|
+
}
|
|
57498
|
+
}
|
|
57499
|
+
function resolveBindAddress(security, deploymentMode) {
|
|
57500
|
+
if (security?.bindAddress) {
|
|
57501
|
+
if (security.bindAddress === "loopback") return "127.0.0.1";
|
|
57502
|
+
if (security.bindAddress === "all") return "0.0.0.0";
|
|
57503
|
+
return security.bindAddress;
|
|
57504
|
+
}
|
|
57505
|
+
if (security?.strict) {
|
|
57506
|
+
return deploymentMode === "distributed" ? "0.0.0.0" : "127.0.0.1";
|
|
57507
|
+
}
|
|
57508
|
+
return "0.0.0.0";
|
|
57509
|
+
}
|
|
57510
|
+
var init_security_audit = __esm({
|
|
57511
|
+
"libs/sdk/src/server/security/security-audit.ts"() {
|
|
57512
|
+
"use strict";
|
|
57513
|
+
}
|
|
57514
|
+
});
|
|
57515
|
+
|
|
56566
57516
|
// libs/sdk/src/server/middleware/host-validation.middleware.ts
|
|
56567
57517
|
function createHostValidationMiddleware(options) {
|
|
56568
57518
|
if (!options.enabled) {
|
|
@@ -56612,14 +57562,14 @@ var init_base_host_adapter = __esm({
|
|
|
56612
57562
|
});
|
|
56613
57563
|
|
|
56614
57564
|
// libs/sdk/src/server/adapters/express.host.adapter.ts
|
|
56615
|
-
var http, import_cors, import_express,
|
|
57565
|
+
var http, import_cors, import_express, import_utils96, DEFAULT_EXPRESS_BODY_LIMIT, ExpressHostAdapter;
|
|
56616
57566
|
var init_express_host_adapter = __esm({
|
|
56617
57567
|
"libs/sdk/src/server/adapters/express.host.adapter.ts"() {
|
|
56618
57568
|
"use strict";
|
|
56619
57569
|
http = __toESM(require("node:http"));
|
|
56620
57570
|
import_cors = __toESM(require("cors"));
|
|
56621
57571
|
import_express = __toESM(require("express"));
|
|
56622
|
-
|
|
57572
|
+
import_utils96 = require("@frontmcp/utils");
|
|
56623
57573
|
init_mcp_error();
|
|
56624
57574
|
init_host_validation_middleware();
|
|
56625
57575
|
init_base_host_adapter();
|
|
@@ -56730,8 +57680,8 @@ var init_express_host_adapter = __esm({
|
|
|
56730
57680
|
server.on("error", reject);
|
|
56731
57681
|
server.listen(portOrSocketPath, () => {
|
|
56732
57682
|
try {
|
|
56733
|
-
const
|
|
56734
|
-
|
|
57683
|
+
const fs = require("node:fs");
|
|
57684
|
+
fs.chmodSync(portOrSocketPath, 432);
|
|
56735
57685
|
} catch {
|
|
56736
57686
|
}
|
|
56737
57687
|
console.log(`MCP HTTP (Express) on unix://${portOrSocketPath}`);
|
|
@@ -56751,8 +57701,8 @@ var init_express_host_adapter = __esm({
|
|
|
56751
57701
|
}
|
|
56752
57702
|
async cleanupStaleSocket(socketPath) {
|
|
56753
57703
|
try {
|
|
56754
|
-
if (await (0,
|
|
56755
|
-
await (0,
|
|
57704
|
+
if (await (0, import_utils96.fileExists)(socketPath)) {
|
|
57705
|
+
await (0, import_utils96.unlink)(socketPath);
|
|
56756
57706
|
}
|
|
56757
57707
|
} catch {
|
|
56758
57708
|
}
|
|
@@ -56762,6 +57712,11 @@ var init_express_host_adapter = __esm({
|
|
|
56762
57712
|
});
|
|
56763
57713
|
|
|
56764
57714
|
// libs/sdk/src/server/adapters/polyfills/node-express-host.ts
|
|
57715
|
+
var node_express_host_exports = {};
|
|
57716
|
+
__export(node_express_host_exports, {
|
|
57717
|
+
DEFAULT_EXPRESS_BODY_LIMIT: () => DEFAULT_EXPRESS_BODY_LIMIT,
|
|
57718
|
+
ExpressHostAdapter: () => ExpressHostAdapter
|
|
57719
|
+
});
|
|
56765
57720
|
var init_node_express_host = __esm({
|
|
56766
57721
|
"libs/sdk/src/server/adapters/polyfills/node-express-host.ts"() {
|
|
56767
57722
|
"use strict";
|
|
@@ -56769,129 +57724,12 @@ var init_node_express_host = __esm({
|
|
|
56769
57724
|
}
|
|
56770
57725
|
});
|
|
56771
57726
|
|
|
56772
|
-
// libs/sdk/src/server/security/security-audit.ts
|
|
56773
|
-
function auditSecurityDefaults(config, isProduction5) {
|
|
56774
|
-
const findings = [];
|
|
56775
|
-
if (!isProduction5 && config.deploymentMode !== "distributed") {
|
|
56776
|
-
return findings;
|
|
56777
|
-
}
|
|
56778
|
-
const strict = config.security?.strict === true;
|
|
56779
|
-
if (config.cors === void 0 && !strict) {
|
|
56780
|
-
findings.push({
|
|
56781
|
-
level: "warn",
|
|
56782
|
-
code: "CORS_PERMISSIVE_DEFAULT",
|
|
56783
|
-
message: "CORS is using the permissive default (origin: true), which allows all origins.",
|
|
56784
|
-
recommendation: "Set explicit cors.origin to restrict allowed origins in production."
|
|
56785
|
-
});
|
|
56786
|
-
} else if (config.cors !== false && config.cors?.origin === true && !strict) {
|
|
56787
|
-
findings.push({
|
|
56788
|
-
level: "warn",
|
|
56789
|
-
code: "CORS_ORIGIN_TRUE",
|
|
56790
|
-
message: "CORS origin=true allows all origins to make cross-origin requests.",
|
|
56791
|
-
recommendation: "Set cors.origin to specific allowed origins."
|
|
56792
|
-
});
|
|
56793
|
-
} else if (config.cors === false) {
|
|
56794
|
-
findings.push({
|
|
56795
|
-
level: "info",
|
|
56796
|
-
code: "CORS_DISABLED",
|
|
56797
|
-
message: "CORS is disabled. Cross-origin requests will be blocked by browsers."
|
|
56798
|
-
});
|
|
56799
|
-
} else {
|
|
56800
|
-
findings.push({
|
|
56801
|
-
level: "info",
|
|
56802
|
-
code: "CORS_CONFIGURED",
|
|
56803
|
-
message: "CORS is explicitly configured."
|
|
56804
|
-
});
|
|
56805
|
-
}
|
|
56806
|
-
const bindAddress = config.resolvedBindAddress ?? "0.0.0.0";
|
|
56807
|
-
if (bindAddress === "0.0.0.0" || bindAddress === "::") {
|
|
56808
|
-
if (config.deploymentMode !== "distributed") {
|
|
56809
|
-
findings.push({
|
|
56810
|
-
level: "warn",
|
|
56811
|
-
code: "BIND_ALL_INTERFACES",
|
|
56812
|
-
message: `Server bound to ${bindAddress} \u2014 accessible from all network interfaces.`,
|
|
56813
|
-
recommendation: "Set security.bindAddress to 'loopback' or '127.0.0.1' for local-only access, or configure a reverse proxy. Distributed deployments require 'all' (0.0.0.0)."
|
|
56814
|
-
});
|
|
56815
|
-
} else {
|
|
56816
|
-
findings.push({
|
|
56817
|
-
level: "info",
|
|
56818
|
-
code: "BIND_ALL_INTERFACES_DISTRIBUTED",
|
|
56819
|
-
message: `Server bound to ${bindAddress} (expected for distributed deployment).`
|
|
56820
|
-
});
|
|
56821
|
-
}
|
|
56822
|
-
} else {
|
|
56823
|
-
findings.push({
|
|
56824
|
-
level: "info",
|
|
56825
|
-
code: "BIND_RESTRICTED",
|
|
56826
|
-
message: `Server bound to ${bindAddress}.`
|
|
56827
|
-
});
|
|
56828
|
-
}
|
|
56829
|
-
const dnsProtectionEnabled = config.security?.dnsRebindingProtection?.enabled ?? strict;
|
|
56830
|
-
if (!dnsProtectionEnabled) {
|
|
56831
|
-
findings.push({
|
|
56832
|
-
level: "warn",
|
|
56833
|
-
code: "DNS_REBINDING_UNPROTECTED",
|
|
56834
|
-
message: "DNS rebinding protection is disabled.",
|
|
56835
|
-
recommendation: "Enable security.dnsRebindingProtection with allowedHosts to prevent DNS rebinding attacks."
|
|
56836
|
-
});
|
|
56837
|
-
} else {
|
|
56838
|
-
findings.push({
|
|
56839
|
-
level: "info",
|
|
56840
|
-
code: "DNS_REBINDING_PROTECTED",
|
|
56841
|
-
message: "DNS rebinding protection is enabled."
|
|
56842
|
-
});
|
|
56843
|
-
}
|
|
56844
|
-
if (config.security?.strict) {
|
|
56845
|
-
findings.push({
|
|
56846
|
-
level: "info",
|
|
56847
|
-
code: "STRICT_MODE_ENABLED",
|
|
56848
|
-
message: "Strict security mode is enabled: loopback binding, restrictive CORS, DNS rebinding protection."
|
|
56849
|
-
});
|
|
56850
|
-
} else {
|
|
56851
|
-
findings.push({
|
|
56852
|
-
level: "info",
|
|
56853
|
-
code: "STRICT_MODE_HINT",
|
|
56854
|
-
message: "To enable strict security defaults, set security.strict = true in HttpOptions."
|
|
56855
|
-
});
|
|
56856
|
-
}
|
|
56857
|
-
return findings;
|
|
56858
|
-
}
|
|
56859
|
-
function logSecurityFindings(findings, logger) {
|
|
56860
|
-
if (findings.length === 0) return;
|
|
56861
|
-
for (const finding of findings) {
|
|
56862
|
-
const prefix = `[Security] ${finding.code}:`;
|
|
56863
|
-
const message = finding.recommendation ? `${prefix} ${finding.message} ${finding.recommendation}` : `${prefix} ${finding.message}`;
|
|
56864
|
-
if (finding.level === "warn") {
|
|
56865
|
-
logger.warn(message);
|
|
56866
|
-
} else {
|
|
56867
|
-
logger.info(message);
|
|
56868
|
-
}
|
|
56869
|
-
}
|
|
56870
|
-
}
|
|
56871
|
-
function resolveBindAddress(security, deploymentMode) {
|
|
56872
|
-
if (security?.bindAddress) {
|
|
56873
|
-
if (security.bindAddress === "loopback") return "127.0.0.1";
|
|
56874
|
-
if (security.bindAddress === "all") return "0.0.0.0";
|
|
56875
|
-
return security.bindAddress;
|
|
56876
|
-
}
|
|
56877
|
-
if (security?.strict) {
|
|
56878
|
-
return deploymentMode === "distributed" ? "0.0.0.0" : "127.0.0.1";
|
|
56879
|
-
}
|
|
56880
|
-
return "0.0.0.0";
|
|
56881
|
-
}
|
|
56882
|
-
var init_security_audit = __esm({
|
|
56883
|
-
"libs/sdk/src/server/security/security-audit.ts"() {
|
|
56884
|
-
"use strict";
|
|
56885
|
-
}
|
|
56886
|
-
});
|
|
56887
|
-
|
|
56888
57727
|
// libs/sdk/src/server/server.instance.ts
|
|
56889
|
-
var
|
|
57728
|
+
var import_utils97, DEFAULT_CORS, FrontMcpServerInstance;
|
|
56890
57729
|
var init_server_instance = __esm({
|
|
56891
57730
|
"libs/sdk/src/server/server.instance.ts"() {
|
|
56892
57731
|
"use strict";
|
|
56893
|
-
|
|
56894
|
-
init_node_express_host();
|
|
57732
|
+
import_utils97 = require("@frontmcp/utils");
|
|
56895
57733
|
init_common();
|
|
56896
57734
|
init_health2();
|
|
56897
57735
|
init_metrics2();
|
|
@@ -56919,7 +57757,8 @@ var init_server_instance = __esm({
|
|
|
56919
57757
|
this.host = this.config.hostFactory;
|
|
56920
57758
|
} else {
|
|
56921
57759
|
const corsConfig = this.config.cors === false ? void 0 : this.config.cors ?? DEFAULT_CORS;
|
|
56922
|
-
|
|
57760
|
+
const { ExpressHostAdapter: ExpressHostAdapter2 } = (init_node_express_host(), __toCommonJS(node_express_host_exports));
|
|
57761
|
+
this.host = new ExpressHostAdapter2({
|
|
56923
57762
|
...corsConfig ? { cors: corsConfig } : {},
|
|
56924
57763
|
...this.config.security ? { security: this.config.security } : {},
|
|
56925
57764
|
...this.config.bodyLimit !== void 0 ? { bodyLimit: this.config.bodyLimit } : {},
|
|
@@ -56992,7 +57831,7 @@ var init_server_instance = __esm({
|
|
|
56992
57831
|
}
|
|
56993
57832
|
async start() {
|
|
56994
57833
|
this.prepare();
|
|
56995
|
-
const deploymentMode = (0,
|
|
57834
|
+
const deploymentMode = (0, import_utils97.getRuntimeContext)().deployment;
|
|
56996
57835
|
const bindAddress = resolveBindAddress(this.config.security, deploymentMode);
|
|
56997
57836
|
const isProduction5 = process.env["NODE_ENV"] === "production";
|
|
56998
57837
|
const findings = auditSecurityDefaults(
|
|
@@ -57070,11 +57909,11 @@ function resolveConfigInput(optionsOrClass) {
|
|
|
57070
57909
|
}
|
|
57071
57910
|
return optionsOrClass;
|
|
57072
57911
|
}
|
|
57073
|
-
var
|
|
57912
|
+
var import_utils98, stdioServing, FrontMcpInstance;
|
|
57074
57913
|
var init_front_mcp = __esm({
|
|
57075
57914
|
"libs/sdk/src/front-mcp/front-mcp.ts"() {
|
|
57076
57915
|
"use strict";
|
|
57077
|
-
|
|
57916
|
+
import_utils98 = require("@frontmcp/utils");
|
|
57078
57917
|
init_common();
|
|
57079
57918
|
init_direct();
|
|
57080
57919
|
init_errors();
|
|
@@ -57086,6 +57925,7 @@ var init_front_mcp = __esm({
|
|
|
57086
57925
|
init_scope_registry();
|
|
57087
57926
|
init_skill_instructions_helper();
|
|
57088
57927
|
init_task();
|
|
57928
|
+
init_web_fetch_handler();
|
|
57089
57929
|
init_front_mcp_providers();
|
|
57090
57930
|
stdioServing = false;
|
|
57091
57931
|
FrontMcpInstance = class _FrontMcpInstance2 {
|
|
@@ -57230,6 +58070,44 @@ var init_front_mcp = __esm({
|
|
|
57230
58070
|
frontMcp.log?.info("FrontMCP handler created (serverless mode)");
|
|
57231
58071
|
return server.getHandler();
|
|
57232
58072
|
}
|
|
58073
|
+
/**
|
|
58074
|
+
* Creates and initializes a FrontMCP instance and returns a Web-standard
|
|
58075
|
+
* `fetch` handler — `(request: Request) => Promise<Response>` — backed by the
|
|
58076
|
+
* MCP WebStandard transport. Unlike {@link createHandler} this needs no
|
|
58077
|
+
* Express / Node `req`/`res` and runs on V8-isolate targets (Cloudflare
|
|
58078
|
+
* Workers, Deno Deploy, Bun).
|
|
58079
|
+
*
|
|
58080
|
+
* @example
|
|
58081
|
+
* // worker entry
|
|
58082
|
+
* const handler = await FrontMcpInstance.createFetchHandler(config);
|
|
58083
|
+
* export default { fetch: (request) => handler(request) };
|
|
58084
|
+
*/
|
|
58085
|
+
static async createFetchHandler(options) {
|
|
58086
|
+
let inner;
|
|
58087
|
+
let building;
|
|
58088
|
+
const build = async () => {
|
|
58089
|
+
const frontMcp = new _FrontMcpInstance2(options);
|
|
58090
|
+
await frontMcp.ready;
|
|
58091
|
+
const scope = frontMcp.getScopes()[0];
|
|
58092
|
+
if (!scope) {
|
|
58093
|
+
throw new ServerNotFoundError();
|
|
58094
|
+
}
|
|
58095
|
+
frontMcp.log?.info("FrontMCP fetch handler created (web-standard transport)");
|
|
58096
|
+
return createWebFetchHandler(scope);
|
|
58097
|
+
};
|
|
58098
|
+
return async (request) => {
|
|
58099
|
+
if (!inner) {
|
|
58100
|
+
if (!building) {
|
|
58101
|
+
building = build().catch((err) => {
|
|
58102
|
+
building = void 0;
|
|
58103
|
+
throw err;
|
|
58104
|
+
});
|
|
58105
|
+
}
|
|
58106
|
+
inner = await building;
|
|
58107
|
+
}
|
|
58108
|
+
return inner(request);
|
|
58109
|
+
};
|
|
58110
|
+
}
|
|
57233
58111
|
/**
|
|
57234
58112
|
* Creates and initializes a FrontMCP instance without starting any server.
|
|
57235
58113
|
* Returns the instance for graph extraction and introspection purposes.
|
|
@@ -57362,8 +58240,8 @@ var init_front_mcp = __esm({
|
|
|
57362
58240
|
frontMcp.log?.info(`MCP server listening on unix://${socketPath}`);
|
|
57363
58241
|
const cleanup = async () => {
|
|
57364
58242
|
try {
|
|
57365
|
-
if (await (0,
|
|
57366
|
-
await (0,
|
|
58243
|
+
if (await (0, import_utils98.fileExists)(socketPath)) {
|
|
58244
|
+
await (0, import_utils98.unlink)(socketPath);
|
|
57367
58245
|
}
|
|
57368
58246
|
} catch {
|
|
57369
58247
|
}
|
|
@@ -57453,7 +58331,7 @@ var init_front_mcp = __esm({
|
|
|
57453
58331
|
serve: false
|
|
57454
58332
|
});
|
|
57455
58333
|
if (parsedConfig.logging) {
|
|
57456
|
-
parsedConfig.logging.enableConsole =
|
|
58334
|
+
parsedConfig.logging.enableConsole = true;
|
|
57457
58335
|
const transports = parsedConfig.logging.transports ?? [];
|
|
57458
58336
|
if (!transports.includes(FileLogTransportInstance)) {
|
|
57459
58337
|
transports.push(FileLogTransportInstance);
|
|
@@ -57461,7 +58339,7 @@ var init_front_mcp = __esm({
|
|
|
57461
58339
|
parsedConfig.logging.transports = transports;
|
|
57462
58340
|
} else {
|
|
57463
58341
|
parsedConfig["logging"] = {
|
|
57464
|
-
enableConsole:
|
|
58342
|
+
enableConsole: true,
|
|
57465
58343
|
transports: [FileLogTransportInstance]
|
|
57466
58344
|
};
|
|
57467
58345
|
}
|
|
@@ -57512,7 +58390,7 @@ var init_front_mcp = __esm({
|
|
|
57512
58390
|
};
|
|
57513
58391
|
const mcpServer = new McpServer2(scope.metadata.info, serverOptions);
|
|
57514
58392
|
startupCleanups.push(() => mcpServer.close());
|
|
57515
|
-
const sessionId = `stdio:${(0,
|
|
58393
|
+
const sessionId = `stdio:${(0, import_utils98.randomUUID)()}`;
|
|
57516
58394
|
const handlers = createMcpHandlers2({ scope, serverOptions, composeInstructions });
|
|
57517
58395
|
for (const handler of handlers) {
|
|
57518
58396
|
const originalHandler = handler.handler;
|
|
@@ -57810,9 +58688,9 @@ function FrontMcp(providedMetadata) {
|
|
|
57810
58688
|
Reflect.defineMetadata(FrontMcpTokens[property] ?? property, metadata[property], target);
|
|
57811
58689
|
}
|
|
57812
58690
|
Reflect.defineMetadata(FRONTMCP_CONFIG_METADATA_KEY, metadata, target);
|
|
57813
|
-
const isServerless2 = (0,
|
|
57814
|
-
const isSchemaExtract = (0,
|
|
57815
|
-
const isStdio = (0,
|
|
58691
|
+
const isServerless2 = (0, import_utils99.getEnvFlag)("FRONTMCP_SERVERLESS");
|
|
58692
|
+
const isSchemaExtract = (0, import_utils99.getEnvFlag)("FRONTMCP_SCHEMA_EXTRACT");
|
|
58693
|
+
const isStdio = (0, import_utils99.getEnvFlag)("FRONTMCP_STDIO");
|
|
57816
58694
|
const taskWorkerId = typeof process !== "undefined" ? process.env?.["FRONTMCP_RUN_TASK_ID"] : void 0;
|
|
57817
58695
|
if (taskWorkerId && metadata.serve !== false) {
|
|
57818
58696
|
void (async () => {
|
|
@@ -57838,7 +58716,8 @@ function FrontMcp(providedMetadata) {
|
|
|
57838
58716
|
} else if (isServerless2) {
|
|
57839
58717
|
const ServerlessInstance = getFrontMcpInstance();
|
|
57840
58718
|
const { setServerlessHandler: setServerlessHandler2, setServerlessHandlerPromise: setServerlessHandlerPromise2, setServerlessHandlerError: setServerlessHandlerError2 } = getServerlessHandlerFns();
|
|
57841
|
-
const
|
|
58719
|
+
const isWorker = (0, import_utils99.getEnvFlag)("FRONTMCP_WORKER");
|
|
58720
|
+
const handlerPromise = isWorker ? ServerlessInstance.createFetchHandler(metadata) : ServerlessInstance.createHandler(metadata);
|
|
57842
58721
|
setServerlessHandlerPromise2(handlerPromise);
|
|
57843
58722
|
handlerPromise.then(setServerlessHandler2).catch((err) => {
|
|
57844
58723
|
const e = err instanceof Error ? err : new InternalMcpError(String(err), "SERVERLESS_INIT_FAILED");
|
|
@@ -57850,12 +58729,12 @@ function FrontMcp(providedMetadata) {
|
|
|
57850
58729
|
}
|
|
57851
58730
|
};
|
|
57852
58731
|
}
|
|
57853
|
-
var import_reflect_metadata28,
|
|
58732
|
+
var import_reflect_metadata28, import_utils99, FRONT_MCP_DECORATOR_BASENAMES, FRONTMCP_CONFIG_METADATA_KEY, _FrontMcpInstance, _serverlessHandlerFns;
|
|
57854
58733
|
var init_front_mcp_decorator = __esm({
|
|
57855
58734
|
"libs/sdk/src/common/decorators/front-mcp.decorator.ts"() {
|
|
57856
58735
|
"use strict";
|
|
57857
58736
|
import_reflect_metadata28 = require("reflect-metadata");
|
|
57858
|
-
|
|
58737
|
+
import_utils99 = require("@frontmcp/utils");
|
|
57859
58738
|
init_decorator_errors();
|
|
57860
58739
|
init_mcp_error();
|
|
57861
58740
|
init_metadata();
|
|
@@ -57981,6 +58860,12 @@ function remoteApp(url, options) {
|
|
|
57981
58860
|
filter: options?.filter
|
|
57982
58861
|
};
|
|
57983
58862
|
}
|
|
58863
|
+
function frontMcpApp(metadata) {
|
|
58864
|
+
const FunctionalApp = class {
|
|
58865
|
+
};
|
|
58866
|
+
FrontMcpApp(metadata)(FunctionalApp);
|
|
58867
|
+
return FunctionalApp;
|
|
58868
|
+
}
|
|
57984
58869
|
var import_reflect_metadata29, APP_DECORATOR_BASENAMES, App;
|
|
57985
58870
|
var init_app_decorator = __esm({
|
|
57986
58871
|
"libs/sdk/src/common/decorators/app.decorator.ts"() {
|
|
@@ -58826,12 +59711,12 @@ var init_adapter_entry = __esm({
|
|
|
58826
59711
|
});
|
|
58827
59712
|
|
|
58828
59713
|
// libs/sdk/src/common/entries/tool.entry.ts
|
|
58829
|
-
var import_lazy_zod106,
|
|
59714
|
+
var import_lazy_zod106, import_utils101, ToolEntry;
|
|
58830
59715
|
var init_tool_entry = __esm({
|
|
58831
59716
|
"libs/sdk/src/common/entries/tool.entry.ts"() {
|
|
58832
59717
|
"use strict";
|
|
58833
59718
|
import_lazy_zod106 = require("@frontmcp/lazy-zod");
|
|
58834
|
-
|
|
59719
|
+
import_utils101 = require("@frontmcp/utils");
|
|
58835
59720
|
init_base_entry();
|
|
58836
59721
|
ToolEntry = class extends BaseEntry {
|
|
58837
59722
|
owner;
|
|
@@ -58898,7 +59783,7 @@ var init_tool_entry = __esm({
|
|
|
58898
59783
|
try {
|
|
58899
59784
|
return (0, import_lazy_zod106.toJSONSchema)(import_lazy_zod106.z.object(this.inputSchema));
|
|
58900
59785
|
} catch (error) {
|
|
58901
|
-
if ((0,
|
|
59786
|
+
if ((0, import_utils101.isDebug)() || (0, import_utils101.isDevelopment)()) {
|
|
58902
59787
|
console.warn("[ToolEntry] Failed to convert Zod schema to JSON Schema:", error);
|
|
58903
59788
|
}
|
|
58904
59789
|
return { type: "object", properties: {} };
|
|
@@ -58944,7 +59829,7 @@ var init_tool_entry = __esm({
|
|
|
58944
59829
|
const json = (0, import_lazy_zod106.toJSONSchema)(zodSchema);
|
|
58945
59830
|
return json && json["type"] === "object" ? json : null;
|
|
58946
59831
|
} catch (error) {
|
|
58947
|
-
if ((0,
|
|
59832
|
+
if ((0, import_utils101.isDebug)() || (0, import_utils101.isDevelopment)()) {
|
|
58948
59833
|
console.warn("[ToolEntry] Failed to convert output Zod schema to JSON Schema:", error);
|
|
58949
59834
|
}
|
|
58950
59835
|
return null;
|
|
@@ -59793,6 +60678,7 @@ __export(index_exports, {
|
|
|
59793
60678
|
HttpStatus: () => HttpStatus,
|
|
59794
60679
|
HttpStreamSchema: () => HttpStreamSchema,
|
|
59795
60680
|
HttpTextSchema: () => HttpTextSchema,
|
|
60681
|
+
HttpWebResponseSchema: () => HttpWebResponseSchema,
|
|
59796
60682
|
ImageOutputSchema: () => ImageOutputSchema,
|
|
59797
60683
|
InMemoryOrchestratedTokenStore: () => import_auth40.InMemoryOrchestratedTokenStore,
|
|
59798
60684
|
InMemoryStoreRequiredError: () => import_auth11.InMemoryStoreRequiredError,
|
|
@@ -60062,6 +60948,7 @@ __export(index_exports, {
|
|
|
60062
60948
|
annotatedFrontMcpSkillsSchema: () => annotatedFrontMcpSkillsSchema,
|
|
60063
60949
|
annotatedFrontMcpToolsSchema: () => annotatedFrontMcpToolsSchema,
|
|
60064
60950
|
annotatedFrontMcpWorkflowsSchema: () => annotatedFrontMcpWorkflowsSchema,
|
|
60951
|
+
app: () => frontMcpApp,
|
|
60065
60952
|
appAuthOptionsSchema: () => import_auth9.appAuthOptionsSchema,
|
|
60066
60953
|
appFilterConfigSchema: () => appFilterConfigSchema,
|
|
60067
60954
|
applyPrimitiveFilter: () => applyPrimitiveFilter,
|
|
@@ -60076,6 +60963,7 @@ __export(index_exports, {
|
|
|
60076
60963
|
buildEsmResourceRecord: () => buildEsmResourceRecord,
|
|
60077
60964
|
buildEsmShUrl: () => buildEsmShUrl,
|
|
60078
60965
|
buildEsmToolRecord: () => buildEsmToolRecord,
|
|
60966
|
+
buildPersistentWebStandardMcp: () => buildPersistentWebStandardMcp,
|
|
60079
60967
|
buildRemotePromptRecord: () => buildRemotePromptRecord,
|
|
60080
60968
|
buildRemoteResourceRecord: () => buildRemoteResourceRecord,
|
|
60081
60969
|
buildRemoteResourceTemplateRecord: () => buildRemoteResourceTemplateRecord,
|
|
@@ -60128,6 +61016,7 @@ __export(index_exports, {
|
|
|
60128
61016
|
createSkillInstance: () => createSkillInstance,
|
|
60129
61017
|
createSkillStorageProvider: () => createSkillStorageProvider,
|
|
60130
61018
|
createTaskStore: () => createTaskStore,
|
|
61019
|
+
createWebFetchHandler: () => createWebFetchHandler,
|
|
60131
61020
|
decideIntent: () => decideIntent,
|
|
60132
61021
|
decisionSchema: () => decisionSchema,
|
|
60133
61022
|
decryptElicitationData: () => decryptElicitationData,
|
|
@@ -60171,6 +61060,7 @@ __export(index_exports, {
|
|
|
60171
61060
|
frontMcpAdapterMetadataSchema: () => frontMcpAdapterMetadataSchema,
|
|
60172
61061
|
frontMcpAgent: () => frontMcpAgent,
|
|
60173
61062
|
frontMcpAgentMetadataSchema: () => frontMcpAgentMetadataSchema,
|
|
61063
|
+
frontMcpApp: () => frontMcpApp,
|
|
60174
61064
|
frontMcpAuthProviderMetadataSchema: () => frontMcpAuthProviderMetadataSchema,
|
|
60175
61065
|
frontMcpBaseSchema: () => frontMcpBaseSchema,
|
|
60176
61066
|
frontMcpChannelMetadataSchema: () => frontMcpChannelMetadataSchema,
|
|
@@ -60257,7 +61147,7 @@ __export(index_exports, {
|
|
|
60257
61147
|
isValidVersion: () => isValidVersion,
|
|
60258
61148
|
isVercelKvProvider: () => isVercelKvProvider,
|
|
60259
61149
|
job: () => frontMcpJob,
|
|
60260
|
-
joinPath: () =>
|
|
61150
|
+
joinPath: () => import_utils81.joinPath,
|
|
60261
61151
|
jsonWebKeySetSchema: () => import_auth.jsonWebKeySetSchema,
|
|
60262
61152
|
jwkParametersSchema: () => import_auth.jwkParametersSchema,
|
|
60263
61153
|
jwkSchema: () => import_auth.jwkSchema,
|
|
@@ -60330,7 +61220,9 @@ __export(index_exports, {
|
|
|
60330
61220
|
resource: () => frontMcpResource,
|
|
60331
61221
|
resourceTemplate: () => frontMcpResourceTemplate,
|
|
60332
61222
|
resourceUriMatches: () => resourceUriMatches,
|
|
61223
|
+
runHttpRequestFlowWeb: () => runHttpRequestFlowWeb,
|
|
60333
61224
|
runTaskInBackground: () => runTaskInBackground,
|
|
61225
|
+
runWebStandardMcp: () => runWebStandardMcp,
|
|
60334
61226
|
satisfiesRange: () => satisfiesRange,
|
|
60335
61227
|
scanSkillResources: () => scanSkillResources,
|
|
60336
61228
|
secureStoreConfigSchema: () => import_auth4.secureStoreConfigSchema,
|
|
@@ -60372,7 +61264,7 @@ __export(index_exports, {
|
|
|
60372
61264
|
toolPaginationOptionsSchema: () => toolPaginationOptionsSchema,
|
|
60373
61265
|
transparentAuthOptionsSchema: () => import_auth6.transparentAuthOptionsSchema,
|
|
60374
61266
|
transportOptionsSchema: () => transportOptionsSchema,
|
|
60375
|
-
trimSlashes: () =>
|
|
61267
|
+
trimSlashes: () => import_utils81.trimSlashes,
|
|
60376
61268
|
tryDecryptStoredValue: () => tryDecryptStoredValue,
|
|
60377
61269
|
tryGetConfig: () => tryGetConfig,
|
|
60378
61270
|
upstreamProviderSchema: () => import_auth4.upstreamProviderSchema,
|
|
@@ -60586,22 +61478,22 @@ function createMemorySkillProvider(options = {}) {
|
|
|
60586
61478
|
init_skill_utils();
|
|
60587
61479
|
|
|
60588
61480
|
// libs/sdk/src/skill/skill-directory-loader.ts
|
|
60589
|
-
var
|
|
61481
|
+
var import_utils102 = require("@frontmcp/utils");
|
|
60590
61482
|
init_skill_metadata();
|
|
60591
61483
|
init_sdk_errors();
|
|
60592
61484
|
init_skill_md_parser();
|
|
60593
61485
|
async function scanSkillResources(dirPath) {
|
|
60594
61486
|
const resources = {};
|
|
60595
|
-
const scriptsPath = (0,
|
|
60596
|
-
const referencesPath = (0,
|
|
60597
|
-
const assetsPath = (0,
|
|
60598
|
-
const examplesPath = (0,
|
|
61487
|
+
const scriptsPath = (0, import_utils102.joinPath)(dirPath, "scripts");
|
|
61488
|
+
const referencesPath = (0, import_utils102.joinPath)(dirPath, "references");
|
|
61489
|
+
const assetsPath = (0, import_utils102.joinPath)(dirPath, "assets");
|
|
61490
|
+
const examplesPath = (0, import_utils102.joinPath)(dirPath, "examples");
|
|
60599
61491
|
const checks = await Promise.all([
|
|
60600
61492
|
checkDirectory(scriptsPath),
|
|
60601
61493
|
checkDirectory(referencesPath),
|
|
60602
61494
|
checkDirectory(assetsPath),
|
|
60603
61495
|
checkDirectory(examplesPath),
|
|
60604
|
-
(0,
|
|
61496
|
+
(0, import_utils102.fileExists)((0, import_utils102.joinPath)(dirPath, "SKILL.md"))
|
|
60605
61497
|
]);
|
|
60606
61498
|
if (checks[0]) resources.scripts = scriptsPath;
|
|
60607
61499
|
if (checks[1]) resources.references = referencesPath;
|
|
@@ -60614,7 +61506,7 @@ async function scanSkillResources(dirPath) {
|
|
|
60614
61506
|
}
|
|
60615
61507
|
async function checkDirectory(path3) {
|
|
60616
61508
|
try {
|
|
60617
|
-
const s = await (0,
|
|
61509
|
+
const s = await (0, import_utils102.stat)(path3);
|
|
60618
61510
|
return s.isDirectory();
|
|
60619
61511
|
} catch (err) {
|
|
60620
61512
|
if (err.code === "ENOENT") return false;
|
|
@@ -60627,16 +61519,16 @@ async function findNestedSkillMd(dirPath, maxDepth = Number.POSITIVE_INFINITY) {
|
|
|
60627
61519
|
if (depth > maxDepth) return;
|
|
60628
61520
|
let entries;
|
|
60629
61521
|
try {
|
|
60630
|
-
entries = await (0,
|
|
61522
|
+
entries = await (0, import_utils102.readdir)(current);
|
|
60631
61523
|
} catch (err) {
|
|
60632
61524
|
if (err.code === "ENOENT") return;
|
|
60633
61525
|
throw err;
|
|
60634
61526
|
}
|
|
60635
61527
|
for (const entry of entries) {
|
|
60636
|
-
const full = (0,
|
|
61528
|
+
const full = (0, import_utils102.joinPath)(current, entry);
|
|
60637
61529
|
let entryStat;
|
|
60638
61530
|
try {
|
|
60639
|
-
entryStat = await (0,
|
|
61531
|
+
entryStat = await (0, import_utils102.stat)(full);
|
|
60640
61532
|
} catch (err) {
|
|
60641
61533
|
if (err.code === "ENOENT") continue;
|
|
60642
61534
|
throw err;
|
|
@@ -60652,19 +61544,19 @@ async function findNestedSkillMd(dirPath, maxDepth = Number.POSITIVE_INFINITY) {
|
|
|
60652
61544
|
return found.sort();
|
|
60653
61545
|
}
|
|
60654
61546
|
async function loadSkillDirectory(dirPath, logger) {
|
|
60655
|
-
const skillMdPath = (0,
|
|
60656
|
-
const exists = await (0,
|
|
61547
|
+
const skillMdPath = (0, import_utils102.joinPath)(dirPath, "SKILL.md");
|
|
61548
|
+
const exists = await (0, import_utils102.fileExists)(skillMdPath);
|
|
60657
61549
|
if (!exists) {
|
|
60658
|
-
throw new InvalidSkillError((0,
|
|
61550
|
+
throw new InvalidSkillError((0, import_utils102.basename)(dirPath), "SKILL.md not found in directory");
|
|
60659
61551
|
}
|
|
60660
61552
|
let content;
|
|
60661
61553
|
let partialMetadata;
|
|
60662
61554
|
try {
|
|
60663
|
-
content = await (0,
|
|
61555
|
+
content = await (0, import_utils102.readFile)(skillMdPath, "utf-8");
|
|
60664
61556
|
const { frontmatter, body } = parseSkillMdFrontmatter(content);
|
|
60665
61557
|
partialMetadata = skillMdFrontmatterToMetadata(frontmatter, body);
|
|
60666
61558
|
} catch (err) {
|
|
60667
|
-
const name41 = (0,
|
|
61559
|
+
const name41 = (0, import_utils102.basename)(dirPath);
|
|
60668
61560
|
const message = err instanceof Error ? err.message : String(err);
|
|
60669
61561
|
throw new InvalidSkillError(name41, `Failed to read or parse SKILL.md: ${message}`);
|
|
60670
61562
|
}
|
|
@@ -60675,13 +61567,13 @@ async function loadSkillDirectory(dirPath, logger) {
|
|
|
60675
61567
|
}
|
|
60676
61568
|
const nested = await findNestedSkillMd(dirPath);
|
|
60677
61569
|
if (nested.length > 0) {
|
|
60678
|
-
const skillName2 = partialMetadata.name ?? (0,
|
|
61570
|
+
const skillName2 = partialMetadata.name ?? (0, import_utils102.basename)(dirPath);
|
|
60679
61571
|
throw new InvalidSkillError(
|
|
60680
61572
|
skillName2,
|
|
60681
61573
|
`Skill directory contains nested SKILL.md files (forbidden by SEP-2640 \xA7Resource Mapping): ${nested.join(", ")}`
|
|
60682
61574
|
);
|
|
60683
61575
|
}
|
|
60684
|
-
const dirName = (0,
|
|
61576
|
+
const dirName = (0, import_utils102.basename)(dirPath);
|
|
60685
61577
|
if (partialMetadata.name && dirName && partialMetadata.name !== dirName) {
|
|
60686
61578
|
const msg = `Skill name "${partialMetadata.name}" does not match directory name "${dirName}"`;
|
|
60687
61579
|
if (logger) {
|
|
@@ -60740,6 +61632,8 @@ init_direct();
|
|
|
60740
61632
|
|
|
60741
61633
|
// libs/sdk/src/transport/index.ts
|
|
60742
61634
|
init_in_memory_server();
|
|
61635
|
+
init_web_fetch_handler();
|
|
61636
|
+
init_web_standard_mcp();
|
|
60743
61637
|
|
|
60744
61638
|
// libs/sdk/src/index.ts
|
|
60745
61639
|
init_ext_apps2();
|
|
@@ -60970,6 +61864,7 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
60970
61864
|
HttpStatus,
|
|
60971
61865
|
HttpStreamSchema,
|
|
60972
61866
|
HttpTextSchema,
|
|
61867
|
+
HttpWebResponseSchema,
|
|
60973
61868
|
ImageOutputSchema,
|
|
60974
61869
|
InMemoryOrchestratedTokenStore,
|
|
60975
61870
|
InMemoryStoreRequiredError,
|
|
@@ -61239,6 +62134,7 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
61239
62134
|
annotatedFrontMcpSkillsSchema,
|
|
61240
62135
|
annotatedFrontMcpToolsSchema,
|
|
61241
62136
|
annotatedFrontMcpWorkflowsSchema,
|
|
62137
|
+
app,
|
|
61242
62138
|
appAuthOptionsSchema,
|
|
61243
62139
|
appFilterConfigSchema,
|
|
61244
62140
|
applyPrimitiveFilter,
|
|
@@ -61253,6 +62149,7 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
61253
62149
|
buildEsmResourceRecord,
|
|
61254
62150
|
buildEsmShUrl,
|
|
61255
62151
|
buildEsmToolRecord,
|
|
62152
|
+
buildPersistentWebStandardMcp,
|
|
61256
62153
|
buildRemotePromptRecord,
|
|
61257
62154
|
buildRemoteResourceRecord,
|
|
61258
62155
|
buildRemoteResourceTemplateRecord,
|
|
@@ -61305,6 +62202,7 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
61305
62202
|
createSkillInstance,
|
|
61306
62203
|
createSkillStorageProvider,
|
|
61307
62204
|
createTaskStore,
|
|
62205
|
+
createWebFetchHandler,
|
|
61308
62206
|
decideIntent,
|
|
61309
62207
|
decisionSchema,
|
|
61310
62208
|
decryptElicitationData,
|
|
@@ -61347,6 +62245,7 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
61347
62245
|
frontMcpAdapterMetadataSchema,
|
|
61348
62246
|
frontMcpAgent,
|
|
61349
62247
|
frontMcpAgentMetadataSchema,
|
|
62248
|
+
frontMcpApp,
|
|
61350
62249
|
frontMcpAuthProviderMetadataSchema,
|
|
61351
62250
|
frontMcpBaseSchema,
|
|
61352
62251
|
frontMcpChannelMetadataSchema,
|
|
@@ -61506,7 +62405,9 @@ var ChannelListHook = FlowHooksOf("channels:list");
|
|
|
61506
62405
|
resource,
|
|
61507
62406
|
resourceTemplate,
|
|
61508
62407
|
resourceUriMatches,
|
|
62408
|
+
runHttpRequestFlowWeb,
|
|
61509
62409
|
runTaskInBackground,
|
|
62410
|
+
runWebStandardMcp,
|
|
61510
62411
|
satisfiesRange,
|
|
61511
62412
|
scanSkillResources,
|
|
61512
62413
|
secureStoreConfigSchema,
|