UNPKG

@gshaxor/helperpro-mcp

Version:

A TypeScript implementation of the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) for code analysis. This server enables LLMs to interact with codebases.

179 lines (155 loc) 4.95 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { ReadResourceRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import path from 'path'; // Import utility functions import { createIgnoreFilter, extractFunctions, extractClasses, getFilesRecursively } from './utils.js'; // Create an MCP server const server = new Server({ name: "HelperPro Code Analyzer", version: "1.2.3", }, { capabilities: { resources: {}, tools: {}, }, }); // Define available resources const RESOURCES = [ { name: "get_functions", description: "Get all functions in a directory. Returns an list of function names, file paths, and line numbers.", inputSchema: { type: "object", properties: { path: { type: "string" }, maxDepth: { type: "number", default: 4 }, }, required: ["path"], }, }, { name: "get_classes", description: "Get all classes in a directory. Returns an list of class names, file paths, and line numbers.", inputSchema: { type: "object", properties: { path: { type: "string" }, maxDepth: { type: "number", default: 4 }, }, required: ["path"], }, }, ]; const TOOLS = RESOURCES; /** * Handle tool calls from the MCP client * @param {string} name - Tool name * @param {object} args - Tool arguments * @returns {object} - Tool response */ async function handleToolCall(name, args) { switch (name) { case "get_functions": try { // Normalize and resolve the path const absolutePath = path.resolve(args.path); // Get patterns to ignore from .gitignore const ignoredPatterns = await createIgnoreFilter(absolutePath); // Get all files const files = await getFilesRecursively(absolutePath, args.maxDepth, ignoredPatterns); // Extract functions from all files let allFunctions = []; for (const file of files) { const functions = await extractFunctions(file, absolutePath); allFunctions = [...allFunctions, ...functions]; } // Convert to text format const textOutput = allFunctions .map(f => `${f.function}; ${f.file}:${f.line}`) .join('\n'); return { content: [{ type: "text", text: textOutput }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: error.message }, null, 2) }] }; } case "get_classes": try { // Normalize and resolve the path const absolutePath = path.resolve(args.path); // Get patterns to ignore from .gitignore const ignoredPatterns = await createIgnoreFilter(absolutePath); // Get all files const files = await getFilesRecursively(absolutePath, args.maxDepth, ignoredPatterns); // Extract classes from all files let allClasses = []; for (const file of files) { const classes = await extractClasses(file, absolutePath); allClasses = [...allClasses, ...classes]; } // Convert to text format const textOutput = allClasses .map(c => `${c.class}; ${c.file}:${c.line}`) .join('\n'); return { content: [{ type: "text", text: textOutput }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: error.message }, null, 2) }] }; } default: return { content: [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }, null, 2) }] }; } } // Register request handlers server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: RESOURCES, })); server.setRequestHandler(ReadResourceRequestSchema, async (request) => handleToolCall(request.params.name, request.params.arguments ?? {}) ); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS, })); server.setRequestHandler(CallToolRequestSchema, async (request) => handleToolCall(request.params.name, request.params.arguments ?? {}) ); // Start the server async function runServer() { console.error('Starting HelperPro Code Analyzer MCP server...'); const transport = new StdioServerTransport(); await server.connect(transport); console.error('MCP server connected and ready to receive requests'); } runServer().catch(error => { console.error('Error starting MCP server:', error); process.exit(1); });