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