UNPKG

vscode-mcp-comprehensive

Version:

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

269 lines 12.2 kB
import * as vscode from 'vscode'; export class WorkspaceTools { constructor(server) { this.server = server; this.registerTools(); } registerTools() { // Get workspace folders this.server.registerTool('workspace_get_folders', 'Get all workspace folders', { type: 'object', properties: {}, }, this.getWorkspaceFolders.bind(this)); // Open folder this.server.registerTool('workspace_open_folder', 'Open a folder in workspace', { type: 'object', properties: { uri: { type: 'string', description: 'Folder URI to open' }, newWindow: { type: 'boolean', description: 'Open in new window', default: false }, }, required: ['uri'], }, this.openFolder.bind(this)); // Save all files this.server.registerTool('workspace_save_all', 'Save all open files', { type: 'object', properties: { includeUntitled: { type: 'boolean', description: 'Include untitled files', default: true }, }, }, this.saveAll.bind(this)); // Find files this.server.registerTool('workspace_find_files', 'Search for files by pattern', { type: 'object', properties: { include: { type: 'string', description: 'Glob pattern to include' }, exclude: { type: 'string', description: 'Glob pattern to exclude' }, maxResults: { type: 'number', description: 'Maximum number of results', default: 100 }, }, required: ['include'], }, this.findFiles.bind(this)); // Read file this.server.registerTool('workspace_read_file', 'Read file contents', { type: 'object', properties: { uri: { type: 'string', description: 'File URI to read' }, encoding: { type: 'string', description: 'File encoding', default: 'utf8' }, }, required: ['uri'], }, this.readFile.bind(this)); // Write file this.server.registerTool('workspace_write_file', 'Write content to file', { type: 'object', properties: { uri: { type: 'string', description: 'File URI to write' }, content: { type: 'string', description: 'Content to write' }, encoding: { type: 'string', description: 'File encoding', default: 'utf8' }, createDirectories: { type: 'boolean', description: 'Create parent directories', default: true }, }, required: ['uri', 'content'], }, this.writeFile.bind(this)); // Delete file this.server.registerTool('workspace_delete_file', 'Delete a file', { type: 'object', properties: { uri: { type: 'string', description: 'File URI to delete' }, useTrash: { type: 'boolean', description: 'Move to trash instead of permanent delete', default: true }, }, required: ['uri'], }, this.deleteFile.bind(this)); // Rename file this.server.registerTool('workspace_rename_file', 'Rename or move a file', { type: 'object', properties: { oldUri: { type: 'string', description: 'Current file URI' }, newUri: { type: 'string', description: 'New file URI' }, overwrite: { type: 'boolean', description: 'Overwrite if target exists', default: false }, }, required: ['oldUri', 'newUri'], }, this.renameFile.bind(this)); // Create folder this.server.registerTool('workspace_create_folder', 'Create new directory', { type: 'object', properties: { uri: { type: 'string', description: 'Directory URI to create' }, }, required: ['uri'], }, this.createFolder.bind(this)); // Get configuration this.server.registerTool('workspace_get_configuration', 'Get settings/configuration', { type: 'object', properties: { section: { type: 'string', description: 'Configuration section' }, scope: { type: 'string', description: 'Configuration scope (workspace/user)' }, }, }, this.getConfiguration.bind(this)); // Update configuration this.server.registerTool('workspace_update_configuration', 'Update settings/configuration', { type: 'object', properties: { section: { type: 'string', description: 'Configuration section' }, value: { description: 'Configuration value' }, configurationTarget: { type: 'string', description: 'Target (Global/Workspace/WorkspaceFolder)', default: 'Workspace' }, }, required: ['section', 'value'], }, this.updateConfiguration.bind(this)); // Watch files this.server.registerTool('workspace_watch_files', 'Watch for file changes', { type: 'object', properties: { globPattern: { type: 'string', description: 'Glob pattern to watch' }, ignoreCreateEvents: { type: 'boolean', description: 'Ignore create events', default: false }, ignoreChangeEvents: { type: 'boolean', description: 'Ignore change events', default: false }, ignoreDeleteEvents: { type: 'boolean', description: 'Ignore delete events', default: false }, }, required: ['globPattern'], }, this.watchFiles.bind(this)); } async getWorkspaceFolders() { try { const folders = vscode.workspace.workspaceFolders; if (!folders) { return this.server.createSuccessResponse([], 'No workspace folders open'); } const workspaceFolders = folders.map(folder => ({ uri: folder.uri.toString(), name: folder.name, index: folder.index, })); return this.server.createSuccessResponse(workspaceFolders); } catch (error) { return this.server.createErrorResponse(error); } } async openFolder(args) { try { this.server.validateRequiredParams(args, ['uri']); const uri = vscode.Uri.parse(args.uri); await vscode.commands.executeCommand('vscode.openFolder', uri, args.newWindow); return this.server.createSuccessResponse({ success: true }, `Folder opened: ${args.uri}`); } catch (error) { return this.server.createErrorResponse(error); } } async saveAll(args) { try { await vscode.workspace.saveAll(args.includeUntitled); return this.server.createSuccessResponse({ success: true }, 'All files saved'); } catch (error) { return this.server.createErrorResponse(error); } } async findFiles(args) { try { this.server.validateRequiredParams(args, ['include']); const files = await vscode.workspace.findFiles(args.include, args.exclude, args.maxResults || 100); const fileUris = files.map(uri => uri.toString()); return this.server.createSuccessResponse(fileUris); } catch (error) { return this.server.createErrorResponse(error); } } async readFile(args) { try { this.server.validateRequiredParams(args, ['uri']); const uri = vscode.Uri.parse(args.uri); const content = await vscode.workspace.fs.readFile(uri); const text = Buffer.from(content).toString(args.encoding || 'utf8'); return this.server.createSuccessResponse({ content: text, uri: args.uri }); } catch (error) { return this.server.createErrorResponse(error); } } async writeFile(args) { try { this.server.validateRequiredParams(args, ['uri', 'content']); const uri = vscode.Uri.parse(args.uri); if (args.createDirectories) { const dirUri = vscode.Uri.joinPath(uri, '..'); await vscode.workspace.fs.createDirectory(dirUri); } const content = Buffer.from(args.content, args.encoding || 'utf8'); await vscode.workspace.fs.writeFile(uri, content); return this.server.createSuccessResponse({ success: true }, `File written: ${args.uri}`); } catch (error) { return this.server.createErrorResponse(error); } } async deleteFile(args) { try { this.server.validateRequiredParams(args, ['uri']); const uri = vscode.Uri.parse(args.uri); await vscode.workspace.fs.delete(uri, { recursive: true, useTrash: args.useTrash !== false }); return this.server.createSuccessResponse({ success: true }, `File deleted: ${args.uri}`); } catch (error) { return this.server.createErrorResponse(error); } } async renameFile(args) { try { this.server.validateRequiredParams(args, ['oldUri', 'newUri']); const oldUri = vscode.Uri.parse(args.oldUri); const newUri = vscode.Uri.parse(args.newUri); await vscode.workspace.fs.rename(oldUri, newUri, { overwrite: args.overwrite || false }); return this.server.createSuccessResponse({ success: true }, `File renamed: ${args.oldUri} -> ${args.newUri}`); } catch (error) { return this.server.createErrorResponse(error); } } async createFolder(args) { try { this.server.validateRequiredParams(args, ['uri']); const uri = vscode.Uri.parse(args.uri); await vscode.workspace.fs.createDirectory(uri); return this.server.createSuccessResponse({ success: true }, `Folder created: ${args.uri}`); } catch (error) { return this.server.createErrorResponse(error); } } async getConfiguration(args) { try { const config = vscode.workspace.getConfiguration(args.section); const configData = JSON.parse(JSON.stringify(config)); return this.server.createSuccessResponse(configData); } catch (error) { return this.server.createErrorResponse(error); } } async updateConfiguration(args) { try { this.server.validateRequiredParams(args, ['section', 'value']); const config = vscode.workspace.getConfiguration(); const target = args.configurationTarget === 'Global' ? vscode.ConfigurationTarget.Global : args.configurationTarget === 'WorkspaceFolder' ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; await config.update(args.section, args.value, target); return this.server.createSuccessResponse({ success: true }, `Configuration updated: ${args.section}`); } catch (error) { return this.server.createErrorResponse(error); } } async watchFiles(args) { try { this.server.validateRequiredParams(args, ['globPattern']); const watcher = vscode.workspace.createFileSystemWatcher(args.globPattern, args.ignoreCreateEvents || false, args.ignoreChangeEvents || false, args.ignoreDeleteEvents || false); // Note: In a real implementation, you'd want to store the watcher and provide a way to dispose it // For now, we'll just return success return this.server.createSuccessResponse({ success: true, watcherId: Date.now().toString() }, `File watcher created for pattern: ${args.globPattern}`); } catch (error) { return this.server.createErrorResponse(error); } } } //# sourceMappingURL=workspaceTools.js.map