@frontmcp/sdk 0.11.2 → 0.11.3
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/adapter/adapter.registry.d.ts.map +1 -1
- package/agent/flows/call-agent.flow.d.ts.map +1 -1
- package/app/app.registry.d.ts +1 -0
- package/app/app.registry.d.ts.map +1 -1
- package/app/instances/app.local.instance.d.ts +1 -0
- package/app/instances/app.local.instance.d.ts.map +1 -1
- package/app/instances/app.remote.instance.d.ts.map +1 -1
- package/auth/flows/session.verify.flow.d.ts +2 -0
- package/auth/flows/session.verify.flow.d.ts.map +1 -1
- package/common/decorators/skill.decorator.d.ts +13 -1
- package/common/decorators/skill.decorator.d.ts.map +1 -1
- package/common/entries/skill.entry.d.ts +21 -1
- package/common/entries/skill.entry.d.ts.map +1 -1
- package/common/interfaces/internal/registry.interface.d.ts +1 -0
- package/common/interfaces/internal/registry.interface.d.ts.map +1 -1
- package/common/interfaces/skill.interface.d.ts +21 -1
- package/common/interfaces/skill.interface.d.ts.map +1 -1
- package/common/metadata/skill.metadata.d.ts +56 -0
- package/common/metadata/skill.metadata.d.ts.map +1 -1
- package/common/tokens/skill.tokens.d.ts +5 -0
- package/common/tokens/skill.tokens.d.ts.map +1 -1
- package/esm/index.mjs +393 -70
- package/esm/package.json +6 -6
- package/flows/flow.instance.d.ts +1 -0
- package/flows/flow.instance.d.ts.map +1 -1
- package/front-mcp/front-mcp.d.ts +1 -0
- package/front-mcp/front-mcp.d.ts.map +1 -1
- package/index.js +522 -198
- package/package.json +6 -6
- package/plugin/plugin.registry.d.ts +7 -0
- package/plugin/plugin.registry.d.ts.map +1 -1
- package/scope/scope.instance.d.ts +1 -0
- package/scope/scope.instance.d.ts.map +1 -1
- package/scope/scope.registry.d.ts +1 -0
- package/scope/scope.registry.d.ts.map +1 -1
- package/skill/index.d.ts +16 -0
- package/skill/index.d.ts.map +1 -1
- package/skill/skill-directory-loader.d.ts +51 -0
- package/skill/skill-directory-loader.d.ts.map +1 -0
- package/skill/skill-http.utils.d.ts +6 -1
- package/skill/skill-http.utils.d.ts.map +1 -1
- package/skill/skill-md-parser.d.ts +60 -0
- package/skill/skill-md-parser.d.ts.map +1 -0
- package/skill/skill.instance.d.ts.map +1 -1
- package/skill/skill.utils.d.ts.map +1 -1
- package/tool/flows/call-tool.flow.d.ts.map +1 -1
- package/transport/flows/handle.stateless-http.flow.d.ts.map +1 -1
- package/transport/flows/handle.streamable-http.flow.d.ts.map +1 -1
- package/transport/mcp-handlers/call-tool-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/complete-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/get-prompt-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/list-prompts-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/list-resource-templates-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/list-resources-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/list-tools-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/read-resource-request.handler.d.ts.map +1 -1
- package/transport/mcp-handlers/unsubscribe-request.handler.d.ts.map +1 -1
package/esm/index.mjs
CHANGED
|
@@ -406,6 +406,11 @@ var init_skill_tokens = __esm({
|
|
|
406
406
|
hideFromDiscovery: tokenFactory.meta("skill:hideFromDiscovery"),
|
|
407
407
|
toolValidation: tokenFactory.meta("skill:toolValidation"),
|
|
408
408
|
visibility: tokenFactory.meta("skill:visibility"),
|
|
409
|
+
license: tokenFactory.meta("skill:license"),
|
|
410
|
+
compatibility: tokenFactory.meta("skill:compatibility"),
|
|
411
|
+
specMetadata: tokenFactory.meta("skill:specMetadata"),
|
|
412
|
+
allowedTools: tokenFactory.meta("skill:allowedTools"),
|
|
413
|
+
resources: tokenFactory.meta("skill:resources"),
|
|
409
414
|
metadata: tokenFactory.meta("skill:metadata")
|
|
410
415
|
// used in skill({}) construction
|
|
411
416
|
};
|
|
@@ -2645,7 +2650,7 @@ function isFileInstructions(source) {
|
|
|
2645
2650
|
function isUrlInstructions(source) {
|
|
2646
2651
|
return typeof source === "object" && "url" in source;
|
|
2647
2652
|
}
|
|
2648
|
-
var skillToolRefSchema, skillToolRefWithClassSchema, skillToolInputSchema, skillParameterSchema, skillExampleSchema, skillInstructionSourceSchema, skillMetadataSchema;
|
|
2653
|
+
var skillToolRefSchema, skillToolRefWithClassSchema, skillToolInputSchema, skillParameterSchema, skillExampleSchema, skillInstructionSourceSchema, skillResourcesSchema, skillMetadataSchema;
|
|
2649
2654
|
var init_skill_metadata = __esm({
|
|
2650
2655
|
"libs/sdk/src/common/metadata/skill.metadata.ts"() {
|
|
2651
2656
|
"use strict";
|
|
@@ -2696,10 +2701,21 @@ var init_skill_metadata = __esm({
|
|
|
2696
2701
|
}).strict()
|
|
2697
2702
|
// URL
|
|
2698
2703
|
]);
|
|
2704
|
+
skillResourcesSchema = z29.object({
|
|
2705
|
+
scripts: z29.string().optional(),
|
|
2706
|
+
references: z29.string().optional(),
|
|
2707
|
+
assets: z29.string().optional()
|
|
2708
|
+
});
|
|
2699
2709
|
skillMetadataSchema = z29.object({
|
|
2700
2710
|
id: z29.string().optional(),
|
|
2701
|
-
name: z29.string().min(1)
|
|
2702
|
-
|
|
2711
|
+
name: z29.string().min(1).max(64).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/, {
|
|
2712
|
+
message: "Skill name must be kebab-case: lowercase letters, numbers, and hyphens only. Must not start/end with a hyphen."
|
|
2713
|
+
}).refine((n) => !n.includes("--"), {
|
|
2714
|
+
message: "Skill name must not contain consecutive hyphens."
|
|
2715
|
+
}),
|
|
2716
|
+
description: z29.string().min(1).max(1024).refine((d) => !/<[a-zA-Z][^>]*>/.test(d), {
|
|
2717
|
+
message: "Skill description must not contain XML/HTML tags (per Agent Skills spec)."
|
|
2718
|
+
}),
|
|
2703
2719
|
instructions: skillInstructionSourceSchema,
|
|
2704
2720
|
tools: z29.array(skillToolInputSchema).optional(),
|
|
2705
2721
|
tags: z29.array(z29.string().min(1)).optional(),
|
|
@@ -2708,7 +2724,12 @@ var init_skill_metadata = __esm({
|
|
|
2708
2724
|
priority: z29.number().optional().default(0),
|
|
2709
2725
|
hideFromDiscovery: z29.boolean().optional().default(false),
|
|
2710
2726
|
toolValidation: z29.enum(["strict", "warn", "ignore"]).optional().default("warn"),
|
|
2711
|
-
visibility: z29.enum(["mcp", "http", "both"]).optional().default("both")
|
|
2727
|
+
visibility: z29.enum(["mcp", "http", "both"]).optional().default("both"),
|
|
2728
|
+
license: z29.string().optional(),
|
|
2729
|
+
compatibility: z29.string().max(500).optional(),
|
|
2730
|
+
specMetadata: z29.record(z29.string(), z29.string()).optional(),
|
|
2731
|
+
allowedTools: z29.string().optional(),
|
|
2732
|
+
resources: skillResourcesSchema.optional()
|
|
2712
2733
|
}).passthrough();
|
|
2713
2734
|
}
|
|
2714
2735
|
});
|
|
@@ -9333,7 +9354,11 @@ ${JSON.stringify(error.schema, null, 2)}
|
|
|
9333
9354
|
this.logger.info("finalize: sending response", {
|
|
9334
9355
|
tool: tool.metadata.name,
|
|
9335
9356
|
hasContent: Array.isArray(result.content) && result.content.length > 0,
|
|
9336
|
-
|
|
9357
|
+
contentParts: Array.isArray(result.content) ? result.content.length : 0,
|
|
9358
|
+
contentBytes: Array.isArray(result.content) ? result.content.reduce((sum, part) => {
|
|
9359
|
+
const str = JSON.stringify(part);
|
|
9360
|
+
return sum + (typeof Buffer !== "undefined" ? Buffer.byteLength(str, "utf8") : new TextEncoder().encode(str).byteLength);
|
|
9361
|
+
}, 0) : 0,
|
|
9337
9362
|
hasStructuredContent: result.structuredContent !== void 0,
|
|
9338
9363
|
hasMeta: result._meta !== void 0,
|
|
9339
9364
|
metaKeys: result._meta ? Object.keys(result._meta) : [],
|
|
@@ -13078,9 +13103,10 @@ var init_adapter_registry = __esm({
|
|
|
13078
13103
|
const instance = new AdapterInstance(rec, deps, this.providers);
|
|
13079
13104
|
this.instances.set(token, instance);
|
|
13080
13105
|
readyArr.push(instance.ready);
|
|
13106
|
+
this.logger?.verbose(`AdapterRegistry: initialized adapter '${rec.metadata.name}'`);
|
|
13081
13107
|
}
|
|
13082
13108
|
await Promise.all(readyArr);
|
|
13083
|
-
this.logger?.
|
|
13109
|
+
this.logger?.verbose(`AdapterRegistry: initialization complete (${this.instances.size} adapter(s))`);
|
|
13084
13110
|
}
|
|
13085
13111
|
getAdapters() {
|
|
13086
13112
|
return [...this.instances.values()];
|
|
@@ -13217,9 +13243,46 @@ var init_skill_events = __esm({
|
|
|
13217
13243
|
}
|
|
13218
13244
|
});
|
|
13219
13245
|
|
|
13246
|
+
// libs/sdk/src/skill/skill-md-parser.ts
|
|
13247
|
+
import * as yaml from "js-yaml";
|
|
13248
|
+
import { readFile } from "@frontmcp/utils";
|
|
13249
|
+
function parseSkillMdFrontmatter(content) {
|
|
13250
|
+
const trimmed = content.trimStart();
|
|
13251
|
+
if (!trimmed.startsWith("---")) {
|
|
13252
|
+
return { frontmatter: {}, body: content };
|
|
13253
|
+
}
|
|
13254
|
+
const closingIndex = trimmed.indexOf("\n---", 3);
|
|
13255
|
+
if (closingIndex === -1) {
|
|
13256
|
+
return { frontmatter: {}, body: content };
|
|
13257
|
+
}
|
|
13258
|
+
const yamlBlock = trimmed.substring(3, closingIndex).trim();
|
|
13259
|
+
const afterClose = closingIndex + 4;
|
|
13260
|
+
const bodyStart = trimmed[afterClose] === "\n" ? afterClose + 1 : afterClose;
|
|
13261
|
+
const body = trimmed.substring(bodyStart);
|
|
13262
|
+
let frontmatter = {};
|
|
13263
|
+
try {
|
|
13264
|
+
const parsed = yaml.load(yamlBlock);
|
|
13265
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
13266
|
+
frontmatter = parsed;
|
|
13267
|
+
}
|
|
13268
|
+
} catch {
|
|
13269
|
+
return { frontmatter: {}, body: content };
|
|
13270
|
+
}
|
|
13271
|
+
return { frontmatter, body };
|
|
13272
|
+
}
|
|
13273
|
+
function stripFrontmatter(content) {
|
|
13274
|
+
const { body } = parseSkillMdFrontmatter(content);
|
|
13275
|
+
return body;
|
|
13276
|
+
}
|
|
13277
|
+
var init_skill_md_parser = __esm({
|
|
13278
|
+
"libs/sdk/src/skill/skill-md-parser.ts"() {
|
|
13279
|
+
"use strict";
|
|
13280
|
+
}
|
|
13281
|
+
});
|
|
13282
|
+
|
|
13220
13283
|
// libs/sdk/src/skill/skill.utils.ts
|
|
13221
13284
|
import { isClass as isClass11, getMetadata as getMetadata13, depsOfClass as depsOfClass8 } from "@frontmcp/di";
|
|
13222
|
-
import { readFile } from "@frontmcp/utils";
|
|
13285
|
+
import { readFile as readFile2 } from "@frontmcp/utils";
|
|
13223
13286
|
function collectSkillMetadata(cls) {
|
|
13224
13287
|
const extended = getMetadata13(extendedSkillMetadata, cls);
|
|
13225
13288
|
const seed = extended ? { ...extended } : {};
|
|
@@ -13285,7 +13348,8 @@ async function loadInstructions(source, basePath) {
|
|
|
13285
13348
|
}
|
|
13286
13349
|
if (isFileInstructions(source)) {
|
|
13287
13350
|
const filePath = basePath ? `${basePath}/${source.file}` : source.file;
|
|
13288
|
-
|
|
13351
|
+
const content = await readFile2(filePath, "utf-8");
|
|
13352
|
+
return stripFrontmatter(content);
|
|
13289
13353
|
}
|
|
13290
13354
|
if (isUrlInstructions(source)) {
|
|
13291
13355
|
const response = await fetch(source.url);
|
|
@@ -13304,7 +13368,12 @@ function buildSkillContent(metadata, instructions) {
|
|
|
13304
13368
|
instructions,
|
|
13305
13369
|
tools: normalizeToolRefs(metadata.tools),
|
|
13306
13370
|
parameters: metadata.parameters,
|
|
13307
|
-
examples: metadata.examples
|
|
13371
|
+
examples: metadata.examples,
|
|
13372
|
+
license: metadata.license,
|
|
13373
|
+
compatibility: metadata.compatibility,
|
|
13374
|
+
specMetadata: metadata.specMetadata,
|
|
13375
|
+
allowedTools: metadata.allowedTools,
|
|
13376
|
+
resources: metadata.resources
|
|
13308
13377
|
};
|
|
13309
13378
|
}
|
|
13310
13379
|
function normalizeToolRefs(tools) {
|
|
@@ -13338,6 +13407,14 @@ function formatSkillForLLM(skill, availableTools, missingTools) {
|
|
|
13338
13407
|
parts.push("");
|
|
13339
13408
|
parts.push(skill.description);
|
|
13340
13409
|
parts.push("");
|
|
13410
|
+
if (skill.license) {
|
|
13411
|
+
parts.push(`**License:** ${skill.license}`);
|
|
13412
|
+
parts.push("");
|
|
13413
|
+
}
|
|
13414
|
+
if (skill.compatibility) {
|
|
13415
|
+
parts.push(`**Compatibility:** ${skill.compatibility}`);
|
|
13416
|
+
parts.push("");
|
|
13417
|
+
}
|
|
13341
13418
|
if (missingTools.length > 0) {
|
|
13342
13419
|
parts.push("> **Warning:** Some tools referenced by this skill are not available:");
|
|
13343
13420
|
parts.push(`> Missing: ${missingTools.join(", ")}`);
|
|
@@ -13412,6 +13489,7 @@ var init_skill_utils = __esm({
|
|
|
13412
13489
|
"use strict";
|
|
13413
13490
|
init_common();
|
|
13414
13491
|
init_errors();
|
|
13492
|
+
init_skill_md_parser();
|
|
13415
13493
|
}
|
|
13416
13494
|
});
|
|
13417
13495
|
|
|
@@ -14697,6 +14775,7 @@ var init_plugin_registry = __esm({
|
|
|
14697
14775
|
init_hooks_utils();
|
|
14698
14776
|
init_errors();
|
|
14699
14777
|
init_context();
|
|
14778
|
+
init_common();
|
|
14700
14779
|
PluginRegistry = class _PluginRegistry extends RegistryAbstract {
|
|
14701
14780
|
/** providers by token */
|
|
14702
14781
|
pProviders = /* @__PURE__ */ new Map();
|
|
@@ -14715,15 +14794,29 @@ var init_plugin_registry = __esm({
|
|
|
14715
14794
|
scope;
|
|
14716
14795
|
scopeInfo;
|
|
14717
14796
|
owner;
|
|
14797
|
+
logger;
|
|
14718
14798
|
constructor(providers, list, owner, scopeInfo) {
|
|
14719
14799
|
super("PluginRegistry", providers, list);
|
|
14720
14800
|
this.scope = providers.getActiveScope();
|
|
14721
14801
|
this.scopeInfo = scopeInfo;
|
|
14722
14802
|
this.owner = owner;
|
|
14803
|
+
try {
|
|
14804
|
+
this.logger = providers.get(FrontMcpLogger)?.child("PluginRegistry");
|
|
14805
|
+
} catch (e) {
|
|
14806
|
+
console.debug("PluginRegistry: logger initialization failed", e);
|
|
14807
|
+
}
|
|
14723
14808
|
}
|
|
14724
14809
|
getPlugins() {
|
|
14725
14810
|
return [...this.instances.values()];
|
|
14726
14811
|
}
|
|
14812
|
+
/**
|
|
14813
|
+
* Returns the names of all registered plugins from their definition records.
|
|
14814
|
+
* Unlike getPlugins().map(p => p.metadata.name), this is safe because
|
|
14815
|
+
* raw plugin instances (e.g. DynamicPlugin subclasses) may not carry a .metadata property.
|
|
14816
|
+
*/
|
|
14817
|
+
getPluginNames() {
|
|
14818
|
+
return [...this.defs.values()].map((rec) => rec.metadata.name);
|
|
14819
|
+
}
|
|
14727
14820
|
buildMap(list) {
|
|
14728
14821
|
const tokens = /* @__PURE__ */ new Set();
|
|
14729
14822
|
const defs = /* @__PURE__ */ new Map();
|
|
@@ -14750,6 +14843,7 @@ var init_plugin_registry = __esm({
|
|
|
14750
14843
|
}
|
|
14751
14844
|
}
|
|
14752
14845
|
async initialize() {
|
|
14846
|
+
this.logger?.verbose(`PluginRegistry: initializing ${this.tokens.size} plugin(s)`);
|
|
14753
14847
|
for (const token of this.tokens) {
|
|
14754
14848
|
const rec = this.defs.get(token);
|
|
14755
14849
|
const deps = this.graph.get(token);
|
|
@@ -14857,6 +14951,9 @@ var init_plugin_registry = __esm({
|
|
|
14857
14951
|
}
|
|
14858
14952
|
}
|
|
14859
14953
|
this.instances.set(token, pluginInstance);
|
|
14954
|
+
this.logger?.verbose(
|
|
14955
|
+
`PluginRegistry: registered plugin '${rec.metadata.name}' (${hooks.length} hook(s), ${contextExtensions?.length ?? 0} context extension(s))`
|
|
14956
|
+
);
|
|
14860
14957
|
}
|
|
14861
14958
|
}
|
|
14862
14959
|
};
|
|
@@ -15990,7 +16087,7 @@ var init_config_symbols = __esm({
|
|
|
15990
16087
|
});
|
|
15991
16088
|
|
|
15992
16089
|
// libs/sdk/src/builtin/config/providers/env-loader.ts
|
|
15993
|
-
import { readFile as
|
|
16090
|
+
import { readFile as readFile3, fileExists } from "@frontmcp/utils";
|
|
15994
16091
|
import * as path from "path";
|
|
15995
16092
|
function parseEnvContent(content) {
|
|
15996
16093
|
const result = {};
|
|
@@ -16021,12 +16118,12 @@ async function loadEnvFiles(basePath = process.cwd(), envPath = ".env", localEnv
|
|
|
16021
16118
|
const result = {};
|
|
16022
16119
|
const envFile = path.resolve(basePath, envPath);
|
|
16023
16120
|
if (await fileExists(envFile)) {
|
|
16024
|
-
const content = await
|
|
16121
|
+
const content = await readFile3(envFile);
|
|
16025
16122
|
Object.assign(result, parseEnvContent(content));
|
|
16026
16123
|
}
|
|
16027
16124
|
const localFile = path.resolve(basePath, localEnvPath);
|
|
16028
16125
|
if (await fileExists(localFile)) {
|
|
16029
|
-
const content = await
|
|
16126
|
+
const content = await readFile3(localFile);
|
|
16030
16127
|
Object.assign(result, parseEnvContent(content));
|
|
16031
16128
|
}
|
|
16032
16129
|
return result;
|
|
@@ -16145,9 +16242,9 @@ var init_env_loader = __esm({
|
|
|
16145
16242
|
});
|
|
16146
16243
|
|
|
16147
16244
|
// libs/sdk/src/builtin/config/providers/config-loader.ts
|
|
16148
|
-
import * as
|
|
16245
|
+
import * as yaml2 from "js-yaml";
|
|
16149
16246
|
import * as path2 from "path";
|
|
16150
|
-
import { readFile as
|
|
16247
|
+
import { readFile as readFile4, fileExists as fileExists2 } from "@frontmcp/utils";
|
|
16151
16248
|
async function loadConfig(schema, options = {}) {
|
|
16152
16249
|
const {
|
|
16153
16250
|
basePath = process.cwd(),
|
|
@@ -16190,8 +16287,8 @@ async function loadYamlConfig(basePath, configPath) {
|
|
|
16190
16287
|
for (const ext of extensions) {
|
|
16191
16288
|
const fullPath = path2.resolve(basePath, baseName + ext);
|
|
16192
16289
|
if (await fileExists2(fullPath)) {
|
|
16193
|
-
const content = await
|
|
16194
|
-
const parsed =
|
|
16290
|
+
const content = await readFile4(fullPath);
|
|
16291
|
+
const parsed = yaml2.load(content);
|
|
16195
16292
|
if (parsed && typeof parsed === "object") {
|
|
16196
16293
|
return parsed;
|
|
16197
16294
|
}
|
|
@@ -16657,6 +16754,7 @@ var init_flow_instance = __esm({
|
|
|
16657
16754
|
FlowClass;
|
|
16658
16755
|
stages;
|
|
16659
16756
|
hooks;
|
|
16757
|
+
logger;
|
|
16660
16758
|
constructor(scope, record, deps, globalProviders) {
|
|
16661
16759
|
super(scope, record);
|
|
16662
16760
|
this.deps = [...deps];
|
|
@@ -16665,6 +16763,7 @@ var init_flow_instance = __esm({
|
|
|
16665
16763
|
this.ready = this.initialize();
|
|
16666
16764
|
this.plan = this.record.metadata.plan;
|
|
16667
16765
|
this.hooks = scope.providers.getHooksRegistry();
|
|
16766
|
+
this.logger = scope.logger.child("FlowInstance");
|
|
16668
16767
|
}
|
|
16669
16768
|
async initialize() {
|
|
16670
16769
|
const server = this.globalProviders.getActiveServer();
|
|
@@ -16699,7 +16798,8 @@ var init_flow_instance = __esm({
|
|
|
16699
16798
|
return writeHttpResponse(response, e.output);
|
|
16700
16799
|
}
|
|
16701
16800
|
}
|
|
16702
|
-
|
|
16801
|
+
this.logger.error("Unhandled error in flow", {
|
|
16802
|
+
flow: this.name,
|
|
16703
16803
|
name: e instanceof Error ? e.name : "UnknownError",
|
|
16704
16804
|
message: e instanceof Error ? e.message : String(e)
|
|
16705
16805
|
});
|
|
@@ -16732,6 +16832,7 @@ var init_flow_instance = __esm({
|
|
|
16732
16832
|
try {
|
|
16733
16833
|
return this.globalProviders.get(FrontMcpContextStorage);
|
|
16734
16834
|
} catch {
|
|
16835
|
+
this.logger.verbose("getContextStorage: FrontMcpContextStorage not available");
|
|
16735
16836
|
return void 0;
|
|
16736
16837
|
}
|
|
16737
16838
|
}
|
|
@@ -16765,6 +16866,7 @@ var init_flow_instance = __esm({
|
|
|
16765
16866
|
);
|
|
16766
16867
|
}
|
|
16767
16868
|
async run(input, deps) {
|
|
16869
|
+
this.logger.verbose(`run: starting flow '${this.name}'`);
|
|
16768
16870
|
const scope = this.globalProviders.getActiveScope();
|
|
16769
16871
|
const { FlowClass, plan: plan32, name: name33 } = this;
|
|
16770
16872
|
const contextStorage = this.getContextStorage();
|
|
@@ -16800,10 +16902,10 @@ var init_flow_instance = __esm({
|
|
|
16800
16902
|
try {
|
|
16801
16903
|
metas.push(h2.metadata);
|
|
16802
16904
|
} catch (e) {
|
|
16803
|
-
|
|
16804
|
-
|
|
16805
|
-
e instanceof Error ? e.message : "Unknown error"
|
|
16806
|
-
);
|
|
16905
|
+
this.logger.warn("Ignoring injected hook that failed to materialize", {
|
|
16906
|
+
flow: this.name,
|
|
16907
|
+
error: e instanceof Error ? e.message : "Unknown error"
|
|
16908
|
+
});
|
|
16807
16909
|
}
|
|
16808
16910
|
}
|
|
16809
16911
|
if (metas.length) {
|
|
@@ -16911,6 +17013,7 @@ var init_flow_instance = __esm({
|
|
|
16911
17013
|
};
|
|
16912
17014
|
{
|
|
16913
17015
|
const pre = await runStageGroup(plan32.pre, true);
|
|
17016
|
+
this.logger.verbose(`run: PRE completed, outcome=${pre.outcome}`);
|
|
16914
17017
|
if (pre.outcome === "respond") {
|
|
16915
17018
|
const post = await runStageGroup(plan32.post, false);
|
|
16916
17019
|
if (post.outcome === "unknown_error" || post.outcome === "fail") {
|
|
@@ -16949,6 +17052,7 @@ var init_flow_instance = __esm({
|
|
|
16949
17052
|
}
|
|
16950
17053
|
if (!responded) {
|
|
16951
17054
|
const exec = await runStageGroup(plan32.execute, true);
|
|
17055
|
+
this.logger.verbose(`run: EXECUTE completed, outcome=${exec.outcome}`);
|
|
16952
17056
|
if (exec.outcome === "respond") {
|
|
16953
17057
|
} else if (exec.outcome === "unknown_error" || exec.outcome === "fail") {
|
|
16954
17058
|
try {
|
|
@@ -16967,6 +17071,7 @@ var init_flow_instance = __esm({
|
|
|
16967
17071
|
}
|
|
16968
17072
|
{
|
|
16969
17073
|
const post = await runStageGroup(plan32.post, false);
|
|
17074
|
+
this.logger.verbose(`run: POST completed, outcome=${post.outcome}`);
|
|
16970
17075
|
if (post.outcome === "unknown_error" || post.outcome === "fail") {
|
|
16971
17076
|
try {
|
|
16972
17077
|
await runErrorStage();
|
|
@@ -18456,13 +18561,19 @@ var init_app_local_instance = __esm({
|
|
|
18456
18561
|
appPrompts;
|
|
18457
18562
|
appAgents;
|
|
18458
18563
|
appSkills;
|
|
18564
|
+
logger;
|
|
18459
18565
|
constructor(record, scopeProviders) {
|
|
18460
18566
|
super(record);
|
|
18461
18567
|
this.scopeProviders = scopeProviders;
|
|
18462
18568
|
this.id = this.metadata.id ?? idFromString(this.metadata.name);
|
|
18569
|
+
try {
|
|
18570
|
+
this.logger = scopeProviders.get(FrontMcpLogger)?.child("AppLocalInstance");
|
|
18571
|
+
} catch {
|
|
18572
|
+
}
|
|
18463
18573
|
this.ready = this.initialize();
|
|
18464
18574
|
}
|
|
18465
18575
|
async initialize() {
|
|
18576
|
+
this.logger?.verbose(`Initializing app: ${this.metadata.name} (id: ${this.id})`);
|
|
18466
18577
|
this.appProviders = new ProviderRegistry(this.metadata.providers ?? [], this.scopeProviders);
|
|
18467
18578
|
await this.appProviders.ready;
|
|
18468
18579
|
const appOwner = {
|
|
@@ -18478,15 +18589,37 @@ var init_app_local_instance = __esm({
|
|
|
18478
18589
|
};
|
|
18479
18590
|
this.appPlugins = new PluginRegistry(this.appProviders, this.metadata.plugins ?? [], appOwner, scopeInfo);
|
|
18480
18591
|
await this.appPlugins.ready;
|
|
18592
|
+
this.logger?.verbose(`App ${this.metadata.name}: ${this.appPlugins.getPlugins().length} plugin(s) registered`);
|
|
18481
18593
|
this.appAdapters = new AdapterRegistry(this.appProviders, this.metadata.adapters ?? []);
|
|
18482
18594
|
await this.appAdapters.ready;
|
|
18595
|
+
this.logger?.verbose(`App ${this.metadata.name}: ${this.appAdapters.getAdapters().length} adapter(s) found`);
|
|
18483
18596
|
this.appTools = new ToolRegistry(this.appProviders, this.metadata.tools ?? [], appOwner);
|
|
18484
18597
|
await this.appTools.ready;
|
|
18598
|
+
const toolNames = this.appTools.getTools(true).map((t) => t.metadata.name);
|
|
18599
|
+
this.logger?.verbose(
|
|
18600
|
+
`App ${this.metadata.name}: ${toolNames.length} tool(s) registered: [${toolNames.join(", ")}]`
|
|
18601
|
+
);
|
|
18485
18602
|
this.appResources = new ResourceRegistry(this.appProviders, this.metadata.resources ?? [], appOwner);
|
|
18486
18603
|
this.appPrompts = new PromptRegistry(this.appProviders, this.metadata.prompts ?? [], appOwner);
|
|
18487
18604
|
this.appAgents = new AgentRegistry(this.appProviders, this.metadata.agents ?? [], appOwner);
|
|
18488
18605
|
this.appSkills = new SkillRegistry(this.appProviders, this.metadata.skills ?? [], appOwner);
|
|
18489
18606
|
await Promise.all([this.appResources.ready, this.appPrompts.ready, this.appAgents.ready, this.appSkills.ready]);
|
|
18607
|
+
this.logger?.verbose(
|
|
18608
|
+
`App ${this.metadata.name}: ${this.appResources.getResources().length} resource(s) registered`
|
|
18609
|
+
);
|
|
18610
|
+
this.logger?.verbose(`App ${this.metadata.name}: ${this.appPrompts.getPrompts().length} prompt(s) registered`);
|
|
18611
|
+
const parts = [];
|
|
18612
|
+
const toolCount = this.appTools.getTools(true).length;
|
|
18613
|
+
const resourceCount = this.appResources.getResources().length;
|
|
18614
|
+
const promptCount = this.appPrompts.getPrompts().length;
|
|
18615
|
+
const adapterCount = this.appAdapters.getAdapters().length;
|
|
18616
|
+
const pluginCount = this.appPlugins.getPlugins().length;
|
|
18617
|
+
if (toolCount > 0) parts.push(`${toolCount} tool${toolCount !== 1 ? "s" : ""}`);
|
|
18618
|
+
if (resourceCount > 0) parts.push(`${resourceCount} resource${resourceCount !== 1 ? "s" : ""}`);
|
|
18619
|
+
if (promptCount > 0) parts.push(`${promptCount} prompt${promptCount !== 1 ? "s" : ""}`);
|
|
18620
|
+
if (adapterCount > 0) parts.push(`${adapterCount} adapter${adapterCount !== 1 ? "s" : ""}`);
|
|
18621
|
+
if (pluginCount > 0) parts.push(`${pluginCount} plugin${pluginCount !== 1 ? "s" : ""}`);
|
|
18622
|
+
this.logger?.info(`${this.metadata.name}: ${parts.length > 0 ? parts.join(", ") : "no entries"}`);
|
|
18490
18623
|
}
|
|
18491
18624
|
get providers() {
|
|
18492
18625
|
return this.appProviders;
|
|
@@ -20152,6 +20285,9 @@ var init_app_remote_instance = __esm({
|
|
|
20152
20285
|
getPlugins() {
|
|
20153
20286
|
return [];
|
|
20154
20287
|
}
|
|
20288
|
+
getPluginNames() {
|
|
20289
|
+
return [];
|
|
20290
|
+
}
|
|
20155
20291
|
};
|
|
20156
20292
|
EmptyAdapterRegistry = class {
|
|
20157
20293
|
getAdapters() {
|
|
@@ -20532,15 +20668,21 @@ var AppRegistry;
|
|
|
20532
20668
|
var init_app_registry = __esm({
|
|
20533
20669
|
"libs/sdk/src/app/app.registry.ts"() {
|
|
20534
20670
|
"use strict";
|
|
20671
|
+
init_common();
|
|
20535
20672
|
init_app_utils();
|
|
20536
20673
|
init_regsitry();
|
|
20537
20674
|
init_instances();
|
|
20538
20675
|
init_errors();
|
|
20539
20676
|
AppRegistry = class extends RegistryAbstract {
|
|
20540
20677
|
owner;
|
|
20678
|
+
logger;
|
|
20541
20679
|
constructor(globalProviders, list, owner) {
|
|
20542
20680
|
super("AppRegistry", globalProviders, list);
|
|
20543
20681
|
this.owner = owner;
|
|
20682
|
+
try {
|
|
20683
|
+
this.logger = globalProviders.get(FrontMcpLogger)?.child("AppRegistry");
|
|
20684
|
+
} catch {
|
|
20685
|
+
}
|
|
20544
20686
|
}
|
|
20545
20687
|
buildMap(list) {
|
|
20546
20688
|
const tokens = /* @__PURE__ */ new Set();
|
|
@@ -20569,6 +20711,7 @@ var init_app_registry = __esm({
|
|
|
20569
20711
|
}
|
|
20570
20712
|
/** Instantiate adapters, run fetch/transform, and populate registries. */
|
|
20571
20713
|
async initialize() {
|
|
20714
|
+
this.logger?.verbose(`AppRegistry: initializing ${this.tokens.size} app(s)`);
|
|
20572
20715
|
const readyArr = [];
|
|
20573
20716
|
for (const token of this.tokens) {
|
|
20574
20717
|
const rec = this.defs.get(token);
|
|
@@ -20582,8 +20725,10 @@ var init_app_registry = __esm({
|
|
|
20582
20725
|
}
|
|
20583
20726
|
this.instances.set(token, app);
|
|
20584
20727
|
readyArr.push(app.ready);
|
|
20728
|
+
this.logger?.verbose(`AppRegistry: registered ${rec.kind} app '${rec.metadata.name}'`);
|
|
20585
20729
|
}
|
|
20586
20730
|
await Promise.all(readyArr);
|
|
20731
|
+
this.logger?.debug(`AppRegistry: initialization complete (${this.instances.size} app(s))`);
|
|
20587
20732
|
}
|
|
20588
20733
|
getApps() {
|
|
20589
20734
|
return [...this.instances.values()];
|
|
@@ -21123,12 +21268,19 @@ var init_session_verify_flow = __esm({
|
|
|
21123
21268
|
name13 = "session:verify";
|
|
21124
21269
|
Stage13 = StageHookOf(name13);
|
|
21125
21270
|
SessionVerifyFlow = class extends FlowBase {
|
|
21271
|
+
logger = this.scopeLogger.child("SessionVerifyFlow");
|
|
21272
|
+
maskSub(sub) {
|
|
21273
|
+
if (!sub) return "***";
|
|
21274
|
+
if (sub.length <= 10) return "***" + sub.slice(-4);
|
|
21275
|
+
return sub.slice(0, 6) + "***" + sub.slice(-4);
|
|
21276
|
+
}
|
|
21126
21277
|
/**
|
|
21127
21278
|
* Create an anonymous session with consistent structure for both public and transparent-anon modes.
|
|
21128
21279
|
* Encapsulates the shared logic for session creation, payload encryption, and user derivation.
|
|
21129
21280
|
*/
|
|
21130
21281
|
createAnonymousSession(options) {
|
|
21131
21282
|
const { authMode, issuer, scopes = ["anonymous"], sessionIdHeader } = options;
|
|
21283
|
+
this.logger.verbose("createAnonymousSession", { authMode, hasExistingSession: !!sessionIdHeader });
|
|
21132
21284
|
const machineId = getMachineId2();
|
|
21133
21285
|
if (sessionIdHeader) {
|
|
21134
21286
|
const existingPayload = decryptPublicSession(sessionIdHeader);
|
|
@@ -21191,6 +21343,12 @@ var init_session_verify_flow = __esm({
|
|
|
21191
21343
|
const userAgent = request.headers?.["user-agent"] ?? void 0;
|
|
21192
21344
|
const prmMetadataPath = `/.well-known/oauth-protected-resource${entryPath}${routeBase}`;
|
|
21193
21345
|
const prmMetadataHeader = `Bearer resource_metadata="${baseUrl}${prmMetadataPath}"`;
|
|
21346
|
+
this.logger.verbose("parseInput", {
|
|
21347
|
+
hasAuthHeader: !!authorizationHeader,
|
|
21348
|
+
hasToken: !!token,
|
|
21349
|
+
sessionProtocol,
|
|
21350
|
+
hasSessionId: !!sessionIdHeader
|
|
21351
|
+
});
|
|
21194
21352
|
this.state.set({
|
|
21195
21353
|
baseUrl,
|
|
21196
21354
|
authorizationHeader,
|
|
@@ -21210,6 +21368,7 @@ var init_session_verify_flow = __esm({
|
|
|
21210
21368
|
if (this.state.token) {
|
|
21211
21369
|
return;
|
|
21212
21370
|
}
|
|
21371
|
+
this.logger.info("handlePublicMode: allowing anonymous access (public mode)");
|
|
21213
21372
|
this.createAnonymousSession({
|
|
21214
21373
|
authMode: "public",
|
|
21215
21374
|
issuer: "public",
|
|
@@ -21218,6 +21377,7 @@ var init_session_verify_flow = __esm({
|
|
|
21218
21377
|
});
|
|
21219
21378
|
}
|
|
21220
21379
|
async handleAnonymousFallback() {
|
|
21380
|
+
this.logger.verbose("handleAnonymousFallback: creating anonymous session (transparent-anon)");
|
|
21221
21381
|
const authOptions = this.scope.auth?.options;
|
|
21222
21382
|
const scopes = authOptions?.anonymousScopes ?? ["anonymous"];
|
|
21223
21383
|
this.createAnonymousSession({
|
|
@@ -21228,6 +21388,7 @@ var init_session_verify_flow = __esm({
|
|
|
21228
21388
|
});
|
|
21229
21389
|
}
|
|
21230
21390
|
async requireAuthorizationOrChallenge() {
|
|
21391
|
+
this.logger.verbose("requireAuthorizationOrChallenge: returning 401");
|
|
21231
21392
|
this.respond({
|
|
21232
21393
|
kind: "unauthorized",
|
|
21233
21394
|
prmMetadataHeader: this.state.required.prmMetadataHeader
|
|
@@ -21237,6 +21398,7 @@ var init_session_verify_flow = __esm({
|
|
|
21237
21398
|
const jwks = this.get(JwksService2);
|
|
21238
21399
|
const token = this.state.token;
|
|
21239
21400
|
if (!token) {
|
|
21401
|
+
this.logger.warn("verifyIfJwt: missing or empty bearer token, returning 401");
|
|
21240
21402
|
this.respond({
|
|
21241
21403
|
kind: "unauthorized",
|
|
21242
21404
|
prmMetadataHeader: this.state.required.prmMetadataHeader
|
|
@@ -21244,6 +21406,7 @@ var init_session_verify_flow = __esm({
|
|
|
21244
21406
|
return;
|
|
21245
21407
|
}
|
|
21246
21408
|
if (!isJwt(token)) {
|
|
21409
|
+
this.logger.warn("verifyIfJwt: token is not a JWT, returning 401");
|
|
21247
21410
|
this.respond({
|
|
21248
21411
|
kind: "unauthorized",
|
|
21249
21412
|
prmMetadataHeader: this.state.required.prmMetadataHeader
|
|
@@ -21252,6 +21415,7 @@ var init_session_verify_flow = __esm({
|
|
|
21252
21415
|
}
|
|
21253
21416
|
const auth = this.scope.auth;
|
|
21254
21417
|
if (!auth) {
|
|
21418
|
+
this.logger.warn("verifyIfJwt: auth registry not available, returning 401");
|
|
21255
21419
|
this.respond({
|
|
21256
21420
|
kind: "unauthorized",
|
|
21257
21421
|
prmMetadataHeader: this.state.required.prmMetadataHeader
|
|
@@ -21260,6 +21424,8 @@ var init_session_verify_flow = __esm({
|
|
|
21260
21424
|
}
|
|
21261
21425
|
let verify;
|
|
21262
21426
|
const authOptions = auth.options;
|
|
21427
|
+
const mode = isTransparentMode(authOptions) ? "transparent" : "gateway";
|
|
21428
|
+
this.logger.verbose(`verifyIfJwt: verifying using ${mode} mode`);
|
|
21263
21429
|
if (isTransparentMode(authOptions)) {
|
|
21264
21430
|
const primary = authOptions;
|
|
21265
21431
|
const issuer = auth.issuer;
|
|
@@ -21280,6 +21446,7 @@ var init_session_verify_flow = __esm({
|
|
|
21280
21446
|
this.state.set({ jwtPayload: result.payload });
|
|
21281
21447
|
return;
|
|
21282
21448
|
}
|
|
21449
|
+
this.logger.warn("verifyIfJwt: JWT verification failed", { error: result.error });
|
|
21283
21450
|
this.respond({
|
|
21284
21451
|
kind: "unauthorized",
|
|
21285
21452
|
prmMetadataHeader: this.state.required.prmMetadataHeader
|
|
@@ -21294,6 +21461,7 @@ var init_session_verify_flow = __esm({
|
|
|
21294
21461
|
required: { token }
|
|
21295
21462
|
} = this.state;
|
|
21296
21463
|
const session = parseSessionHeader(sessionIdHeader, token);
|
|
21464
|
+
this.logger.verbose("parseSessionHeader", { hasSessionId: !!sessionIdHeader, parsed: !!session });
|
|
21297
21465
|
if (session) {
|
|
21298
21466
|
this.state.set("session", session);
|
|
21299
21467
|
}
|
|
@@ -21303,6 +21471,10 @@ var init_session_verify_flow = __esm({
|
|
|
21303
21471
|
required: { token, user },
|
|
21304
21472
|
session
|
|
21305
21473
|
} = this.state;
|
|
21474
|
+
this.logger.info("Session verified successfully", {
|
|
21475
|
+
sub: this.maskSub(user.sub),
|
|
21476
|
+
hasSession: !!session
|
|
21477
|
+
});
|
|
21306
21478
|
this.respond({
|
|
21307
21479
|
kind: "authorized",
|
|
21308
21480
|
authorization: {
|
|
@@ -25178,9 +25350,12 @@ function listToolsRequestHandler({
|
|
|
25178
25350
|
return {
|
|
25179
25351
|
requestSchema: ListToolsRequestSchema2,
|
|
25180
25352
|
handler: async (request, ctx) => {
|
|
25181
|
-
logger.verbose("tools/list
|
|
25353
|
+
logger.verbose("tools/list requested");
|
|
25354
|
+
const start = Date.now();
|
|
25182
25355
|
try {
|
|
25183
|
-
|
|
25356
|
+
const result = await scope.runFlowForOutput("tools:list-tools", { request, ctx });
|
|
25357
|
+
logger.verbose("tools/list completed", { durationMs: Date.now() - start });
|
|
25358
|
+
return result;
|
|
25184
25359
|
} catch (e) {
|
|
25185
25360
|
logger.error("tools/list failed", {
|
|
25186
25361
|
error: e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e
|
|
@@ -25209,9 +25384,12 @@ function callToolRequestHandler({
|
|
|
25209
25384
|
requestSchema: CallToolRequestSchema2,
|
|
25210
25385
|
handler: async (request, ctx) => {
|
|
25211
25386
|
const toolName = request.params?.name || "unknown";
|
|
25212
|
-
logger.
|
|
25387
|
+
logger.info(`tools/call: ${toolName}`);
|
|
25388
|
+
const start = Date.now();
|
|
25213
25389
|
try {
|
|
25214
|
-
|
|
25390
|
+
const result = await scope.runFlowForOutput("tools:call-tool", { request, ctx });
|
|
25391
|
+
logger.verbose("tools/call completed", { tool: toolName, durationMs: Date.now() - start });
|
|
25392
|
+
return result;
|
|
25215
25393
|
} catch (e) {
|
|
25216
25394
|
if (e instanceof FlowControl) {
|
|
25217
25395
|
if (e.type === "respond") {
|
|
@@ -25256,9 +25434,12 @@ function listResourcesRequestHandler({
|
|
|
25256
25434
|
return {
|
|
25257
25435
|
requestSchema: ListResourcesRequestSchema2,
|
|
25258
25436
|
handler: async (request, ctx) => {
|
|
25259
|
-
logger.verbose("resources/list
|
|
25437
|
+
logger.verbose("resources/list requested");
|
|
25438
|
+
const start = Date.now();
|
|
25260
25439
|
try {
|
|
25261
|
-
|
|
25440
|
+
const result = await scope.runFlowForOutput("resources:list-resources", { request, ctx });
|
|
25441
|
+
logger.verbose("resources/list completed", { durationMs: Date.now() - start });
|
|
25442
|
+
return result;
|
|
25262
25443
|
} catch (e) {
|
|
25263
25444
|
logger.error("resources/list failed", {
|
|
25264
25445
|
error: e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e
|
|
@@ -25285,9 +25466,12 @@ function listResourceTemplatesRequestHandler({
|
|
|
25285
25466
|
return {
|
|
25286
25467
|
requestSchema: ListResourceTemplatesRequestSchema2,
|
|
25287
25468
|
handler: async (request, ctx) => {
|
|
25288
|
-
logger.verbose("resources/listTemplates
|
|
25469
|
+
logger.verbose("resources/listTemplates requested");
|
|
25470
|
+
const start = Date.now();
|
|
25289
25471
|
try {
|
|
25290
|
-
|
|
25472
|
+
const result = await scope.runFlowForOutput("resources:list-resource-templates", { request, ctx });
|
|
25473
|
+
logger.verbose("resources/listTemplates completed", { durationMs: Date.now() - start });
|
|
25474
|
+
return result;
|
|
25291
25475
|
} catch (e) {
|
|
25292
25476
|
logger.error("resources/listTemplates failed", {
|
|
25293
25477
|
error: e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e
|
|
@@ -25313,9 +25497,12 @@ function readResourceRequestHandler({
|
|
|
25313
25497
|
requestSchema: ReadResourceRequestSchema2,
|
|
25314
25498
|
handler: async (request, ctx) => {
|
|
25315
25499
|
const uri = request.params?.uri || "unknown";
|
|
25316
|
-
logger.
|
|
25500
|
+
logger.info(`resources/read: ${uri}`);
|
|
25501
|
+
const start = Date.now();
|
|
25317
25502
|
try {
|
|
25318
|
-
|
|
25503
|
+
const result = await scope.runFlowForOutput("resources:read-resource", { request, ctx });
|
|
25504
|
+
logger.verbose("resources/read completed", { uri, durationMs: Date.now() - start });
|
|
25505
|
+
return result;
|
|
25319
25506
|
} catch (e) {
|
|
25320
25507
|
logger.error("resources/read failed", {
|
|
25321
25508
|
uri,
|
|
@@ -25346,9 +25533,9 @@ function SubscribeRequestHandler({ scope }) {
|
|
|
25346
25533
|
}
|
|
25347
25534
|
const isNew = scope.notifications.subscribeResource(sessionId, uri);
|
|
25348
25535
|
if (isNew) {
|
|
25349
|
-
scope.logger.
|
|
25536
|
+
scope.logger.info(`resources/subscribe: Session ${sessionId.slice(0, 20)}... subscribed to ${uri}`);
|
|
25350
25537
|
} else {
|
|
25351
|
-
scope.logger.
|
|
25538
|
+
scope.logger.debug(`resources/subscribe: Session ${sessionId.slice(0, 20)}... already subscribed to ${uri}`);
|
|
25352
25539
|
}
|
|
25353
25540
|
return {};
|
|
25354
25541
|
}
|
|
@@ -25374,11 +25561,9 @@ function UnsubscribeRequestHandler({ scope }) {
|
|
|
25374
25561
|
}
|
|
25375
25562
|
const wasSubscribed = scope.notifications.unsubscribeResource(sessionId, uri);
|
|
25376
25563
|
if (wasSubscribed) {
|
|
25377
|
-
scope.logger.
|
|
25564
|
+
scope.logger.info(`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... unsubscribed from ${uri}`);
|
|
25378
25565
|
} else {
|
|
25379
|
-
scope.logger.
|
|
25380
|
-
`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... was not subscribed to ${uri}`
|
|
25381
|
-
);
|
|
25566
|
+
scope.logger.debug(`resources/unsubscribe: Session ${sessionId.slice(0, 20)}... was not subscribed to ${uri}`);
|
|
25382
25567
|
}
|
|
25383
25568
|
return {};
|
|
25384
25569
|
}
|
|
@@ -25399,9 +25584,12 @@ function listPromptsRequestHandler({
|
|
|
25399
25584
|
return {
|
|
25400
25585
|
requestSchema: ListPromptsRequestSchema2,
|
|
25401
25586
|
handler: async (request, ctx) => {
|
|
25402
|
-
logger.verbose("prompts/list
|
|
25587
|
+
logger.verbose("prompts/list requested");
|
|
25588
|
+
const start = Date.now();
|
|
25403
25589
|
try {
|
|
25404
|
-
|
|
25590
|
+
const result = await scope.runFlowForOutput("prompts:list-prompts", { request, ctx });
|
|
25591
|
+
logger.verbose("prompts/list completed", { durationMs: Date.now() - start });
|
|
25592
|
+
return result;
|
|
25405
25593
|
} catch (e) {
|
|
25406
25594
|
logger.error("prompts/list failed", {
|
|
25407
25595
|
error: e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e
|
|
@@ -25427,9 +25615,12 @@ function getPromptRequestHandler({
|
|
|
25427
25615
|
requestSchema: GetPromptRequestSchema2,
|
|
25428
25616
|
handler: async (request, ctx) => {
|
|
25429
25617
|
const promptName = request.params?.name || "unknown";
|
|
25430
|
-
logger.
|
|
25618
|
+
logger.info(`prompts/get: ${promptName}`);
|
|
25619
|
+
const start = Date.now();
|
|
25431
25620
|
try {
|
|
25432
|
-
|
|
25621
|
+
const result = await scope.runFlowForOutput("prompts:get-prompt", { request, ctx });
|
|
25622
|
+
logger.verbose("prompts/get completed", { prompt: promptName, durationMs: Date.now() - start });
|
|
25623
|
+
return result;
|
|
25433
25624
|
} catch (e) {
|
|
25434
25625
|
logger.error("prompts/get failed", {
|
|
25435
25626
|
prompt: promptName,
|
|
@@ -25455,9 +25646,12 @@ function completeRequestHandler({
|
|
|
25455
25646
|
return {
|
|
25456
25647
|
requestSchema: CompleteRequestSchema,
|
|
25457
25648
|
handler: async (request, ctx) => {
|
|
25458
|
-
logger.verbose("completion/complete
|
|
25649
|
+
logger.verbose("completion/complete requested");
|
|
25650
|
+
const start = Date.now();
|
|
25459
25651
|
try {
|
|
25460
|
-
|
|
25652
|
+
const result = await scope.runFlowForOutput("completion:complete", { request, ctx });
|
|
25653
|
+
logger.verbose("completion/complete completed", { durationMs: Date.now() - start });
|
|
25654
|
+
return result;
|
|
25461
25655
|
} catch (e) {
|
|
25462
25656
|
logger.error("completion/complete failed", {
|
|
25463
25657
|
error: e instanceof Error ? { name: e.name, message: e.message, stack: e.stack } : e
|
|
@@ -25708,6 +25902,9 @@ function formatSkillsForLlmCompact(skills) {
|
|
|
25708
25902
|
if (tags && tags.length > 0) {
|
|
25709
25903
|
lines.push(`Tags: ${tags.join(", ")}`);
|
|
25710
25904
|
}
|
|
25905
|
+
if (skill.metadata.license) {
|
|
25906
|
+
lines.push(`License: ${skill.metadata.license}`);
|
|
25907
|
+
}
|
|
25711
25908
|
parts.push(lines.join("\n"));
|
|
25712
25909
|
}
|
|
25713
25910
|
return parts.join("\n\n---\n\n");
|
|
@@ -25734,6 +25931,14 @@ function formatSkillForLLMWithSchemas(skill, availableTools, missingTools, toolR
|
|
|
25734
25931
|
parts.push("");
|
|
25735
25932
|
parts.push(skill.description);
|
|
25736
25933
|
parts.push("");
|
|
25934
|
+
if (skill.license) {
|
|
25935
|
+
parts.push(`**License:** ${skill.license}`);
|
|
25936
|
+
parts.push("");
|
|
25937
|
+
}
|
|
25938
|
+
if (skill.compatibility) {
|
|
25939
|
+
parts.push(`**Compatibility:** ${skill.compatibility}`);
|
|
25940
|
+
parts.push("");
|
|
25941
|
+
}
|
|
25737
25942
|
if (missingTools.length > 0) {
|
|
25738
25943
|
parts.push("> **Warning:** Some tools are not available:");
|
|
25739
25944
|
parts.push(`> Missing: ${missingTools.join(", ")}`);
|
|
@@ -25818,7 +26023,12 @@ function skillToApiResponse(skill, loadResult) {
|
|
|
25818
26023
|
type: p.type ?? "string"
|
|
25819
26024
|
})),
|
|
25820
26025
|
priority: skill.metadata.priority ?? 0,
|
|
25821
|
-
visibility: skill.metadata.visibility ?? "both"
|
|
26026
|
+
visibility: skill.metadata.visibility ?? "both",
|
|
26027
|
+
license: skill.metadata.license,
|
|
26028
|
+
compatibility: skill.metadata.compatibility,
|
|
26029
|
+
specMetadata: skill.metadata.specMetadata,
|
|
26030
|
+
allowedTools: skill.metadata.allowedTools,
|
|
26031
|
+
resources: skill.metadata.resources
|
|
25822
26032
|
};
|
|
25823
26033
|
if (loadResult) {
|
|
25824
26034
|
result.availableTools = loadResult.availableTools;
|
|
@@ -28435,10 +28645,12 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28435
28645
|
const { request } = this.rawInput;
|
|
28436
28646
|
const authorization = request[ServerRequestTokens.auth];
|
|
28437
28647
|
const { token } = authorization;
|
|
28648
|
+
const logger = this.scopeLogger.child("handle:streamable-http:parseInput");
|
|
28438
28649
|
const raw = request.headers?.["mcp-session-id"];
|
|
28439
28650
|
const rawMcpSessionHeader = typeof raw === "string" ? raw : void 0;
|
|
28440
28651
|
const mcpSessionHeader = validateMcpSessionHeader(rawMcpSessionHeader);
|
|
28441
28652
|
if (raw !== void 0 && !mcpSessionHeader) {
|
|
28653
|
+
logger.warn("parseInput: invalid mcp-session-id header");
|
|
28442
28654
|
this.respond(httpRespond.sessionNotFound("invalid session id"));
|
|
28443
28655
|
return;
|
|
28444
28656
|
}
|
|
@@ -28461,24 +28673,32 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28461
28673
|
});
|
|
28462
28674
|
}
|
|
28463
28675
|
this.state.set(stateSchema18.parse({ token, session }));
|
|
28676
|
+
logger.info("parseInput: session resolved", { sessionId: session.id?.slice(0, 20) });
|
|
28464
28677
|
}
|
|
28465
28678
|
async router() {
|
|
28466
28679
|
const { request } = this.rawInput;
|
|
28680
|
+
const logger = this.scopeLogger.child("handle:streamable-http:router");
|
|
28467
28681
|
if (request.method.toUpperCase() === "GET") {
|
|
28468
28682
|
this.state.set("requestType", "sseListener");
|
|
28683
|
+
logger.info("router: requestType=sseListener, method=GET");
|
|
28469
28684
|
return;
|
|
28470
28685
|
}
|
|
28471
28686
|
const body = request.body;
|
|
28472
28687
|
const method = body?.method;
|
|
28473
28688
|
if (method === "initialize") {
|
|
28474
28689
|
this.state.set("requestType", "initialize");
|
|
28690
|
+
logger.info("router: requestType=initialize, method=POST");
|
|
28475
28691
|
} else if (typeof method === "string" && method.startsWith("ui/")) {
|
|
28476
28692
|
this.state.set("requestType", "extApps");
|
|
28693
|
+
logger.info(`router: requestType=extApps, method=${method}`);
|
|
28477
28694
|
} else if (ElicitResultSchema2.safeParse(request.body?.result).success) {
|
|
28478
28695
|
this.state.set("requestType", "elicitResult");
|
|
28696
|
+
logger.info("router: requestType=elicitResult, method=POST");
|
|
28479
28697
|
} else if (method && RequestSchema.safeParse(request.body).success) {
|
|
28480
28698
|
this.state.set("requestType", "message");
|
|
28699
|
+
logger.info(`router: requestType=message, method=${method}`);
|
|
28481
28700
|
} else {
|
|
28701
|
+
logger.warn("router: invalid request, no valid method");
|
|
28482
28702
|
this.respond(httpRespond.rpcError("Invalid Request"));
|
|
28483
28703
|
}
|
|
28484
28704
|
}
|
|
@@ -28488,7 +28708,7 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28488
28708
|
const { request, response } = this.rawInput;
|
|
28489
28709
|
const { token, session } = this.state.required;
|
|
28490
28710
|
logger.info("onInitialize: creating transport", {
|
|
28491
|
-
sessionId: session.id
|
|
28711
|
+
sessionId: session.id?.slice(0, 20),
|
|
28492
28712
|
hasToken: !!token,
|
|
28493
28713
|
tokenPrefix: token?.slice(0, 10)
|
|
28494
28714
|
});
|
|
@@ -28521,12 +28741,12 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28521
28741
|
let transport = await transportService.getTransporter("streamable-http", token, session.id);
|
|
28522
28742
|
if (!transport) {
|
|
28523
28743
|
try {
|
|
28524
|
-
logger.
|
|
28744
|
+
logger.verbose("onElicitResult: transport not in memory, checking stored session", {
|
|
28525
28745
|
sessionId: session.id?.slice(0, 20)
|
|
28526
28746
|
});
|
|
28527
28747
|
const storedSession = await transportService.getStoredSession("streamable-http", token, session.id);
|
|
28528
28748
|
if (storedSession) {
|
|
28529
|
-
logger.
|
|
28749
|
+
logger.verbose("onElicitResult: recreating transport from stored session", {
|
|
28530
28750
|
sessionId: session.id?.slice(0, 20),
|
|
28531
28751
|
createdAt: storedSession.createdAt,
|
|
28532
28752
|
initialized: storedSession.initialized
|
|
@@ -28569,19 +28789,19 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28569
28789
|
hasToken: !!token
|
|
28570
28790
|
});
|
|
28571
28791
|
let transport = await transportService.getTransporter("streamable-http", token, session.id);
|
|
28572
|
-
logger.
|
|
28792
|
+
logger.verbose("onMessage: getTransporter result", { found: !!transport });
|
|
28573
28793
|
if (!transport) {
|
|
28574
28794
|
try {
|
|
28575
|
-
logger.
|
|
28795
|
+
logger.verbose("onMessage: transport not in memory, checking Redis", {
|
|
28576
28796
|
sessionId: session.id?.slice(0, 20)
|
|
28577
28797
|
});
|
|
28578
28798
|
const storedSession = await transportService.getStoredSession("streamable-http", token, session.id);
|
|
28579
|
-
logger.
|
|
28799
|
+
logger.verbose("onMessage: getStoredSession result", {
|
|
28580
28800
|
found: !!storedSession,
|
|
28581
28801
|
initialized: storedSession?.initialized
|
|
28582
28802
|
});
|
|
28583
28803
|
if (storedSession) {
|
|
28584
|
-
logger.
|
|
28804
|
+
logger.verbose("onMessage: recreating transport from stored session", {
|
|
28585
28805
|
sessionId: session.id?.slice(0, 20),
|
|
28586
28806
|
createdAt: storedSession.createdAt,
|
|
28587
28807
|
initialized: storedSession.initialized
|
|
@@ -28593,7 +28813,7 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28593
28813
|
storedSession,
|
|
28594
28814
|
response
|
|
28595
28815
|
);
|
|
28596
|
-
logger.
|
|
28816
|
+
logger.verbose("onMessage: transport recreated successfully");
|
|
28597
28817
|
}
|
|
28598
28818
|
} catch (error) {
|
|
28599
28819
|
logger.warn("Failed to recreate transport from stored session", {
|
|
@@ -28673,6 +28893,7 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28673
28893
|
}
|
|
28674
28894
|
}
|
|
28675
28895
|
if (!transport) {
|
|
28896
|
+
logger.warn("onSseListener: transport not found", { sessionId: session.id?.slice(0, 20) });
|
|
28676
28897
|
this.respond(httpRespond.notFound("Session not found"));
|
|
28677
28898
|
return;
|
|
28678
28899
|
}
|
|
@@ -28691,12 +28912,12 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28691
28912
|
let transport = await transportService.getTransporter("streamable-http", token, session.id);
|
|
28692
28913
|
if (!transport) {
|
|
28693
28914
|
try {
|
|
28694
|
-
logger.
|
|
28915
|
+
logger.verbose("onExtApps: transport not in memory, checking stored session", {
|
|
28695
28916
|
sessionId: session.id?.slice(0, 20)
|
|
28696
28917
|
});
|
|
28697
28918
|
const storedSession = await transportService.getStoredSession("streamable-http", token, session.id);
|
|
28698
28919
|
if (storedSession) {
|
|
28699
|
-
logger.
|
|
28920
|
+
logger.verbose("onExtApps: recreating transport from stored session", {
|
|
28700
28921
|
sessionId: session.id?.slice(0, 20),
|
|
28701
28922
|
createdAt: storedSession.createdAt,
|
|
28702
28923
|
initialized: storedSession.initialized
|
|
@@ -28719,8 +28940,14 @@ var init_handle_streamable_http_flow = __esm({
|
|
|
28719
28940
|
if (!transport) {
|
|
28720
28941
|
const wasCreated = await transportService.wasSessionCreatedAsync("streamable-http", token, session.id);
|
|
28721
28942
|
if (wasCreated) {
|
|
28943
|
+
logger.info("onExtApps: session expired - client should re-initialize", {
|
|
28944
|
+
sessionId: session.id?.slice(0, 20)
|
|
28945
|
+
});
|
|
28722
28946
|
this.respond(httpRespond.sessionExpired("session expired"));
|
|
28723
28947
|
} else {
|
|
28948
|
+
logger.warn("onExtApps: session not initialized - client attempted request without initializing", {
|
|
28949
|
+
sessionId: session.id?.slice(0, 20)
|
|
28950
|
+
});
|
|
28724
28951
|
this.respond(httpRespond.sessionNotFound("session not initialized"));
|
|
28725
28952
|
}
|
|
28726
28953
|
return;
|
|
@@ -29005,9 +29232,11 @@ var init_handle_stateless_http_flow = __esm({
|
|
|
29005
29232
|
name = name22;
|
|
29006
29233
|
async parseInput() {
|
|
29007
29234
|
const { request } = this.rawInput;
|
|
29235
|
+
const logger = this.scope.logger.child("HandleStatelessHttpFlow");
|
|
29008
29236
|
const auth = request[ServerRequestTokens.auth];
|
|
29009
29237
|
const token = auth?.token;
|
|
29010
29238
|
const isAuthenticated = !!token && token.length > 0;
|
|
29239
|
+
logger.verbose("parseInput", { isAuthenticated, hasToken: !!token });
|
|
29011
29240
|
this.state.set(
|
|
29012
29241
|
stateSchema20.parse({
|
|
29013
29242
|
token: token || void 0,
|
|
@@ -29017,28 +29246,44 @@ var init_handle_stateless_http_flow = __esm({
|
|
|
29017
29246
|
}
|
|
29018
29247
|
async router() {
|
|
29019
29248
|
const { request } = this.rawInput;
|
|
29249
|
+
const logger = this.scope.logger.child("HandleStatelessHttpFlow");
|
|
29020
29250
|
const body = request.body;
|
|
29021
29251
|
const method = body?.method;
|
|
29022
29252
|
if (method === "initialize") {
|
|
29023
29253
|
this.state.set("requestType", "initialize");
|
|
29254
|
+
logger.info("router: requestType=initialize, method=POST");
|
|
29024
29255
|
} else if (method && RequestSchema2.safeParse(request.body).success) {
|
|
29025
29256
|
this.state.set("requestType", "message");
|
|
29257
|
+
logger.info(`router: requestType=message, method=${method}`);
|
|
29026
29258
|
} else {
|
|
29259
|
+
logger.warn("router: invalid request, no valid method");
|
|
29027
29260
|
this.respond(httpRespond.rpcError("Invalid Request"));
|
|
29028
29261
|
}
|
|
29029
29262
|
}
|
|
29030
29263
|
async handleRequest() {
|
|
29031
29264
|
const transportService = this.scope.transportService;
|
|
29265
|
+
const logger = this.scope.logger.child("HandleStatelessHttpFlow");
|
|
29032
29266
|
const { request, response } = this.rawInput;
|
|
29033
29267
|
const { token, isAuthenticated, requestType } = this.state;
|
|
29268
|
+
logger.info(`handleRequest: using ${isAuthenticated ? "authenticated" : "anonymous"} stateless transport`);
|
|
29034
29269
|
const transport = isAuthenticated && token ? await transportService.getOrCreateAuthenticatedStatelessTransport("stateless-http", token, response) : await transportService.getOrCreateAnonymousStatelessTransport("stateless-http", response);
|
|
29035
29270
|
if (!request.headers["mcp-session-id"]) {
|
|
29036
29271
|
request.headers["mcp-session-id"] = "__stateless__";
|
|
29272
|
+
logger.verbose("handleRequest: injected __stateless__ session ID");
|
|
29037
29273
|
}
|
|
29038
|
-
|
|
29039
|
-
|
|
29040
|
-
|
|
29041
|
-
|
|
29274
|
+
logger.verbose(`handleRequest: requestType=${requestType}, forwarding to transport`);
|
|
29275
|
+
try {
|
|
29276
|
+
if (requestType === "initialize") {
|
|
29277
|
+
await transport.initialize(request, response);
|
|
29278
|
+
} else {
|
|
29279
|
+
await transport.handleRequest(request, response);
|
|
29280
|
+
}
|
|
29281
|
+
} catch (error) {
|
|
29282
|
+
logger.error("handleRequest: transport failed", {
|
|
29283
|
+
requestType,
|
|
29284
|
+
error: error instanceof Error ? { name: error.name, message: error.message } : String(error)
|
|
29285
|
+
});
|
|
29286
|
+
throw error;
|
|
29042
29287
|
}
|
|
29043
29288
|
this.handled();
|
|
29044
29289
|
}
|
|
@@ -32877,7 +33122,11 @@ var init_call_agent_flow = __esm({
|
|
|
32877
33122
|
this.logger.info("finalize: sending response", {
|
|
32878
33123
|
agent: agent.metadata.name,
|
|
32879
33124
|
hasContent: Array.isArray(result.content) && result.content.length > 0,
|
|
32880
|
-
|
|
33125
|
+
contentParts: Array.isArray(result.content) ? result.content.length : 0,
|
|
33126
|
+
contentBytes: Array.isArray(result.content) ? result.content.reduce((sum, part) => {
|
|
33127
|
+
const str = JSON.stringify(part);
|
|
33128
|
+
return sum + (typeof Buffer !== "undefined" ? Buffer.byteLength(str, "utf8") : new TextEncoder().encode(str).byteLength);
|
|
33129
|
+
}, 0) : 0,
|
|
32881
33130
|
hasStructuredContent: result.structuredContent !== void 0,
|
|
32882
33131
|
hasMeta: result._meta !== void 0,
|
|
32883
33132
|
metaKeys: result._meta ? Object.keys(result._meta) : [],
|
|
@@ -33326,30 +33575,30 @@ var require_dist = __commonJS({
|
|
|
33326
33575
|
sqliteStorageOptionsSchema: () => sqliteStorageOptionsSchema
|
|
33327
33576
|
});
|
|
33328
33577
|
module.exports = __toCommonJS2(index_exports);
|
|
33329
|
-
var
|
|
33578
|
+
var import_utils56 = __require("@frontmcp/utils");
|
|
33330
33579
|
var HKDF_SALT = new TextEncoder().encode("frontmcp-sqlite-storage-v1");
|
|
33331
33580
|
var HKDF_INFO = new TextEncoder().encode("aes-256-gcm-value-encryption");
|
|
33332
33581
|
var KEY_LENGTH = 32;
|
|
33333
33582
|
function deriveEncryptionKey(secret) {
|
|
33334
33583
|
const ikm = new TextEncoder().encode(secret);
|
|
33335
|
-
return (0,
|
|
33584
|
+
return (0, import_utils56.hkdfSha256)(ikm, HKDF_SALT, HKDF_INFO, KEY_LENGTH);
|
|
33336
33585
|
}
|
|
33337
33586
|
var SEPARATOR = ":";
|
|
33338
33587
|
function encryptValue(key, plaintext) {
|
|
33339
|
-
const iv = (0,
|
|
33588
|
+
const iv = (0, import_utils56.randomBytes)(12);
|
|
33340
33589
|
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
33341
|
-
const { ciphertext, tag } = (0,
|
|
33342
|
-
return [(0,
|
|
33590
|
+
const { ciphertext, tag } = (0, import_utils56.encryptAesGcm)(key, plaintextBytes, iv);
|
|
33591
|
+
return [(0, import_utils56.base64urlEncode)(iv), (0, import_utils56.base64urlEncode)(tag), (0, import_utils56.base64urlEncode)(ciphertext)].join(SEPARATOR);
|
|
33343
33592
|
}
|
|
33344
33593
|
function decryptValue(key, encrypted) {
|
|
33345
33594
|
const parts = encrypted.split(SEPARATOR);
|
|
33346
33595
|
if (parts.length !== 3) {
|
|
33347
33596
|
throw new Error("Invalid encrypted value format");
|
|
33348
33597
|
}
|
|
33349
|
-
const iv = (0,
|
|
33350
|
-
const tag = (0,
|
|
33351
|
-
const ciphertext = (0,
|
|
33352
|
-
const plaintext = (0,
|
|
33598
|
+
const iv = (0, import_utils56.base64urlDecode)(parts[0]);
|
|
33599
|
+
const tag = (0, import_utils56.base64urlDecode)(parts[1]);
|
|
33600
|
+
const ciphertext = (0, import_utils56.base64urlDecode)(parts[2]);
|
|
33601
|
+
const plaintext = (0, import_utils56.decryptAesGcm)(key, ciphertext, iv, tag);
|
|
33353
33602
|
return new TextDecoder().decode(plaintext);
|
|
33354
33603
|
}
|
|
33355
33604
|
var SqliteKvStore = class {
|
|
@@ -34227,10 +34476,13 @@ var init_scope_instance = __esm({
|
|
|
34227
34476
|
const scopeProviders = this.scopeProviders;
|
|
34228
34477
|
this.scopeHooks = new HookRegistry(scopeProviders, []);
|
|
34229
34478
|
await this.scopeHooks.ready;
|
|
34479
|
+
this.logger.verbose("HookRegistry initialized");
|
|
34230
34480
|
this.scopeFlows = new FlowRegistry(scopeProviders, [HttpRequestFlow]);
|
|
34231
34481
|
await this.scopeFlows.ready;
|
|
34482
|
+
this.logger.verbose("FlowRegistry initialized");
|
|
34232
34483
|
const transportConfig = this.metadata.transport;
|
|
34233
34484
|
this.transportService = new TransportService(this, transportConfig?.persistence);
|
|
34485
|
+
this.logger.verbose("TransportService initialized");
|
|
34234
34486
|
const eventStoreConfig = transportConfig?.eventStore;
|
|
34235
34487
|
if (eventStoreConfig?.enabled) {
|
|
34236
34488
|
const { eventStore } = createEventStore(eventStoreConfig, this.logger);
|
|
@@ -34252,7 +34504,10 @@ var init_scope_instance = __esm({
|
|
|
34252
34504
|
}
|
|
34253
34505
|
this.scopeAuth = new AuthRegistry(this, scopeProviders, [], scopeRef, this.metadata.auth);
|
|
34254
34506
|
await this.scopeAuth.ready;
|
|
34507
|
+
this.logger.verbose("AuthRegistry initialized");
|
|
34255
34508
|
this.scopeApps = new AppRegistry(this.scopeProviders, this.metadata.apps, scopeRef);
|
|
34509
|
+
const appCount = this.metadata.apps.length;
|
|
34510
|
+
this.logger.info(`Initializing ${appCount} app(s)...`);
|
|
34256
34511
|
await this.scopeApps.ready;
|
|
34257
34512
|
const serverPlugins = this.metadata.plugins ?? [];
|
|
34258
34513
|
if (serverPlugins.length > 0) {
|
|
@@ -34264,15 +34519,20 @@ var init_scope_instance = __esm({
|
|
|
34264
34519
|
};
|
|
34265
34520
|
this.scopePlugins = new PluginRegistry(this.scopeProviders, serverPlugins, scopeRef, serverPluginScopeInfo);
|
|
34266
34521
|
await this.scopePlugins.ready;
|
|
34522
|
+
const pluginNames = this.scopePlugins.getPluginNames();
|
|
34523
|
+
this.logger.verbose(`PluginRegistry initialized (${pluginNames.length} plugin(s): [${pluginNames.join(", ")}])`);
|
|
34267
34524
|
}
|
|
34268
34525
|
this.scopeTools = new ToolRegistry(this.scopeProviders, [], scopeRef);
|
|
34269
34526
|
await this.scopeTools.ready;
|
|
34527
|
+
const toolNames = this.scopeTools.getTools(true).map((t) => t.metadata.name);
|
|
34528
|
+
this.logger.verbose(`ToolRegistry initialized with initial ${toolNames.length} tool(s): [${toolNames.join(", ")}]`);
|
|
34270
34529
|
if (elicitationEnabled) {
|
|
34271
34530
|
this.registerSendElicitationResultTool(scopeRef);
|
|
34272
34531
|
}
|
|
34273
34532
|
this.toolUIRegistry = new ToolUIRegistry();
|
|
34274
34533
|
this.scopeResources = new ResourceRegistry(this.scopeProviders, [], scopeRef);
|
|
34275
34534
|
await this.scopeResources.ready;
|
|
34535
|
+
this.logger.verbose(`ResourceRegistry initialized (${this.scopeResources.getResources().length} resource(s))`);
|
|
34276
34536
|
const toolsWithUI = this.scopeTools.getTools(true).filter((t) => hasUIConfig(t.metadata));
|
|
34277
34537
|
if (toolsWithUI.length > 0) {
|
|
34278
34538
|
this.scopeResources.registerDynamicResource(StaticWidgetResourceTemplate);
|
|
@@ -34378,10 +34638,13 @@ var init_scope_instance = __esm({
|
|
|
34378
34638
|
}
|
|
34379
34639
|
this.scopePrompts = new PromptRegistry(this.scopeProviders, [], scopeRef);
|
|
34380
34640
|
await this.scopePrompts.ready;
|
|
34641
|
+
this.logger.verbose(`PromptRegistry initialized (${this.scopePrompts.getPrompts().length} prompt(s))`);
|
|
34381
34642
|
this.scopeAgents = new AgentRegistry(this.scopeProviders, [], scopeRef);
|
|
34382
34643
|
await this.scopeAgents.ready;
|
|
34644
|
+
this.logger.verbose(`AgentRegistry initialized (${this.scopeAgents.getAgents().length} agent(s))`);
|
|
34383
34645
|
this.scopeSkills = new SkillRegistry(this.scopeProviders, this.metadata.skills ?? [], scopeRef);
|
|
34384
34646
|
await this.scopeSkills.ready;
|
|
34647
|
+
this.logger.verbose(`SkillRegistry initialized (${this.scopeSkills.getSkills().length} skill(s))`);
|
|
34385
34648
|
if (this.scopeSkills.hasAny()) {
|
|
34386
34649
|
const store = createSkillSessionStore({ type: "memory" });
|
|
34387
34650
|
this._skillSession = new SkillSessionManager(
|
|
@@ -34438,6 +34701,7 @@ var init_scope_instance = __esm({
|
|
|
34438
34701
|
});
|
|
34439
34702
|
this.notificationService = new NotificationService(this);
|
|
34440
34703
|
await this.notificationService.initialize();
|
|
34704
|
+
this.logger.verbose("NotificationService initialized");
|
|
34441
34705
|
await this.scopeFlows.registryFlows([
|
|
34442
34706
|
SetLevelFlow,
|
|
34443
34707
|
CompleteFlow,
|
|
@@ -34446,7 +34710,20 @@ var init_scope_instance = __esm({
|
|
|
34446
34710
|
ElicitationResultFlow
|
|
34447
34711
|
]);
|
|
34448
34712
|
await this.auth.ready;
|
|
34449
|
-
this.logger.info(
|
|
34713
|
+
this.logger.info(`Scope ready \u2014 ${this.formatScopeSummary()}`);
|
|
34714
|
+
}
|
|
34715
|
+
formatScopeSummary() {
|
|
34716
|
+
const entries = [];
|
|
34717
|
+
const add = (count, label) => {
|
|
34718
|
+
if (count > 0) entries.push(`${count} ${label}${count !== 1 ? "s" : ""}`);
|
|
34719
|
+
};
|
|
34720
|
+
add(this.scopeApps.getApps().length, "app");
|
|
34721
|
+
add(this.scopeTools.getTools(true).length, "tool");
|
|
34722
|
+
add(this.scopeResources.getResources().length, "resource");
|
|
34723
|
+
add(this.scopePrompts.getPrompts().length, "prompt");
|
|
34724
|
+
add(this.scopeAgents.getAgents().length, "agent");
|
|
34725
|
+
add(this.scopeSkills.getSkills().length, "skill");
|
|
34726
|
+
return entries.length > 0 ? entries.join(", ") : "empty";
|
|
34450
34727
|
}
|
|
34451
34728
|
get defaultScopeProviders() {
|
|
34452
34729
|
return [
|
|
@@ -34685,6 +34962,7 @@ var ScopeRegistry;
|
|
|
34685
34962
|
var init_scope_registry = __esm({
|
|
34686
34963
|
"libs/sdk/src/scope/scope.registry.ts"() {
|
|
34687
34964
|
"use strict";
|
|
34965
|
+
init_common();
|
|
34688
34966
|
init_regsitry();
|
|
34689
34967
|
init_front_mcp_tokens2();
|
|
34690
34968
|
init_app_utils();
|
|
@@ -34692,9 +34970,11 @@ var init_scope_registry = __esm({
|
|
|
34692
34970
|
init_scope_instance();
|
|
34693
34971
|
init_errors();
|
|
34694
34972
|
ScopeRegistry = class extends RegistryAbstract {
|
|
34973
|
+
logger;
|
|
34695
34974
|
constructor(globalProviders) {
|
|
34696
34975
|
const metadata = globalProviders.get(FrontMcpConfig);
|
|
34697
34976
|
super("ScopeRegistry", globalProviders, metadata);
|
|
34977
|
+
this.logger = globalProviders.get(FrontMcpLogger)?.child("ScopeRegistry");
|
|
34698
34978
|
}
|
|
34699
34979
|
buildMap(metadata) {
|
|
34700
34980
|
const tokens = /* @__PURE__ */ new Set();
|
|
@@ -34751,6 +35031,7 @@ var init_scope_registry = __esm({
|
|
|
34751
35031
|
}
|
|
34752
35032
|
}
|
|
34753
35033
|
async initialize() {
|
|
35034
|
+
this.logger?.verbose(`ScopeRegistry: initializing ${this.tokens.size} scope(s)`);
|
|
34754
35035
|
for (const token of this.tokens) {
|
|
34755
35036
|
const rec = this.defs.get(token);
|
|
34756
35037
|
let scope;
|
|
@@ -34766,7 +35047,9 @@ var init_scope_registry = __esm({
|
|
|
34766
35047
|
}
|
|
34767
35048
|
await scope.ready;
|
|
34768
35049
|
this.instances.set(token, scope);
|
|
35050
|
+
this.logger?.verbose(`ScopeRegistry: initialized scope '${tokenName16(token)}'`);
|
|
34769
35051
|
}
|
|
35052
|
+
this.logger?.verbose(`ScopeRegistry: initialization complete (${this.instances.size} scope(s))`);
|
|
34770
35053
|
}
|
|
34771
35054
|
/**
|
|
34772
35055
|
* Get all initialized scope instances.
|
|
@@ -36201,6 +36484,7 @@ var init_front_mcp = __esm({
|
|
|
36201
36484
|
logger;
|
|
36202
36485
|
providers;
|
|
36203
36486
|
scopes;
|
|
36487
|
+
log;
|
|
36204
36488
|
constructor(config) {
|
|
36205
36489
|
this.config = config;
|
|
36206
36490
|
this.ready = this.initialize();
|
|
@@ -36210,10 +36494,16 @@ var init_front_mcp = __esm({
|
|
|
36210
36494
|
await this.providers.ready;
|
|
36211
36495
|
this.logger = new LoggerRegistry(this.providers);
|
|
36212
36496
|
await this.logger.ready;
|
|
36497
|
+
this.log = this.providers.get(FrontMcpLogger);
|
|
36498
|
+
const name33 = this.config.info?.name;
|
|
36499
|
+
const version = this.config.info?.version;
|
|
36500
|
+
const tag = [name33, version].filter(Boolean).join(" v");
|
|
36501
|
+
this.log?.info(`Initializing FrontMCP${tag ? ` "${tag}"` : ""}...`);
|
|
36213
36502
|
this.scopes = new ScopeRegistry(this.providers);
|
|
36214
36503
|
await this.scopes.ready;
|
|
36215
36504
|
}
|
|
36216
36505
|
async start() {
|
|
36506
|
+
this.log?.info("Starting FrontMCP server...");
|
|
36217
36507
|
const server = this.providers.get(FrontMcpServer);
|
|
36218
36508
|
if (!server) {
|
|
36219
36509
|
throw new ServerNotFoundError();
|
|
@@ -36237,6 +36527,7 @@ var init_front_mcp = __esm({
|
|
|
36237
36527
|
const frontMcp = new _FrontMcpInstance2(options);
|
|
36238
36528
|
await frontMcp.ready;
|
|
36239
36529
|
await frontMcp.start();
|
|
36530
|
+
frontMcp.log?.info("FrontMCP bootstrap complete");
|
|
36240
36531
|
}
|
|
36241
36532
|
/**
|
|
36242
36533
|
* Creates and initializes a FrontMCP instance without starting the HTTP server.
|
|
@@ -36257,6 +36548,7 @@ var init_front_mcp = __esm({
|
|
|
36257
36548
|
throw new ServerNotFoundError();
|
|
36258
36549
|
}
|
|
36259
36550
|
server.prepare();
|
|
36551
|
+
frontMcp.log?.info("FrontMCP handler created (serverless mode)");
|
|
36260
36552
|
return server.getHandler();
|
|
36261
36553
|
}
|
|
36262
36554
|
/**
|
|
@@ -36316,6 +36608,7 @@ var init_front_mcp = __esm({
|
|
|
36316
36608
|
if (scopes.length === 0) {
|
|
36317
36609
|
throw new InternalMcpError("No scopes initialized. Ensure at least one app is configured.");
|
|
36318
36610
|
}
|
|
36611
|
+
frontMcp.log?.info("FrontMCP direct server created");
|
|
36319
36612
|
return new DirectMcpServerImpl(scopes[0]);
|
|
36320
36613
|
}
|
|
36321
36614
|
/**
|
|
@@ -36383,7 +36676,7 @@ var init_front_mcp = __esm({
|
|
|
36383
36676
|
const frontMcp = new _FrontMcpInstance2(parsedConfig);
|
|
36384
36677
|
await frontMcp.ready;
|
|
36385
36678
|
await frontMcp.start();
|
|
36386
|
-
|
|
36679
|
+
frontMcp.log?.info(`MCP server listening on unix://${socketPath}`);
|
|
36387
36680
|
const cleanup = async () => {
|
|
36388
36681
|
try {
|
|
36389
36682
|
if (await fileExists4(socketPath)) {
|
|
@@ -39451,6 +39744,36 @@ var init_skill_entry = __esm({
|
|
|
39451
39744
|
getPriority() {
|
|
39452
39745
|
return this.metadata.priority ?? 0;
|
|
39453
39746
|
}
|
|
39747
|
+
/**
|
|
39748
|
+
* Get the skill's license.
|
|
39749
|
+
*/
|
|
39750
|
+
getLicense() {
|
|
39751
|
+
return this.metadata.license;
|
|
39752
|
+
}
|
|
39753
|
+
/**
|
|
39754
|
+
* Get the skill's compatibility notes.
|
|
39755
|
+
*/
|
|
39756
|
+
getCompatibility() {
|
|
39757
|
+
return this.metadata.compatibility;
|
|
39758
|
+
}
|
|
39759
|
+
/**
|
|
39760
|
+
* Get the skill's spec metadata (arbitrary key-value pairs).
|
|
39761
|
+
*/
|
|
39762
|
+
getSpecMetadata() {
|
|
39763
|
+
return this.metadata.specMetadata;
|
|
39764
|
+
}
|
|
39765
|
+
/**
|
|
39766
|
+
* Get the skill's allowed tools (space-delimited string).
|
|
39767
|
+
*/
|
|
39768
|
+
getAllowedTools() {
|
|
39769
|
+
return this.metadata.allowedTools;
|
|
39770
|
+
}
|
|
39771
|
+
/**
|
|
39772
|
+
* Get the skill's bundled resource directories.
|
|
39773
|
+
*/
|
|
39774
|
+
getResources() {
|
|
39775
|
+
return this.metadata.resources;
|
|
39776
|
+
}
|
|
39454
39777
|
};
|
|
39455
39778
|
}
|
|
39456
39779
|
});
|