@frontmcp/sdk 0.3.1 → 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.
Files changed (148) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +192 -164
  3. package/package.json +7 -4
  4. package/src/__test-utils__/fixtures/hook.fixtures.d.ts +46 -0
  5. package/src/__test-utils__/fixtures/hook.fixtures.js +114 -0
  6. package/src/__test-utils__/fixtures/hook.fixtures.js.map +1 -0
  7. package/src/__test-utils__/fixtures/index.d.ts +7 -0
  8. package/src/__test-utils__/fixtures/index.js +11 -0
  9. package/src/__test-utils__/fixtures/index.js.map +1 -0
  10. package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +46 -0
  11. package/src/__test-utils__/fixtures/plugin.fixtures.js +127 -0
  12. package/src/__test-utils__/fixtures/plugin.fixtures.js.map +1 -0
  13. package/src/__test-utils__/fixtures/provider.fixtures.d.ts +69 -0
  14. package/src/__test-utils__/fixtures/provider.fixtures.js +131 -0
  15. package/src/__test-utils__/fixtures/provider.fixtures.js.map +1 -0
  16. package/src/__test-utils__/fixtures/scope.fixtures.d.ts +14 -0
  17. package/src/__test-utils__/fixtures/scope.fixtures.js +59 -0
  18. package/src/__test-utils__/fixtures/scope.fixtures.js.map +1 -0
  19. package/src/__test-utils__/fixtures/tool.fixtures.d.ts +36 -0
  20. package/src/__test-utils__/fixtures/tool.fixtures.js +91 -0
  21. package/src/__test-utils__/fixtures/tool.fixtures.js.map +1 -0
  22. package/src/__test-utils__/helpers/assertion.helpers.d.ts +45 -0
  23. package/src/__test-utils__/helpers/assertion.helpers.js +153 -0
  24. package/src/__test-utils__/helpers/assertion.helpers.js.map +1 -0
  25. package/src/__test-utils__/helpers/async.helpers.d.ts +48 -0
  26. package/src/__test-utils__/helpers/async.helpers.js +112 -0
  27. package/src/__test-utils__/helpers/async.helpers.js.map +1 -0
  28. package/src/__test-utils__/helpers/index.d.ts +6 -0
  29. package/src/__test-utils__/helpers/index.js +10 -0
  30. package/src/__test-utils__/helpers/index.js.map +1 -0
  31. package/src/__test-utils__/helpers/setup.helpers.d.ts +54 -0
  32. package/src/__test-utils__/helpers/setup.helpers.js +106 -0
  33. package/src/__test-utils__/helpers/setup.helpers.js.map +1 -0
  34. package/src/__test-utils__/index.d.ts +9 -0
  35. package/src/__test-utils__/index.js +14 -0
  36. package/src/__test-utils__/index.js.map +1 -0
  37. package/src/__test-utils__/mocks/flow-instance.mock.d.ts +50 -0
  38. package/src/__test-utils__/mocks/flow-instance.mock.js +72 -0
  39. package/src/__test-utils__/mocks/flow-instance.mock.js.map +1 -0
  40. package/src/__test-utils__/mocks/hook-registry.mock.d.ts +25 -0
  41. package/src/__test-utils__/mocks/hook-registry.mock.js +65 -0
  42. package/src/__test-utils__/mocks/hook-registry.mock.js.map +1 -0
  43. package/src/__test-utils__/mocks/index.d.ts +8 -0
  44. package/src/__test-utils__/mocks/index.js +12 -0
  45. package/src/__test-utils__/mocks/index.js.map +1 -0
  46. package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +43 -0
  47. package/src/__test-utils__/mocks/plugin-registry.mock.js +70 -0
  48. package/src/__test-utils__/mocks/plugin-registry.mock.js.map +1 -0
  49. package/src/__test-utils__/mocks/provider-registry.mock.d.ts +39 -0
  50. package/src/__test-utils__/mocks/provider-registry.mock.js +72 -0
  51. package/src/__test-utils__/mocks/provider-registry.mock.js.map +1 -0
  52. package/src/__test-utils__/mocks/tool-registry.mock.d.ts +43 -0
  53. package/src/__test-utils__/mocks/tool-registry.mock.js +79 -0
  54. package/src/__test-utils__/mocks/tool-registry.mock.js.map +1 -0
  55. package/src/app/app.utils.js.map +1 -1
  56. package/src/app/instances/app.local.instance.js +8 -11
  57. package/src/app/instances/app.local.instance.js.map +1 -1
  58. package/src/auth/flows/oauth.authorize.flow.d.ts +8 -8
  59. package/src/auth/flows/oauth.register.flow.d.ts +4 -4
  60. package/src/auth/flows/oauth.token.flow.d.ts +4 -4
  61. package/src/auth/flows/well-known.jwks.flow.d.ts +12 -12
  62. package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +8 -8
  63. package/src/auth/flows/well-known.prm.flow.d.ts +4 -4
  64. package/src/common/decorators/tool.decorator.d.ts +97 -36
  65. package/src/common/decorators/tool.decorator.js +0 -1
  66. package/src/common/decorators/tool.decorator.js.map +1 -1
  67. package/src/common/entries/tool.entry.d.ts +54 -11
  68. package/src/common/entries/tool.entry.js +19 -0
  69. package/src/common/entries/tool.entry.js.map +1 -1
  70. package/src/common/interfaces/internal/registry.interface.d.ts +10 -2
  71. package/src/common/interfaces/internal/registry.interface.js.map +1 -1
  72. package/src/common/interfaces/plugin.interface.d.ts +1 -1
  73. package/src/common/interfaces/plugin.interface.js.map +1 -1
  74. package/src/common/interfaces/tool.interface.d.ts +12 -7
  75. package/src/common/interfaces/tool.interface.js +1 -1
  76. package/src/common/interfaces/tool.interface.js.map +1 -1
  77. package/src/common/metadata/front-mcp.metadata.d.ts +145 -145
  78. package/src/common/metadata/hook.metadata.d.ts +4 -2
  79. package/src/common/metadata/hook.metadata.js.map +1 -1
  80. package/src/common/metadata/prompt.metadata.d.ts +28 -28
  81. package/src/common/metadata/prompt.metadata.js.map +1 -1
  82. package/src/common/metadata/resource.metadata.d.ts +54 -54
  83. package/src/common/metadata/tool.metadata.d.ts +190 -7
  84. package/src/common/metadata/tool.metadata.js +41 -6
  85. package/src/common/metadata/tool.metadata.js.map +1 -1
  86. package/src/common/schemas/http-output.schema.d.ts +106 -106
  87. package/src/common/tokens/tool.tokens.js.map +1 -1
  88. package/src/common/types/options/logging.options.d.ts +1 -2
  89. package/src/common/types/options/logging.options.js +1 -9
  90. package/src/common/types/options/logging.options.js.map +1 -1
  91. package/src/common/types/options/server-info.options.d.ts +19 -19
  92. package/src/errors/error-handler.d.ts +65 -0
  93. package/src/errors/error-handler.js +107 -0
  94. package/src/errors/error-handler.js.map +1 -0
  95. package/src/errors/index.d.ts +2 -0
  96. package/src/errors/index.js +26 -0
  97. package/src/errors/index.js.map +1 -0
  98. package/src/errors/mcp.error.d.ts +156 -0
  99. package/src/errors/mcp.error.js +243 -0
  100. package/src/errors/mcp.error.js.map +1 -0
  101. package/src/flows/flow.instance.js +7 -6
  102. package/src/flows/flow.instance.js.map +1 -1
  103. package/src/flows/flow.registry.js +1 -1
  104. package/src/flows/flow.registry.js.map +1 -1
  105. package/src/front-mcp/front-mcp.providers.d.ts +20 -20
  106. package/src/hooks/hook.registry.d.ts +5 -3
  107. package/src/hooks/hook.registry.js +13 -1
  108. package/src/hooks/hook.registry.js.map +1 -1
  109. package/src/plugin/plugin.registry.d.ts +7 -2
  110. package/src/plugin/plugin.registry.js +23 -11
  111. package/src/plugin/plugin.registry.js.map +1 -1
  112. package/src/prompt/prompt.registry.js +1 -0
  113. package/src/prompt/prompt.registry.js.map +1 -1
  114. package/src/resource/resource.registry.js +1 -0
  115. package/src/resource/resource.registry.js.map +1 -1
  116. package/src/scope/scope.registry.js +1 -1
  117. package/src/scope/scope.registry.js.map +1 -1
  118. package/src/store/adapters/store.memory.adapter.js +3 -1
  119. package/src/store/adapters/store.memory.adapter.js.map +1 -1
  120. package/src/tool/flows/call-tool.flow.d.ts +1012 -676
  121. package/src/tool/flows/call-tool.flow.js +94 -61
  122. package/src/tool/flows/call-tool.flow.js.map +1 -1
  123. package/src/tool/flows/tools-list.flow.d.ts +347 -590
  124. package/src/tool/flows/tools-list.flow.js +90 -43
  125. package/src/tool/flows/tools-list.flow.js.map +1 -1
  126. package/src/tool/tool.instance.d.ts +27 -8
  127. package/src/tool/tool.instance.js +40 -5
  128. package/src/tool/tool.instance.js.map +1 -1
  129. package/src/tool/tool.registry.js +19 -21
  130. package/src/tool/tool.registry.js.map +1 -1
  131. package/src/tool/tool.utils.d.ts +3 -2
  132. package/src/tool/tool.utils.js +377 -14
  133. package/src/tool/tool.utils.js.map +1 -1
  134. package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
  135. package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
  136. package/src/transport/flows/handle.sse.flow.js +6 -13
  137. package/src/transport/flows/handle.sse.flow.js.map +1 -1
  138. package/src/transport/flows/handle.streamable-http.flow.js +1 -0
  139. package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
  140. package/src/transport/mcp-handlers/call-tool-request.handler.d.ts +1 -1
  141. package/src/transport/mcp-handlers/call-tool-request.handler.js +10 -5
  142. package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
  143. package/src/transport/mcp-handlers/index.d.ts +151 -268
  144. package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +124 -216
  145. package/src/transport/transport.local.js +1 -0
  146. package/src/transport/transport.local.js.map +1 -1
  147. package/src/utils/string.utils.js +1 -1
  148. package/src/utils/string.utils.js.map +1 -1
@@ -1,42 +1,103 @@
1
1
  import 'reflect-metadata';
2
- import { ToolMetadata } from '../metadata';
2
+ import { ToolMetadata, ImageOutputSchema, AudioOutputSchema, ResourceOutputSchema, ResourceLinkOutputSchema, ToolInputType, ToolOutputType } from '../metadata';
3
3
  import z from 'zod';
4
- import { ToolContext } from "../interfaces";
5
- export type FrontMcpToolExecuteHandler<In extends object, Out extends object> = (input: In, ctx: ToolContext<In, Out>) => Out | Promise<Out>;
4
+ import { ToolContext } from '../interfaces';
5
+ export type FrontMcpToolExecuteHandler<InSchema extends ToolInputType, OutSchema extends ToolOutputType, In = ToolInputOf<{
6
+ inputSchema: InSchema;
7
+ }>, Out = ToolOutputOf<{
8
+ outputSchema: OutSchema;
9
+ }>> = (input: In, ctx: ToolContext<InSchema, OutSchema>) => Out | Promise<Out>;
6
10
  /**
7
11
  * Decorator that marks a class as a McpTool module and provides metadata
8
12
  */
9
- declare function frontMcpTool<T extends ToolMetadata, In extends object = z.baseObjectInputType<T['inputSchema']>, Out extends object = T['outputSchema'] extends z.ZodRawShape ? z.baseObjectInputType<T['outputSchema']> : object>(providedMetadata: T): (handler: FrontMcpToolExecuteHandler<In, Out>) => (() => void);
10
- export { FrontMcpTool, FrontMcpTool as Tool, frontMcpTool, frontMcpTool as tool, };
11
- declare module "@frontmcp/sdk" {
12
- type __Shape = z.ZodRawShape;
13
- type __AsZodObj<T> = T extends z.ZodObject<infer S> ? z.ZodObject<S> : T extends z.ZodRawShape ? z.ZodObject<T> : never;
14
- type __InputOf<Opt> = Opt extends {
15
- inputSchema: infer I;
16
- } ? z.infer<__AsZodObj<I>> : never;
17
- type __OutputOf<Opt> = Opt extends {
18
- outputSchema: infer O;
19
- } ? z.infer<__AsZodObj<O>> : never;
20
- type __ToolOptions<I extends __Shape, O extends __Shape> = ToolMetadata<I | z.ZodObject<I>, O | z.ZodObject<O>>;
21
- type __Ctor = new (...a: any[]) => any | (abstract new (...a: any[]) => any);
22
- type __A<C extends __Ctor> = C extends new (...a: infer A) => any ? A : C extends abstract new (...a: infer A) => any ? A : never;
23
- type __R<C extends __Ctor> = C extends new (...a: any[]) => infer R ? R : C extends abstract new (...a: any[]) => infer R ? R : never;
24
- type __Param<C extends __Ctor> = __R<C> extends {
25
- execute: (arg: infer P, ...r: any) => any;
26
- } ? P : never;
27
- type __Return<C extends __Ctor> = __R<C> extends {
28
- execute: (...a: any) => infer R;
29
- } ? R : never;
30
- type __Unwrap<T> = T extends Promise<infer U> ? U : T;
31
- type __IsAny<T> = 0 extends (1 & T) ? true : false;
32
- type __Err<M extends string> = {
33
- __type_error__: M;
34
- } & {
35
- never?: never;
36
- };
37
- type __MustExtendCtx<C extends __Ctor> = __R<C> extends ToolContext ? {} : __Err<"Class must extend ToolContext">;
38
- type __MustParam<C extends __Ctor, In> = __IsAny<__Param<C>> extends true ? __Err<"execute(input) must not be any and must exactly match input schema"> : __Param<C> extends In ? (In extends __Param<C> ? {} : __Err<"execute(input) must be exactly the input schema (no widening or narrowing)">) : __Err<"execute(input) parameter does not match input schema">;
39
- type __MustReturn<C extends __Ctor, Out> = __Unwrap<__Return<C>> extends Out ? {} : __Err<"execute return type must be output schema or Promise<output schema>">;
40
- type __Rewrap<C extends __Ctor, In, Out> = C extends abstract new (...a: __A<C>) => __R<C> ? C & (abstract new (...a: __A<C>) => (ToolContext<In, Out> & __R<C>)) : C extends new (...a: __A<C>) => __R<C> ? C & (new (...a: __A<C>) => (ToolContext<In, Out> & __R<C>)) : never;
41
- function Tool<I extends __Shape, O extends __Shape, T extends __ToolOptions<I, O>>(opts: T): <C extends __Ctor>(cls: C & __MustExtendCtx<C> & __MustParam<C, __InputOf<T>> & __MustReturn<C, __OutputOf<T>>) => __Rewrap<C, __InputOf<T>, __OutputOf<T>>;
13
+ declare function frontMcpTool<T extends ToolMetadata, InSchema extends ToolInputType = T['inputSchema'], OutSchema extends ToolOutputType = T['outputSchema']>(providedMetadata: T): (handler: FrontMcpToolExecuteHandler<InSchema, OutSchema>) => () => void;
14
+ export { FrontMcpTool, FrontMcpTool as Tool, frontMcpTool, frontMcpTool as tool };
15
+ /**
16
+ * This is a modified version of the original decorator, with the following changes:
17
+ * - Added support for ZodRawShape as inputSchema
18
+ * - Added support for outputSchema: any of the allowed forms
19
+ * - Added rich error messages for input/output type mismatches
20
+ *
21
+ * Don't move below code outside the decorator file, it will break the module augmentation.
22
+ */
23
+ type __Shape = z.ZodRawShape;
24
+ type __AsZodObj<T> = T extends z.ZodObject<infer S> ? z.ZodObject<S> : T extends z.ZodRawShape ? z.ZodObject<T> : never;
25
+ export type ToolInputOf<Opt> = Opt extends {
26
+ inputSchema: infer I;
27
+ } ? z.infer<__AsZodObj<I>> : never;
28
+ /**
29
+ * Helper to infer the return type from any Zod schema,
30
+ * including ZodRawShape.
31
+ */
32
+ type __InferZod<S> = S extends z.ZodTypeAny ? z.infer<S> : S extends z.ZodRawShape ? z.infer<z.ZodObject<S>> : never;
33
+ /**
34
+ * Infers the *output type* from a *single schema definition*
35
+ * based on the new ToolSingleOutputType.
36
+ */
37
+ type __InferFromSingleSchema<S> = S extends 'image' ? z.infer<typeof ImageOutputSchema> : S extends 'audio' ? z.infer<typeof AudioOutputSchema> : S extends 'resource' ? z.infer<typeof ResourceOutputSchema> : S extends 'resource_link' ? z.infer<typeof ResourceLinkOutputSchema> : S extends 'string' ? string : S extends 'number' ? number : S extends 'boolean' ? boolean : S extends 'date' ? Date : S extends z.ZodTypeAny | z.ZodRawShape ? __InferZod<S> : any;
38
+ /**
39
+ * Infers a tuple/array of output types from an array of schemas
40
+ */
41
+ type __InferFromArraySchema<A> = A extends readonly any[] ? {
42
+ [K in keyof A]: __InferFromSingleSchema<A[K]>;
43
+ } : never;
44
+ /**
45
+ * Main output type inference.
46
+ * Handles single schemas, arrays of schemas, or no schema.
47
+ */
48
+ export type ToolOutputOf<Opt> = Opt extends {
49
+ outputSchema: infer O;
50
+ } ? O extends readonly any[] ? __InferFromArraySchema<O> : __InferFromSingleSchema<O> : any;
51
+ type __PrimitiveOutputType = 'string' | 'number' | 'date' | 'boolean' | z.ZodString | z.ZodNumber | z.ZodBoolean | z.ZodBigInt | z.ZodDate;
52
+ type __ImageOutputType = 'image';
53
+ type __AudioOutputType = 'audio';
54
+ type __ResourceOutputType = 'resource';
55
+ type __ResourceLinkOutputType = 'resource_link';
56
+ type __StructuredOutputType = z.ZodRawShape | z.ZodObject<any> | z.ZodArray<any> | z.ZodUnion<[z.ZodObject<any>, ...z.ZodObject<any>[]]> | z.ZodDiscriminatedUnion<any, any>;
57
+ type __ToolSingleOutputType = __PrimitiveOutputType | __ImageOutputType | __AudioOutputType | __ResourceOutputType | __ResourceLinkOutputType | __StructuredOutputType;
58
+ type __OutputSchema = __ToolSingleOutputType | __ToolSingleOutputType[];
59
+ export type ToolMetadataOptions<I extends __Shape, O extends __OutputSchema> = ToolMetadata<I | z.ZodObject<I>, // inputSchema can be a raw shape or ZodObject
60
+ O>;
61
+ type __Ctor = (new (...a: any[]) => any) | (abstract new (...a: any[]) => any);
62
+ type __A<C extends __Ctor> = C extends new (...a: infer A) => any ? A : C extends abstract new (...a: infer A) => any ? A : never;
63
+ type __R<C extends __Ctor> = C extends new (...a: any[]) => infer R ? R : C extends abstract new (...a: any[]) => infer R ? R : never;
64
+ type __Param<C extends __Ctor> = __R<C> extends {
65
+ execute: (arg: infer P, ...r: any) => any;
66
+ } ? P : never;
67
+ type __Return<C extends __Ctor> = __R<C> extends {
68
+ execute: (...a: any) => infer R;
69
+ } ? R : never;
70
+ type __Unwrap<T> = T extends Promise<infer U> ? U : T;
71
+ type __IsAny<T> = 0 extends 1 & T ? true : false;
72
+ type __MustExtendCtx<C extends __Ctor> = __R<C> extends ToolContext ? unknown : {
73
+ 'Tool class error': 'Class must extend ToolContext';
74
+ };
75
+ type __MustParam<C extends __Ctor, In> = __IsAny<In> extends true ? unknown : __IsAny<__Param<C>> extends true ? {
76
+ 'execute() parameter error': "Parameter type must not be 'any'.";
77
+ expected_input_type: In;
78
+ } : __Param<C> extends In ? In extends __Param<C> ? unknown : {
79
+ 'execute() parameter error': 'Parameter type is too wide. It must exactly match the input schema.';
80
+ expected_input_type: In;
81
+ actual_parameter_type: __Param<C>;
82
+ } : {
83
+ 'execute() parameter error': 'Parameter type does not match the input schema.';
84
+ expected_input_type: In;
85
+ actual_parameter_type: __Param<C>;
86
+ };
87
+ type __MustReturn<C extends __Ctor, Out> = __IsAny<Out> extends true ? unknown : __Unwrap<__Return<C>> extends Out ? unknown : {
88
+ 'execute() return type error': "The method's return type is not assignable to the expected output schema type.";
89
+ expected_output_type: Out;
90
+ 'actual_return_type (unwrapped)': __Unwrap<__Return<C>>;
91
+ };
92
+ type __Rewrap<C extends __Ctor, In, Out> = C extends abstract new (...a: __A<C>) => __R<C> ? C & (abstract new (...a: __A<C>) => ToolContext<any, any, In, Out> & __R<C>) : C extends new (...a: __A<C>) => __R<C> ? C & (new (...a: __A<C>) => ToolContext<any, any, In, Out> & __R<C>) : never;
93
+ declare module '@frontmcp/sdk' {
94
+ function Tool<I extends __Shape, O extends __OutputSchema, // Use our new output schema constraint
95
+ T extends ToolMetadataOptions<I, O> & {
96
+ outputSchema: any;
97
+ }>(opts: T): <C extends __Ctor>(cls: C & __MustExtendCtx<C> & __MustParam<C, ToolInputOf<T>> & // <-- Will now show a rich error
98
+ __MustReturn<C, ToolOutputOf<T>>) => __Rewrap<C, ToolInputOf<T>, ToolOutputOf<T>>;
99
+ function Tool<I extends __Shape, T extends ToolMetadataOptions<I, any> & {
100
+ outputSchema?: never;
101
+ }>(opts: T): <C extends __Ctor>(cls: C & __MustExtendCtx<C> & __MustParam<C, ToolInputOf<T>> & // <-- Will now show a rich error
102
+ __MustReturn<C, ToolOutputOf<T>>) => __Rewrap<C, ToolInputOf<T>, ToolOutputOf<T>>;
42
103
  }
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // @ts-ignore
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.FrontMcpTool = FrontMcpTool;
5
4
  exports.Tool = FrontMcpTool;
@@ -1 +1 @@
1
- {"version":3,"file":"tool.decorator.js","sourceRoot":"","sources":["../../../../src/common/decorators/tool.decorator.ts"],"names":[],"mappings":";AAAA,aAAa;;AAoDX,oCAAY;AACI,4BAAI;AACpB,oCAAY;AACI,4BAAI;AArDtB,4BAA0B;AAC1B,sCAAmE;AACnE,0CAAqE;AAIrE;;GAEG;AACH,SAAS,YAAY,CAAC,gBAA8B;IAElD,OAAO,CAAC,MAAW,EAAE,EAAE;QACrB,MAAM,QAAQ,GAAG,qCAA0B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpE,OAAO,CAAC,cAAc,CAAC,2BAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,IAAI,2BAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,cAAc,CAAC,2BAAkB,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;YACnF,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,OAAO,CAAC,cAAc,CAAC,6BAAoB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC,CAAC;AACJ,CAAC;AAKD;;GAEG;AACH,SAAS,YAAY,CAGnB,gBAAmB;IACnB,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,MAAM,QAAQ,GAAG,qCAA0B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpE,MAAM,YAAY,GAAG;YACnB,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE;YAC1B,CAAC,2BAAkB,CAAC,IAAI,CAAC,EAAE,eAAe;YAC1C,CAAC,2BAAkB,CAAC,QAAQ,CAAC,EAAE,QAAQ;SACxC,CAAC,CAAC;QACH,OAAO,YAAY,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// @ts-ignore\n\nimport 'reflect-metadata';\nimport {extendedToolMetadata, FrontMcpToolTokens} from '../tokens';\nimport {ToolMetadata, frontMcpToolMetadataSchema} from '../metadata';\nimport z from 'zod';\nimport {ToolContext} from \"../interfaces\";\n\n/**\n * Decorator that marks a class as a McpTool module and provides metadata\n */\nfunction FrontMcpTool(providedMetadata: ToolMetadata): ClassDecorator {\n\n return (target: any) => {\n const metadata = frontMcpToolMetadataSchema.parse(providedMetadata);\n Reflect.defineMetadata(FrontMcpToolTokens.type, true, target);\n const extended = {};\n for (const property in metadata) {\n if (FrontMcpToolTokens[property]) {\n Reflect.defineMetadata(FrontMcpToolTokens[property], metadata[property], target);\n } else {\n extended[property] = metadata[property];\n }\n }\n Reflect.defineMetadata(extendedToolMetadata, extended, target);\n };\n}\n\n\nexport type FrontMcpToolExecuteHandler<In extends object, Out extends object> = (input: In, ctx: ToolContext<In, Out>) => Out | Promise<Out>;\n\n/**\n * Decorator that marks a class as a McpTool module and provides metadata\n */\nfunction frontMcpTool<T extends ToolMetadata,\n In extends object = z.baseObjectInputType<T['inputSchema']>,\n Out extends object = T['outputSchema'] extends z.ZodRawShape ? z.baseObjectInputType<T['outputSchema']> : object\n>(providedMetadata: T): (handler: FrontMcpToolExecuteHandler<In, Out>) => (() => void) {\n return (execute) => {\n const metadata = frontMcpToolMetadataSchema.parse(providedMetadata);\n const toolFunction = function () {\n return execute;\n };\n Object.assign(toolFunction, {\n [FrontMcpToolTokens.type]: 'function-tool',\n [FrontMcpToolTokens.metadata]: metadata,\n });\n return toolFunction;\n };\n}\n\nexport {\n FrontMcpTool,\n FrontMcpTool as Tool,\n frontMcpTool,\n frontMcpTool as tool,\n};\n\n\ndeclare module \"@frontmcp/sdk\" {\n // ---------- zod helpers ----------\n type __Shape = z.ZodRawShape; // = Record<string, z.ZodTypeAny>\n type __AsZodObj<T> =\n T extends z.ZodObject<infer S> ? z.ZodObject<S> :\n T extends z.ZodRawShape ? z.ZodObject<T> :\n never;\n\n export type __InputOf<Opt> =\n Opt extends { inputSchema: infer I } ? z.infer<__AsZodObj<I>> : never;\n\n export type __OutputOf<Opt> =\n Opt extends { outputSchema: infer O } ? z.infer<__AsZodObj<O>> : never;\n\n export type __ToolOptions<I extends __Shape, O extends __Shape> = ToolMetadata<I | z.ZodObject<I>, O | z.ZodObject<O>>;\n\n // ---------- ctor & reflection ----------\n type __Ctor = new (...a: any[]) => any | (abstract new (...a: any[]) => any);\n type __A<C extends __Ctor> = C extends new (...a: infer A) => any ? A\n : C extends abstract new (...a: infer A) => any ? A : never;\n type __R<C extends __Ctor> = C extends new (...a: any[]) => infer R ? R\n : C extends abstract new (...a: any[]) => infer R ? R : never;\n\n type __Param<C extends __Ctor> =\n __R<C> extends { execute: (arg: infer P, ...r: any) => any } ? P : never;\n\n type __Return<C extends __Ctor> =\n __R<C> extends { execute: (...a: any) => infer R } ? R : never;\n\n type __Unwrap<T> = T extends Promise<infer U> ? U : T;\n type __IsAny<T> = 0 extends (1 & T) ? true : false;\n\n // ---------- friendly branded errors ----------\n type __Err<M extends string> = { __type_error__: M } & { never?: never };\n\n // Must extend ToolContext\n type __MustExtendCtx<C extends __Ctor> =\n __R<C> extends ToolContext ? {} :\n __Err<\"Class must extend ToolContext\">;\n\n // execute param must exactly match In (and not be any)\n type __MustParam<C extends __Ctor, In> =\n __IsAny<__Param<C>> extends true\n ? __Err<\"execute(input) must not be any and must exactly match input schema\">\n : __Param<C> extends In\n ? (In extends __Param<C> ? {} : __Err<\"execute(input) must be exactly the input schema (no widening or narrowing)\">)\n : __Err<\"execute(input) parameter does not match input schema\">;\n\n // execute return must be Out or Promise<Out>\n type __MustReturn<C extends __Ctor, Out> =\n __Unwrap<__Return<C>> extends Out ? {} :\n __Err<\"execute return type must be output schema or Promise<output schema>\">;\n\n // Rewrapped constructor: preserve concrete/abstract + original type, but guarantee ToolContext<In,Out> on instance\n type __Rewrap<C extends __Ctor, In, Out> =\n C extends abstract new (...a: __A<C>) => __R<C>\n ? C & (abstract new (...a: __A<C>) => (ToolContext<In, Out> & __R<C>))\n : C extends new (...a: __A<C>) => __R<C>\n ? C & (new (...a: __A<C>) => (ToolContext<In, Out> & __R<C>))\n : never;\n\n // ---------- the decorator ----------\n // @ts-expect-error - Module augmentation requires decorator overload\n export function Tool<\n I extends __Shape,\n O extends __Shape,\n T extends __ToolOptions<I, O>\n >(opts: T): <\n C extends __Ctor\n >(cls: C &\n __MustExtendCtx<C> &\n __MustParam<C, __InputOf<T>> &\n __MustReturn<C, __OutputOf<T>>\n ) => __Rewrap<C, __InputOf<T>, __OutputOf<T>>;\n}"]}
1
+ {"version":3,"file":"tool.decorator.js","sourceRoot":"","sources":["../../../../src/common/decorators/tool.decorator.ts"],"names":[],"mappings":";;AA8DS,oCAAY;AAAkB,4BAAI;AAAE,oCAAY;AAAkB,4BAAI;AA9D/E,4BAA0B;AAC1B,sCAAqE;AACrE,0CASqB;AAIrB;;GAEG;AACH,SAAS,YAAY,CAAC,gBAA8B;IAClD,OAAO,CAAC,MAAW,EAAE,EAAE;QACrB,MAAM,QAAQ,GAAG,qCAA0B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpE,OAAO,CAAC,cAAc,CAAC,2BAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,IAAI,2BAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,cAAc,CAAC,2BAAkB,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;YACnF,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,OAAO,CAAC,cAAc,CAAC,6BAAoB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC,CAAC;AACJ,CAAC;AASD;;GAEG;AACH,SAAS,YAAY,CAInB,gBAAmB;IACnB,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,MAAM,QAAQ,GAAG,qCAA0B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpE,MAAM,YAAY,GAAG;YACnB,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE;YAC1B,CAAC,2BAAkB,CAAC,IAAI,CAAC,EAAE,eAAe;YAC1C,CAAC,2BAAkB,CAAC,QAAQ,CAAC,EAAE,QAAQ;SACxC,CAAC,CAAC;QACH,OAAO,YAAY,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import 'reflect-metadata';\nimport { extendedToolMetadata, FrontMcpToolTokens } from '../tokens';\nimport {\n ToolMetadata,\n frontMcpToolMetadataSchema,\n ImageOutputSchema,\n AudioOutputSchema,\n ResourceOutputSchema,\n ResourceLinkOutputSchema,\n ToolInputType,\n ToolOutputType,\n} from '../metadata';\nimport z from 'zod';\nimport { ToolContext } from '../interfaces';\n\n/**\n * Decorator that marks a class as a McpTool module and provides metadata\n */\nfunction FrontMcpTool(providedMetadata: ToolMetadata): ClassDecorator {\n return (target: any) => {\n const metadata = frontMcpToolMetadataSchema.parse(providedMetadata);\n Reflect.defineMetadata(FrontMcpToolTokens.type, true, target);\n const extended = {};\n for (const property in metadata) {\n if (FrontMcpToolTokens[property]) {\n Reflect.defineMetadata(FrontMcpToolTokens[property], metadata[property], target);\n } else {\n extended[property] = metadata[property];\n }\n }\n Reflect.defineMetadata(extendedToolMetadata, extended, target);\n };\n}\n\nexport type FrontMcpToolExecuteHandler<\n InSchema extends ToolInputType,\n OutSchema extends ToolOutputType,\n In = ToolInputOf<{ inputSchema: InSchema }>,\n Out = ToolOutputOf<{ outputSchema: OutSchema }>,\n> = (input: In, ctx: ToolContext<InSchema, OutSchema>) => Out | Promise<Out>;\n\n/**\n * Decorator that marks a class as a McpTool module and provides metadata\n */\nfunction frontMcpTool<\n T extends ToolMetadata,\n InSchema extends ToolInputType = T['inputSchema'],\n OutSchema extends ToolOutputType = T['outputSchema'],\n>(providedMetadata: T): (handler: FrontMcpToolExecuteHandler<InSchema, OutSchema>) => () => void {\n return (execute) => {\n const metadata = frontMcpToolMetadataSchema.parse(providedMetadata);\n const toolFunction = function () {\n return execute;\n };\n Object.assign(toolFunction, {\n [FrontMcpToolTokens.type]: 'function-tool',\n [FrontMcpToolTokens.metadata]: metadata,\n });\n return toolFunction;\n };\n}\n\nexport { FrontMcpTool, FrontMcpTool as Tool, frontMcpTool, frontMcpTool as tool };\n\n/**\n * This is a modified version of the original decorator, with the following changes:\n * - Added support for ZodRawShape as inputSchema\n * - Added support for outputSchema: any of the allowed forms\n * - Added rich error messages for input/output type mismatches\n *\n * Don't move below code outside the decorator file, it will break the module augmentation.\n */\n// ---------- zod helpers ----------\ntype __Shape = z.ZodRawShape;\ntype __AsZodObj<T> = T extends z.ZodObject<infer S> ? z.ZodObject<S> : T extends z.ZodRawShape ? z.ZodObject<T> : never;\n\nexport type ToolInputOf<Opt> = Opt extends { inputSchema: infer I } ? z.infer<__AsZodObj<I>> : never;\n\n// ---------- output inference helpers for NEW schemas ----------\n\n/**\n * Helper to infer the return type from any Zod schema,\n * including ZodRawShape.\n */\ntype __InferZod<S> = S extends z.ZodTypeAny ? z.infer<S> : S extends z.ZodRawShape ? z.infer<z.ZodObject<S>> : never;\n\n/**\n * Infers the *output type* from a *single schema definition*\n * based on the new ToolSingleOutputType.\n */\ntype __InferFromSingleSchema<S> =\n // Handle specific MCP type literals\n S extends 'image'\n ? z.infer<typeof ImageOutputSchema>\n : S extends 'audio'\n ? z.infer<typeof AudioOutputSchema>\n : S extends 'resource'\n ? z.infer<typeof ResourceOutputSchema>\n : S extends 'resource_link'\n ? z.infer<typeof ResourceLinkOutputSchema>\n : // Handle primitive type literals\n S extends 'string'\n ? string\n : S extends 'number'\n ? number\n : S extends 'boolean'\n ? boolean\n : S extends 'date'\n ? Date\n : // Handle all Zod schemas (primitives, objects, arrays, etc.)\n // This will correctly infer z.ZodString to string, etc.\n S extends z.ZodTypeAny | z.ZodRawShape\n ? __InferZod<S>\n : // Fallback for unknown/unrecognized schema\n any;\n\n/**\n * Infers a tuple/array of output types from an array of schemas\n */\ntype __InferFromArraySchema<A> = A extends readonly any[] ? { [K in keyof A]: __InferFromSingleSchema<A[K]> } : never;\n\n/**\n * Main output type inference.\n * Handles single schemas, arrays of schemas, or no schema.\n */\nexport type ToolOutputOf<Opt> = Opt extends { outputSchema: infer O }\n ? O extends readonly any[] // Check for array/tuple first\n ? __InferFromArraySchema<O>\n : __InferFromSingleSchema<O> // Handle a single schema\n : any; // no outputSchema property at all -> allow anything\n\n// --- Define the schema types locally to constrain the generic ---\n// This mirrors your `ToolOutputType` definitions for use in constraints.\n\ntype __PrimitiveOutputType =\n | 'string'\n | 'number'\n | 'date'\n | 'boolean'\n | z.ZodString\n | z.ZodNumber\n | z.ZodBoolean\n | z.ZodBigInt\n | z.ZodDate;\ntype __ImageOutputType = 'image';\ntype __AudioOutputType = 'audio';\ntype __ResourceOutputType = 'resource';\ntype __ResourceLinkOutputType = 'resource_link';\ntype __StructuredOutputType =\n | z.ZodRawShape\n | z.ZodObject<any>\n | z.ZodArray<any>\n | z.ZodUnion<[z.ZodObject<any>, ...z.ZodObject<any>[]]>\n | z.ZodDiscriminatedUnion<any, any>;\n\ntype __ToolSingleOutputType =\n | __PrimitiveOutputType\n | __ImageOutputType\n | __AudioOutputType\n | __ResourceOutputType\n | __ResourceLinkOutputType\n | __StructuredOutputType;\n\n// This is the final constraint for the `outputSchema` option\ntype __OutputSchema = __ToolSingleOutputType | __ToolSingleOutputType[];\n\nexport type ToolMetadataOptions<I extends __Shape, O extends __OutputSchema> = ToolMetadata<\n I | z.ZodObject<I>, // inputSchema can be a raw shape or ZodObject\n O // outputSchema: any of the allowed forms\n>;\n\n// ---------- ctor & reflection ----------\ntype __Ctor = (new (...a: any[]) => any) | (abstract new (...a: any[]) => any);\ntype __A<C extends __Ctor> = C extends new (...a: infer A) => any\n ? A\n : C extends abstract new (...a: infer A) => any\n ? A\n : never;\ntype __R<C extends __Ctor> = C extends new (...a: any[]) => infer R\n ? R\n : C extends abstract new (...a: any[]) => infer R\n ? R\n : never;\ntype __Param<C extends __Ctor> = __R<C> extends { execute: (arg: infer P, ...r: any) => any } ? P : never;\ntype __Return<C extends __Ctor> = __R<C> extends { execute: (...a: any) => infer R } ? R : never;\ntype __Unwrap<T> = T extends Promise<infer U> ? U : T;\ntype __IsAny<T> = 0 extends 1 & T ? true : false;\n\n// ---------- friendly branded errors (UPDATED) ----------\n\n// Must extend ToolContext (assuming ToolContext is exported by the SDK)\ntype __MustExtendCtx<C extends __Ctor> = __R<C> extends ToolContext\n ? unknown\n : { 'Tool class error': 'Class must extend ToolContext' };\n\n// execute param must exactly match In (and not be any)\ntype __MustParam<C extends __Ctor, In> =\n // 1. If 'In' (from schema) is 'any', we can't check, so allow.\n __IsAny<In> extends true\n ? unknown\n : // 2. Check if the actual param type is 'any'. This is an error.\n __IsAny<__Param<C>> extends true\n ? { 'execute() parameter error': \"Parameter type must not be 'any'.\"; expected_input_type: In }\n : // 3. Check for the exact match: Param extends In AND In extends Param\n __Param<C> extends In\n ? In extends __Param<C>\n ? unknown // OK, exact match\n : {\n 'execute() parameter error': 'Parameter type is too wide. It must exactly match the input schema.';\n expected_input_type: In;\n actual_parameter_type: __Param<C>;\n }\n : {\n 'execute() parameter error': 'Parameter type does not match the input schema.';\n expected_input_type: In;\n actual_parameter_type: __Param<C>;\n };\n\n// execute return must be Out or Promise<Out>\ntype __MustReturn<C extends __Ctor, Out> =\n // 1. If 'Out' (from schema) is 'any', no check is needed.\n __IsAny<Out> extends true\n ? unknown\n : // 2. Check if the unwrapped return type is assignable to Out.\n __Unwrap<__Return<C>> extends Out\n ? unknown // OK\n : {\n 'execute() return type error': \"The method's return type is not assignable to the expected output schema type.\";\n expected_output_type: Out;\n 'actual_return_type (unwrapped)': __Unwrap<__Return<C>>;\n };\n\n// Rewrapped constructor with updated ToolContext generic params\ntype __Rewrap<C extends __Ctor, In, Out> = C extends abstract new (...a: __A<C>) => __R<C>\n ? C & (abstract new (...a: __A<C>) => ToolContext<any, any, In, Out> & __R<C>)\n : C extends new (...a: __A<C>) => __R<C>\n ? C & (new (...a: __A<C>) => ToolContext<any, any, In, Out> & __R<C>)\n : never;\n\ndeclare module '@frontmcp/sdk' {\n // ---------- the decorator (overloads) ----------\n\n // 1) Overload: outputSchema PROVIDED → strict return typing\n // @ts-expect-error - Module augmentation requires decorator overload\n export function Tool<\n I extends __Shape,\n O extends __OutputSchema, // Use our new output schema constraint\n T extends ToolMetadataOptions<I, O> & { outputSchema: any }, // ensure present\n >(\n opts: T,\n ): <C extends __Ctor>(\n cls: C &\n __MustExtendCtx<C> &\n __MustParam<C, ToolInputOf<T>> & // <-- Will now show a rich error\n __MustReturn<C, ToolOutputOf<T>>, // <-- Will now show a rich error\n ) => __Rewrap<C, ToolInputOf<T>, ToolOutputOf<T>>;\n\n // 2) Overload: outputSchema NOT PROVIDED → execute() can return any\n // @ts-expect-error - Module augmentation requires decorator overload\n export function Tool<\n I extends __Shape,\n // Note: 'O' is omitted, 'any' is used for the generic\n T extends ToolMetadataOptions<I, any> & { outputSchema?: never }, // ensure absent\n >(\n opts: T,\n ): <C extends __Ctor>(\n cls: C &\n __MustExtendCtx<C> &\n __MustParam<C, ToolInputOf<T>> & // <-- Will now show a rich error\n __MustReturn<C, ToolOutputOf<T>>, // <-- Will now show 'any'\n ) => __Rewrap<C, ToolInputOf<T>, ToolOutputOf<T>>;\n}\n"]}
@@ -1,19 +1,62 @@
1
- import { z } from 'zod';
2
1
  import { BaseEntry, EntryOwnerRef } from './base.entry';
3
2
  import { ToolRecord } from '../records';
4
3
  import { ToolContext } from '../interfaces';
5
- import { ToolMetadata } from '../metadata';
6
- import { Request, Notification, CallToolRequest } from "@modelcontextprotocol/sdk/types.js";
7
- import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
8
- import { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
9
- export type ToolCallArgs = CallToolRequest["params"]["arguments"];
4
+ import { ToolInputType, ToolMetadata, ToolOutputType } from '../metadata';
5
+ import { Request, Notification, CallToolRequest, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
6
+ import { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
7
+ import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
8
+ import { ToolInputOf, ToolOutputOf } from '../decorators';
9
+ export type ToolCallArgs = CallToolRequest['params']['arguments'];
10
10
  export type ToolCallExtra = RequestHandlerExtra<Request, Notification> & {
11
11
  authInfo: AuthInfo;
12
12
  };
13
- export declare abstract class ToolEntry<In extends object = any, Out extends object = any> extends BaseEntry<ToolRecord, ToolContext<In, Out>, ToolMetadata> {
13
+ export type ParsedToolResult = CallToolResult;
14
+ export type SafeTransformResult<T> = {
15
+ success: true;
16
+ data: T;
17
+ } | {
18
+ success: false;
19
+ error: Error;
20
+ };
21
+ export declare abstract class ToolEntry<InSchema extends ToolInputType = ToolInputType, OutSchema extends ToolOutputType = ToolOutputType, In = ToolInputOf<{
22
+ inputSchema: InSchema;
23
+ }>, Out = ToolOutputOf<{
24
+ outputSchema: OutSchema;
25
+ }>> extends BaseEntry<ToolRecord, ToolContext<InSchema, OutSchema, In, Out>, ToolMetadata> {
14
26
  owner: EntryOwnerRef;
15
- inputSchema: z.ZodObject<any>;
16
- rawInputSchema: z.ZodObject<any>;
17
- outputSchema: z.ZodObject<any>;
18
- abstract create(input: ToolCallArgs, ctx: ToolCallExtra): ToolContext<In, Out>;
27
+ /**
28
+ * The name of the tool, as declared in the metadata.
29
+ */
30
+ name: string;
31
+ /**
32
+ * The full name of the tool, including the owner name as prefix.
33
+ */
34
+ fullName: string;
35
+ inputSchema: InSchema;
36
+ rawInputSchema: any;
37
+ outputSchema?: OutSchema;
38
+ /**
39
+ * Accessor used by tools/list to expose the tool's declared outputSchema.
40
+ * This returns the exact value from metadata (string literal, zod schema,
41
+ * raw shape, or an array of those).
42
+ */
43
+ getOutputSchema(): OutSchema | undefined;
44
+ /**
45
+ * Create a tool context (class or function wrapper).
46
+ */
47
+ abstract create(input: ToolCallArgs, ctx: ToolCallExtra): ToolContext<InSchema, OutSchema, In, Out>;
48
+ /**
49
+ * Convert the raw tool request input into an MCP CallToolRequest-shaped object.
50
+ */
51
+ abstract parseInput(input: CallToolRequest['params']): CallToolRequest['params']['arguments'];
52
+ /**
53
+ * Convert the raw tool return value (Out) into an MCP CallToolResult-shaped object.
54
+ * Concrete logic is implemented in ToolInstance.
55
+ */
56
+ abstract parseOutput(result: Out | Partial<Out> | any): ParsedToolResult;
57
+ /**
58
+ * Convert the raw tool return value (Out) into an MCP CallToolResult-shaped object.
59
+ * Concrete logic is implemented in ToolInstance.
60
+ */
61
+ abstract safeParseOutput(raw: Out | Partial<Out> | any): SafeTransformResult<ParsedToolResult>;
19
62
  }
@@ -1,12 +1,31 @@
1
1
  "use strict";
2
+ // file: libs/sdk/src/common/entries/tool.entry.ts
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.ToolEntry = void 0;
4
5
  const base_entry_1 = require("./base.entry");
5
6
  class ToolEntry extends base_entry_1.BaseEntry {
6
7
  owner;
8
+ /**
9
+ * The name of the tool, as declared in the metadata.
10
+ */
11
+ name;
12
+ /**
13
+ * The full name of the tool, including the owner name as prefix.
14
+ */
15
+ fullName;
7
16
  inputSchema;
17
+ // This is whatever JSON-schema-ish thing you store for input; keeping type loose
8
18
  rawInputSchema;
19
+ // This is your *metadata* outputSchema (literals / zod / raw shapes / arrays)
9
20
  outputSchema;
21
+ /**
22
+ * Accessor used by tools/list to expose the tool's declared outputSchema.
23
+ * This returns the exact value from metadata (string literal, zod schema,
24
+ * raw shape, or an array of those).
25
+ */
26
+ getOutputSchema() {
27
+ return this.outputSchema;
28
+ }
10
29
  }
11
30
  exports.ToolEntry = ToolEntry;
12
31
  //# sourceMappingURL=tool.entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.entry.js","sourceRoot":"","sources":["../../../../src/common/entries/tool.entry.ts"],"names":[],"mappings":";;;AACA,6CAAsD;AActD,MAAsB,SAA6D,SAAQ,sBAAyD;IAClJ,KAAK,CAAgB;IACrB,WAAW,CAAmB;IAC9B,cAAc,CAAmB;IACjC,YAAY,CAAmB;CAGhC;AAPD,8BAOC","sourcesContent":["import {z} from 'zod';\nimport {BaseEntry, EntryOwnerRef} from './base.entry';\nimport {ToolRecord} from '../records';\nimport {ToolContext} from '../interfaces';\nimport {ToolMetadata} from '../metadata';\nimport {Request, Notification, CallToolRequest} from \"@modelcontextprotocol/sdk/types.js\";\nimport {RequestHandlerExtra} from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport {AuthInfo} from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\n\nexport type ToolCallArgs = CallToolRequest[\"params\"][\"arguments\"];\nexport type ToolCallExtra = RequestHandlerExtra<Request, Notification> & {\n authInfo: AuthInfo;\n};\n\nexport abstract class ToolEntry<In extends object = any, Out extends object = any> extends BaseEntry<ToolRecord, ToolContext<In, Out>, ToolMetadata> {\n owner: EntryOwnerRef;\n inputSchema: z.ZodObject<any>;\n rawInputSchema: z.ZodObject<any>;\n outputSchema: z.ZodObject<any>;\n\n abstract create(input: ToolCallArgs, ctx: ToolCallExtra): ToolContext<In, Out>;\n}\n"]}
1
+ {"version":3,"file":"tool.entry.js","sourceRoot":"","sources":["../../../../src/common/entries/tool.entry.ts"],"names":[],"mappings":";AAAA,kDAAkD;;;AAElD,6CAAwD;AAiBxD,MAAsB,SAKpB,SAAQ,sBAA8E;IACtF,KAAK,CAAgB;IACrB;;OAEG;IACH,IAAI,CAAS;IACb;;OAEG;IACH,QAAQ,CAAS;IAEjB,WAAW,CAAW;IACtB,iFAAiF;IACjF,cAAc,CAAM;IACpB,8EAA8E;IAC9E,YAAY,CAAa;IAEzB;;;;OAIG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CAsBF;AAnDD,8BAmDC","sourcesContent":["// file: libs/sdk/src/common/entries/tool.entry.ts\n\nimport { BaseEntry, EntryOwnerRef } from './base.entry';\nimport { ToolRecord } from '../records';\nimport { ToolContext } from '../interfaces';\nimport { ToolInputType, ToolMetadata, ToolOutputType } from '../metadata';\nimport { Request, Notification, CallToolRequest, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { ToolInputOf, ToolOutputOf } from '../decorators';\n\nexport type ToolCallArgs = CallToolRequest['params']['arguments'];\nexport type ToolCallExtra = RequestHandlerExtra<Request, Notification> & {\n authInfo: AuthInfo;\n};\n\nexport type ParsedToolResult = CallToolResult;\nexport type SafeTransformResult<T> = { success: true; data: T } | { success: false; error: Error };\n\nexport abstract class ToolEntry<\n InSchema extends ToolInputType = ToolInputType,\n OutSchema extends ToolOutputType = ToolOutputType,\n In = ToolInputOf<{ inputSchema: InSchema }>,\n Out = ToolOutputOf<{ outputSchema: OutSchema }>,\n> extends BaseEntry<ToolRecord, ToolContext<InSchema, OutSchema, In, Out>, ToolMetadata> {\n owner: EntryOwnerRef;\n /**\n * The name of the tool, as declared in the metadata.\n */\n name: string;\n /**\n * The full name of the tool, including the owner name as prefix.\n */\n fullName: string;\n\n inputSchema: InSchema;\n // This is whatever JSON-schema-ish thing you store for input; keeping type loose\n rawInputSchema: any;\n // This is your *metadata* outputSchema (literals / zod / raw shapes / arrays)\n outputSchema?: OutSchema;\n\n /**\n * Accessor used by tools/list to expose the tool's declared outputSchema.\n * This returns the exact value from metadata (string literal, zod schema,\n * raw shape, or an array of those).\n */\n getOutputSchema(): OutSchema | undefined {\n return this.outputSchema;\n }\n\n /**\n * Create a tool context (class or function wrapper).\n */\n abstract create(input: ToolCallArgs, ctx: ToolCallExtra): ToolContext<InSchema, OutSchema, In, Out>;\n\n /**\n * Convert the raw tool request input into an MCP CallToolRequest-shaped object.\n */\n abstract parseInput(input: CallToolRequest['params']): CallToolRequest['params']['arguments'];\n\n /**\n * Convert the raw tool return value (Out) into an MCP CallToolResult-shaped object.\n * Concrete logic is implemented in ToolInstance.\n */\n abstract parseOutput(result: Out | Partial<Out> | any): ParsedToolResult;\n /**\n * Convert the raw tool return value (Out) into an MCP CallToolResult-shaped object.\n * Concrete logic is implemented in ToolInstance.\n */\n abstract safeParseOutput(raw: Out | Partial<Out> | any): SafeTransformResult<ParsedToolResult>;\n}\n"]}
@@ -2,8 +2,8 @@ import { ScopeEntry, FlowEntry, AuthProviderEntry, AppEntry, ProviderEntry, Plug
2
2
  import { Token } from '../base.interface';
3
3
  import { FrontMcpAuth } from './primary-auth-provider.interface';
4
4
  import { FlowName } from '../../metadata';
5
- import { FlowCtxOf, FlowInputOf, FlowStagesOf } from "../flow.interface";
6
- import { HookRecord } from "../../records";
5
+ import { FlowCtxOf, FlowInputOf, FlowStagesOf } from '../flow.interface';
6
+ import { HookRecord } from '../../records';
7
7
  export interface ScopeRegistryInterface {
8
8
  getScopes(): ScopeEntry[];
9
9
  }
@@ -30,6 +30,14 @@ export interface HookRegistryInterface {
30
30
  * @param stage
31
31
  */
32
32
  getFlowStageHooks<Name extends FlowName>(flow: Name, stage: FlowStagesOf<Name> | string): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];
33
+ /**
34
+ * Used to pull hooks for a specific flow, optionally filtered by owner ID.
35
+ * Returns all hooks if no ownerId is provided, or only hooks belonging to
36
+ * the specified owner or global hooks (no owner) if ownerId is provided.
37
+ * @param flow
38
+ * @param ownerId
39
+ */
40
+ getFlowHooksForOwner<Name extends FlowName>(flow: Name, ownerId?: string): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];
33
41
  registerHooks(embedded: boolean, ...records: HookRecord[]): Promise<void[]>;
34
42
  }
35
43
  export interface ProviderViews {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.interface.js","sourceRoot":"","sources":["../../../../../src/common/interfaces/internal/registry.interface.ts"],"names":[],"mappings":"","sourcesContent":["import {\n ScopeEntry,\n FlowEntry,\n AuthProviderEntry,\n AppEntry,\n ProviderEntry,\n PluginEntry,\n AdapterEntry,\n PromptEntry,\n ResourceEntry,\n ToolEntry,\n LoggerEntry,\n EntryOwnerRef,\n HookEntry\n} from '../../entries';\nimport {Token} from '../base.interface';\nimport {FrontMcpAuth} from './primary-auth-provider.interface';\nimport {FlowName} from '../../metadata';\nimport {FlowCtxOf, FlowInputOf, FlowStagesOf} from \"../flow.interface\";\nimport {HookRecord} from \"../../records\";\n\nexport interface ScopeRegistryInterface {\n getScopes(): ScopeEntry[];\n}\n\nexport interface FlowRegistryInterface {\n getFlows(): FlowEntry<FlowName>[];\n}\n\nexport interface HookRegistryInterface {\n /**\n * used to pull hooks registered by a class and related to that class only,\n * like registering hooks on specific tool execution\n * @param token\n */\n getClsHooks(token: Token): HookEntry[];\n\n /**\n * Used to pull all hooks registered to specific flow by name,\n * this is used to construct the flow graph and execute hooks in order\n * @param flow\n */\n getFlowHooks<Name extends FlowName>(flow: Name): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];\n\n\n /**\n * Used to pull all hooks registered to specific flow and stage by name,\n * this is used to construct the flow graph and execute hooks in order\n * @param flow\n * @param stage\n */\n getFlowStageHooks<Name extends FlowName>(\n flow: Name,\n stage: FlowStagesOf<Name> | string\n ): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[]\n\n registerHooks(embedded: boolean, ...records: HookRecord[]): Promise<void[]>;\n}\n\n\nexport interface ProviderViews {\n /** App-wide singletons, created at boot. Immutable from invokes POV. */\n global: ReadonlyMap<Token, unknown>;\n /** Session-scoped cache for this sessionId. Mutable. */\n session: Map<Token, unknown>;\n /** Request-scoped providers for this single invocation. Mutable. */\n request: Map<Token, unknown>;\n}\n\n\nexport interface ProviderRegistryInterface {\n get<T>(token: Token<T>): T;\n\n getProviders(): ProviderEntry[];\n\n getRegistries<T extends RegistryKind>(type: T): RegistryType[T][];\n\n // TODO: fix session type\n buildViews(session: any): Promise<ProviderViews>;\n}\n\nexport interface AuthRegistryInterface {\n getPrimary(): FrontMcpAuth;\n\n getAuthProviders(): AuthProviderEntry[];\n}\n\nexport interface AppRegistryInterface {\n getApps(): AppEntry[];\n}\n\nexport interface PluginRegistryInterface {\n getPlugins(): PluginEntry[];\n}\n\nexport interface AdapterRegistryInterface {\n getAdapters(): AdapterEntry[];\n}\n\nexport interface ToolRegistryInterface {\n owner: EntryOwnerRef;\n\n // inline tools plus discovered by nested tool registries\n getTools(includeHidden?: boolean): ToolEntry[];\n\n // inline tools only\n getInlineTools(): ToolEntry<any, any>[];\n}\n\n\nexport interface ResourceRegistryInterface {\n // inline resources plus discovered by nested tool registries\n getResources(): ResourceEntry<any, any>[];\n\n // inline resources only\n getInlineResources(): ResourceEntry<any, any>[];\n}\n\n\nexport interface PromptRegistryInterface {\n // inline prompts plus discovered by nested tool registries\n getPrompts(): PromptEntry[];\n\n // inline prompts only\n getInlinePrompts(): PromptEntry[];\n}\n\n\nexport interface LoggerRegistryInterface {\n getLoggers(): LoggerEntry[];\n\n}\n\n\nexport type GlobalRegistryKind =\n | 'LoggerRegistry'\n | 'ScopeRegistry'\n\nexport type ScopedRegistryKind =\n | 'AppRegistry'\n | 'AuthRegistry'\n | 'FlowRegistry'\n | 'HookRegistry'\n\nexport type AppRegistryKind =\n | 'ProviderRegistry'\n | 'PluginRegistry'\n | 'AdapterRegistry'\n | 'ToolRegistry'\n | 'PromptRegistry'\n | 'ResourceRegistry'\n\n\nexport type RegistryKind = GlobalRegistryKind | ScopedRegistryKind | AppRegistryKind;\n\nexport type RegistryType = {\n LoggerRegistry: LoggerRegistryInterface;\n ScopeRegistry: ScopeRegistryInterface;\n FlowRegistry: FlowRegistryInterface;\n HookRegistry: HookRegistryInterface;\n AppRegistry: AppRegistryInterface;\n AuthRegistry: AuthRegistryInterface,\n ProviderRegistry: ProviderRegistryInterface;\n PluginRegistry: PluginRegistryInterface;\n AdapterRegistry: AdapterRegistryInterface;\n ToolRegistry: ToolRegistryInterface;\n ResourceRegistry: ResourceRegistryInterface;\n PromptRegistry: PromptRegistryInterface;\n}"]}
1
+ {"version":3,"file":"registry.interface.js","sourceRoot":"","sources":["../../../../../src/common/interfaces/internal/registry.interface.ts"],"names":[],"mappings":"","sourcesContent":["import {\n ScopeEntry,\n FlowEntry,\n AuthProviderEntry,\n AppEntry,\n ProviderEntry,\n PluginEntry,\n AdapterEntry,\n PromptEntry,\n ResourceEntry,\n ToolEntry,\n LoggerEntry,\n EntryOwnerRef,\n HookEntry,\n} from '../../entries';\nimport { Token } from '../base.interface';\nimport { FrontMcpAuth } from './primary-auth-provider.interface';\nimport { FlowName } from '../../metadata';\nimport { FlowCtxOf, FlowInputOf, FlowStagesOf } from '../flow.interface';\nimport { HookRecord } from '../../records';\n\nexport interface ScopeRegistryInterface {\n getScopes(): ScopeEntry[];\n}\n\nexport interface FlowRegistryInterface {\n getFlows(): FlowEntry<FlowName>[];\n}\n\nexport interface HookRegistryInterface {\n /**\n * used to pull hooks registered by a class and related to that class only,\n * like registering hooks on specific tool execution\n * @param token\n */\n getClsHooks(token: Token): HookEntry[];\n\n /**\n * Used to pull all hooks registered to specific flow by name,\n * this is used to construct the flow graph and execute hooks in order\n * @param flow\n */\n getFlowHooks<Name extends FlowName>(\n flow: Name,\n ): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];\n\n /**\n * Used to pull all hooks registered to specific flow and stage by name,\n * this is used to construct the flow graph and execute hooks in order\n * @param flow\n * @param stage\n */\n getFlowStageHooks<Name extends FlowName>(\n flow: Name,\n stage: FlowStagesOf<Name> | string,\n ): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];\n\n /**\n * Used to pull hooks for a specific flow, optionally filtered by owner ID.\n * Returns all hooks if no ownerId is provided, or only hooks belonging to\n * the specified owner or global hooks (no owner) if ownerId is provided.\n * @param flow\n * @param ownerId\n */\n getFlowHooksForOwner<Name extends FlowName>(\n flow: Name,\n ownerId?: string,\n ): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];\n\n registerHooks(embedded: boolean, ...records: HookRecord[]): Promise<void[]>;\n}\n\nexport interface ProviderViews {\n /** App-wide singletons, created at boot. Immutable from invokes POV. */\n global: ReadonlyMap<Token, unknown>;\n /** Session-scoped cache for this sessionId. Mutable. */\n session: Map<Token, unknown>;\n /** Request-scoped providers for this single invocation. Mutable. */\n request: Map<Token, unknown>;\n}\n\nexport interface ProviderRegistryInterface {\n get<T>(token: Token<T>): T;\n\n getProviders(): ProviderEntry[];\n\n getRegistries<T extends RegistryKind>(type: T): RegistryType[T][];\n\n // TODO: fix session type\n buildViews(session: any): Promise<ProviderViews>;\n}\n\nexport interface AuthRegistryInterface {\n getPrimary(): FrontMcpAuth;\n\n getAuthProviders(): AuthProviderEntry[];\n}\n\nexport interface AppRegistryInterface {\n getApps(): AppEntry[];\n}\n\nexport interface PluginRegistryInterface {\n getPlugins(): PluginEntry[];\n}\n\nexport interface AdapterRegistryInterface {\n getAdapters(): AdapterEntry[];\n}\n\nexport interface ToolRegistryInterface {\n owner: EntryOwnerRef;\n\n // inline tools plus discovered by nested tool registries\n getTools(includeHidden?: boolean): ToolEntry[];\n\n // inline tools only\n getInlineTools(): ToolEntry<any, any>[];\n}\n\nexport interface ResourceRegistryInterface {\n // inline resources plus discovered by nested tool registries\n getResources(): ResourceEntry<any, any>[];\n\n // inline resources only\n getInlineResources(): ResourceEntry<any, any>[];\n}\n\nexport interface PromptRegistryInterface {\n // inline prompts plus discovered by nested tool registries\n getPrompts(): PromptEntry[];\n\n // inline prompts only\n getInlinePrompts(): PromptEntry[];\n}\n\nexport interface LoggerRegistryInterface {\n getLoggers(): LoggerEntry[];\n}\n\nexport type GlobalRegistryKind = 'LoggerRegistry' | 'ScopeRegistry';\n\nexport type ScopedRegistryKind = 'AppRegistry' | 'AuthRegistry' | 'FlowRegistry' | 'HookRegistry';\n\nexport type AppRegistryKind =\n | 'ProviderRegistry'\n | 'PluginRegistry'\n | 'AdapterRegistry'\n | 'ToolRegistry'\n | 'PromptRegistry'\n | 'ResourceRegistry';\n\nexport type RegistryKind = GlobalRegistryKind | ScopedRegistryKind | AppRegistryKind;\n\nexport type RegistryType = {\n LoggerRegistry: LoggerRegistryInterface;\n ScopeRegistry: ScopeRegistryInterface;\n FlowRegistry: FlowRegistryInterface;\n HookRegistry: HookRegistryInterface;\n AppRegistry: AppRegistryInterface;\n AuthRegistry: AuthRegistryInterface;\n ProviderRegistry: ProviderRegistryInterface;\n PluginRegistry: PluginRegistryInterface;\n AdapterRegistry: AdapterRegistryInterface;\n ToolRegistry: ToolRegistryInterface;\n ResourceRegistry: ResourceRegistryInterface;\n PromptRegistry: PromptRegistryInterface;\n};\n"]}
@@ -5,4 +5,4 @@ export interface PluginInterface {
5
5
  export type PluginClassType<Provide> = ClassType<Provide> & PluginMetadata;
6
6
  export type PluginValueType<Provide> = ValueType<Provide> & PluginMetadata;
7
7
  export type PluginFactoryType<Provide, Tokens extends readonly Token[]> = FactoryType<Provide, Tokens> & PluginMetadata;
8
- export type PluginType<Provide extends PluginInterface = PluginInterface> = Type<Provide> | PluginClassType<Provide> | PluginValueType<Provide> | PluginFactoryType<Provide, any[]>;
8
+ export type PluginType<Provide extends PluginInterface = PluginInterface> = Type<Provide> | PluginClassType<Provide> | PluginValueType<Provide> | PluginFactoryType<Provide, readonly any[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/plugin.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { Type, Token, ValueType, ClassType, FactoryType } from './base.interface';\nimport { PluginMetadata } from '../metadata';\n\nexport interface PluginInterface {\n\n}\n\n\nexport type PluginClassType<Provide> = ClassType<Provide> & PluginMetadata;\nexport type PluginValueType<Provide> = ValueType<Provide> & PluginMetadata;\nexport type PluginFactoryType<Provide, Tokens extends readonly Token[]> = FactoryType<Provide, Tokens> & PluginMetadata;\n\n\nexport type PluginType<Provide extends PluginInterface = PluginInterface> =\n | Type<Provide>\n | PluginClassType<Provide>\n | PluginValueType<Provide>\n | PluginFactoryType<Provide, any[]>\n\n"]}
1
+ {"version":3,"file":"plugin.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/plugin.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { Type, Token, ValueType, ClassType, FactoryType } from './base.interface';\nimport { PluginMetadata } from '../metadata';\n\nexport interface PluginInterface {\n\n}\n\n\nexport type PluginClassType<Provide> = ClassType<Provide> & PluginMetadata;\nexport type PluginValueType<Provide> = ValueType<Provide> & PluginMetadata;\nexport type PluginFactoryType<Provide, Tokens extends readonly Token[]> = FactoryType<Provide, Tokens> & PluginMetadata;\n\n\nexport type PluginType<Provide extends PluginInterface = PluginInterface> =\n | Type<Provide>\n | PluginClassType<Provide>\n | PluginValueType<Provide>\n | PluginFactoryType<Provide, readonly any[]>\n\n"]}
@@ -1,9 +1,10 @@
1
- import { FuncType, Token, Type } from "./base.interface";
2
- import { ProviderRegistryInterface } from "./internal";
3
- import { ToolMetadata } from "../metadata";
4
- import { FrontMcpLogger } from "./logger.interface";
5
- import { URL } from "url";
6
- import { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
1
+ import { FuncType, Token, Type } from './base.interface';
2
+ import { ProviderRegistryInterface } from './internal';
3
+ import { ToolInputType, ToolMetadata, ToolOutputType } from '../metadata';
4
+ import { FrontMcpLogger } from './logger.interface';
5
+ import { URL } from 'url';
6
+ import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
7
+ import { ToolInputOf, ToolOutputOf } from '../decorators';
7
8
  export type ToolType<T = any> = Type<T> | FuncType<T>;
8
9
  type HistoryEntry<T> = {
9
10
  at: number;
@@ -18,7 +19,11 @@ export type ToolCtorArgs<In> = {
18
19
  logger: FrontMcpLogger;
19
20
  authInfo: AuthInfo;
20
21
  };
21
- export declare abstract class ToolContext<In = any, Out = any> {
22
+ export declare abstract class ToolContext<InSchema extends ToolInputType = ToolInputType, OutSchema extends ToolOutputType = ToolOutputType, In = ToolInputOf<{
23
+ inputSchema: InSchema;
24
+ }>, Out = ToolOutputOf<{
25
+ outputSchema: OutSchema;
26
+ }>> {
22
27
  private providers;
23
28
  readonly authInfo: AuthInfo;
24
29
  protected readonly runId: string;
@@ -64,7 +64,7 @@ class ToolContext {
64
64
  }
65
65
  set output(v) {
66
66
  this._output = v;
67
- this._outputHistory.push({ at: Date.now(), stage: this.activeStage, value: v, });
67
+ this._outputHistory.push({ at: Date.now(), stage: this.activeStage, value: v });
68
68
  }
69
69
  get outputHistory() {
70
70
  return this._outputHistory;
@@ -1 +1 @@
1
- {"version":3,"file":"tool.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/tool.interface.ts"],"names":[],"mappings":"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","sourcesContent":["import {randomUUID} from \"crypto\";\nimport {FuncType, Token, Type} from \"./base.interface\";\nimport {ProviderRegistryInterface} from \"./internal\";\nimport {ToolMetadata} from \"../metadata\";\nimport {FrontMcpLogger} from \"./logger.interface\";\nimport {FlowControl} from \"./flow.interface\";\nimport {URL} from \"url\";\nimport {AuthInfo} from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\nexport type ToolType<T = any> =\n | Type<T>\n | FuncType<T>\n\ntype HistoryEntry<T> = {\n at: number;\n stage?: string;\n value: T | undefined;\n note?: string;\n};\n\nexport type ToolCtorArgs<In> = {\n metadata: ToolMetadata;\n input: In;\n providers: ProviderRegistryInterface;\n logger: FrontMcpLogger\n authInfo: AuthInfo;\n}\n\nexport abstract class ToolContext<In = any, Out= any> {\n private providers: ProviderRegistryInterface;\n readonly authInfo: AuthInfo;\n\n protected readonly runId: string;\n protected readonly toolId: string;\n protected readonly toolName: string;\n readonly metadata: ToolMetadata;\n protected readonly logger: FrontMcpLogger;\n\n protected activeStage: string;\n\n // ---- INPUT storages (backing fields)\n private _rawInput?: Partial<In> | any;\n private _input?: In;\n\n // ---- OUTPUT storages (backing fields)\n private _outputDraft?: Partial<Out> | any;\n private _output?: Out;\n\n private _error?: Error;\n\n // ---- histories\n private readonly _inputHistory: HistoryEntry<In>[] = [];\n private readonly _outputHistory: HistoryEntry<Out>[] = [];\n\n\n constructor(args: ToolCtorArgs<In>) {\n const {metadata, input, providers, logger, authInfo} = args;\n this.runId = randomUUID();\n this.toolName = metadata.name;\n this.toolId = metadata.id ?? metadata.name;\n this.metadata = metadata;\n this._input = input;\n this.providers = providers;\n this.logger = logger.child(`tool:${this.toolId}`);\n this.authInfo = authInfo;\n }\n\n abstract execute(input: In): Promise<Out>;\n\n get<T>(token: Token<T>): T {\n return this.providers.get(token);\n }\n\n tryGet<T>(token: Token<T>): T | undefined {\n try {\n return this.providers.get(token);\n } catch (e) {\n this.logger.warn(\"Requesting provider that doesn't exist: \", token);\n return undefined;\n }\n }\n\n public get input(): In {\n return this._input as In;\n }\n\n public set input(v: In | undefined) {\n this._input = v;\n this._inputHistory.push({\n at: Date.now(),\n stage: this.activeStage,\n value: v,\n });\n }\n\n public get inputHistory(): ReadonlyArray<HistoryEntry<In>> {\n return this._inputHistory;\n }\n\n public get output(): Out | undefined {\n return this._output;\n }\n\n public set output(v: Out | undefined) {\n this._output = v;\n this._outputHistory.push({at: Date.now(), stage: this.activeStage, value: v,});\n }\n\n public get outputHistory(): ReadonlyArray<HistoryEntry<Out>> {\n return this._outputHistory;\n }\n\n respond(value: Out): never {\n // record validated output and surface the value via control flow\n this.output = value;\n FlowControl.respond<Out>(value);\n }\n\n /** Fail the run (invoker will run error/finalize). */\n protected fail(err: Error): never {\n this._error = err;\n FlowControl.fail(err);\n }\n\n mark(stage: string): void {\n this.activeStage = stage;\n }\n\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n}\n\n"]}
1
+ {"version":3,"file":"tool.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/tool.interface.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'crypto';\nimport { FuncType, Token, Type } from './base.interface';\nimport { ProviderRegistryInterface } from './internal';\nimport { ToolInputType, ToolMetadata, ToolOutputType } from '../metadata';\nimport { FrontMcpLogger } from './logger.interface';\nimport { FlowControl } from './flow.interface';\nimport { URL } from 'url';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { ToolInputOf, ToolOutputOf } from '../decorators';\n\nexport type ToolType<T = any> = Type<T> | FuncType<T>;\n\ntype HistoryEntry<T> = {\n at: number;\n stage?: string;\n value: T | undefined;\n note?: string;\n};\n\nexport type ToolCtorArgs<In> = {\n metadata: ToolMetadata;\n input: In;\n providers: ProviderRegistryInterface;\n logger: FrontMcpLogger;\n authInfo: AuthInfo;\n};\n\nexport abstract class ToolContext<\n InSchema extends ToolInputType = ToolInputType,\n OutSchema extends ToolOutputType = ToolOutputType,\n In = ToolInputOf<{ inputSchema: InSchema }>,\n Out = ToolOutputOf<{ outputSchema: OutSchema }>,\n> {\n private providers: ProviderRegistryInterface;\n readonly authInfo: AuthInfo;\n\n protected readonly runId: string;\n protected readonly toolId: string;\n protected readonly toolName: string;\n readonly metadata: ToolMetadata;\n protected readonly logger: FrontMcpLogger;\n\n protected activeStage: string;\n\n // ---- INPUT storages (backing fields)\n private _rawInput?: Partial<In> | any;\n private _input?: In;\n\n // ---- OUTPUT storages (backing fields)\n private _outputDraft?: Partial<Out> | any;\n private _output?: Out;\n\n private _error?: Error;\n\n // ---- histories\n private readonly _inputHistory: HistoryEntry<In>[] = [];\n private readonly _outputHistory: HistoryEntry<Out>[] = [];\n\n constructor(args: ToolCtorArgs<In>) {\n const { metadata, input, providers, logger, authInfo } = args;\n this.runId = randomUUID();\n this.toolName = metadata.name;\n this.toolId = metadata.id ?? metadata.name;\n this.metadata = metadata;\n this._input = input;\n this.providers = providers;\n this.logger = logger.child(`tool:${this.toolId}`);\n this.authInfo = authInfo;\n }\n\n abstract execute(input: In): Promise<Out>;\n\n get<T>(token: Token<T>): T {\n return this.providers.get(token);\n }\n\n tryGet<T>(token: Token<T>): T | undefined {\n try {\n return this.providers.get(token);\n } catch (e) {\n this.logger.warn(\"Requesting provider that doesn't exist: \", token);\n return undefined;\n }\n }\n\n public get input(): In {\n return this._input as In;\n }\n\n public set input(v: In | undefined) {\n this._input = v;\n this._inputHistory.push({\n at: Date.now(),\n stage: this.activeStage,\n value: v,\n });\n }\n\n public get inputHistory(): ReadonlyArray<HistoryEntry<In>> {\n return this._inputHistory;\n }\n\n public get output(): Out | undefined {\n return this._output;\n }\n\n public set output(v: Out | undefined) {\n this._output = v;\n this._outputHistory.push({ at: Date.now(), stage: this.activeStage, value: v });\n }\n\n public get outputHistory(): ReadonlyArray<HistoryEntry<Out>> {\n return this._outputHistory;\n }\n\n respond(value: Out): never {\n // record validated output and surface the value via control flow\n this.output = value;\n FlowControl.respond<Out>(value);\n }\n\n /** Fail the run (invoker will run error/finalize). */\n protected fail(err: Error): never {\n this._error = err;\n FlowControl.fail(err);\n }\n\n mark(stage: string): void {\n this.activeStage = stage;\n }\n\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n}\n"]}