@@ -60,6 +60,27 @@ export class IntegrationTestRunner {
6060 this . options = options ;
6161 }
6262
63+ /**
64+ * Call an MCP tool with an appropriate timeout.
65+ *
66+ * All codeql_* tools invoke the CodeQL CLI or language server JVM, which
67+ * can be slow in CI (cold JVM start, network pack downloads, Windows
68+ * runner overhead). A generous 5-minute timeout avoids intermittent
69+ * -32001 RequestTimeout failures.
70+ */
71+ async callTool ( toolName , args ) {
72+ const isCodeQLTool = toolName . startsWith ( "codeql_" ) ;
73+ const requestOptions = {
74+ timeout : isCodeQLTool ? 300000 : 60000 ,
75+ resetTimeoutOnProgress : isCodeQLTool
76+ } ;
77+ return await this . client . callTool (
78+ { name : toolName , arguments : args } ,
79+ undefined ,
80+ requestOptions
81+ ) ;
82+ }
83+
6384 /**
6485 * Run integration tests for a specific tool
6586 */
@@ -268,12 +289,9 @@ export class IntegrationTestRunner {
268289 }
269290
270291 // Run the tool
271- const result = await this . client . callTool ( {
272- name : toolName ,
273- arguments : {
274- "files" : files ,
275- "in-place" : true
276- }
292+ const result = await this . callTool ( toolName , {
293+ "files" : files ,
294+ "in-place" : true
277295 } ) ;
278296
279297 this . logger . log ( `Tool ${ toolName } result: ${ result . content ?. [ 0 ] ?. text || "No output" } ` ) ;
@@ -337,11 +355,8 @@ export class IntegrationTestRunner {
337355 const _afterContent = fs . readFileSync ( afterPath , "utf8" ) ;
338356
339357 // Run the codeql_lsp_diagnostics tool on the before content
340- const result = await this . client . callTool ( {
341- name : toolName ,
342- arguments : {
343- ql_code : beforeContent
344- }
358+ const result = await this . callTool ( toolName , {
359+ ql_code : beforeContent
345360 } ) ;
346361
347362 this . logger . log (
@@ -472,10 +487,7 @@ export class IntegrationTestRunner {
472487 resolvePathPlaceholders ( testConfig . arguments , this . logger ) ;
473488
474489 // Run the tool with custom arguments
475- const result = await this . client . callTool ( {
476- name : toolName ,
477- arguments : testConfig . arguments
478- } ) ;
490+ const result = await this . callTool ( toolName , testConfig . arguments ) ;
479491
480492 this . logger . log ( `Tool ${ toolName } result: ${ result . content ?. [ 0 ] ?. text || "No output" } ` ) ;
481493
@@ -659,10 +671,7 @@ export class IntegrationTestRunner {
659671 // Check if qlpack.yml exists and install dependencies
660672 if ( fs . existsSync ( path . join ( packDir , "codeql-pack.yml" ) ) ) {
661673 try {
662- await this . client . callTool ( {
663- name : "codeql_pack_install" ,
664- arguments : { packDir : packDir }
665- } ) ;
674+ await this . callTool ( "codeql_pack_install" , { packDir : packDir } ) ;
666675 } catch ( installError ) {
667676 this . logger . log (
668677 ` Warning: Could not install pack dependencies: ${ installError . message } `
@@ -708,9 +717,8 @@ export class IntegrationTestRunner {
708717
709718 if ( fs . existsSync ( absoluteTestSourceDir ) ) {
710719 this . logger . log ( `Database not found, extracting from ${ testSourceDir } ` ) ;
711- const extractResult = await this . client . callTool ( {
712- name : "codeql_test_extract" ,
713- arguments : { tests : [ testSourceDir ] }
720+ const extractResult = await this . callTool ( "codeql_test_extract" , {
721+ tests : [ testSourceDir ]
714722 } ) ;
715723 if ( extractResult . isError ) {
716724 const errorText = extractResult . content ?. [ 0 ] ?. text || "Unknown error" ;
@@ -739,38 +747,10 @@ export class IntegrationTestRunner {
739747 params = await this . getToolSpecificParams ( toolName , testCase ) ;
740748 }
741749
742- // Call the tool with appropriate parameters
743- // Set extended timeout for long-running operations
744- const longRunningTools = [
745- "codeql_database_analyze" ,
746- "codeql_database_create" ,
747- "codeql_lsp_completion" ,
748- "codeql_lsp_definition" ,
749- "codeql_lsp_diagnostics" ,
750- "codeql_lsp_references" ,
751- "codeql_query_run" ,
752- "codeql_test_run"
753- ] ;
754-
755- const requestOptions = longRunningTools . includes ( toolName )
756- ? {
757- timeout : 300000 , // 5 minutes for long-running tools
758- resetTimeoutOnProgress : true
759- }
760- : {
761- timeout : 60000 // 60 seconds for other tools
762- } ;
763-
764- this . logger . log ( `Calling tool ${ toolName } with timeout: ${ requestOptions . timeout } ms` ) ;
750+ // Call the tool with appropriate parameters (timeout is handled by this.callTool)
751+ this . logger . log ( `Calling tool ${ toolName } ` ) ;
765752
766- const result = await this . client . callTool (
767- {
768- name : toolName ,
769- arguments : params
770- } ,
771- undefined ,
772- requestOptions
773- ) ;
753+ const result = await this . callTool ( toolName , params ) ;
774754
775755 // For monitoring tests, we primarily check if the tool executed successfully
776756 // Special handling for session management tools that expect sessions to exist
@@ -979,9 +959,8 @@ export class IntegrationTestRunner {
979959 if ( ! fs . existsSync ( databaseDir ) && fs . existsSync ( testDir ) ) {
980960 this . logger . log ( `Database not found for query run, extracting first: ${ databaseDir } ` ) ;
981961 // Call codeql test extract to create the database
982- const extractResult = await this . client . callTool ( {
983- name : "codeql_test_extract" ,
984- arguments : { tests : [ testDir ] }
962+ const extractResult = await this . callTool ( "codeql_test_extract" , {
963+ tests : [ testDir ]
985964 } ) ;
986965 if ( extractResult . isError ) {
987966 throw new Error ( `Failed to extract database: ${ extractResult . content [ 0 ] . text } ` ) ;
0 commit comments