Skip to main content
Glama
mdz-axo

PT-MCP (Paul Test Man Context Protocol)

by mdz-axo

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

TableJSON Schema
NameRequiredDescriptionDefault
pathYesRoot directory path to analyze
languagesNoLanguages to analyze (auto-detect if omitted)
depthNoAnalysis depth (1-5, default: 3)
include_patternsNoGlob patterns to include
exclude_patternsNoGlob patterns to exclude
analysis_typeNoAnalysis thoroughness levelstandard

Implementation Reference

  • 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), }, ], }; }
  • 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"], },
  • 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);
  • 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"; }

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/mdz-axo/pt-mcp'

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