@frontmcp/sdk 0.4.0 → 0.4.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "FrontMCP SDK",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"zod": "^3.25.76"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "
|
|
40
|
+
"@modelcontextprotocol/sdk": "1.22.0",
|
|
41
41
|
"axios": "^1.6.0",
|
|
42
42
|
"ioredis": "^5.8.0",
|
|
43
43
|
"jose": "^6.1.0",
|
|
@@ -117,26 +117,46 @@ let ToolsListFlow = class ToolsListFlow extends common_1.FlowBase {
|
|
|
117
117
|
}
|
|
118
118
|
async parseTools() {
|
|
119
119
|
this.logger.verbose('parseTools:start');
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
const resolved = this.state.required.resolvedTools;
|
|
121
|
+
const tools = resolved.map(({ finalName, tool }) => {
|
|
122
|
+
// Get the input schema - prefer rawInputSchema (JSON Schema), then convert from tool.inputSchema
|
|
123
|
+
let inputSchema;
|
|
124
|
+
if (tool.rawInputSchema) {
|
|
125
|
+
// Already converted to JSON Schema
|
|
126
|
+
inputSchema = tool.rawInputSchema;
|
|
127
|
+
}
|
|
128
|
+
else if (tool.inputSchema && Object.keys(tool.inputSchema).length > 0) {
|
|
129
|
+
// tool.inputSchema is a ZodRawShape (extracted .shape from ZodObject in ToolInstance constructor)
|
|
130
|
+
// Convert to JSON Schema
|
|
131
|
+
try {
|
|
132
|
+
// as any used here to prevent hard ts-check on tool input that is redundant
|
|
133
|
+
// and just slow down the build process. types here are unnecessary.
|
|
134
|
+
// eslint-disable-next-line
|
|
135
|
+
inputSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(zod_1.z.object(tool.inputSchema));
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
this.logger.warn(`Failed to convert inputSchema for tool ${finalName}:`, e);
|
|
139
|
+
inputSchema = { type: 'object', properties: {} };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// No schema defined - use empty object schema
|
|
144
|
+
inputSchema = { type: 'object', properties: {} };
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
123
147
|
name: finalName,
|
|
124
148
|
title: tool.metadata.name,
|
|
125
149
|
description: tool.metadata.description,
|
|
126
150
|
annotations: tool.metadata.annotations,
|
|
127
|
-
inputSchema
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
catch (error) {
|
|
137
|
-
this.logger.error('parseTools: failed to parse tools', error);
|
|
138
|
-
throw error;
|
|
139
|
-
}
|
|
151
|
+
inputSchema,
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
const preview = this.sample(tools.map((t) => t.name)).join(', ');
|
|
155
|
+
const extra = tools.length > 5 ? `, +${tools.length - 5} more` : '';
|
|
156
|
+
this.logger.info(`parseTools: prepared ${tools.length} tool descriptor(s): ${preview}${extra}`);
|
|
157
|
+
this.respond({ tools });
|
|
158
|
+
this.logger.info('parseTools: response sent');
|
|
159
|
+
this.logger.verbose('parseTools:done');
|
|
140
160
|
}
|
|
141
161
|
};
|
|
142
162
|
tslib_1.__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools-list.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/tools-list.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// tools/flows/list-tools.flow.ts\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions, ToolEntry } from '../../common';\nimport 'reflect-metadata';\nimport { z } from 'zod';\nimport { ListToolsRequestSchema, ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { InvalidMethodError, InvalidInputError } from '../../errors';\n\nconst inputSchema = z.object({\n request: ListToolsRequestSchema,\n ctx: z.any(),\n});\n\nconst outputSchema = ListToolsResultSchema;\n\nconst stateSchema = z.object({\n cursor: z.string().optional(),\n tools: z.array(\n z.object({\n appName: z.string(),\n tool: z.instanceof(ToolEntry),\n }),\n ),\n resolvedTools: z.array(\n z.object({\n appName: z.string(),\n tool: z.instanceof(ToolEntry),\n finalName: z.string(),\n }),\n ),\n});\n\ntype ResponseToolItem = z.infer<typeof outputSchema>['tools'][number];\n\n// TODO: add support for pagination\n// TODO: add support for session based tools\nconst plan = {\n pre: ['parseInput'],\n execute: ['findTools', 'resolveConflicts'],\n post: ['parseTools'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:list-tools': FlowRunOptions<\n ToolsListFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:list-tools' as const;\nconst { Stage } = FlowHooksOf('tools:list-tools');\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class ToolsListFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('ToolsListFlow');\n\n private sample<T>(arr: T[], n = 5): T[] {\n return arr.slice(0, n);\n }\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: any;\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n } catch (e) {\n throw new InvalidInputError('Invalid request format', e instanceof z.ZodError ? e.errors : undefined);\n }\n\n if (method !== 'tools/list') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'tools/list');\n }\n\n const cursor = params?.cursor;\n if (cursor) this.logger.verbose(`parseInput: cursor=${cursor}`);\n this.state.set('cursor', cursor);\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('findTools')\n async findTools() {\n this.logger.info('findTools:start');\n\n try {\n const apps = this.scope.apps.getApps();\n this.logger.info(`findTools: discovered ${apps.length} app(s)`);\n\n const tools: Array<{ appName: string; tool: ToolEntry }> = [];\n\n const scopeTools = this.scope.tools.getTools();\n this.logger.verbose(`findTools: scope tools=${scopeTools.length}`);\n\n for (const tool of scopeTools) {\n tools.push({ appName: tool.owner.id, tool });\n }\n\n this.logger.info(`findTools: total tools collected=${tools.length}`);\n if (tools.length === 0) {\n this.logger.warn('findTools: no tools found across apps');\n }\n\n this.state.set('tools', tools);\n this.logger.verbose('findTools:done');\n } catch (error) {\n this.logger.error('findTools: failed to collect tools', error);\n throw error;\n }\n }\n\n @Stage('resolveConflicts')\n async resolveConflicts() {\n this.logger.verbose('resolveConflicts:start');\n\n try {\n const found = this.state.required.tools;\n\n const counts = new Map<string, number>();\n for (const { tool } of found) {\n const baseName = tool.metadata.id ?? tool.metadata.name;\n counts.set(baseName, (counts.get(baseName) ?? 0) + 1);\n }\n\n const conflicts = new Set<string>([...counts.entries()].filter(([, n]) => n > 1).map(([k]) => k));\n\n if (conflicts.size > 0) {\n const preview = this.sample(Array.from(conflicts)).join(', ');\n const extra = conflicts.size > 5 ? `, +${conflicts.size - 5} more` : '';\n this.logger.warn(`resolveConflicts: ${conflicts.size} name conflict(s) detected: ${preview}${extra}`);\n } else {\n this.logger.info('resolveConflicts: no name conflicts detected');\n }\n\n const resolved = found.map(({ appName, tool }) => {\n const baseName = tool.metadata.id ?? tool.metadata.name;\n const finalName = conflicts.has(baseName) ? `${appName}:${baseName}` : baseName;\n return { appName, tool, finalName };\n });\n\n this.state.set('resolvedTools', resolved);\n this.logger.verbose('resolveConflicts:done');\n } catch (error) {\n this.logger.error('resolveConflicts: failed to resolve conflicts', error);\n throw error;\n }\n }\n\n @Stage('parseTools')\n async parseTools() {\n this.logger.verbose('parseTools:start');\n\n try {\n const resolved = this.state.required.resolvedTools;\n\n const tools: ResponseToolItem[] = resolved.map(({ finalName, tool }) => ({\n name: finalName,\n title: tool.metadata.name,\n description: tool.metadata.description,\n annotations: tool.metadata.annotations,\n inputSchema:\n (tool.metadata as any).rawInputSchema ?? (zodToJsonSchema(z.object(tool.metadata.inputSchema) as any) as any),\n }));\n\n const preview = this.sample(tools.map((t) => t.name)).join(', ');\n const extra = tools.length > 5 ? `, +${tools.length - 5} more` : '';\n this.logger.info(`parseTools: prepared ${tools.length} tool descriptor(s): ${preview}${extra}`);\n\n this.respond({ tools });\n this.logger.info('parseTools: response sent');\n this.logger.verbose('parseTools:done');\n } catch (error) {\n this.logger.error('parseTools: failed to parse tools', error);\n throw error;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tools-list.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/tools-list.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// tools/flows/list-tools.flow.ts\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions, ToolEntry } from '../../common';\nimport 'reflect-metadata';\nimport { z } from 'zod';\nimport { ListToolsRequestSchema, ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { InvalidMethodError, InvalidInputError } from '../../errors';\n\nconst inputSchema = z.object({\n request: ListToolsRequestSchema,\n ctx: z.any(),\n});\n\nconst outputSchema = ListToolsResultSchema;\n\nconst stateSchema = z.object({\n cursor: z.string().optional(),\n tools: z.array(\n z.object({\n appName: z.string(),\n tool: z.instanceof(ToolEntry),\n }),\n ),\n resolvedTools: z.array(\n z.object({\n appName: z.string(),\n tool: z.instanceof(ToolEntry),\n finalName: z.string(),\n }),\n ),\n});\n\ntype ResponseToolItem = z.infer<typeof outputSchema>['tools'][number];\n\n// TODO: add support for pagination\n// TODO: add support for session based tools\nconst plan = {\n pre: ['parseInput'],\n execute: ['findTools', 'resolveConflicts'],\n post: ['parseTools'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:list-tools': FlowRunOptions<\n ToolsListFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:list-tools' as const;\nconst { Stage } = FlowHooksOf('tools:list-tools');\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class ToolsListFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('ToolsListFlow');\n\n private sample<T>(arr: T[], n = 5): T[] {\n return arr.slice(0, n);\n }\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: any;\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n } catch (e) {\n throw new InvalidInputError('Invalid request format', e instanceof z.ZodError ? e.errors : undefined);\n }\n\n if (method !== 'tools/list') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'tools/list');\n }\n\n const cursor = params?.cursor;\n if (cursor) this.logger.verbose(`parseInput: cursor=${cursor}`);\n this.state.set('cursor', cursor);\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('findTools')\n async findTools() {\n this.logger.info('findTools:start');\n\n try {\n const apps = this.scope.apps.getApps();\n this.logger.info(`findTools: discovered ${apps.length} app(s)`);\n\n const tools: Array<{ appName: string; tool: ToolEntry }> = [];\n\n const scopeTools = this.scope.tools.getTools();\n this.logger.verbose(`findTools: scope tools=${scopeTools.length}`);\n\n for (const tool of scopeTools) {\n tools.push({ appName: tool.owner.id, tool });\n }\n\n this.logger.info(`findTools: total tools collected=${tools.length}`);\n if (tools.length === 0) {\n this.logger.warn('findTools: no tools found across apps');\n }\n\n this.state.set('tools', tools);\n this.logger.verbose('findTools:done');\n } catch (error) {\n this.logger.error('findTools: failed to collect tools', error);\n throw error;\n }\n }\n\n @Stage('resolveConflicts')\n async resolveConflicts() {\n this.logger.verbose('resolveConflicts:start');\n\n try {\n const found = this.state.required.tools;\n\n const counts = new Map<string, number>();\n for (const { tool } of found) {\n const baseName = tool.metadata.id ?? tool.metadata.name;\n counts.set(baseName, (counts.get(baseName) ?? 0) + 1);\n }\n\n const conflicts = new Set<string>([...counts.entries()].filter(([, n]) => n > 1).map(([k]) => k));\n\n if (conflicts.size > 0) {\n const preview = this.sample(Array.from(conflicts)).join(', ');\n const extra = conflicts.size > 5 ? `, +${conflicts.size - 5} more` : '';\n this.logger.warn(`resolveConflicts: ${conflicts.size} name conflict(s) detected: ${preview}${extra}`);\n } else {\n this.logger.info('resolveConflicts: no name conflicts detected');\n }\n\n const resolved = found.map(({ appName, tool }) => {\n const baseName = tool.metadata.id ?? tool.metadata.name;\n const finalName = conflicts.has(baseName) ? `${appName}:${baseName}` : baseName;\n return { appName, tool, finalName };\n });\n\n this.state.set('resolvedTools', resolved);\n this.logger.verbose('resolveConflicts:done');\n } catch (error) {\n this.logger.error('resolveConflicts: failed to resolve conflicts', error);\n throw error;\n }\n }\n\n @Stage('parseTools')\n async parseTools() {\n this.logger.verbose('parseTools:start');\n\n const resolved = this.state.required.resolvedTools;\n\n const tools: ResponseToolItem[] = resolved.map(({ finalName, tool }) => {\n // Get the input schema - prefer rawInputSchema (JSON Schema), then convert from tool.inputSchema\n let inputSchema: any;\n if (tool.rawInputSchema) {\n // Already converted to JSON Schema\n inputSchema = tool.rawInputSchema;\n } else if (tool.inputSchema && Object.keys(tool.inputSchema).length > 0) {\n // tool.inputSchema is a ZodRawShape (extracted .shape from ZodObject in ToolInstance constructor)\n // Convert to JSON Schema\n try {\n // as any used here to prevent hard ts-check on tool input that is redundant\n // and just slow down the build process. types here are unnecessary.\n // eslint-disable-next-line\n inputSchema = zodToJsonSchema(z.object(tool.inputSchema) as any) as any;\n } catch (e) {\n this.logger.warn(`Failed to convert inputSchema for tool ${finalName}:`, e);\n inputSchema = { type: 'object', properties: {} };\n }\n } else {\n // No schema defined - use empty object schema\n inputSchema = { type: 'object', properties: {} };\n }\n\n return {\n name: finalName,\n title: tool.metadata.name,\n description: tool.metadata.description,\n annotations: tool.metadata.annotations,\n inputSchema,\n };\n });\n\n const preview = this.sample(tools.map((t) => t.name)).join(', ');\n const extra = tools.length > 5 ? `, +${tools.length - 5} more` : '';\n this.logger.info(`parseTools: prepared ${tools.length} tool descriptor(s): ${preview}${extra}`);\n\n this.respond({ tools });\n this.logger.info('parseTools: response sent');\n this.logger.verbose('parseTools:done');\n }\n}\n"]}
|