@@ -631,6 +631,9 @@ test('HTTP cloud keyless transport preserves app challenge without advertising O
631631 ) ;
632632 assert . equal ( searchTool . inputSchema . properties . highlights . type , 'boolean' ) ;
633633 assert . equal ( 'default' in searchTool . inputSchema . properties . highlights , false ) ;
634+ assert . equal ( searchTool . inputSchema . properties . limit . type , 'integer' ) ;
635+ assert . equal ( searchTool . inputSchema . properties . limit . minimum , 1 ) ;
636+ assert . equal ( searchTool . inputSchema . properties . limit . maximum , 100 ) ;
634637
635638 assert . equal (
636639 backend . requests . filter ( ( request ) => request . url === '/api/oauth/introspect' ) . length ,
@@ -717,6 +720,49 @@ test('HTTP cloud transport calls Firecrawl API with authenticated session', asyn
717720 assert . equal ( stderr . includes ( 'TypeError' ) , false , stderr ) ;
718721} ) ;
719722
723+ test ( 'HTTP cloud transport rejects invalid search limits before calling Firecrawl' , async ( t ) => {
724+ const fakeApi = await startFakeFirecrawlApi ( ) ;
725+ t . after ( ( ) => fakeApi . close ( ) ) ;
726+
727+ const port = await getFreePort ( ) ;
728+ const child = spawnServer ( {
729+ CLOUD_SERVICE : 'true' ,
730+ FASTMCP_ENDPOINT : '/v2/mcp' ,
731+ FIRECRAWL_API_URL : fakeApi . url ,
732+ FIRECRAWL_OAUTH_ISSUER : fakeApi . url ,
733+ FIRECRAWL_OAUTH_INTROSPECT_SECRET : 'test-secret' ,
734+ HTTP_STREAMABLE_SERVER : 'true' ,
735+ PORT : String ( port ) ,
736+ } ) ;
737+ t . after ( ( ) => stopChild ( child ) ) ;
738+ await waitForHealth ( port , child ) ;
739+
740+ const searchRequestsBefore = fakeApi . requests . filter (
741+ ( request ) => request . url === '/v2/search'
742+ ) . length ;
743+ for ( const [ index , limit ] of [ 0 , 1.5 , 101 ] . entries ( ) ) {
744+ const response = await httpToolCall ( port , {
745+ id : 400 + index ,
746+ headers : { 'x-api-key' : 'fc-test' } ,
747+ params : {
748+ arguments : { limit, query : 'invalid search limit' } ,
749+ name : 'firecrawl_search' ,
750+ } ,
751+ } ) ;
752+ assert . equal ( response . status , 200 ) ;
753+ const message = parseSseJson ( await response . text ( ) ) ;
754+ assert . equal (
755+ Boolean ( message . error ) || message . result ?. isError === true ,
756+ true ,
757+ JSON . stringify ( message )
758+ ) ;
759+ }
760+ const searchRequestsAfter = fakeApi . requests . filter (
761+ ( request ) => request . url === '/v2/search'
762+ ) . length ;
763+ assert . equal ( searchRequestsAfter , searchRequestsBefore ) ;
764+ } ) ;
765+
720766class StdioMcpClient {
721767 #buffer = '' ;
722768 #child;
0 commit comments