Skip to main content
Glama

interactive_edit_session

Initiate an interactive editing session to modify complex files using clear instructions. Part of the Edit-MCP server, enabling precise file operations and refactoring.

Instructions

Start an interactive editing session for complex edits

Input Schema

NameRequiredDescriptionDefault
filesYesList of files to edit
instructionsNoInstructions for the editing session

Input Schema (JSON Schema)

{ "properties": { "files": { "description": "List of files to edit", "type": "array" }, "instructions": { "description": "Instructions for the editing session", "type": "string" } }, "required": [ "files" ], "type": "object" }

Implementation Reference

  • Handler for 'interactive_edit_session' tool: creates an edit session using EditInstanceManager and returns the session ID without closing the session.
    case 'interactive_edit_session': // Return the session ID for the client to use return { sessionId };
  • Core implementation of creating an interactive edit session: spawns EditInstance process, opens specified files, returns sessionId.
    public async createEditSession(files: string[]): Promise<string> { const sessionId = uuidv4(); const instance = await this.createInstance(sessionId); // Open all files for (const file of files) { await instance.openFile(file); } return sessionId; }
  • src/index.ts:306-329 (registration)
    Registers the 'interactive_edit_session' tool with the MCP server, defining name, description, input schema, and annotations.
    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 } });
  • Input schema definition for the 'interactive_edit_session' tool: requires array of files, optional instructions.
    inputSchema: { type: 'object', properties: { files: { type: 'array', description: 'List of files to edit' }, instructions: { type: 'string', description: 'Instructions for the editing session' } }, required: ['files'] },
  • EditInstance class: manages individual edit process instance, handles commands like open, edit, save via child process.
    export class EditInstance extends EventEmitter { private process: ChildProcess; private sessionId: string; private openFiles: Set<string> = new Set(); private activeFile?: string; private running: boolean = false; private outputBuffer: string = ''; private errorBuffer: string = ''; private commandQueue: Array<{ command: string; resolve: (result: string) => void; reject: (error: Error) => void; }> = []; private commandInProgress: boolean = false; constructor(process: ChildProcess, sessionId: string) { super(); this.process = process; this.sessionId = sessionId; this.setupProcessHandlers(); } private setupProcessHandlers(): void { this.process.stdout?.on('data', (data: Buffer) => { const output = data.toString(); this.outputBuffer += output; this.emit('stdout', output); this.checkCommandCompletion(); }); this.process.stderr?.on('data', (data: Buffer) => { const error = data.toString(); this.errorBuffer += error; this.emit('stderr', error); }); this.process.on('exit', (code: number | null) => { this.running = false; this.emit('exit', code); // Reject any pending commands while (this.commandQueue.length > 0) { const command = this.commandQueue.shift(); if (command) { command.reject(new Error(`Edit process exited with code ${code}`)); } } }); this.running = true; } private checkCommandCompletion(): void { if (this.commandQueue.length === 0 || !this.commandInProgress) { return; } // Check if the command has completed // This is a simplified approach; in a real implementation, we would need // to look for specific markers in the output to determine completion if (this.outputBuffer.includes('Command completed')) { const command = this.commandQueue.shift(); if (command) { this.commandInProgress = false; command.resolve(this.outputBuffer); this.outputBuffer = ''; this.errorBuffer = ''; this.processNextCommand(); } } } private processNextCommand(): void { if (this.commandQueue.length === 0 || this.commandInProgress) { return; } const command = this.commandQueue[0]; this.commandInProgress = true; this.process.stdin?.write(command.command + '\n'); } public async openFile(filePath: string): Promise<void> { await this.executeCommand(`open ${filePath}`); this.openFiles.add(filePath); this.activeFile = filePath; } public async closeFile(filePath: string): Promise<void> { await this.executeCommand(`close ${filePath}`); this.openFiles.delete(filePath); if (this.activeFile === filePath) { this.activeFile = undefined; } } public async executeCommand(command: string): Promise<string> { return new Promise<string>((resolve, reject) => { if (!this.running) { reject(new Error('Edit process is not running')); return; } this.commandQueue.push({ command, resolve, reject }); if (!this.commandInProgress) { this.processNextCommand(); } }); } public async getState(): Promise<EditInstanceState> { return { sessionId: this.sessionId, openFiles: Array.from(this.openFiles), activeFile: this.activeFile, running: this.running }; } public async terminate(): Promise<void> { if (!this.running) { return; } // Try to gracefully exit try { await this.executeCommand('exit'); } catch (error) { // Ignore errors } // Force kill if still running if (this.running) { this.process.kill(); } } }

Other Tools

Related Tools

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

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