Skip to main content
Glama

analyze_complexity

Analyze code complexity by calculating cyclomatic, cognitive, or Halstead metrics to identify difficult sections and improve maintainability.

Instructions

complexity|how complex|complexity|how complex|difficulty - Analyze code complexity

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYesCode to analyze
metricsNoMetrics to calculate

Implementation Reference

  • Main handler function that analyzes code complexity for JS/TS/Python, computes cyclomatic, cognitive, Halstead metrics, and provides overall score.
    export async function analyzeComplexity(args: { code: string; metrics?: string }): Promise<ToolResult> { const { code: complexityCode, metrics: complexityMetrics = 'all' } = args; // Check if this is Python code if (PythonParser.isPythonCode(complexityCode)) { return analyzePythonComplexity(complexityCode); } const complexityAnalysis = { action: 'analyze_complexity', metrics: complexityMetrics, results: {} as any, overallScore: 0, issues: [] as string[], recommendations: [] as string[], status: 'pending' as string }; // AST 기반 cyclomatic complexity 분석 complexityAnalysis.results.astCyclomaticComplexity = calculateAstComplexity(complexityCode); if (complexityMetrics === 'cyclomatic' || complexityMetrics === 'all') { const cyclomaticComplexityScore = (complexityCode.match(/\bif\b|\bfor\b|\bwhile\b|\bcase\b|\b&&\b|\b\|\|\b/g) || []).length + 1; complexityAnalysis.results.cyclomaticComplexity = { value: cyclomaticComplexityScore, threshold: CODE_QUALITY_METRICS.COMPLEXITY.maxCyclomaticComplexity, status: cyclomaticComplexityScore <= CODE_QUALITY_METRICS.COMPLEXITY.maxCyclomaticComplexity ? 'pass' : 'fail', description: 'Number of linearly independent paths through the code' }; } if (complexityMetrics === 'cognitive' || complexityMetrics === 'all') { complexityAnalysis.results.cognitiveComplexity = calculateCognitiveComplexity(complexityCode); } if (complexityMetrics === 'halstead' || complexityMetrics === 'all') { // Halstead metrics calculation (simplified version) const operators = (complexityCode.match(/[+\-*/=<>!&|%^~?:]/g) || []).length; const operands = (complexityCode.match(/\b[a-zA-Z_]\w*\b/g) || []).length; const uniqueOperators = new Set(complexityCode.match(/[+\-*/=<>!&|%^~?:]/g) || []).size; const uniqueOperands = new Set(complexityCode.match(/\b[a-zA-Z_]\w*\b/g) || []).size; const vocabulary = uniqueOperators + uniqueOperands; const length = operators + operands; const calculatedLength = vocabulary > 0 ? uniqueOperators * Math.log2(uniqueOperators) + uniqueOperands * Math.log2(uniqueOperands) : 0; const volume = length * Math.log2(vocabulary); const difficulty = vocabulary > 0 ? (uniqueOperators / 2) * (operands / uniqueOperands) : 0; const effort = difficulty * volume; complexityAnalysis.results.halsteadMetrics = { vocabulary: vocabulary, length: length, calculatedLength: Math.round(calculatedLength), volume: Math.round(volume), difficulty: Math.round(difficulty * 100) / 100, effort: Math.round(effort), timeToProgram: Math.round(effort / 18), // Halstead's formula: effort / 18 seconds bugsDelivered: Math.round(volume / 3000 * 100) / 100, // Halstead's formula: volume / 3000 description: 'Software science metrics measuring program complexity' }; } // Additional complexity metrics if (complexityMetrics === 'all') { const lines = complexityCode.split('\n'); const nonEmptyLines = lines.filter(line => line.trim().length > 0).length; const comments = (complexityCode.match(/\/\*[\s\S]*?\*\/|\/\/.*$/gm) || []).length; const functions = (complexityCode.match(/function\s+\w+|\w+\s*=\s*\(/g) || []).length; const classes = (complexityCode.match(/class\s+\w+/g) || []).length; complexityAnalysis.results.additionalMetrics = { linesOfCode: nonEmptyLines, comments: comments, commentRatio: nonEmptyLines > 0 ? Math.round((comments / nonEmptyLines) * 100) / 100 : 0, functions: functions, classes: classes, averageFunctionLength: functions > 0 ? Math.round(nonEmptyLines / functions) : 0 }; } // Overall assessment const issues = []; let overallScore = 100; if (complexityAnalysis.results.cyclomaticComplexity && complexityAnalysis.results.cyclomaticComplexity.status === 'fail') { issues.push('High cyclomatic complexity detected'); overallScore -= 20; } if (complexityAnalysis.results.cognitiveComplexity && complexityAnalysis.results.cognitiveComplexity.status === 'fail') { issues.push('High cognitive complexity detected'); overallScore -= 25; } if (complexityAnalysis.results.halsteadMetrics && complexityAnalysis.results.halsteadMetrics.difficulty > 10) { issues.push('High Halstead difficulty detected'); overallScore -= 15; } complexityAnalysis.overallScore = Math.max(0, overallScore); complexityAnalysis.issues = issues; return { content: [{ type: 'text', text: `Complexity: ${complexityAnalysis.results.astCyclomaticComplexity?.value ?? 'N/A'}\nScore: ${complexityAnalysis.overallScore}${issues.length ? '\nIssues: ' + issues.join(', ') : ''}` }] }; }
  • Tool schema definition including input schema for code and optional metrics.
    export const analyzeComplexityDefinition: ToolDefinition = { name: 'analyze_complexity', description: 'complexity|how complex|complexity|how complex|difficulty - Analyze code complexity', inputSchema: { type: 'object', properties: { code: { type: 'string', description: 'Code to analyze' }, metrics: { type: 'string', description: 'Metrics to calculate', enum: ['cyclomatic', 'cognitive', 'halstead', 'all'] } }, required: ['code'] }, annotations: { title: 'Analyze Complexity', audience: ['user', 'assistant'] } };
  • src/index.ts:664-665 (registration)
    Tool registration in the main switch dispatcher that calls the analyzeComplexity handler.
    case 'analyze_complexity': return await analyzeComplexity(args as any) as CallToolResult;
  • src/index.ts:140-140 (registration)
    Inclusion of tool definition in the tools array for listTools.
    analyzeComplexityDefinition,
  • Helper function for Python-specific complexity analysis using PythonParser.
    async function analyzePythonComplexity(code: string): Promise<ToolResult> { try { const pythonComplexity = await PythonParser.analyzeComplexity(code); const totalComplexity = pythonComplexity.cyclomaticComplexity; const issues: string[] = []; const MAX_COMPLEXITY = 10; if (totalComplexity > MAX_COMPLEXITY) { issues.push('High complexity'); } pythonComplexity.functions.forEach(f => { if (f.complexity > MAX_COMPLEXITY) { issues.push(`Function ${f.name}: complexity ${f.complexity}`); } }); const issuesText = issues.length ? `\nIssues: ${issues.join(', ')}` : ''; return { content: [{ type: 'text', text: `Python Complexity: ${totalComplexity}\nFunctions: ${pythonComplexity.functions.length}\nClasses: ${pythonComplexity.classes.length}${issuesText}` }] }; } catch (error) { return { content: [{ type: 'text', text: `Python analysis error: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; }

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/ssdeanx/ssd-ai'

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