@@ -30,10 +30,13 @@ const ALLOWED_SELECTOR_TOKENS_LOWER: ReadonlySet<string> = new Set<string>([
3030const DESCRIPTION : string = `A tool for selecting Code Analyzer rules based on a number of criteria.\n` +
3131 `This tool returns a JSON array describing Code Analyzer rules that match a "selector".\n` +
3232 `A selector is a colon-separated (:) string of tokens; tags and severity names are case-insensitive.\n` +
33+ `You can OR multiple tokens of the same type by grouping them in parentheses and separating with commas, e.g. "(Performance,Security)".\n` +
3334 `\n` +
3435 `Examples:\n` +
3536 `- "Recommended" → all rules tagged as Recommended.\n` +
3637 `- "Performance:pmd:Critical" → rules in the PMD engine with the Performance tag and Critical severity.\n` +
38+ `- "pmd:(Performance,Security):2" → PMD rules with Performance OR Security tags and severity 2.\n` +
39+ `- "(Apex,JavaScript):Recommended" → rules for Apex OR JavaScript languages that are Recommended.\n` +
3740 `- "Security:High" → rules tagged Security with High severity.\n` +
3841 `- "Apex:Recommended" → rules for the Apex language that are Recommended.\n` +
3942 `- "DevPreview" → rules marked as DevPreview.\n` +
@@ -46,7 +49,9 @@ const DESCRIPTION: string = `A tool for selecting Code Analyzer rules based on a
4649 `- General tags: Recommended, Custom, All\n` +
4750 `- Categories: BestPractices, CodeStyle, Design, Documentation, ErrorProne, Security, Performance\n` +
4851 `- Languages: Apex, CSS, HTML, JavaScript, TypeScript, Visualforce, XML\n` +
49- `- Engine-specific tags: DevPreview, LWC
52+ `- Engine-specific tags: DevPreview, LWC\n` +
53+ `\n` +
54+ `Tip: Use the "describe_code_analyzer_rule" tool to get details for any listed rule.
5055 ` ;
5156
5257export const inputSchema = z . object ( {
@@ -60,9 +65,7 @@ const outputSchema = z.object({
6065 name : z . string ( ) . describe ( 'The name of the rule, equivalent to the `ruleName` input property.' ) ,
6166 engine : z . string ( ) . describe ( 'The name of the engine to which the rule belongs.' ) ,
6267 severity : z . number ( ) . describe ( 'An integer between 1 and 5 indicating the severity of the rule. Lower numbers are MORE severe.' ) ,
63- tags : z . array ( z . string ( ) ) . describe ( 'An array of strings indicating tags applicable to the rule, e.g. "performance", "security", etc.' ) ,
64- description : z . string ( ) . describe ( 'A string describing the purpose and functionality of the rule.' ) ,
65- resources : z . array ( z . string ( ) ) . describe ( 'A possibly empty array of strings that represent links to documentation or other helpful material.' )
68+ tags : z . array ( z . string ( ) ) . describe ( 'An array of strings indicating tags applicable to the rule, e.g. "performance", "security", etc.' )
6669 } ) ) . optional ( ) . describe ( 'An array of rules that matched the selector. Empty if no rules matched.' )
6770} ) ;
6871type OutputArgsShape = typeof outputSchema . shape ;
@@ -89,6 +92,25 @@ export class CodeAnalyzerListRulesMcpTool extends McpTool<InputArgsShape, Output
8992
9093 const invalid : string [ ] = [ ] ;
9194 for ( const token of rawTokens ) {
95+ // Support OR groups inside parentheses, e.g., (Performance,Security)
96+ if ( token . startsWith ( '(' ) && token . endsWith ( ')' ) ) {
97+ const inner = token . slice ( 1 , - 1 ) ;
98+ const innerTokens = inner
99+ . split ( ',' )
100+ . map ( t => t . trim ( ) )
101+ . filter ( t => t . length > 0 ) ;
102+ if ( innerTokens . length === 0 ) {
103+ invalid . push ( token ) ;
104+ continue ;
105+ }
106+ for ( const innerToken of innerTokens ) {
107+ const normInner = innerToken . toLowerCase ( ) ;
108+ if ( ! ALLOWED_SELECTOR_TOKENS_LOWER . has ( normInner ) ) {
109+ invalid . push ( innerToken ) ;
110+ }
111+ }
112+ continue ;
113+ }
92114 const normalized = token . toLowerCase ( ) ;
93115 if ( ! ALLOWED_SELECTOR_TOKENS_LOWER . has ( normalized ) ) {
94116 invalid . push ( token ) ;
@@ -160,7 +182,10 @@ export class CodeAnalyzerListRulesMcpTool extends McpTool<InputArgsShape, Output
160182 output = { status : getErrorMessage ( e ) }
161183 }
162184 return {
163- content : [ { type : "text" , text : JSON . stringify ( output ) } ] ,
185+ content : [
186+ { type : "text" , text : `Tip: Use the "describe_code_analyzer_rule" tool to get details for any listed rule.` } ,
187+ { type : "text" , text : JSON . stringify ( output ) }
188+ ] ,
164189 structuredContent : output
165190 } ;
166191 }
0 commit comments