UNPKG

vscode-mcp-comprehensive

Version:

Comprehensive MCP server exposing all VSCode features to AI agents with 101 tools including advanced debugging and console access

511 lines 21.3 kB
import * as vscode from 'vscode'; export class EditorTools { constructor(server) { this.server = server; this.registerTools(); } registerTools() { // Get active editor this.server.registerTool('editor_get_active', 'Get active text editor', { type: 'object', properties: {}, }, this.getActiveEditor.bind(this)); // Get all editors this.server.registerTool('editor_get_all', 'Get all open editors', { type: 'object', properties: {}, }, this.getAllEditors.bind(this)); // Get editor text this.server.registerTool('editor_get_text', 'Get editor text content', { type: 'object', properties: { uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, range: { type: 'object', description: 'Text range to get (optional, gets all text if not provided)', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, }, }, this.getEditorText.bind(this)); // Set editor text this.server.registerTool('editor_set_text', 'Replace entire editor content', { type: 'object', properties: { text: { type: 'string', description: 'New text content' }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['text'], }, this.setEditorText.bind(this)); // Insert text this.server.registerTool('editor_insert_text', 'Insert text at position', { type: 'object', properties: { text: { type: 'string', description: 'Text to insert' }, position: { type: 'object', description: 'Position to insert at', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['text', 'position'], }, this.insertText.bind(this)); // Replace text this.server.registerTool('editor_replace_text', 'Replace text in range', { type: 'object', properties: { text: { type: 'string', description: 'Replacement text' }, range: { type: 'object', description: 'Range to replace', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['text', 'range'], }, this.replaceText.bind(this)); // Delete text this.server.registerTool('editor_delete_text', 'Delete text in range', { type: 'object', properties: { range: { type: 'object', description: 'Range to delete', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['range'], }, this.deleteText.bind(this)); // Get selection this.server.registerTool('editor_get_selection', 'Get current selection', { type: 'object', properties: { uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, }, this.getSelection.bind(this)); // Set selection this.server.registerTool('editor_set_selection', 'Set selection range', { type: 'object', properties: { selection: { type: 'object', description: 'Selection to set', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['selection'], }, this.setSelection.bind(this)); // Get cursor position this.server.registerTool('editor_get_cursor_position', 'Get cursor position', { type: 'object', properties: { uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, }, this.getCursorPosition.bind(this)); // Set cursor position this.server.registerTool('editor_set_cursor_position', 'Set cursor position', { type: 'object', properties: { position: { type: 'object', description: 'Position to set cursor at', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['position'], }, this.setCursorPosition.bind(this)); // Format document this.server.registerTool('editor_format_document', 'Format entire document', { type: 'object', properties: { uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, }, this.formatDocument.bind(this)); // Format selection this.server.registerTool('editor_format_selection', 'Format selected text', { type: 'object', properties: { range: { type: 'object', description: 'Range to format (optional, uses current selection if not provided)', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, }, this.formatSelection.bind(this)); // Fold range this.server.registerTool('editor_fold_range', 'Fold code section', { type: 'object', properties: { range: { type: 'object', description: 'Range to fold', properties: { start: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, end: { type: 'object', properties: { line: { type: 'number' }, character: { type: 'number' }, }, required: ['line', 'character'], }, }, required: ['start', 'end'], }, uri: { type: 'string', description: 'Editor URI (optional, uses active if not provided)' }, }, required: ['range'], }, this.foldRange.bind(this)); } getEditor(uri) { if (uri) { const targetUri = vscode.Uri.parse(uri); return vscode.window.visibleTextEditors.find(editor => editor.document.uri.toString() === targetUri.toString()); } return vscode.window.activeTextEditor; } async getActiveEditor() { try { const editor = vscode.window.activeTextEditor; if (!editor) { return this.server.createSuccessResponse(null, 'No active editor'); } const editorInfo = { uri: editor.document.uri.toString(), fileName: editor.document.fileName, languageId: editor.document.languageId, lineCount: editor.document.lineCount, isDirty: editor.document.isDirty, selection: this.server.convertRange(editor.selection), visibleRanges: editor.visibleRanges.map(range => this.server.convertRange(range)), }; return this.server.createSuccessResponse(editorInfo); } catch (error) { return this.server.createErrorResponse(error); } } async getAllEditors() { try { const editors = vscode.window.visibleTextEditors.map(editor => ({ uri: editor.document.uri.toString(), fileName: editor.document.fileName, languageId: editor.document.languageId, lineCount: editor.document.lineCount, isDirty: editor.document.isDirty, selection: this.server.convertRange(editor.selection), })); return this.server.createSuccessResponse(editors); } catch (error) { return this.server.createErrorResponse(error); } } async getEditorText(args) { try { const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } let text; if (args.range) { const range = this.server.toVSCodeRange(args.range); text = editor.document.getText(range); } else { text = editor.document.getText(); } return this.server.createSuccessResponse({ text, uri: editor.document.uri.toString() }); } catch (error) { return this.server.createErrorResponse(error); } } async setEditorText(args) { try { this.server.validateRequiredParams(args, ['text']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const fullRange = new vscode.Range(editor.document.positionAt(0), editor.document.positionAt(editor.document.getText().length)); await editor.edit(editBuilder => { editBuilder.replace(fullRange, args.text); }); return this.server.createSuccessResponse({ success: true }, 'Editor text replaced'); } catch (error) { return this.server.createErrorResponse(error); } } async insertText(args) { try { this.server.validateRequiredParams(args, ['text', 'position']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const position = this.server.toVSCodePosition(args.position); await editor.edit(editBuilder => { editBuilder.insert(position, args.text); }); return this.server.createSuccessResponse({ success: true }, 'Text inserted'); } catch (error) { return this.server.createErrorResponse(error); } } async replaceText(args) { try { this.server.validateRequiredParams(args, ['text', 'range']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const range = this.server.toVSCodeRange(args.range); await editor.edit(editBuilder => { editBuilder.replace(range, args.text); }); return this.server.createSuccessResponse({ success: true }, 'Text replaced'); } catch (error) { return this.server.createErrorResponse(error); } } async deleteText(args) { try { this.server.validateRequiredParams(args, ['range']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const range = this.server.toVSCodeRange(args.range); await editor.edit(editBuilder => { editBuilder.delete(range); }); return this.server.createSuccessResponse({ success: true }, 'Text deleted'); } catch (error) { return this.server.createErrorResponse(error); } } async getSelection(args) { try { const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const selection = { start: this.server.convertPosition(editor.selection.start), end: this.server.convertPosition(editor.selection.end), anchor: this.server.convertPosition(editor.selection.anchor), active: this.server.convertPosition(editor.selection.active), isEmpty: editor.selection.isEmpty, isSingleLine: editor.selection.isSingleLine, }; return this.server.createSuccessResponse(selection); } catch (error) { return this.server.createErrorResponse(error); } } async setSelection(args) { try { this.server.validateRequiredParams(args, ['selection']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const range = this.server.toVSCodeRange(args.selection); editor.selection = new vscode.Selection(range.start, range.end); return this.server.createSuccessResponse({ success: true }, 'Selection set'); } catch (error) { return this.server.createErrorResponse(error); } } async getCursorPosition(args) { try { const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const position = this.server.convertPosition(editor.selection.active); return this.server.createSuccessResponse(position); } catch (error) { return this.server.createErrorResponse(error); } } async setCursorPosition(args) { try { this.server.validateRequiredParams(args, ['position']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const position = this.server.toVSCodePosition(args.position); editor.selection = new vscode.Selection(position, position); return this.server.createSuccessResponse({ success: true }, 'Cursor position set'); } catch (error) { return this.server.createErrorResponse(error); } } async formatDocument(args) { try { const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } await vscode.commands.executeCommand('editor.action.formatDocument'); return this.server.createSuccessResponse({ success: true }, 'Document formatted'); } catch (error) { return this.server.createErrorResponse(error); } } async formatSelection(args) { try { const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } if (args.range) { const range = this.server.toVSCodeRange(args.range); editor.selection = new vscode.Selection(range.start, range.end); } await vscode.commands.executeCommand('editor.action.formatSelection'); return this.server.createSuccessResponse({ success: true }, 'Selection formatted'); } catch (error) { return this.server.createErrorResponse(error); } } async foldRange(args) { try { this.server.validateRequiredParams(args, ['range']); const editor = this.getEditor(args.uri); if (!editor) { return this.server.createErrorResponse('No editor found'); } const range = this.server.toVSCodeRange(args.range); editor.selection = new vscode.Selection(range.start, range.end); await vscode.commands.executeCommand('editor.fold'); return this.server.createSuccessResponse({ success: true }, 'Range folded'); } catch (error) { return this.server.createErrorResponse(error); } } } //# sourceMappingURL=editorTools.js.map