@vinkius-core/mcp-fusion 0.1.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 +190 -0
- package/README.md +391 -0
- package/dist/src/AbstractBase.d.ts +24 -0
- package/dist/src/AbstractBase.d.ts.map +1 -0
- package/dist/src/AbstractBase.js +63 -0
- package/dist/src/AbstractBase.js.map +1 -0
- package/dist/src/AbstractLeaf.d.ts +12 -0
- package/dist/src/AbstractLeaf.d.ts.map +1 -0
- package/dist/src/AbstractLeaf.js +32 -0
- package/dist/src/AbstractLeaf.js.map +1 -0
- package/dist/src/Annotations.d.ts +15 -0
- package/dist/src/Annotations.d.ts.map +1 -0
- package/dist/src/Annotations.js +29 -0
- package/dist/src/Annotations.js.map +1 -0
- package/dist/src/Group.d.ts +32 -0
- package/dist/src/Group.d.ts.map +1 -0
- package/dist/src/Group.js +131 -0
- package/dist/src/Group.js.map +1 -0
- package/dist/src/Icon.d.ts +19 -0
- package/dist/src/Icon.d.ts.map +1 -0
- package/dist/src/Icon.js +33 -0
- package/dist/src/Icon.js.map +1 -0
- package/dist/src/Prompt.d.ts +11 -0
- package/dist/src/Prompt.d.ts.map +1 -0
- package/dist/src/Prompt.js +28 -0
- package/dist/src/Prompt.js.map +1 -0
- package/dist/src/PromptArgument.d.ts +10 -0
- package/dist/src/PromptArgument.d.ts.map +1 -0
- package/dist/src/PromptArgument.js +20 -0
- package/dist/src/PromptArgument.js.map +1 -0
- package/dist/src/Resource.d.ts +19 -0
- package/dist/src/Resource.d.ts.map +1 -0
- package/dist/src/Resource.js +34 -0
- package/dist/src/Resource.js.map +1 -0
- package/dist/src/Role.d.ts +5 -0
- package/dist/src/Role.d.ts.map +1 -0
- package/dist/src/Role.js +6 -0
- package/dist/src/Role.js.map +1 -0
- package/dist/src/Tool.d.ts +16 -0
- package/dist/src/Tool.d.ts.map +1 -0
- package/dist/src/Tool.js +28 -0
- package/dist/src/Tool.js.map +1 -0
- package/dist/src/ToolAnnotations.d.ts +23 -0
- package/dist/src/ToolAnnotations.d.ts.map +1 -0
- package/dist/src/ToolAnnotations.js +44 -0
- package/dist/src/ToolAnnotations.js.map +1 -0
- package/dist/src/converters/GroupConverter.d.ts +14 -0
- package/dist/src/converters/GroupConverter.d.ts.map +1 -0
- package/dist/src/converters/GroupConverter.js +13 -0
- package/dist/src/converters/GroupConverter.js.map +1 -0
- package/dist/src/converters/PromptConverter.d.ts +14 -0
- package/dist/src/converters/PromptConverter.d.ts.map +1 -0
- package/dist/src/converters/PromptConverter.js +13 -0
- package/dist/src/converters/PromptConverter.js.map +1 -0
- package/dist/src/converters/ResourceConverter.d.ts +14 -0
- package/dist/src/converters/ResourceConverter.d.ts.map +1 -0
- package/dist/src/converters/ResourceConverter.js +13 -0
- package/dist/src/converters/ResourceConverter.js.map +1 -0
- package/dist/src/converters/ToolAnnotationsConverter.d.ts +16 -0
- package/dist/src/converters/ToolAnnotationsConverter.d.ts.map +1 -0
- package/dist/src/converters/ToolAnnotationsConverter.js +23 -0
- package/dist/src/converters/ToolAnnotationsConverter.js.map +1 -0
- package/dist/src/converters/ToolConverter.d.ts +14 -0
- package/dist/src/converters/ToolConverter.d.ts.map +1 -0
- package/dist/src/converters/ToolConverter.js +13 -0
- package/dist/src/converters/ToolConverter.js.map +1 -0
- package/dist/src/converters/index.d.ts +6 -0
- package/dist/src/converters/index.d.ts.map +1 -0
- package/dist/src/converters/index.js +6 -0
- package/dist/src/converters/index.js.map +1 -0
- package/dist/src/framework/GroupedToolBuilder.d.ts +137 -0
- package/dist/src/framework/GroupedToolBuilder.d.ts.map +1 -0
- package/dist/src/framework/GroupedToolBuilder.js +289 -0
- package/dist/src/framework/GroupedToolBuilder.js.map +1 -0
- package/dist/src/framework/ResponseHelper.d.ts +43 -0
- package/dist/src/framework/ResponseHelper.d.ts.map +1 -0
- package/dist/src/framework/ResponseHelper.js +49 -0
- package/dist/src/framework/ResponseHelper.js.map +1 -0
- package/dist/src/framework/ToolBuilder.d.ts +46 -0
- package/dist/src/framework/ToolBuilder.d.ts.map +1 -0
- package/dist/src/framework/ToolBuilder.js +2 -0
- package/dist/src/framework/ToolBuilder.js.map +1 -0
- package/dist/src/framework/ToolRegistry.d.ts +85 -0
- package/dist/src/framework/ToolRegistry.d.ts.map +1 -0
- package/dist/src/framework/ToolRegistry.js +153 -0
- package/dist/src/framework/ToolRegistry.js.map +1 -0
- package/dist/src/framework/index.d.ts +9 -0
- package/dist/src/framework/index.d.ts.map +1 -0
- package/dist/src/framework/index.js +8 -0
- package/dist/src/framework/index.js.map +1 -0
- package/dist/src/framework/strategies/AnnotationAggregator.d.ts +11 -0
- package/dist/src/framework/strategies/AnnotationAggregator.d.ts.map +1 -0
- package/dist/src/framework/strategies/AnnotationAggregator.js +25 -0
- package/dist/src/framework/strategies/AnnotationAggregator.js.map +1 -0
- package/dist/src/framework/strategies/DescriptionGenerator.d.ts +12 -0
- package/dist/src/framework/strategies/DescriptionGenerator.d.ts.map +1 -0
- package/dist/src/framework/strategies/DescriptionGenerator.js +70 -0
- package/dist/src/framework/strategies/DescriptionGenerator.js.map +1 -0
- package/dist/src/framework/strategies/MiddlewareCompiler.d.ts +13 -0
- package/dist/src/framework/strategies/MiddlewareCompiler.d.ts.map +1 -0
- package/dist/src/framework/strategies/MiddlewareCompiler.js +24 -0
- package/dist/src/framework/strategies/MiddlewareCompiler.js.map +1 -0
- package/dist/src/framework/strategies/SchemaGenerator.d.ts +15 -0
- package/dist/src/framework/strategies/SchemaGenerator.d.ts.map +1 -0
- package/dist/src/framework/strategies/SchemaGenerator.js +97 -0
- package/dist/src/framework/strategies/SchemaGenerator.js.map +1 -0
- package/dist/src/framework/strategies/SchemaUtils.d.ts +7 -0
- package/dist/src/framework/strategies/SchemaUtils.d.ts.map +1 -0
- package/dist/src/framework/strategies/SchemaUtils.js +17 -0
- package/dist/src/framework/strategies/SchemaUtils.js.map +1 -0
- package/dist/src/framework/strategies/ToonDescriptionGenerator.d.ts +3 -0
- package/dist/src/framework/strategies/ToonDescriptionGenerator.d.ts.map +1 -0
- package/dist/src/framework/strategies/ToonDescriptionGenerator.js +53 -0
- package/dist/src/framework/strategies/ToonDescriptionGenerator.js.map +1 -0
- package/dist/src/framework/strategies/Types.d.ts +34 -0
- package/dist/src/framework/strategies/Types.d.ts.map +1 -0
- package/dist/src/framework/strategies/Types.js +2 -0
- package/dist/src/framework/strategies/Types.js.map +1 -0
- package/dist/src/framework/strategies/index.d.ts +12 -0
- package/dist/src/framework/strategies/index.d.ts.map +1 -0
- package/dist/src/framework/strategies/index.js +11 -0
- package/dist/src/framework/strategies/index.js.map +1 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +15 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tests/AbstractBase.test.d.ts +2 -0
- package/dist/tests/AbstractBase.test.d.ts.map +1 -0
- package/dist/tests/AbstractBase.test.js +130 -0
- package/dist/tests/AbstractBase.test.js.map +1 -0
- package/dist/tests/AbstractLeaf.test.d.ts +2 -0
- package/dist/tests/AbstractLeaf.test.d.ts.map +1 -0
- package/dist/tests/AbstractLeaf.test.js +65 -0
- package/dist/tests/AbstractLeaf.test.js.map +1 -0
- package/dist/tests/Annotations.test.d.ts +2 -0
- package/dist/tests/Annotations.test.d.ts.map +1 -0
- package/dist/tests/Annotations.test.js +34 -0
- package/dist/tests/Annotations.test.js.map +1 -0
- package/dist/tests/BarrelExport.test.d.ts +2 -0
- package/dist/tests/BarrelExport.test.d.ts.map +1 -0
- package/dist/tests/BarrelExport.test.js +42 -0
- package/dist/tests/BarrelExport.test.js.map +1 -0
- package/dist/tests/Converters.test.d.ts +2 -0
- package/dist/tests/Converters.test.d.ts.map +1 -0
- package/dist/tests/Converters.test.js +193 -0
- package/dist/tests/Converters.test.js.map +1 -0
- package/dist/tests/Group.test.d.ts +2 -0
- package/dist/tests/Group.test.d.ts.map +1 -0
- package/dist/tests/Group.test.js +257 -0
- package/dist/tests/Group.test.js.map +1 -0
- package/dist/tests/Icon.test.d.ts +2 -0
- package/dist/tests/Icon.test.d.ts.map +1 -0
- package/dist/tests/Icon.test.js +44 -0
- package/dist/tests/Icon.test.js.map +1 -0
- package/dist/tests/Prompt.test.d.ts +2 -0
- package/dist/tests/Prompt.test.d.ts.map +1 -0
- package/dist/tests/Prompt.test.js +63 -0
- package/dist/tests/Prompt.test.js.map +1 -0
- package/dist/tests/PromptArgument.test.d.ts +2 -0
- package/dist/tests/PromptArgument.test.d.ts.map +1 -0
- package/dist/tests/PromptArgument.test.js +37 -0
- package/dist/tests/PromptArgument.test.js.map +1 -0
- package/dist/tests/Resource.test.d.ts +2 -0
- package/dist/tests/Resource.test.d.ts.map +1 -0
- package/dist/tests/Resource.test.js +61 -0
- package/dist/tests/Resource.test.js.map +1 -0
- package/dist/tests/Role.test.d.ts +2 -0
- package/dist/tests/Role.test.d.ts.map +1 -0
- package/dist/tests/Role.test.js +17 -0
- package/dist/tests/Role.test.js.map +1 -0
- package/dist/tests/Tool.test.d.ts +2 -0
- package/dist/tests/Tool.test.d.ts.map +1 -0
- package/dist/tests/Tool.test.js +62 -0
- package/dist/tests/Tool.test.js.map +1 -0
- package/dist/tests/ToolAnnotations.test.d.ts +2 -0
- package/dist/tests/ToolAnnotations.test.d.ts.map +1 -0
- package/dist/tests/ToolAnnotations.test.js +55 -0
- package/dist/tests/ToolAnnotations.test.js.map +1 -0
- package/dist/tests/framework/AdversarialQA.test.d.ts +2 -0
- package/dist/tests/framework/AdversarialQA.test.d.ts.map +1 -0
- package/dist/tests/framework/AdversarialQA.test.js +906 -0
- package/dist/tests/framework/AdversarialQA.test.js.map +1 -0
- package/dist/tests/framework/GroupedToolBuilder.test.d.ts +2 -0
- package/dist/tests/framework/GroupedToolBuilder.test.d.ts.map +1 -0
- package/dist/tests/framework/GroupedToolBuilder.test.js +712 -0
- package/dist/tests/framework/GroupedToolBuilder.test.js.map +1 -0
- package/dist/tests/framework/LargeScaleScenarios.test.d.ts +2 -0
- package/dist/tests/framework/LargeScaleScenarios.test.d.ts.map +1 -0
- package/dist/tests/framework/LargeScaleScenarios.test.js +1043 -0
- package/dist/tests/framework/LargeScaleScenarios.test.js.map +1 -0
- package/dist/tests/framework/McpServerAdapter.test.d.ts +2 -0
- package/dist/tests/framework/McpServerAdapter.test.d.ts.map +1 -0
- package/dist/tests/framework/McpServerAdapter.test.js +380 -0
- package/dist/tests/framework/McpServerAdapter.test.js.map +1 -0
- package/dist/tests/framework/ResponseHelper.test.d.ts +2 -0
- package/dist/tests/framework/ResponseHelper.test.d.ts.map +1 -0
- package/dist/tests/framework/ResponseHelper.test.js +202 -0
- package/dist/tests/framework/ResponseHelper.test.js.map +1 -0
- package/dist/tests/framework/SecurityDeep.test.d.ts +2 -0
- package/dist/tests/framework/SecurityDeep.test.d.ts.map +1 -0
- package/dist/tests/framework/SecurityDeep.test.js +825 -0
- package/dist/tests/framework/SecurityDeep.test.js.map +1 -0
- package/dist/tests/framework/ToolRegistry.test.d.ts +2 -0
- package/dist/tests/framework/ToolRegistry.test.d.ts.map +1 -0
- package/dist/tests/framework/ToolRegistry.test.js +152 -0
- package/dist/tests/framework/ToolRegistry.test.js.map +1 -0
- package/dist/tests/framework/ToonDescription.test.d.ts +2 -0
- package/dist/tests/framework/ToonDescription.test.d.ts.map +1 -0
- package/dist/tests/framework/ToonDescription.test.js +287 -0
- package/dist/tests/framework/ToonDescription.test.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to the Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
Copyright 2026 Vinkius Labs
|
|
179
|
+
|
|
180
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
|
+
you may not use this file except in compliance with the License.
|
|
182
|
+
You may obtain a copy of the License at
|
|
183
|
+
|
|
184
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
185
|
+
|
|
186
|
+
Unless required by applicable law or agreed to in writing, software
|
|
187
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
188
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
189
|
+
See the License for the specific language governing permissions and
|
|
190
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# MCP Extensions for Primitive Grouping
|
|
2
|
+
|
|
3
|
+
**Stop registering hundreds of individual MCP tools. Ship one.**
|
|
4
|
+
|
|
5
|
+
A TypeScript framework that consolidates related MCP operations into a single tool behind a discriminator field — with a domain model layer for hierarchical entity management and a build-time strategy engine designed for 5,000+ endpoints. Fewer tools means less context pressure on the LLM, fewer routing errors, and cleaner server code.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @vinkius-core/mcp-fusion
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## The Problem
|
|
14
|
+
|
|
15
|
+
MCP servers that expose individual tools for every operation — `create_project`, `update_project`, `delete_project`, `list_projects`, `archive_project` — create two cascading failures:
|
|
16
|
+
|
|
17
|
+
1. **Context exhaustion.** Every tool definition burns tokens in the LLM context window. At 30+ tools, the model starts losing track.
|
|
18
|
+
2. **Routing confusion.** Semantically similar tools compete for selection. The LLM picks `update_project` when it should pick `create_project`.
|
|
19
|
+
|
|
20
|
+
The workaround is writing fewer, bloated tools — or rotating tool sets per conversation. Both are brittle.
|
|
21
|
+
|
|
22
|
+
## The Solution
|
|
23
|
+
|
|
24
|
+
Group related operations under a single tool. The LLM sees one `projects` tool and selects the operation through an `action` enum — a discriminator field. The framework handles description generation, schema composition, annotation aggregation, middleware compilation, validation, and error formatting — all at build time.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { GroupedToolBuilder, ToolRegistry, success, error } from '@vinkius-core/mcp-fusion';
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
|
|
30
|
+
const projects = new GroupedToolBuilder<AppContext>('projects')
|
|
31
|
+
.description('Manage projects')
|
|
32
|
+
.commonSchema(z.object({
|
|
33
|
+
workspace_id: z.string().describe('Workspace identifier'),
|
|
34
|
+
}))
|
|
35
|
+
.action({
|
|
36
|
+
name: 'list',
|
|
37
|
+
readOnly: true,
|
|
38
|
+
schema: z.object({ status: z.enum(['active', 'archived']).optional() }),
|
|
39
|
+
handler: async (ctx, args) => {
|
|
40
|
+
// args is fully typed: { workspace_id: string, status?: 'active' | 'archived' }
|
|
41
|
+
const projects = await ctx.db.projects.findMany({ where: { workspaceId: args.workspace_id, status: args.status } });
|
|
42
|
+
return success(projects);
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
.action({
|
|
46
|
+
name: 'create',
|
|
47
|
+
schema: z.object({ name: z.string(), description: z.string().optional() }),
|
|
48
|
+
handler: async (ctx, args) => {
|
|
49
|
+
const project = await ctx.db.projects.create({ data: { workspaceId: args.workspace_id, name: args.name, description: args.description } });
|
|
50
|
+
return success(project);
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
.action({
|
|
54
|
+
name: 'delete',
|
|
55
|
+
destructive: true,
|
|
56
|
+
schema: z.object({ project_id: z.string() }),
|
|
57
|
+
handler: async (ctx, args) => {
|
|
58
|
+
await ctx.db.projects.delete({ where: { id: args.project_id } });
|
|
59
|
+
return success('Project deleted');
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const registry = new ToolRegistry<AppContext>();
|
|
64
|
+
registry.register(projects);
|
|
65
|
+
registry.attachToServer(server, {
|
|
66
|
+
contextFactory: (extra) => createAppContext(extra),
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Five individual tools become one registered tool. The LLM sees:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Action: list | create | delete
|
|
74
|
+
- 'list': Requires: workspace_id. For: list
|
|
75
|
+
- 'create': Requires: workspace_id, name. For: create
|
|
76
|
+
- 'delete': Requires: workspace_id, project_id ⚠️ DESTRUCTIVE
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
→ [Getting Started Guide](docs/getting-started.md)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## What Makes This Framework Extraordinary
|
|
84
|
+
|
|
85
|
+
### Two-Layer Architecture
|
|
86
|
+
|
|
87
|
+
This is not a simple utility wrapper. The framework has two distinct layers:
|
|
88
|
+
|
|
89
|
+
**Layer 1 — Domain Model.** A hierarchical entity model for MCP primitives (`Group`, `Tool`, `Prompt`, `Resource`, `PromptArgument`) with tree traversal, multi-parent leaves, fully-qualified names (dot-separated, configurable separator), metadata maps, icons, and bidirectional type converters (`AbstractToolConverter`, `AbstractGroupConverter`, etc.). This is the structural backbone — think of it as the AST for your MCP server.
|
|
90
|
+
|
|
91
|
+
**Layer 2 — Build-Time Strategy Engine.** `GroupedToolBuilder` orchestrates six pure-function strategy modules to generate a single MCP tool definition. All computation happens at build time. At runtime, `execute()` does a single `Map.get()` lookup and calls a pre-compiled function.
|
|
92
|
+
|
|
93
|
+
### Per-Field Annotation Intelligence (4-Tier System)
|
|
94
|
+
|
|
95
|
+
The `SchemaGenerator` analyzes every field across every action and produces one of four annotation tiers — automatically, from your Zod schemas:
|
|
96
|
+
|
|
97
|
+
| Tier | Condition | Generated Annotation | LLM Reads As |
|
|
98
|
+
|---|---|---|---|
|
|
99
|
+
| **Always Required** | Field is in `commonSchema` and required | `(always required)` | "I must always send this field" |
|
|
100
|
+
| **Required-For** | Required in every action that uses it | `Required for: create, update` | "I need this for these specific actions" |
|
|
101
|
+
| **Required + Optional** | Required in some, optional in others | `Required for: create. For: update` | "Required for create, optional for update" |
|
|
102
|
+
| **For** | Optional in all actions that use it | `For: list, search` | "Only relevant for these actions" |
|
|
103
|
+
|
|
104
|
+
The LLM knows *exactly* which fields to populate for each action. No guessing. No hallucinated parameters. No manual annotation writing. This is extracted directly from Zod `isOptional()` introspection and cross-referenced across all registered actions.
|
|
105
|
+
|
|
106
|
+
### Pre-Compiled Middleware Chains
|
|
107
|
+
|
|
108
|
+
Middleware follows the `next()` pattern:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const authMiddleware: MiddlewareFn<AppContext> = async (ctx, args, next) => {
|
|
112
|
+
if (!ctx.session) return error('Unauthorized');
|
|
113
|
+
return next();
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
But unlike Express, chains are compiled at build time. The `MiddlewareCompiler` wraps handlers right-to-left into nested closures and stores the result in a `Map<string, ChainFn>`. At runtime, `execute()` does `this._compiledChain.get(action.key)` — one Map lookup, zero chain assembly, zero closure allocation per request.
|
|
118
|
+
|
|
119
|
+
Middleware is hierarchical:
|
|
120
|
+
- **Global** — `.use(mw)` on the builder. Runs for every action (outermost).
|
|
121
|
+
- **Group-scoped** — `.use(mw)` inside a group's `ActionGroupBuilder`. Runs only for actions in that group (inner).
|
|
122
|
+
|
|
123
|
+
### TOON Token Optimization
|
|
124
|
+
|
|
125
|
+
Descriptions and responses can be encoded in TOON (Token-Oriented Object Notation) via `@toon-format/toon` — a compact pipe-delimited format that eliminates repeated key names:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Enable TOON for tool descriptions (saves tokens on tools/list)
|
|
129
|
+
builder.toonDescription();
|
|
130
|
+
|
|
131
|
+
// Enable TOON for handler responses (saves tokens on tools/call)
|
|
132
|
+
return toonSuccess(users); // Instead of success(users)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The `toonSuccess()` helper accepts any JSON-serializable value and encodes it with configurable delimiter (`|` by default). For arrays of uniform objects — the typical API response — TOON achieves significant token reduction because column names are written once as a header, not repeated per row.
|
|
136
|
+
|
|
137
|
+
### Conservative Annotation Aggregation
|
|
138
|
+
|
|
139
|
+
MCP tool annotations operate at the tool level, but your actions have individual behavioral properties. The `AnnotationAggregator` resolves this with conservative rules:
|
|
140
|
+
|
|
141
|
+
- `destructiveHint: true` if **any** action is destructive (worst case assumption)
|
|
142
|
+
- `readOnlyHint: true` only if **all** actions are read-only (one mutation breaks it)
|
|
143
|
+
- `idempotentHint: true` only if **all** actions are idempotent (one non-idempotent breaks it)
|
|
144
|
+
|
|
145
|
+
Explicit annotations via `.annotations()` override aggregated values. The `ToolAnnotations` class also supports `openWorldHint` and `returnDirect`.
|
|
146
|
+
|
|
147
|
+
### Hierarchical Grouping for Large API Surfaces
|
|
148
|
+
|
|
149
|
+
For large API surfaces, actions support `module.action` compound keys:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
new GroupedToolBuilder<AppContext>('platform')
|
|
153
|
+
.description('Platform management API')
|
|
154
|
+
.tags('core') // ← Tag for selective exposure
|
|
155
|
+
.group('users', 'User management', g => {
|
|
156
|
+
g.use(requireAdmin) // Group-scoped middleware
|
|
157
|
+
.action({ name: 'list', readOnly: true, handler: listUsers })
|
|
158
|
+
.action({ name: 'create', schema: createUserSchema, handler: createUser })
|
|
159
|
+
.action({ name: 'ban', destructive: true, schema: banSchema, handler: banUser });
|
|
160
|
+
})
|
|
161
|
+
.group('billing', 'Billing operations', g => {
|
|
162
|
+
g.action({ name: 'invoices', readOnly: true, handler: listInvoices })
|
|
163
|
+
.action({ name: 'refund', destructive: true, schema: refundSchema, handler: issueRefund });
|
|
164
|
+
})
|
|
165
|
+
.group('analytics', g => {
|
|
166
|
+
g.action({ name: 'report', readOnly: true, handler: generateReport })
|
|
167
|
+
.action({ name: 'export', readOnly: true, schema: exportSchema, handler: exportData });
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The discriminator enum becomes: `users.list | users.create | users.ban | billing.invoices | billing.refund | analytics.report | analytics.export`. The description auto-generates group headers: `Modules: users (list,create,ban) | billing (invoices,refund) | analytics (report,export)`.
|
|
172
|
+
|
|
173
|
+
**Flat mode** (`.action()`) and **hierarchical mode** (`.group()`) are mutually exclusive on the same builder — enforced at registration time with clear error messages.
|
|
174
|
+
|
|
175
|
+
### Token Management at Scale — Tag-Based Selective Exposure
|
|
176
|
+
|
|
177
|
+
> **"5,000 endpoints — won't that blow up the token context?"**
|
|
178
|
+
|
|
179
|
+
No. The framework uses a 3-layer strategy to keep token usage under control, even with thousands of endpoints:
|
|
180
|
+
|
|
181
|
+
**Layer 1 — Grouping reduces tool count.** Instead of 5,000 individual tools, you register them as grouped tools. A `platform` tool with 50 actions is ONE tool definition in `tools/list`. The LLM sees 1 tool, not 50.
|
|
182
|
+
|
|
183
|
+
**Layer 2 — Tag filtering controls what the LLM sees.** You do NOT expose all tools at once. Each builder has `.tags()`, and `attachToServer()` accepts a `filter` with `tags` (include) and `exclude` options. Only matching tools appear in `tools/list`.
|
|
184
|
+
|
|
185
|
+
**Layer 3 — TOON compresses descriptions.** For tools that ARE exposed, `.toonDescription()` encodes metadata as compact pipe-delimited tables instead of verbose markdown, reducing token cost per tool.
|
|
186
|
+
|
|
187
|
+
Here's how this works in practice:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Register 5,000 endpoints across domain-specific grouped tools
|
|
191
|
+
const usersTool = new GroupedToolBuilder<AppContext>('users')
|
|
192
|
+
.tags('core', 'user-management')
|
|
193
|
+
.group('profiles', g => { /* 20 actions */ })
|
|
194
|
+
.group('permissions', g => { /* 15 actions */ })
|
|
195
|
+
.group('notifications', g => { /* 10 actions */ });
|
|
196
|
+
|
|
197
|
+
const billingTool = new GroupedToolBuilder<AppContext>('billing')
|
|
198
|
+
.tags('core', 'billing')
|
|
199
|
+
.toonDescription() // Token-optimized descriptions
|
|
200
|
+
.group('invoices', g => { /* 12 actions */ })
|
|
201
|
+
.group('subscriptions', g => { /* 8 actions */ });
|
|
202
|
+
|
|
203
|
+
const analyticsTool = new GroupedToolBuilder<AppContext>('analytics')
|
|
204
|
+
.tags('reporting')
|
|
205
|
+
.toonDescription()
|
|
206
|
+
.group('dashboards', g => { /* 25 actions */ })
|
|
207
|
+
.group('exports', g => { /* 10 actions */ });
|
|
208
|
+
|
|
209
|
+
const adminTool = new GroupedToolBuilder<AppContext>('admin')
|
|
210
|
+
.tags('admin', 'internal')
|
|
211
|
+
.group('system', g => { /* 30 actions */ })
|
|
212
|
+
.group('audit', g => { /* 15 actions */ });
|
|
213
|
+
|
|
214
|
+
const registry = new ToolRegistry<AppContext>();
|
|
215
|
+
registry.registerAll(usersTool, billingTool, analyticsTool, adminTool);
|
|
216
|
+
|
|
217
|
+
// Conversation about user management? Expose only core tools:
|
|
218
|
+
registry.attachToServer(server, {
|
|
219
|
+
filter: { tags: ['core'] }, // LLM sees: users + billing (2 tools)
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Admin session? Expose admin tools, exclude reporting:
|
|
223
|
+
registry.attachToServer(server, {
|
|
224
|
+
filter: { tags: ['admin'] }, // LLM sees: admin only (1 tool)
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Full access, but never internal tools:
|
|
228
|
+
registry.attachToServer(server, {
|
|
229
|
+
filter: { exclude: ['internal'] }, // Everything except admin
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**The result:** 5,000 endpoints registered, but the LLM context only contains the 2-3 tools relevant to the current conversation. Tag filtering acts as a context gate — you control exactly what the LLM sees, per session.
|
|
234
|
+
|
|
235
|
+
### Zod Parameter Stripping — Built-In Security Layer
|
|
236
|
+
|
|
237
|
+
When the LLM sends arguments, `execute()` merges `commonSchema` + `action.schema` using Zod's `.merge().strip()`, then runs `safeParse()`. The framework uses `result.data` — not the raw args — which means:
|
|
238
|
+
|
|
239
|
+
1. Unknown/injected fields are silently stripped.
|
|
240
|
+
2. Type coercion happens through Zod.
|
|
241
|
+
3. The handler receives exactly the shape it declared.
|
|
242
|
+
|
|
243
|
+
The LLM cannot inject parameters that your schema does not declare. This is a security boundary, not just validation.
|
|
244
|
+
|
|
245
|
+
### LLM-Friendly Error Messages
|
|
246
|
+
|
|
247
|
+
When things fail, the framework produces errors that LLMs can parse and self-correct:
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
// Missing discriminator:
|
|
251
|
+
Error: action is required. Available: list, create, delete
|
|
252
|
+
|
|
253
|
+
// Unknown action:
|
|
254
|
+
Error: Unknown action "remove". Available: list, create, delete
|
|
255
|
+
|
|
256
|
+
// Validation failure (from Zod):
|
|
257
|
+
Validation failed: name: Required; email: Invalid email format
|
|
258
|
+
|
|
259
|
+
// Runtime error (from handler):
|
|
260
|
+
[projects/delete] Database connection failed
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Every error includes the `[toolName/action]` prefix for instant debugging. The LLM reads the structured error, fixes the arguments, and retries.
|
|
264
|
+
|
|
265
|
+
### ⚠️ DESTRUCTIVE Warnings in LLM Descriptions
|
|
266
|
+
|
|
267
|
+
When an action is marked `destructive: true`, the `DescriptionGenerator` appends a literal `⚠️ DESTRUCTIVE` warning to the description. LLMs trained on safety data recognize this signal and will often request user confirmation before executing.
|
|
268
|
+
|
|
269
|
+
### Type-Safe Common Schema Propagation
|
|
270
|
+
|
|
271
|
+
`commonSchema()` propagates types through generics. The return type narrows from `GroupedToolBuilder<TContext, Record<string, never>>` to `GroupedToolBuilder<TContext, TSchema["_output"]>`. Every subsequent handler receives `TSchema["_output"] & TCommon` — checked at compile time, not runtime. No `as any`, no type assertions needed.
|
|
272
|
+
|
|
273
|
+
### Duck-Typed Server Resolution
|
|
274
|
+
|
|
275
|
+
`attachToServer()` accepts `unknown` and performs runtime duck-type detection:
|
|
276
|
+
|
|
277
|
+
1. Has `.server.setRequestHandler`? → `McpServer` (high-level). Unwrap the inner `Server`.
|
|
278
|
+
2. Has `.setRequestHandler` directly? → `Server` (low-level). Use directly.
|
|
279
|
+
3. Neither? → Clear error message.
|
|
280
|
+
|
|
281
|
+
No imports from the MCP SDK server modules. No peer dependency coupling. If the SDK restructures its exports, this framework does not break. The method returns a `DetachFn` that resets handlers to no-ops — clean teardown for testing.
|
|
282
|
+
|
|
283
|
+
### Freeze-After-Build Immutability
|
|
284
|
+
|
|
285
|
+
Once `buildToolDefinition()` is called, the builder is permanently frozen. The `_actions` array is sealed with `Object.freeze()`. All mutation methods throw:
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Builder "projects" is frozen after buildToolDefinition(). Cannot modify a built tool.
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
This eliminates an entire class of bugs where tools are accidentally mutated after registration — the same pattern Protocol Buffers uses.
|
|
292
|
+
|
|
293
|
+
### Introspection API
|
|
294
|
+
|
|
295
|
+
`getActionNames()` and `getActionMetadata()` provide runtime access to every action's properties:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
const meta = builder.getActionMetadata();
|
|
299
|
+
// Returns: [{ key, actionName, groupName, description, destructive, idempotent, readOnly, requiredFields, hasMiddleware }]
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Use this for: compliance audits, admin dashboards, middleware coverage validation, programmatic documentation generation, test coverage reports.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Domain Model Layer
|
|
307
|
+
|
|
308
|
+
Beyond the framework, the package provides a full domain model for MCP primitives:
|
|
309
|
+
|
|
310
|
+
| Class | Purpose |
|
|
311
|
+
|---|---|
|
|
312
|
+
| `Group` | Tree node with parent/child relationships, configurable name separator, recursive FQN resolution |
|
|
313
|
+
| `Tool` | Leaf node with input/output schemas and `ToolAnnotations` |
|
|
314
|
+
| `Prompt` | Leaf node with `PromptArgument` list |
|
|
315
|
+
| `Resource` | Leaf node with URI, size, mimeType, and `Annotations` (audience, priority, lastModified) |
|
|
316
|
+
| `AbstractBase` | Name, title, description, meta, icons, hashCode/equals |
|
|
317
|
+
| `AbstractLeaf` | Multi-parent group support, root traversal |
|
|
318
|
+
|
|
319
|
+
**Bidirectional converters** (`AbstractToolConverter`, `AbstractGroupConverter`, `AbstractPromptConverter`, `AbstractResourceConverter`, `AbstractToolAnnotationsConverter`) provide a clean pattern for converting between domain model types and external representations — both directions, single or batch, with null filtering.
|
|
320
|
+
|
|
321
|
+
→ [Architecture Guide](docs/architecture.md)
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Strategy Pattern Internals
|
|
326
|
+
|
|
327
|
+
| Module | Responsibility | Design |
|
|
328
|
+
|---|---|---|
|
|
329
|
+
| `SchemaGenerator` | 4-tier per-field annotations from Zod schemas | Pure function, no state |
|
|
330
|
+
| `DescriptionGenerator` | 3-layer descriptions with ⚠️ DESTRUCTIVE warnings | Pure function, no state |
|
|
331
|
+
| `ToonDescriptionGenerator` | TOON-encoded descriptions via `@toon-format/toon` | Pure function, no state |
|
|
332
|
+
| `AnnotationAggregator` | Conservative behavioral hint aggregation | Pure function, no state |
|
|
333
|
+
| `MiddlewareCompiler` | Right-to-left closure composition at build time | Pure function, no state |
|
|
334
|
+
| `SchemaUtils` | Zod field extraction shared by descriptions + introspection | Pure function, no state |
|
|
335
|
+
|
|
336
|
+
Every module is independently testable. Every module is replaceable. Zero shared state between any of them.
|
|
337
|
+
|
|
338
|
+
→ [API Reference](docs/api-reference.md)
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Key Capabilities
|
|
343
|
+
|
|
344
|
+
| Capability | What It Solves |
|
|
345
|
+
|---|---|
|
|
346
|
+
| **Action Consolidation** | Reduces tool count, improves LLM routing accuracy |
|
|
347
|
+
| **Hierarchical Groups** | Namespace 5,000+ actions with `module.action` compound keys |
|
|
348
|
+
| **4-Tier Field Annotations** | LLM knows exactly which fields to send per action |
|
|
349
|
+
| **Zod `.merge().strip()`** | Type-safe schema composition + unknown field stripping |
|
|
350
|
+
| **Common Schema Propagation** | Shared fields with compile-time generic inference |
|
|
351
|
+
| **Pre-Compiled Middleware** | Auth, rate limiting, audit — zero runtime chain assembly |
|
|
352
|
+
| **Group-Scoped Middleware** | Different middleware per namespace (e.g., admin-only for users) |
|
|
353
|
+
| **TOON Encoding** | Token reduction on descriptions and responses |
|
|
354
|
+
| **Conservative Annotations** | Safe MCP behavioral hints from per-action properties |
|
|
355
|
+
| **⚠️ DESTRUCTIVE Warnings** | Safety signal in LLM tool descriptions |
|
|
356
|
+
| **Tag Filtering** | Include/exclude tags for selective tool exposure |
|
|
357
|
+
| **Introspection API** | Runtime metadata for compliance, dashboards, audit trails |
|
|
358
|
+
| **Freeze-After-Build** | `Object.freeze()` prevents mutation bugs after registration |
|
|
359
|
+
| **Error Isolation** | `[tool/action]` prefixed errors for instant debugging |
|
|
360
|
+
| **Duck-Typed Server** | Works with `Server` and `McpServer` — zero import coupling |
|
|
361
|
+
| **Detach Function** | Clean teardown for testing via `DetachFn` |
|
|
362
|
+
| **Domain Model** | Hierarchical tree with multi-parent, FQN, converters |
|
|
363
|
+
| **Flat ↔ Hierarchical** | Mutual exclusion enforced with clear error messages |
|
|
364
|
+
| **Auto-Build on Execute** | `execute()` triggers `buildToolDefinition()` if not called |
|
|
365
|
+
| **Response Helpers** | `success()`, `error()`, `required()`, `toonSuccess()` |
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Documentation
|
|
370
|
+
|
|
371
|
+
| Guide | What You Will Learn |
|
|
372
|
+
|---|---|
|
|
373
|
+
| [Getting Started](docs/getting-started.md) | First tool, context, common schema, groups, TOON — complete working examples |
|
|
374
|
+
| [Architecture](docs/architecture.md) | Domain model, strategy pattern, build-time engine, execution flow |
|
|
375
|
+
| [Middleware](docs/middleware.md) | Global, group-scoped, pre-compilation, real patterns (auth, rate-limit, audit) |
|
|
376
|
+
| [API Reference](docs/api-reference.md) | Every public class, method, type, and interface |
|
|
377
|
+
| [Introspection](docs/introspection.md) | Runtime metadata, compliance, dashboards, middleware validation |
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Requirements
|
|
382
|
+
|
|
383
|
+
- Node.js 18+
|
|
384
|
+
- TypeScript 5.7+
|
|
385
|
+
- `@modelcontextprotocol/sdk ^1.12.1`
|
|
386
|
+
- `zod ^3.25.1`
|
|
387
|
+
- `@toon-format/toon` (for TOON features)
|
|
388
|
+
|
|
389
|
+
## License
|
|
390
|
+
|
|
391
|
+
Apache-2.0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Icon } from './Icon.js';
|
|
2
|
+
export declare abstract class AbstractBase {
|
|
3
|
+
static readonly DEFAULT_SEPARATOR: string;
|
|
4
|
+
protected readonly nameSeparator: string;
|
|
5
|
+
protected readonly name: string;
|
|
6
|
+
protected title: string | undefined;
|
|
7
|
+
protected description: string | undefined;
|
|
8
|
+
protected meta: Map<string, unknown> | undefined;
|
|
9
|
+
protected icons: Icon[] | undefined;
|
|
10
|
+
protected constructor(name: string, nameSeparator?: string);
|
|
11
|
+
getName(): string;
|
|
12
|
+
getTitle(): string | undefined;
|
|
13
|
+
setTitle(title: string): void;
|
|
14
|
+
getDescription(): string | undefined;
|
|
15
|
+
setDescription(description: string): void;
|
|
16
|
+
getIcons(): Icon[] | undefined;
|
|
17
|
+
setIcons(icons: Icon[]): void;
|
|
18
|
+
getMeta(): Map<string, unknown> | undefined;
|
|
19
|
+
setMeta(meta: Map<string, unknown>): void;
|
|
20
|
+
hashCode(): number;
|
|
21
|
+
equals(obj: unknown): boolean;
|
|
22
|
+
abstract getFullyQualifiedName(): string;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=AbstractBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractBase.d.ts","sourceRoot":"","sources":["../../src/AbstractBase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,8BAAsB,YAAY;IAC9B,gBAAuB,iBAAiB,EAAE,MAAM,CAAO;IAEvD,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IACzC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAEpC,SAAS,aAAa,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM;IAQnD,OAAO,IAAI,MAAM;IAIjB,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIzC,QAAQ,IAAI,IAAI,EAAE,GAAG,SAAS;IAI9B,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAI7B,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAI3C,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIzC,QAAQ,IAAI,MAAM;IAYlB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;aAcpB,qBAAqB,IAAI,MAAM;CAClD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export class AbstractBase {
|
|
2
|
+
constructor(name, nameSeparator) {
|
|
3
|
+
if (name === null || name === undefined) {
|
|
4
|
+
throw new Error("name must not be null");
|
|
5
|
+
}
|
|
6
|
+
this.name = name;
|
|
7
|
+
this.nameSeparator = nameSeparator !== undefined ? nameSeparator : AbstractBase.DEFAULT_SEPARATOR;
|
|
8
|
+
}
|
|
9
|
+
getName() {
|
|
10
|
+
return this.name;
|
|
11
|
+
}
|
|
12
|
+
getTitle() {
|
|
13
|
+
return this.title;
|
|
14
|
+
}
|
|
15
|
+
setTitle(title) {
|
|
16
|
+
this.title = title;
|
|
17
|
+
}
|
|
18
|
+
getDescription() {
|
|
19
|
+
return this.description;
|
|
20
|
+
}
|
|
21
|
+
setDescription(description) {
|
|
22
|
+
this.description = description;
|
|
23
|
+
}
|
|
24
|
+
getIcons() {
|
|
25
|
+
return this.icons;
|
|
26
|
+
}
|
|
27
|
+
setIcons(icons) {
|
|
28
|
+
this.icons = icons;
|
|
29
|
+
}
|
|
30
|
+
getMeta() {
|
|
31
|
+
return this.meta;
|
|
32
|
+
}
|
|
33
|
+
setMeta(meta) {
|
|
34
|
+
this.meta = meta;
|
|
35
|
+
}
|
|
36
|
+
hashCode() {
|
|
37
|
+
// Simple hash code implementation based on name
|
|
38
|
+
let hash = 0;
|
|
39
|
+
if (this.name.length === 0)
|
|
40
|
+
return hash;
|
|
41
|
+
for (let i = 0; i < this.name.length; i++) {
|
|
42
|
+
const chr = this.name.charCodeAt(i);
|
|
43
|
+
hash = ((hash << 5) - hash) + chr;
|
|
44
|
+
hash |= 0; // Convert to 32bit integer
|
|
45
|
+
}
|
|
46
|
+
return hash;
|
|
47
|
+
}
|
|
48
|
+
equals(obj) {
|
|
49
|
+
if (this === obj) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (obj === null || obj === undefined || typeof obj !== 'object') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (this.constructor !== obj.constructor) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const other = obj;
|
|
59
|
+
return this.name === other.name;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
AbstractBase.DEFAULT_SEPARATOR = ".";
|
|
63
|
+
//# sourceMappingURL=AbstractBase.js.map
|