@@ -161,6 +161,7 @@ describe('TOOLS', () => {
161161 expect ( ss . inputSchema . required ) . toContain ( 'query' ) ;
162162 expect ( ss . inputSchema . properties ) . toHaveProperty ( 'limit' ) ;
163163 expect ( ss . inputSchema . properties ) . toHaveProperty ( 'min_score' ) ;
164+ expect ( ss . inputSchema . properties ) . toHaveProperty ( 'file_pattern' ) ;
164165 } ) ;
165166
166167 it ( 'export_graph requires format parameter with enum' , ( ) => {
@@ -1233,4 +1234,75 @@ describe('startMCPServer handler dispatch', () => {
12331234 kind : 'function' ,
12341235 } ) ;
12351236 } ) ;
1237+
1238+ it ( 'dispatches semantic_search and forwards file_pattern as filePattern' , async ( ) => {
1239+ const handlers = { } ;
1240+
1241+ vi . doMock ( '@modelcontextprotocol/sdk/server/index.js' , ( ) => ( {
1242+ Server : class MockServer {
1243+ setRequestHandler ( name , handler ) {
1244+ handlers [ name ] = handler ;
1245+ }
1246+ async connect ( ) { }
1247+ } ,
1248+ } ) ) ;
1249+ vi . doMock ( '@modelcontextprotocol/sdk/server/stdio.js' , ( ) => ( {
1250+ StdioServerTransport : class MockTransport { } ,
1251+ } ) ) ;
1252+ vi . doMock ( '@modelcontextprotocol/sdk/types.js' , ( ) => ( {
1253+ ListToolsRequestSchema : 'tools/list' ,
1254+ CallToolRequestSchema : 'tools/call' ,
1255+ } ) ) ;
1256+
1257+ const hybridSearchMock = vi . fn ( async ( ) => ( { results : [ ] } ) ) ;
1258+ const ftsSearchMock = vi . fn ( ( ) => ( { results : [ ] } ) ) ;
1259+ const searchDataMock = vi . fn ( async ( ) => ( { results : [ ] } ) ) ;
1260+ vi . doMock ( '../../src/domain/search/index.js' , ( ) => ( {
1261+ hybridSearchData : hybridSearchMock ,
1262+ ftsSearchData : ftsSearchMock ,
1263+ searchData : searchDataMock ,
1264+ } ) ) ;
1265+
1266+ const { startMCPServer } = await import ( '../../src/mcp/index.js' ) ;
1267+ await startMCPServer ( '/tmp/test.db' ) ;
1268+
1269+ // hybrid (default): forwards filePattern as array
1270+ await handlers [ 'tools/call' ] ( {
1271+ params : {
1272+ name : 'semantic_search' ,
1273+ arguments : { query : 'GUC variable' , file_pattern : [ 'db/' ] , limit : 5 } ,
1274+ } ,
1275+ } ) ;
1276+ expect ( hybridSearchMock ) . toHaveBeenCalledWith (
1277+ 'GUC variable' ,
1278+ '/tmp/test.db' ,
1279+ expect . objectContaining ( { filePattern : [ 'db/' ] , limit : 5 } ) ,
1280+ ) ;
1281+
1282+ // semantic mode: forwards filePattern as string
1283+ await handlers [ 'tools/call' ] ( {
1284+ params : {
1285+ name : 'semantic_search' ,
1286+ arguments : { query : 'q' , mode : 'semantic' , file_pattern : 'src/mcp/' } ,
1287+ } ,
1288+ } ) ;
1289+ expect ( searchDataMock ) . toHaveBeenCalledWith (
1290+ 'q' ,
1291+ '/tmp/test.db' ,
1292+ expect . objectContaining ( { filePattern : 'src/mcp/' } ) ,
1293+ ) ;
1294+
1295+ // keyword mode: forwards filePattern
1296+ await handlers [ 'tools/call' ] ( {
1297+ params : {
1298+ name : 'semantic_search' ,
1299+ arguments : { query : 'q' , mode : 'keyword' , file_pattern : [ 'tests/' ] } ,
1300+ } ,
1301+ } ) ;
1302+ expect ( ftsSearchMock ) . toHaveBeenCalledWith (
1303+ 'q' ,
1304+ '/tmp/test.db' ,
1305+ expect . objectContaining ( { filePattern : [ 'tests/' ] } ) ,
1306+ ) ;
1307+ } ) ;
12361308} ) ;
0 commit comments