Skip to main content
Glama

find_unused_css

Analyze CSS usage to identify unused selectors for performance optimization. Supports URL, local file, and code analysis to reduce bloat and improve website speed.

Instructions

Analyze CSS usage and identify unused selectors for performance optimization. Supports both URL analysis and local file analysis.

WORKFLOW: Perfect for understanding complex code, identifying issues, and technical debt assessment TIP: Use Desktop Commander to read files, then pass content here for analysis SAVES: Claude context for strategic decisions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
analysisDepthNoLevel of analysis detaildetailed
analysisTypeNoType of CSS analysis to performcomprehensive
codeNoCSS code to analyze (for single-code analysis)
cssPathNoPath to CSS file to analyze
filePathNoPath to CSS file to analyze
filesNoSpecific HTML/CSS file paths to analyze
htmlPathNoPath to HTML file to check CSS usage against
ignorePseudoSelectorsNoIgnore pseudo-selectors like :hover, :focus
includeMediaQueriesNoInclude media query analysis
languageNoFile language (css, html)css
maxDepthNoMaximum directory depth for file discovery
projectPathNoPath to project directory containing HTML/CSS files
urlNoURL to analyze for CSS usage (single page)

Implementation Reference

  • Main handler entry point: wraps execution in security, detects analysis mode (URL/single-file/multi-file), validates params, sets up LLM model, routes to specific analysis implementations, handles errors.
    async execute(params: any, llmClient: any) {
      return await withSecurity(this, params, llmClient, async (secureParams) => {
        try {
          // 1. Auto-detect analysis mode based on parameters
          const analysisMode = this.detectAnalysisMode(secureParams);
          
          // 2. Validate parameters based on detected mode
          this.validateParameters(secureParams, analysisMode);
          
          // 3. Setup model
          const { model, contextLength } = await ModelSetup.getReadyModel(llmClient);
          
          // 4. Route to appropriate analysis method
          if (analysisMode === 'url') {
            return await this.executeURLAnalysis(secureParams, model, contextLength);
          } else if (analysisMode === 'single-file') {
            return await this.executeSingleFileAnalysis(secureParams, model, contextLength);
          } else {
            return await this.executeMultiFileAnalysis(secureParams, model, contextLength);
          }
          
        } catch (error: any) {
          return ErrorHandler.createExecutionError('find_unused_css', error);
        }
      });
    }
  • Comprehensive input schema defining parameters for URL analysis, single/multi-file CSS analysis, and various options like depth, type, media queries.
    // Universal parameter set - supports both URL and local file scenarios
    parameters = {
      // URL analysis
      url: {
        type: 'string' as const,
        description: 'URL to analyze for CSS usage (single page)',
        required: false
      },
      
      // Single-file parameters
      cssPath: {
        type: 'string' as const,
        description: 'Path to CSS file to analyze',
        required: false
      },
      htmlPath: {
        type: 'string' as const,
        description: 'Path to HTML file to check CSS usage against',
        required: false
      },
      code: {
        type: 'string' as const,
        description: 'CSS code to analyze (for single-code analysis)',
        required: false
      },
      
      // Multi-file parameters  
      projectPath: {
        type: 'string' as const,
        description: 'Path to project directory containing HTML/CSS files',
        required: false
      },
      files: {
        type: 'array' as const,
        description: 'Specific HTML/CSS file paths to analyze',
        required: false,
        items: { type: 'string' as const }
      },
      maxDepth: {
        type: 'number' as const,
        description: 'Maximum directory depth for file discovery',
        required: false,
        default: 3
      },
      
      // Analysis options
      analysisDepth: {
        type: 'string' as const,
        description: 'Level of analysis detail',
        enum: ['basic', 'detailed', 'comprehensive'],
        default: 'detailed',
        required: false
      },
      analysisType: {
        type: 'string' as const,
        description: 'Type of CSS analysis to perform',
        enum: ['performance', 'usage', 'comprehensive'],
        default: 'comprehensive',
        required: false
      },
      includeMediaQueries: {
        type: 'boolean' as const,
        description: 'Include media query analysis',
        default: true,
        required: false
      },
      ignorePseudoSelectors: {
        type: 'boolean' as const,
        description: 'Ignore pseudo-selectors like :hover, :focus',
        default: false,
        required: false
      },
      
      // Compatibility
      language: {
        type: 'string' as const,
        description: 'File language (css, html)',
        required: false,
        default: 'css'
      },
      filePath: {
        type: 'string' as const,
        description: 'Path to CSS file to analyze',
        required: false
      }
    };
  • Plugin metadata registration: sets the tool name 'find_unused_css' and category 'analyze', used for dynamic loading and MCP tool registration via getToolDefinition().
    name = 'find_unused_css';
    category = 'analyze' as const;
  • URL-specific handler: uses Puppeteer to extract live CSS rules and usage from webpage, processes with CSS parser, generates specialized prompts, executes with chunking if needed.
    private async executeURLAnalysis(params: any, model: any, contextLength: number) {
      // Step 1: Extract data from URL using Puppeteer
      const urlData = await this.extractURLDataWithPuppeteer(params.url);
      
      // Step 2: Process CSS with our utility
      const processedCSSData = this.processCSSData(urlData);
      
      // Step 3: Generate prompt stages for Houtini LM
      const promptStages = this.getURLAnalysisPromptStages({
        ...params,
        urlData: processedCSSData
      });
      
      // Step 4: Execute with proper chunking
      const promptManager = new ThreeStagePromptManager();
      const needsChunking = TokenCalculator.needsChunking(promptStages, contextLength);
      
      if (needsChunking) {
        const chunkSize = TokenCalculator.calculateOptimalChunkSize(promptStages, contextLength);
        const dataChunks = promptManager.chunkDataPayload(promptStages.dataPayload, chunkSize);
        const conversation = promptManager.createChunkedConversation(promptStages, dataChunks);
        const messages = [
          conversation.systemMessage,
          ...conversation.dataMessages,
          conversation.analysisMessage
        ];
        
        return await ResponseProcessor.executeChunked(
          messages,
          model,
          contextLength,
          'find_unused_css',
          'single'
        );
      } else {
        return await ResponseProcessor.executeDirect(
          promptStages,
          model,
          contextLength,
          'find_unused_css'
        );
      }
    }
  • Single-file handler: reads CSS/HTML files, parses selectors, detects usage against HTML, computes stats, generates prompts, executes LLM analysis.
    private async executeSingleFileAnalysis(params: any, model: any, contextLength: number) {
      // Step 1: Process CSS input
      let cssContent = params.code;
      if (params.cssPath || params.filePath) {
        const filePath = params.cssPath || params.filePath;
        cssContent = await readFileContent(filePath);
      }
    
      // Step 2: Process optional HTML input
      let htmlContent = '';
      if (params.htmlPath) {
        htmlContent = await readFileContent(params.htmlPath);
      }
      
      // Step 3: Process with CSS Parser utility
      const processedData = this.processLocalCSSData(cssContent, htmlContent, params);
      
      // Step 4: Generate prompt stages
      const promptStages = this.getSingleFilePromptStages({
        ...params,
        processedData
      });
      
      // Step 5: Execute with proper chunking
      const promptManager = new ThreeStagePromptManager();
      const needsChunking = TokenCalculator.needsChunking(promptStages, contextLength);
      
      if (needsChunking) {
        const chunkSize = TokenCalculator.calculateOptimalChunkSize(promptStages, contextLength);
        const dataChunks = promptManager.chunkDataPayload(promptStages.dataPayload, chunkSize);
        const conversation = promptManager.createChunkedConversation(promptStages, dataChunks);
        const messages = [
          conversation.systemMessage,
          ...conversation.dataMessages,
          conversation.analysisMessage
        ];
        
        return await ResponseProcessor.executeChunked(
          messages,
          model,
          contextLength,
          'find_unused_css',
          'single'
        );
      } else {
        return await ResponseProcessor.executeDirect(
          promptStages,
          model,
          contextLength,
          'find_unused_css'
        );
      }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/houtini-ai/lm'

If you have feedback or need assistance with the MCP directory API, please join our Discord server