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
JavaScript
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