analyze-dependencies
Analyze code dependencies to identify relationships and visualize imports across repositories or direct source code inputs for better project understanding.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| repositoryUrl | No | URL of the repository to analyze (e.g., 'https://github.com/username/repo') | |
| fileContent | No | Source code content to analyze directly instead of from a repository | |
| language | No | Programming language of the code (e.g., 'javascript', 'python', 'typescript', 'rust') |
Implementation Reference
- The async handler function that executes the analyze-dependencies tool: validates input, calls analyzeDependencies helper, formats the graph output (json/mermaid/dot), and returns MCP-formatted response.async ({ repositoryUrl, repositoryPath, fileContent, format = "json" }) => { try { const repoPath = repositoryPath || repositoryUrl; // Use either one if (!repoPath && !fileContent) { throw new Error("Either repositoryUrl, repositoryPath, or fileContent must be provided"); } console.log(`Analyzing dependencies in: ${repoPath || 'provided content'}`); // Perform the analysis const analysis = await analyzeDependencies(repoPath || '.'); // Format the result based on requested format let formattedResult; switch (format) { case "mermaid": formattedResult = generateMermaidGraph(analysis.graph); break; case "dot": formattedResult = generateDotGraph(analysis.graph); break; default: formattedResult = JSON.stringify(analysis, null, 2); } return { content: [{ type: "text", text: formattedResult }] }; } catch (error) { return { content: [{ type: "text", text: `Error analyzing dependencies: ${(error as Error).message}` }], isError: true }; } }
- Zod input schema defining optional parameters: repositoryUrl/path, fileContent, and output format.{ repositoryUrl: z.string().optional().describe("URL or path to the repository to analyze"), repositoryPath: z.string().optional().describe("Path to the repository to analyze"), fileContent: z.string().optional().describe("File content to analyze"), format: z.enum(["json", "mermaid", "dot"]).optional().describe("Output format for the dependency graph") },
- src/features/dependency-analysis/index.ts:5-56 (registration)Registration of the analyze-dependencies tool with the MCP server using server.tool(), including name, schema, and handler.export function registerDependencyAnalysisTools(server: McpServer) { server.tool( "analyze-dependencies", { repositoryUrl: z.string().optional().describe("URL or path to the repository to analyze"), repositoryPath: z.string().optional().describe("Path to the repository to analyze"), fileContent: z.string().optional().describe("File content to analyze"), format: z.enum(["json", "mermaid", "dot"]).optional().describe("Output format for the dependency graph") }, async ({ repositoryUrl, repositoryPath, fileContent, format = "json" }) => { try { const repoPath = repositoryPath || repositoryUrl; // Use either one if (!repoPath && !fileContent) { throw new Error("Either repositoryUrl, repositoryPath, or fileContent must be provided"); } console.log(`Analyzing dependencies in: ${repoPath || 'provided content'}`); // Perform the analysis const analysis = await analyzeDependencies(repoPath || '.'); // Format the result based on requested format let formattedResult; switch (format) { case "mermaid": formattedResult = generateMermaidGraph(analysis.graph); break; case "dot": formattedResult = generateDotGraph(analysis.graph); break; default: formattedResult = JSON.stringify(analysis, null, 2); } return { content: [{ type: "text", text: formattedResult }] }; } catch (error) { return { content: [{ type: "text", text: `Error analyzing dependencies: ${(error as Error).message}` }], isError: true }; } } ); }
- Core helper function analyzeDependencies that orchestrates dependency analysis: detects project type, analyzes package files and code imports, builds graph of nodes/edges and summary.export async function analyzeDependencies(repositoryPath: string): Promise<{ graph: DependencyGraph; summary: { totalDependencies: number; directDependencies: number; devDependencies: number; internalDependencies: number; }; }> { if (!repositoryPath) { throw new Error("Repository path is required"); } // Detect project type const projectType = await detectProjectType(repositoryPath); let dependencyGraph: DependencyGraph; // Analyze based on project type switch (projectType) { case 'node': dependencyGraph = await analyzeNodeDependencies(repositoryPath); break; case 'python': dependencyGraph = await analyzePythonDependencies(repositoryPath); break; case 'java': dependencyGraph = await analyzeJavaDependencies(repositoryPath); break; default: dependencyGraph = await analyzeGenericDependencies(repositoryPath); } // Generate summary const summary = { totalDependencies: dependencyGraph.nodes.length, directDependencies: dependencyGraph.nodes.filter(n => n.type === 'direct').length, devDependencies: dependencyGraph.nodes.filter(n => n.type === 'dev').length, internalDependencies: dependencyGraph.nodes.filter(n => n.type === 'internal').length }; return { graph: dependencyGraph, summary }; }
- Helper function to generate Mermaid diagram syntax from the dependency graph for visualization.function generateMermaidGraph(graph: any): string { let mermaid = "graph TD;\n"; // Add nodes for (const node of graph.nodes) { mermaid += ` ${formatNodeId(node.name)}["${node.name}${node.version ? ` (${node.version})` : ''}"`; // Style nodes based on type if (node.type === 'direct') { mermaid += ' style="fill:#a8d08d"'; } else if (node.type === 'dev') { mermaid += ' style="fill:#ffcc99"'; } else if (node.type === 'internal') { mermaid += ' style="fill:#a4c2f4"'; } mermaid += "];\n"; } // Add edges for (const edge of graph.edges) { mermaid += ` ${formatNodeId(edge.source)} --> ${formatNodeId(edge.target)};\n`; } return mermaid; }