@@ -12,10 +12,8 @@ import {Client} from '@modelcontextprotocol/sdk/client/index.js';
1212import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js' ;
1313import { executablePath } from 'puppeteer' ;
1414
15- import {
16- OFF_BY_DEFAULT_CATEGORIES ,
17- ToolCategory ,
18- } from '../src/tools/categories.js' ;
15+ import type { ToolCategory } from '../src/tools/categories.js' ;
16+ import { OFF_BY_DEFAULT_CATEGORIES } from '../src/tools/categories.js' ;
1917import type { ToolDefinition } from '../src/tools/ToolDefinition.js' ;
2018
2119describe ( 'e2e' , ( ) => {
@@ -80,44 +78,7 @@ describe('e2e', () => {
8078 async client => {
8179 const { tools} = await client . listTools ( ) ;
8280 const exposedNames = tools . map ( t => t . name ) . sort ( ) ;
83- const files = fs . readdirSync ( 'build/src/tools' ) ;
84- const definedNames = [ ] ;
85- for ( const file of files ) {
86- if (
87- file === 'ToolDefinition.js' ||
88- file === 'tools.js' ||
89- file === 'slim'
90- ) {
91- continue ;
92- }
93- const fileTools = await import ( `../src/tools/${ file } ` ) ;
94- for ( const maybeTool of Object . values < unknown > ( fileTools ) ) {
95- if ( typeof maybeTool === 'function' ) {
96- const tool = ( maybeTool as ( val : boolean ) => ToolDefinition ) (
97- false ,
98- ) ;
99- if ( tool && typeof tool === 'object' && 'name' in tool ) {
100- if ( tool . annotations ?. conditions ) {
101- continue ;
102- }
103- definedNames . push ( tool . name ) ;
104- }
105- continue ;
106- }
107- if (
108- typeof maybeTool === 'object' &&
109- maybeTool !== null &&
110- 'name' in maybeTool
111- ) {
112- const tool = maybeTool as ToolDefinition ;
113- if ( tool . annotations ?. conditions ) {
114- continue ;
115- }
116- definedNames . push ( tool . name ) ;
117- }
118- }
119- }
120-
81+ const definedNames = await getToolsWithFilteredCategories ( ) ;
12182 definedNames . sort ( ) ;
12283 assert . deepStrictEqual ( exposedNames , definedNames ) ;
12384 } ,
@@ -129,54 +90,9 @@ describe('e2e', () => {
12990 await withClient ( async client => {
13091 const { tools} = await client . listTools ( ) ;
13192 const exposedNames = tools . map ( t => t . name ) . sort ( ) ;
132- const files = fs . readdirSync ( 'build/src/tools' ) ;
133- const definedNames = [ ] ;
134- for ( const file of files ) {
135- if (
136- file === 'ToolDefinition.js' ||
137- file === 'tools.js' ||
138- file === 'slim'
139- ) {
140- continue ;
141- }
142- const fileTools = await import ( `../src/tools/${ file } ` ) ;
143- for ( const maybeTool of Object . values < unknown > ( fileTools ) ) {
144- if ( typeof maybeTool === 'function' ) {
145- const tool = ( maybeTool as ( val : boolean ) => ToolDefinition ) ( false ) ;
146- if ( tool && typeof tool === 'object' && 'name' in tool ) {
147- if ( tool . annotations ?. conditions ) {
148- continue ;
149- }
150- if (
151- tool . annotations ?. category &&
152- tool . annotations ?. category === ToolCategory . EXTENSIONS
153- ) {
154- continue ;
155- }
156- definedNames . push ( tool . name ) ;
157- }
158- continue ;
159- }
160- if (
161- typeof maybeTool === 'object' &&
162- maybeTool !== null &&
163- 'name' in maybeTool
164- ) {
165- const tool = maybeTool as ToolDefinition ;
166- if ( tool . annotations ?. conditions ) {
167- continue ;
168- }
169- if (
170- tool . annotations ?. category &&
171- tool . annotations ?. category === ToolCategory . EXTENSIONS
172- ) {
173- continue ;
174- }
175- definedNames . push ( tool . name ) ;
176- }
177- }
178- }
179-
93+ const definedNames = await getToolsWithFilteredCategories (
94+ OFF_BY_DEFAULT_CATEGORIES ,
95+ ) ;
18096 definedNames . sort ( ) ;
18197 assert . deepStrictEqual ( exposedNames , definedNames ) ;
18298 } ) ;
@@ -245,3 +161,57 @@ describe('e2e', () => {
245161 ) ;
246162 } ) ;
247163} ) ;
164+
165+ async function getToolsWithFilteredCategories (
166+ filterOutCategories : ToolCategory [ ] = [ ] ,
167+ ) : Promise < string [ ] > {
168+ const files = fs . readdirSync ( 'build/src/tools' ) ;
169+ const definedNames = [ ] ;
170+ for ( const file of files ) {
171+ if (
172+ file === 'ToolDefinition.js' ||
173+ file === 'tools.js' ||
174+ file === 'slim'
175+ ) {
176+ continue ;
177+ }
178+ const fileTools = await import ( `../src/tools/${ file } ` ) ;
179+
180+ for ( const maybeTool of Object . values < unknown > ( fileTools ) ) {
181+ let tool ;
182+ if ( typeof maybeTool === 'function' ) {
183+ tool = ( maybeTool as ( val : boolean ) => ToolDefinition ) ( false ) ;
184+ } else {
185+ tool = maybeTool as ToolDefinition ;
186+ }
187+
188+ // Skipping all files that are not tool files
189+ if ( tool === null || typeof tool !== 'object' || ! ( 'name' in tool ) ) {
190+ continue ;
191+ }
192+
193+ if ( toolShouldBeSkipped ( tool , filterOutCategories ) ) {
194+ continue ;
195+ }
196+ definedNames . push ( tool . name ) ;
197+ }
198+ }
199+ return definedNames ;
200+ }
201+
202+ function toolShouldBeSkipped (
203+ tool : ToolDefinition ,
204+ filteredOutCategories : ToolCategory [ ] ,
205+ ) {
206+ if ( tool . annotations ?. conditions ) {
207+ return true ;
208+ }
209+ if (
210+ tool . annotations ?. category &&
211+ filteredOutCategories . includes ( tool . annotations ?. category )
212+ ) {
213+ return true ;
214+ }
215+
216+ return false ;
217+ }
0 commit comments