@frontmcp/sdk 0.3.1 → 0.4.0
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/LICENSE +201 -0
- package/README.md +192 -164
- package/package.json +7 -4
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js +114 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/index.d.ts +7 -0
- package/src/__test-utils__/fixtures/index.js +11 -0
- package/src/__test-utils__/fixtures/index.js.map +1 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js +127 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +69 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js +131 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +14 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js +59 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +36 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js +91 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +1 -0
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +45 -0
- package/src/__test-utils__/helpers/assertion.helpers.js +153 -0
- package/src/__test-utils__/helpers/assertion.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/async.helpers.d.ts +48 -0
- package/src/__test-utils__/helpers/async.helpers.js +112 -0
- package/src/__test-utils__/helpers/async.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/index.d.ts +6 -0
- package/src/__test-utils__/helpers/index.js +10 -0
- package/src/__test-utils__/helpers/index.js.map +1 -0
- package/src/__test-utils__/helpers/setup.helpers.d.ts +54 -0
- package/src/__test-utils__/helpers/setup.helpers.js +106 -0
- package/src/__test-utils__/helpers/setup.helpers.js.map +1 -0
- package/src/__test-utils__/index.d.ts +9 -0
- package/src/__test-utils__/index.js +14 -0
- package/src/__test-utils__/index.js.map +1 -0
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +50 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js +72 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +1 -0
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +25 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js +65 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/index.d.ts +8 -0
- package/src/__test-utils__/mocks/index.js +12 -0
- package/src/__test-utils__/mocks/index.js.map +1 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js +70 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +39 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js +72 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js +79 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +1 -0
- package/src/app/app.utils.js.map +1 -1
- package/src/app/instances/app.local.instance.js +8 -11
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/flows/oauth.authorize.flow.d.ts +8 -8
- package/src/auth/flows/oauth.register.flow.d.ts +4 -4
- package/src/auth/flows/oauth.token.flow.d.ts +4 -4
- package/src/auth/flows/well-known.jwks.flow.d.ts +12 -12
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +8 -8
- package/src/auth/flows/well-known.prm.flow.d.ts +4 -4
- package/src/common/decorators/tool.decorator.d.ts +97 -36
- package/src/common/decorators/tool.decorator.js +0 -1
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/entries/tool.entry.d.ts +54 -11
- package/src/common/entries/tool.entry.js +19 -0
- package/src/common/entries/tool.entry.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +10 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.d.ts +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +12 -7
- package/src/common/interfaces/tool.interface.js +1 -1
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/front-mcp.metadata.d.ts +145 -145
- package/src/common/metadata/hook.metadata.d.ts +4 -2
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/prompt.metadata.d.ts +28 -28
- package/src/common/metadata/prompt.metadata.js.map +1 -1
- package/src/common/metadata/resource.metadata.d.ts +54 -54
- package/src/common/metadata/tool.metadata.d.ts +190 -7
- package/src/common/metadata/tool.metadata.js +41 -6
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/schemas/http-output.schema.d.ts +106 -106
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/options/logging.options.d.ts +1 -2
- package/src/common/types/options/logging.options.js +1 -9
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +19 -19
- package/src/errors/error-handler.d.ts +65 -0
- package/src/errors/error-handler.js +107 -0
- package/src/errors/error-handler.js.map +1 -0
- package/src/errors/index.d.ts +2 -0
- package/src/errors/index.js +26 -0
- package/src/errors/index.js.map +1 -0
- package/src/errors/mcp.error.d.ts +156 -0
- package/src/errors/mcp.error.js +243 -0
- package/src/errors/mcp.error.js.map +1 -0
- package/src/flows/flow.instance.js +7 -6
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +20 -20
- package/src/hooks/hook.registry.d.ts +5 -3
- package/src/hooks/hook.registry.js +13 -1
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/plugin/plugin.registry.d.ts +7 -2
- package/src/plugin/plugin.registry.js +23 -11
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/prompt.registry.js +1 -0
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/resource/resource.registry.js +1 -0
- package/src/resource/resource.registry.js.map +1 -1
- package/src/scope/scope.registry.js +1 -1
- package/src/scope/scope.registry.js.map +1 -1
- package/src/store/adapters/store.memory.adapter.js +3 -1
- package/src/store/adapters/store.memory.adapter.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +1012 -676
- package/src/tool/flows/call-tool.flow.js +94 -61
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +347 -590
- package/src/tool/flows/tools-list.flow.js +76 -49
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.instance.d.ts +27 -8
- package/src/tool/tool.instance.js +40 -5
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.js +19 -21
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -2
- package/src/tool/tool.utils.js +377 -14
- package/src/tool/tool.utils.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.js +6 -13
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.streamable-http.flow.js +1 -0
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +10 -5
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/index.d.ts +151 -268
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +124 -216
- package/src/transport/transport.local.js +1 -0
- package/src/transport/transport.local.js.map +1 -1
- package/src/utils/string.utils.js +1 -1
- package/src/utils/string.utils.js.map +1 -1
|
@@ -5,38 +5,30 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const common_1 = require("../../common");
|
|
6
6
|
const zod_1 = require("zod");
|
|
7
7
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
8
|
+
const errors_1 = require("../../errors");
|
|
8
9
|
const inputSchema = zod_1.z.object({
|
|
9
10
|
request: types_js_1.CallToolRequestSchema,
|
|
10
11
|
ctx: zod_1.z.any(),
|
|
11
12
|
});
|
|
12
13
|
const outputSchema = types_js_1.CallToolResultSchema;
|
|
13
14
|
const stateSchema = zod_1.z.object({
|
|
14
|
-
input: zod_1.z
|
|
15
|
+
input: zod_1.z
|
|
16
|
+
.object({
|
|
15
17
|
name: zod_1.z.string().min(1).max(64),
|
|
16
18
|
arguments: zod_1.z.object({}).passthrough().optional(),
|
|
17
|
-
})
|
|
19
|
+
})
|
|
20
|
+
.passthrough(),
|
|
18
21
|
authInfo: zod_1.z.any().optional(),
|
|
19
22
|
tool: zod_1.z.instanceof(common_1.ToolEntry),
|
|
20
23
|
toolContext: zod_1.z.instanceof(common_1.ToolContext),
|
|
24
|
+
// Store the raw executed output for plugins to see
|
|
25
|
+
rawOutput: zod_1.z.any().optional(),
|
|
26
|
+
output: outputSchema,
|
|
21
27
|
});
|
|
22
28
|
const plan = {
|
|
23
|
-
pre: [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
'createToolCallContext',
|
|
27
|
-
'acquireQuota',
|
|
28
|
-
'acquireSemaphore',
|
|
29
|
-
],
|
|
30
|
-
execute: [
|
|
31
|
-
'validateInput',
|
|
32
|
-
'execute',
|
|
33
|
-
'validateOutput',
|
|
34
|
-
],
|
|
35
|
-
finalize: [
|
|
36
|
-
'releaseSemaphore',
|
|
37
|
-
'releaseQuota',
|
|
38
|
-
'finalize',
|
|
39
|
-
],
|
|
29
|
+
pre: ['parseInput', 'findTool', 'createToolCallContext', 'acquireQuota', 'acquireSemaphore'],
|
|
30
|
+
execute: ['validateInput', 'execute', 'validateOutput'],
|
|
31
|
+
finalize: ['releaseSemaphore', 'releaseQuota', 'finalize'],
|
|
40
32
|
};
|
|
41
33
|
const name = 'tools:call-tool';
|
|
42
34
|
const { Stage } = (0, common_1.FlowHooksOf)(name);
|
|
@@ -44,10 +36,31 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
44
36
|
logger = this.scopeLogger.child('CallToolFlow');
|
|
45
37
|
async parseInput() {
|
|
46
38
|
this.logger.verbose('parseInput:start');
|
|
47
|
-
|
|
39
|
+
let method;
|
|
40
|
+
let params;
|
|
41
|
+
let ctx;
|
|
42
|
+
try {
|
|
43
|
+
const inputData = inputSchema.parse(this.rawInput);
|
|
44
|
+
method = inputData.request.method;
|
|
45
|
+
params = inputData.request.params;
|
|
46
|
+
ctx = inputData.ctx;
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new errors_1.InvalidInputError('Invalid Input', e instanceof zod_1.z.ZodError ? e.errors : undefined);
|
|
50
|
+
}
|
|
48
51
|
if (method !== 'tools/call') {
|
|
49
52
|
this.logger.warn(`parseInput: invalid method "${method}"`);
|
|
50
|
-
throw new
|
|
53
|
+
throw new errors_1.InvalidMethodError(method, 'tools/call');
|
|
54
|
+
}
|
|
55
|
+
// Find the tool early to get its owner ID for hook filtering
|
|
56
|
+
const { name } = params;
|
|
57
|
+
const activeTools = this.scope.tools.getTools(true);
|
|
58
|
+
const tool = activeTools.find((entry) => {
|
|
59
|
+
return entry.fullName === name || entry.name === name;
|
|
60
|
+
});
|
|
61
|
+
// Store tool owner ID in the flow input for hook filtering
|
|
62
|
+
if (tool?.owner) {
|
|
63
|
+
this.rawInput._toolOwnerId = tool.owner.id;
|
|
51
64
|
}
|
|
52
65
|
this.state.set({ input: params, authInfo: ctx.authInfo });
|
|
53
66
|
this.logger.verbose('parseInput:done');
|
|
@@ -58,11 +71,12 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
58
71
|
const activeTools = this.scope.tools.getTools(true);
|
|
59
72
|
this.logger.info(`findTool: discovered ${activeTools.length} active tool(s) (including hidden)`);
|
|
60
73
|
const { name } = this.state.required.input;
|
|
61
|
-
const tool = activeTools.find(
|
|
74
|
+
const tool = activeTools.find((entry) => {
|
|
75
|
+
return entry.fullName === name || entry.name === name;
|
|
76
|
+
});
|
|
62
77
|
if (!tool) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.fail(new Error(errorMessage));
|
|
78
|
+
this.logger.warn(`findTool: tool "${name}" not found`);
|
|
79
|
+
throw new errors_1.ToolNotFoundError(name);
|
|
66
80
|
}
|
|
67
81
|
this.logger = this.logger.child(`CallToolFlow(${name})`);
|
|
68
82
|
this.state.set('tool', tool);
|
|
@@ -73,19 +87,23 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
73
87
|
this.logger.verbose('createToolCallContext:start');
|
|
74
88
|
const { ctx } = this.input;
|
|
75
89
|
const { tool, input } = this.state.required;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.map(hook => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
try {
|
|
91
|
+
const context = tool.create(input.arguments, ctx);
|
|
92
|
+
const toolHooks = this.scope.hooks.getClsHooks(tool.record.provide).map((hook) => {
|
|
93
|
+
hook.run = async () => {
|
|
94
|
+
return context[hook.metadata.method]();
|
|
95
|
+
};
|
|
96
|
+
return hook;
|
|
97
|
+
});
|
|
98
|
+
this.appendContextHooks(toolHooks);
|
|
99
|
+
context.mark('createToolCallContext');
|
|
100
|
+
this.state.set('toolContext', context);
|
|
101
|
+
this.logger.verbose('createToolCallContext:done');
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
this.logger.error('createToolCallContext: failed to create context', error);
|
|
105
|
+
throw new errors_1.ToolExecutionError(tool.metadata.name, error instanceof Error ? error : undefined);
|
|
106
|
+
}
|
|
89
107
|
}
|
|
90
108
|
async acquireQuota() {
|
|
91
109
|
this.logger.verbose('acquireQuota:start');
|
|
@@ -108,12 +126,16 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
108
126
|
}
|
|
109
127
|
toolContext.mark('validateInput');
|
|
110
128
|
try {
|
|
111
|
-
toolContext.input = tool.
|
|
129
|
+
toolContext.input = tool.parseInput(input);
|
|
130
|
+
this.logger.verbose('validateInput:done');
|
|
112
131
|
}
|
|
113
132
|
catch (err) {
|
|
114
|
-
|
|
133
|
+
if (err instanceof zod_1.z.ZodError) {
|
|
134
|
+
throw new errors_1.InvalidInputError('Invalid tool input', err.errors);
|
|
135
|
+
}
|
|
136
|
+
this.logger.error('validateInput: failed to parse input', err);
|
|
137
|
+
throw new errors_1.InvalidInputError('Unknown error occurred when trying to parse input');
|
|
115
138
|
}
|
|
116
|
-
this.logger.verbose('validateInput:done');
|
|
117
139
|
}
|
|
118
140
|
async execute() {
|
|
119
141
|
this.logger.verbose('execute:start');
|
|
@@ -122,17 +144,24 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
122
144
|
return;
|
|
123
145
|
}
|
|
124
146
|
toolContext.mark('execute');
|
|
125
|
-
|
|
126
|
-
|
|
147
|
+
try {
|
|
148
|
+
toolContext.output = await toolContext.execute(toolContext.input);
|
|
149
|
+
this.logger.verbose('execute:done');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.logger.error('execute: tool execution failed', error);
|
|
153
|
+
throw new errors_1.ToolExecutionError(this.state.tool?.metadata.name || 'unknown', error instanceof Error ? error : undefined);
|
|
154
|
+
}
|
|
127
155
|
}
|
|
128
156
|
async validateOutput() {
|
|
129
157
|
this.logger.verbose('validateOutput:start');
|
|
130
|
-
const {
|
|
131
|
-
if (!toolContext
|
|
158
|
+
const { toolContext } = this.state;
|
|
159
|
+
if (!toolContext) {
|
|
132
160
|
return;
|
|
133
161
|
}
|
|
134
162
|
toolContext.mark('validateOutput');
|
|
135
|
-
|
|
163
|
+
// Store the RAW output for plugins (cache, PII, etc.) to inspect
|
|
164
|
+
this.state.set('rawOutput', toolContext.output);
|
|
136
165
|
this.logger.verbose('validateOutput:done');
|
|
137
166
|
}
|
|
138
167
|
async releaseSemaphore() {
|
|
@@ -149,24 +178,28 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
149
178
|
}
|
|
150
179
|
async finalize() {
|
|
151
180
|
this.logger.verbose('finalize:start');
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
181
|
+
const { tool, rawOutput } = this.state;
|
|
182
|
+
if (!tool) {
|
|
183
|
+
this.logger.error('finalize: tool not found in state');
|
|
184
|
+
throw new errors_1.ToolExecutionError('unknown', new Error('Tool not found in state'));
|
|
155
185
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const response = toolContext.output;
|
|
160
|
-
this.respond({
|
|
161
|
-
content: [{
|
|
162
|
-
type: 'text',
|
|
163
|
-
text: JSON.stringify(response)
|
|
164
|
-
}],
|
|
165
|
-
});
|
|
186
|
+
if (rawOutput === undefined) {
|
|
187
|
+
this.logger.error('finalize: tool output not found in state');
|
|
188
|
+
throw new errors_1.ToolExecutionError(tool.metadata.name, new Error('Tool output not found'));
|
|
166
189
|
}
|
|
167
|
-
|
|
168
|
-
|
|
190
|
+
// Parse and construct the MCP-compliant output using safeParseOutput
|
|
191
|
+
const parseResult = tool.safeParseOutput(rawOutput);
|
|
192
|
+
if (!parseResult.success) {
|
|
193
|
+
// add support for request id in error messages
|
|
194
|
+
this.logger.error('finalize: output validation failed', {
|
|
195
|
+
tool: tool.metadata.name,
|
|
196
|
+
errors: parseResult.error,
|
|
197
|
+
});
|
|
198
|
+
// Use InvalidOutputError, which hides internal details in production
|
|
199
|
+
throw new errors_1.InvalidOutputError();
|
|
169
200
|
}
|
|
201
|
+
// Respond with the properly formatted MCP result
|
|
202
|
+
this.respond(parseResult.data);
|
|
170
203
|
this.logger.verbose('finalize:done');
|
|
171
204
|
}
|
|
172
205
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-tool.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/call-tool.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// tools/flows/call-tool.flow.ts\nimport {Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions, ToolContext, ToolEntry} from '../../common';\nimport {z} from 'zod';\nimport {CallToolRequestSchema, CallToolResultSchema} from '@modelcontextprotocol/sdk/types.js';\nimport {AuthInfo} from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\nconst inputSchema = z.object({\n request: CallToolRequestSchema,\n ctx: z.any(),\n});\n\nconst outputSchema = CallToolResultSchema;\n\nconst stateSchema = z.object({\n input: z.object({\n name: z.string().min(1).max(64),\n arguments: z.object({}).passthrough().optional(),\n }).passthrough(),\n authInfo: z.any().optional() as z.ZodType<AuthInfo>,\n tool: z.instanceof(ToolEntry),\n toolContext: z.instanceof(ToolContext),\n});\n\nconst plan = {\n pre: [\n 'parseInput',\n 'findTool',\n 'createToolCallContext',\n 'acquireQuota',\n 'acquireSemaphore',\n ],\n execute: [\n 'validateInput',\n 'execute',\n 'validateOutput',\n ],\n finalize: [\n 'releaseSemaphore',\n 'releaseQuota',\n 'finalize',\n ],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:call-tool': FlowRunOptions<\n CallToolFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:call-tool' as const;\nconst {Stage} = FlowHooksOf<'tools:call-tool'>(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CallToolFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CallToolFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n const {request: {method, params}, ctx} = inputSchema.parse(this.rawInput);\n\n if (method !== 'tools/call') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new Error('Invalid method');\n }\n\n this.state.set({input: params, authInfo: ctx.authInfo});\n this.logger.verbose('parseInput:done');\n }\n\n\n @Stage('findTool')\n async findTool() {\n this.logger.verbose('findTool:start');\n // TODO: add support for session based tools\n const activeTools = this.scope.tools.getTools(true)\n this.logger.info(`findTool: discovered ${activeTools.length} active tool(s) (including hidden)`);\n\n const {name} = this.state.required.input;\n const tool = activeTools.find(t => t.metadata.name === name);\n if (!tool) {\n const errorMessage = `Tool \"${name}\" not found`\n this.logger.warn(errorMessage);\n this.fail(new Error(errorMessage))\n }\n this.logger = this.logger.child(`CallToolFlow(${name})`);\n this.state.set('tool', tool!);\n this.logger.info(`findTool: tool \"${name}\" found`);\n this.logger.verbose('findTool:done');\n }\n\n @Stage('createToolCallContext')\n async createToolCallContext() {\n this.logger.verbose('createToolCallContext:start');\n const {ctx} = this.input\n const {tool, input} = this.state.required;\n const context = tool.create(input, ctx)\n const toolHooks = this.scope.hooks.getClsHooks(tool.record.provide)\n .map(hook => {\n hook.run = async () => {\n return context[hook.metadata.method]()\n }\n return hook;\n })\n\n this.appendContextHooks(toolHooks)\n context.input = input;\n context.mark('createToolCallContext')\n this.state.set('toolContext', context)\n this.logger.verbose('createToolCallContext:done');\n }\n\n @Stage('acquireQuota')\n async acquireQuota() {\n this.logger.verbose('acquireQuota:start');\n // used for rate limiting\n this.state.toolContext?.mark('acquireQuota')\n this.logger.verbose('acquireQuota:done');\n }\n\n @Stage('acquireSemaphore')\n async acquireSemaphore() {\n this.logger.verbose('acquireSemaphore:start');\n // used for concurrency control\n this.state.toolContext?.mark('acquireSemaphore')\n this.logger.verbose('acquireSemaphore:done');\n }\n\n\n @Stage('validateInput')\n async validateInput() {\n this.logger.verbose('validateInput:start');\n const {tool, input} = this.state.required;\n const {toolContext} = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateInput')\n try {\n toolContext.input = tool.inputSchema.parse(input.arguments ?? {});\n } catch (err) {\n this.fail(new Error(`Invalid input: validation failed`));\n }\n this.logger.verbose('validateInput:done');\n }\n\n @Stage('execute')\n async execute() {\n this.logger.verbose('execute:start');\n const toolContext = this.state.toolContext;\n if (!toolContext) {\n return;\n }\n toolContext.mark('execute')\n toolContext.output = await toolContext.execute(toolContext.input)\n this.logger.verbose('execute:done');\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n this.logger.verbose('validateOutput:start');\n const {tool, toolContext} = this.state;\n if (!toolContext || !tool) {\n return;\n }\n toolContext.mark('validateOutput')\n toolContext.output = tool.outputSchema.parse(toolContext.output)\n this.logger.verbose('validateOutput:done');\n }\n\n @Stage('releaseSemaphore')\n async releaseSemaphore() {\n this.logger.verbose('releaseSemaphore:start');\n // release concurrency control\n this.state.toolContext?.mark('releaseSemaphore')\n this.logger.verbose('releaseSemaphore:done');\n }\n\n @Stage('releaseQuota')\n async releaseQuota() {\n this.logger.verbose('releaseQuota:start');\n // release rate limiting\n this.state.toolContext?.mark('releaseQuota')\n this.logger.verbose('releaseQuota:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n if (!this.state.toolContext) {\n this.fail(new Error(\"error\"))\n return;\n }\n const {tool, toolContext} = this.state.required;\n const success = tool.outputSchema.safeParse(toolContext.output).success;\n if (success) {\n const response = toolContext.output;\n this.respond({\n content: [{\n type: 'text',\n text: JSON.stringify(response)\n }],\n })\n\n } else {\n this.fail(new Error(\"invalid output schema\"))\n }\n this.logger.verbose('finalize:done');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"call-tool.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/call-tool.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// tools/flows/call-tool.flow.ts\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions, ToolContext, ToolEntry } from '../../common';\nimport { z } from 'zod';\nimport { CallToolRequestSchema, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport {\n InvalidMethodError,\n ToolNotFoundError,\n InvalidInputError,\n InvalidOutputError,\n ToolExecutionError,\n} from '../../errors';\n\nconst inputSchema = z.object({\n request: CallToolRequestSchema,\n ctx: z.any(),\n});\n\nconst outputSchema = CallToolResultSchema;\n\nconst stateSchema = z.object({\n input: z\n .object({\n name: z.string().min(1).max(64),\n arguments: z.object({}).passthrough().optional(),\n })\n .passthrough(),\n authInfo: z.any().optional() as z.ZodType<AuthInfo>,\n tool: z.instanceof(ToolEntry),\n toolContext: z.instanceof(ToolContext),\n // Store the raw executed output for plugins to see\n rawOutput: z.any().optional(),\n output: outputSchema,\n});\n\nconst plan = {\n pre: ['parseInput', 'findTool', 'createToolCallContext', 'acquireQuota', 'acquireSemaphore'],\n execute: ['validateInput', 'execute', 'validateOutput'],\n finalize: ['releaseSemaphore', 'releaseQuota', 'finalize'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:call-tool': FlowRunOptions<\n CallToolFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:call-tool' as const;\nconst { Stage } = FlowHooksOf<'tools:call-tool'>(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CallToolFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CallToolFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: any;\n let ctx: any;\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n ctx = inputData.ctx;\n } catch (e) {\n throw new InvalidInputError('Invalid Input', e instanceof z.ZodError ? e.errors : undefined);\n }\n\n if (method !== 'tools/call') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'tools/call');\n }\n\n // Find the tool early to get its owner ID for hook filtering\n const { name } = params;\n const activeTools = this.scope.tools.getTools(true);\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n // Store tool owner ID in the flow input for hook filtering\n if (tool?.owner) {\n (this.rawInput as any)._toolOwnerId = tool.owner.id;\n }\n\n this.state.set({ input: params, authInfo: ctx.authInfo });\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('findTool')\n async findTool() {\n this.logger.verbose('findTool:start');\n // TODO: add support for session based tools\n const activeTools = this.scope.tools.getTools(true);\n this.logger.info(`findTool: discovered ${activeTools.length} active tool(s) (including hidden)`);\n\n const { name } = this.state.required.input;\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n if (!tool) {\n this.logger.warn(`findTool: tool \"${name}\" not found`);\n throw new ToolNotFoundError(name);\n }\n\n this.logger = this.logger.child(`CallToolFlow(${name})`);\n this.state.set('tool', tool);\n this.logger.info(`findTool: tool \"${name}\" found`);\n this.logger.verbose('findTool:done');\n }\n\n @Stage('createToolCallContext')\n async createToolCallContext() {\n this.logger.verbose('createToolCallContext:start');\n const { ctx } = this.input;\n const { tool, input } = this.state.required;\n\n try {\n const context = tool.create(input.arguments, ctx);\n const toolHooks = this.scope.hooks.getClsHooks(tool.record.provide).map((hook) => {\n hook.run = async () => {\n return context[hook.metadata.method]();\n };\n return hook;\n });\n\n this.appendContextHooks(toolHooks);\n context.mark('createToolCallContext');\n this.state.set('toolContext', context);\n this.logger.verbose('createToolCallContext:done');\n } catch (error) {\n this.logger.error('createToolCallContext: failed to create context', error);\n throw new ToolExecutionError(tool.metadata.name, error instanceof Error ? error : undefined);\n }\n }\n\n @Stage('acquireQuota')\n async acquireQuota() {\n this.logger.verbose('acquireQuota:start');\n // used for rate limiting\n this.state.toolContext?.mark('acquireQuota');\n this.logger.verbose('acquireQuota:done');\n }\n\n @Stage('acquireSemaphore')\n async acquireSemaphore() {\n this.logger.verbose('acquireSemaphore:start');\n // used for concurrency control\n this.state.toolContext?.mark('acquireSemaphore');\n this.logger.verbose('acquireSemaphore:done');\n }\n\n @Stage('validateInput')\n async validateInput() {\n this.logger.verbose('validateInput:start');\n const { tool, input } = this.state.required;\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateInput');\n\n try {\n toolContext.input = tool.parseInput(input);\n this.logger.verbose('validateInput:done');\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new InvalidInputError('Invalid tool input', err.errors);\n }\n\n this.logger.error('validateInput: failed to parse input', err);\n throw new InvalidInputError('Unknown error occurred when trying to parse input');\n }\n }\n\n @Stage('execute')\n async execute() {\n this.logger.verbose('execute:start');\n const toolContext = this.state.toolContext;\n if (!toolContext) {\n return;\n }\n toolContext.mark('execute');\n\n try {\n toolContext.output = await toolContext.execute(toolContext.input);\n this.logger.verbose('execute:done');\n } catch (error) {\n this.logger.error('execute: tool execution failed', error);\n throw new ToolExecutionError(\n this.state.tool?.metadata.name || 'unknown',\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n this.logger.verbose('validateOutput:start');\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateOutput');\n\n // Store the RAW output for plugins (cache, PII, etc.) to inspect\n this.state.set('rawOutput', toolContext.output);\n\n this.logger.verbose('validateOutput:done');\n }\n\n @Stage('releaseSemaphore')\n async releaseSemaphore() {\n this.logger.verbose('releaseSemaphore:start');\n // release concurrency control\n this.state.toolContext?.mark('releaseSemaphore');\n this.logger.verbose('releaseSemaphore:done');\n }\n\n @Stage('releaseQuota')\n async releaseQuota() {\n this.logger.verbose('releaseQuota:start');\n // release rate limiting\n this.state.toolContext?.mark('releaseQuota');\n this.logger.verbose('releaseQuota:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n const { tool, rawOutput } = this.state;\n\n if (!tool) {\n this.logger.error('finalize: tool not found in state');\n throw new ToolExecutionError('unknown', new Error('Tool not found in state'));\n }\n\n if (rawOutput === undefined) {\n this.logger.error('finalize: tool output not found in state');\n throw new ToolExecutionError(tool.metadata.name, new Error('Tool output not found'));\n }\n\n // Parse and construct the MCP-compliant output using safeParseOutput\n const parseResult = tool.safeParseOutput(rawOutput);\n\n if (!parseResult.success) {\n // add support for request id in error messages\n this.logger.error('finalize: output validation failed', {\n tool: tool.metadata.name,\n errors: parseResult.error,\n });\n\n // Use InvalidOutputError, which hides internal details in production\n throw new InvalidOutputError();\n }\n\n // Respond with the properly formatted MCP result\n this.respond(parseResult.data);\n this.logger.verbose('finalize:done');\n }\n}\n"]}
|