ide-analyzer.ts•4.42 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import path from 'path';
export function registerIdeTools(server: McpServer) {
// Tool for analyzing code at cursor position
server.tool(
"analyze-cursor",
{
filePath: z.string().describe("Path to the file"),
fileContent: z.string().describe("Content of the file"),
line: z.number().describe("Cursor line position (1-based)"),
column: z.number().describe("Cursor column position (1-based)"),
context: z.object({
before: z.array(z.string()).describe("Lines before cursor"),
target: z.string().describe("Line at cursor"),
after: z.array(z.string()).describe("Lines after cursor")
}).describe("Context around cursor")
},
async (args: {
filePath: string;
fileContent: string;
line: number;
column: number;
context: {
before: string[];
target: string;
after: string[];
}
}) => {
const { filePath, fileContent, line, column, context } = args;
// Determine language from file extension
const extension = path.extname(filePath).slice(1);
// Find the code entity at the cursor position
const entity = identifyCodeEntity(fileContent, line, column, extension);
// Analyze the entity
const analysis = analyzeCodeEntity(entity, extension);
return {
content: [{
type: "text",
text: JSON.stringify({
file: path.basename(filePath),
position: { line, column },
entity: entity.type,
name: entity.name,
analysis
}, null, 2)
}]
};
}
);
// Tool for analyzing multiple files
server.tool(
"analyze-files",
{
files: z.array(z.object({
path: z.string().describe("Path to the file"),
content: z.string().describe("Content of the file")
})).describe("Files to analyze")
},
async (args: { files: Array<{ path: string; content: string }> }) => {
const { files } = args;
// Analyze each file
const results = await Promise.all(
files.map(async (file: { path: string; content: string }) => {
const extension = path.extname(file.path).slice(1);
const metrics = calculateMetrics(file.content, extension);
return {
file: path.basename(file.path),
metrics
};
})
);
return {
content: [{
type: "text",
text: JSON.stringify({ results }, null, 2)
}]
};
}
);
}
// Helper function to identify code entity at cursor
function identifyCodeEntity(
content: string,
line: number,
column: number,
language: string
): {
type: string;
name: string;
startLine: number;
endLine: number;
complexity: number;
} {
// This is a placeholder implementation
// In a real implementation, you would use a language parser to identify
// the function, class, or other entity at the cursor position
return {
type: "function",
name: "exampleFunction",
startLine: line - 2,
endLine: line + 5,
complexity: 3
};
}
// Helper function to analyze a code entity
function analyzeCodeEntity(
entity: {
type: string;
name: string;
startLine: number;
endLine: number;
complexity: number
},
language: string
): {
complexity: number;
linesOfCode: number;
recommendations: string[];
} {
// This is a placeholder implementation
// In a real implementation, you would perform deeper analysis on the entity
return {
complexity: entity.complexity,
linesOfCode: entity.endLine - entity.startLine + 1,
recommendations: [
"Consider breaking this function into smaller parts",
"Add more descriptive variable names"
]
};
}
// Helper function to calculate metrics for a file
function calculateMetrics(
content: string,
language: string
): {
linesOfCode: number;
complexity: number;
maintainability: string;
} {
// This is a placeholder implementation
// In a real implementation, you would calculate actual metrics
const lines = content.split("\n");
return {
linesOfCode: lines.length,
complexity: Math.floor(lines.length / 10) + 1,
maintainability: "medium"
};
}