analyze_codebase
Analyze codebase structure, dependencies, and metrics to understand project architecture and identify patterns for improved development workflows.
Instructions
Perform comprehensive codebase analysis including structure, dependencies, and metrics
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Root directory path to analyze | |
| languages | No | Languages to analyze (auto-detect if omitted) | |
| depth | No | Analysis depth (1-5, default: 3) | |
| include_patterns | No | Glob patterns to include | |
| exclude_patterns | No | Glob patterns to exclude | |
| analysis_type | No | Analysis thoroughness level | standard |
Implementation Reference
- src/tools/analyze-codebase.ts:210-336 (handler)Core handler function for the analyze_codebase tool. Performs comprehensive analysis: file traversal with glob/ignore, language detection by extension, LOC counting, directory structure, entry point detection, package.json parsing, and generates JSON summary with metrics.
export async function analyzeCodebase( args: AnalyzeCodebaseArgs ): Promise<{ content: Array<{ type: string; text: string }> }> { const { path: projectPath, languages = [], depth = 3, include_patterns = ["**/*"], exclude_patterns = [ "**/node_modules/**", "**/.git/**", "**/dist/**", "**/build/**", "**/.next/**", "**/__pycache__/**", "**/*.pyc", "**/venv/**", "**/.venv/**", ], analysis_type = "standard", } = args; // Validate path exists try { await fs.access(projectPath); } catch { throw new Error(`Path does not exist: ${projectPath}`); } // Load .gitignore const ignore = await loadGitignore(projectPath); // Find all files const files = await glob(include_patterns, { cwd: projectPath, ignore: exclude_patterns, nodir: true, dot: false, }); // Analyze each file const fileInfos: FileInfo[] = []; const languageStats: Record<string, { files: number; lines: number }> = {}; const entryPoints: string[] = []; let totalLines = 0; let totalSize = 0; for (const file of files) { const fullPath = path.join(projectPath, file); const language = detectLanguage(file); // Skip if language filtering is active and this language is not included if (languages.length > 0 && !languages.includes(language)) { continue; } // Get file stats const stats = await fs.stat(fullPath); const lines = analysis_type !== "quick" ? await countLines(fullPath) : 0; fileInfos.push({ relativePath: file, language, size: stats.size, lines, }); // Update language statistics if (!languageStats[language]) { languageStats[language] = { files: 0, lines: 0 }; } languageStats[language].files++; languageStats[language].lines += lines; // Update totals totalLines += lines; totalSize += stats.size; // Check for entry points if (isEntryPoint(file) && path.dirname(file).split(path.sep).length <= depth) { entryPoints.push(file); } } // Calculate language percentages const languages_result: Record<string, { files: number; lines: number; percentage: number }> = {}; for (const [lang, stats] of Object.entries(languageStats)) { languages_result[lang] = { ...stats, percentage: totalLines > 0 ? (stats.lines / totalLines) * 100 : 0, }; } // Get directory structure const directories = analysis_type !== "quick" ? await getDirectories(projectPath, ignore) : []; // Load package info const packageInfo = analysis_type !== "quick" ? await loadPackageInfo(projectPath) : undefined; // Build result const result: AnalysisResult = { projectPath, totalFiles: fileInfos.length, totalLines, totalSize, languages: languages_result, structure: { directories, depth: Math.max(...directories.map((d) => d.split(path.sep).length), 0), }, files: analysis_type === "deep" ? fileInfos : [], entryPoints, packageInfo, analysisType: analysis_type, timestamp: new Date().toISOString(), }; return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } - src/index.ts:57-96 (schema)Input schema definition for the analyze_codebase tool, used in the ListTools response to describe parameters, types, and validation rules.
name: "analyze_codebase", description: "Perform comprehensive codebase analysis including structure, dependencies, and metrics", inputSchema: { type: "object", properties: { path: { type: "string", description: "Root directory path to analyze", }, languages: { type: "array", items: { type: "string" }, description: "Languages to analyze (auto-detect if omitted)", }, depth: { type: "number", description: "Analysis depth (1-5, default: 3)", minimum: 1, maximum: 5, default: 3, }, include_patterns: { type: "array", items: { type: "string" }, description: "Glob patterns to include", }, exclude_patterns: { type: "array", items: { type: "string" }, description: "Glob patterns to exclude", }, analysis_type: { type: "string", enum: ["quick", "standard", "deep"], description: "Analysis thoroughness level", default: "standard", }, }, required: ["path"], }, - src/tools/index.ts:27-29 (registration)Tool dispatch registration in the CallToolRequestSchema handler. Routes calls to 'analyze_codebase' to the analyzeCodebase function.
case "analyze_codebase": return await analyzeCodebase(args as any); - src/index.ts:47-47 (registration)Main server initialization calls registerTools(server), which sets up the tool handlers including analyze_codebase.
registerTools(server); - src/tools/analyze-codebase.ts:19-26 (schema)TypeScript interface defining the input arguments for the analyzeCodebase handler function.
interface AnalyzeCodebaseArgs { path: string; languages?: string[]; depth?: number; include_patterns?: string[]; exclude_patterns?: string[]; analysis_type?: "quick" | "standard" | "deep"; }