@@ -14,6 +14,8 @@ program
1414program
1515 . requiredOption ( '--command <command>' , 'Command to run the client (should accept server URL as argument)' )
1616 . option ( '--suite <name>' , 'Run specific test suite (basic, oauth, metadata, behavior, all)' , 'all' )
17+ . option ( '--test <name>' , 'Run specific test by name (partial match supported)' )
18+ . option ( '--list' , 'List all available tests' , false )
1719 . option ( '--timeout <ms>' , 'Timeout for client execution in milliseconds' , '30000' )
1820 . option ( '--json' , 'Output results as JSON' , false )
1921 . option ( '--verbose' , 'Verbose output' , false )
@@ -23,11 +25,61 @@ program
2325
2426
2527async function runTests ( options : any ) {
28+ const allSuites = [ basicSuite , oauthSuite , metadataLocationSuite , behaviorSuite ] ;
29+
30+ // List mode - show all available tests
31+ if ( options . list ) {
32+ console . log ( 'Available test suites and scenarios:\n' ) ;
33+ allSuites . forEach ( suite => {
34+ console . log ( `Suite: ${ suite . name } ` ) ;
35+ if ( suite . description ) {
36+ console . log ( ` ${ suite . description } ` ) ;
37+ }
38+ suite . scenarios . forEach ( ( scenario , index ) => {
39+ console . log ( ` ${ index + 1 } . ${ scenario . name } ` ) ;
40+ if ( scenario . description ) {
41+ console . log ( ` ${ scenario . description } ` ) ;
42+ }
43+ } ) ;
44+ console . log ( ) ;
45+ } ) ;
46+ process . exit ( 0 ) ;
47+ }
48+
2649 const verbose = options . verbose ;
2750 const runner = new ComplianceTestRunner ( options . command , { verbose, json : options . json } ) ;
2851
2952 console . log ( 'Running MCP compliance tests...' ) ;
3053
54+ // If specific test is requested, filter to just that test
55+ if ( options . test ) {
56+ const testName = options . test . toLowerCase ( ) ;
57+ let foundScenarios : TestSuite [ ] = [ ] ;
58+
59+ allSuites . forEach ( suite => {
60+ const matchingScenarios = suite . scenarios . filter ( scenario =>
61+ scenario . name . toLowerCase ( ) . includes ( testName )
62+ ) ;
63+
64+ if ( matchingScenarios . length > 0 ) {
65+ foundScenarios . push ( {
66+ ...suite ,
67+ scenarios : matchingScenarios
68+ } ) ;
69+ }
70+ } ) ;
71+
72+ if ( foundScenarios . length === 0 ) {
73+ console . error ( `No test found matching: ${ options . test } ` ) ;
74+ console . log ( '\nUse --list to see all available tests' ) ;
75+ process . exit ( 1 ) ;
76+ }
77+
78+ console . log ( `Found ${ foundScenarios . reduce ( ( acc , s ) => acc + s . scenarios . length , 0 ) } test(s) matching "${ options . test } "\n` ) ;
79+ await runner . runSuites ( foundScenarios ) ;
80+ return ;
81+ }
82+
3183 // Select which suites to run
3284 let suitesToRun : TestSuite [ ] = [ ] ;
3385
@@ -39,7 +91,7 @@ async function runTests(options: any) {
3991 } ;
4092
4193 if ( options . suite === 'all' ) {
42- suitesToRun = [ basicSuite , oauthSuite , metadataLocationSuite , behaviorSuite ] ;
94+ suitesToRun = allSuites ;
4395 } else if ( suiteMap [ options . suite ] ) {
4496 suitesToRun = [ suiteMap [ options . suite ] ] ;
4597 } else {
0 commit comments