Skip to main content
Glama

Edit-MCP

index.js15.9 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path = __importStar(require("path")); const fs = __importStar(require("fs")); const commander_1 = require("commander"); const chalk_1 = __importDefault(require("chalk")); const mcp_server_1 = require("./core/mcp-server"); const file_system_manager_1 = require("./file-system/file-system-manager"); const edit_instance_manager_1 = require("./edit-instance/edit-instance-manager"); const operation_router_1 = require("./router/operation-router"); const http_server_1 = require("./http/http-server"); // Define the program version const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'), 'utf8')); const version = packageJson.version; // Create the command line interface const program = new commander_1.Command(); program .name('edit-mcp') .description('Model Context Protocol server for Microsoft Edit') .version(version) .option('-p, --port <port>', 'Port to listen on for HTTP transport', '3000') .option('-e, --edit-path <path>', 'Path to the Edit executable') .option('-m, --max-instances <number>', 'Maximum number of Edit instances', '5') .option('-t, --timeout <milliseconds>', 'Timeout for Edit instances in milliseconds', '300000') .option('-c, --config <path>', 'Path to configuration file') .option('-d, --debug', 'Enable debug logging') .option('-s, --stdio', 'Use stdio transport instead of HTTP') .parse(process.argv); const options = program.opts(); // Load configuration let config = { editExecutable: options.editPath, maxEditInstances: parseInt(options.maxInstances, 10), instanceTimeout: parseInt(options.timeout, 10), port: parseInt(options.port, 10), debug: options.debug, useStdio: options.stdio }; if (options.config) { try { const configFile = fs.readFileSync(options.config, 'utf8'); const fileConfig = JSON.parse(configFile); config = { ...config, ...fileConfig }; } catch (error) { console.error(chalk_1.default.red(`Error loading configuration file: ${error}`)); process.exit(1); } } // Set up logging const log = { info: (message) => console.log(chalk_1.default.blue(`[INFO] ${message}`)), warn: (message) => console.warn(chalk_1.default.yellow(`[WARN] ${message}`)), error: (message) => console.error(chalk_1.default.red(`[ERROR] ${message}`)), debug: (message) => { if (config.debug) { console.log(chalk_1.default.gray(`[DEBUG] ${message}`)); } } }; // Initialize the MCP server components async function initServer() { log.info('Initializing Edit-MCP server...'); // Create the file system manager const fileSystemManager = new file_system_manager_1.FileSystemManager(); log.debug('File system manager initialized'); // Create the Edit instance manager const editInstanceManager = new edit_instance_manager_1.EditInstanceManager(config.editExecutable, config.maxEditInstances, config.instanceTimeout); log.debug('Edit instance manager initialized'); // Create the operation router const operationRouter = new operation_router_1.OperationRouter(fileSystemManager, editInstanceManager, config.simpleOperationThreshold || 1000, config.complexityFactors); log.debug('Operation router initialized'); // Create the MCP server const mcpServer = new mcp_server_1.MCPServer({ name: 'Edit-MCP', version, editExecutablePath: config.editExecutable, maxEditInstances: config.maxEditInstances, instanceTimeout: config.instanceTimeout, instructions: 'Edit-MCP provides file editing capabilities through Microsoft Edit' }); log.debug('MCP server initialized'); // Register file system tools registerFileSystemTools(mcpServer); log.debug('File system tools registered'); // Register Edit tools registerEditTools(mcpServer); log.debug('Edit tools registered'); // Register hybrid tools registerHybridTools(mcpServer, operationRouter); log.debug('Hybrid tools registered'); // Start the server if (config.useStdio) { startStdioServer(mcpServer); } else { await startHttpServer(mcpServer, config.port); } // Handle process termination process.on('SIGINT', () => { log.info('Shutting down...'); editInstanceManager.dispose(); fileSystemManager.dispose(); process.exit(0); }); } // Register file system tools function registerFileSystemTools(mcpServer) { // Read file tool mcpServer.registerTool({ name: 'read_file', description: 'Read the contents of a file', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the file to read' }, encoding: { type: 'string', description: 'Encoding to use when reading the file (default: utf8)' } }, required: ['path'] }, annotations: { readOnlyHint: true, openWorldHint: false } }); // Write file tool mcpServer.registerTool({ name: 'write_file', description: 'Write content to a file', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the file to write' }, content: { type: 'string', description: 'Content to write to the file' }, encoding: { type: 'string', description: 'Encoding to use when writing the file (default: utf8)' } }, required: ['path', 'content'] }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false } }); // List files tool mcpServer.registerTool({ name: 'list_files', description: 'List files in a directory', inputSchema: { type: 'object', properties: { directory: { type: 'string', description: 'Path to the directory to list files from' }, pattern: { type: 'string', description: 'Pattern to filter files by (e.g., *.txt)' } }, required: ['directory'] }, annotations: { readOnlyHint: true, openWorldHint: false } }); // Find in file tool mcpServer.registerTool({ name: 'find_in_file', description: 'Find occurrences of a pattern in a file', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the file to search in' }, pattern: { type: 'string', description: 'Regular expression pattern to search for' }, contextLines: { type: 'number', description: 'Number of context lines to include before and after matches (default: 2)' } }, required: ['path', 'pattern'] }, annotations: { readOnlyHint: true, openWorldHint: false } }); } // Register Edit tools function registerEditTools(mcpServer) { // Format code tool mcpServer.registerTool({ name: 'format_code', description: 'Format code in a file', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the file to format' }, language: { type: 'string', description: 'Language of the code (e.g., javascript, python, rust)' } }, required: ['path'] }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false } }); // Complex find and replace tool mcpServer.registerTool({ name: 'complex_find_replace', description: 'Perform advanced find and replace operations with context awareness', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the file to perform find and replace on' }, pattern: { type: 'string', description: 'Regular expression pattern to search for' }, replacement: { type: 'string', description: 'Replacement text' }, options: { type: 'object', description: 'Additional options for the find and replace operation' } }, required: ['path', 'pattern', 'replacement'] }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } }); // Interactive edit session tool mcpServer.registerTool({ name: 'interactive_edit_session', description: 'Start an interactive editing session for complex edits', inputSchema: { type: 'object', properties: { files: { type: 'array', description: 'List of files to edit' }, instructions: { type: 'string', description: 'Instructions for the editing session' } }, required: ['files'] }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } }); } // Register hybrid tools function registerHybridTools(mcpServer, operationRouter) { // Smart refactor tool mcpServer.registerTool({ name: 'smart_refactor', description: 'Intelligently refactor code by renaming symbols across multiple files', inputSchema: { type: 'object', properties: { files: { type: 'array', description: 'List of files to search and refactor' }, oldName: { type: 'string', description: 'The symbol name to replace' }, newName: { type: 'string', description: 'The new symbol name' } }, required: ['files', 'oldName', 'newName'] }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false } }); // Backup and edit tool mcpServer.registerTool({ name: 'backup_and_edit', description: 'Create backups of files before editing them', inputSchema: { type: 'object', properties: { files: { type: 'array', description: 'List of files to backup and edit' }, operation: { type: 'object', description: 'The edit operation to perform' } }, required: ['files', 'operation'] }, annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } }); } // Start the server using stdio transport function startStdioServer(mcpServer) { log.info('Starting Edit-MCP server with stdio transport...'); // Set up stdin/stdout handling process.stdin.setEncoding('utf8'); let buffer = ''; process.stdin.on('data', async (chunk) => { buffer += chunk; // Process complete messages const messages = buffer.split('\n'); buffer = messages.pop() || ''; for (const message of messages) { if (message.trim()) { try { const response = await mcpServer.handleMessage(message); if (response) { process.stdout.write(response + '\n'); } } catch (error) { log.error(`Error handling message: ${error}`); } } } }); process.stdin.on('end', () => { log.info('Stdin stream ended, shutting down...'); process.exit(0); }); log.info('Edit-MCP server started with stdio transport'); } // Start the server using HTTP transport async function startHttpServer(mcpServer, port) { log.info(`Starting Edit-MCP server with HTTP transport on port ${port}...`); const httpServer = new http_server_1.HttpServer(mcpServer, { port, corsOrigins: config.corsOrigins || ['*'], rateLimitWindowMs: config.rateLimitWindowMs, rateLimitMax: config.rateLimitMax, authEnabled: config.authEnabled || false, apiKey: config.apiKey }); await httpServer.start(); log.info(`Edit-MCP server started with HTTP transport on port ${port}`); log.info(`Server URL: http://localhost:${port}`); log.info(`API documentation: http://localhost:${port}/api/docs`); log.info(`Health check: http://localhost:${port}/health`); } // Start the server initServer().catch(error => { log.error(`Failed to initialize server: ${error}`); process.exit(1); }); //# sourceMappingURL=index.js.map

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/mixelpixx/microsoft-edit-mcp'

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