vscode-mcp-comprehensive
Version:
Comprehensive MCP server exposing all VSCode features to AI agents with 101 tools including advanced debugging and console access
441 lines • 19.2 kB
JavaScript
import * as vscode from 'vscode';
export class UITools {
constructor(server) {
this.server = server;
this.statusBarItems = new Map();
this.registerTools();
}
registerTools() {
// Show information message
this.server.registerTool('ui_show_information_message', 'Show info notification', {
type: 'object',
properties: {
message: { type: 'string', description: 'Message to display' },
modal: { type: 'boolean', description: 'Show as modal dialog', default: false },
items: {
type: 'array',
items: { type: 'string' },
description: 'Action items to show'
},
},
required: ['message'],
}, this.showInformationMessage.bind(this));
// Show warning message
this.server.registerTool('ui_show_warning_message', 'Show warning notification', {
type: 'object',
properties: {
message: { type: 'string', description: 'Warning message to display' },
modal: { type: 'boolean', description: 'Show as modal dialog', default: false },
items: {
type: 'array',
items: { type: 'string' },
description: 'Action items to show'
},
},
required: ['message'],
}, this.showWarningMessage.bind(this));
// Show error message
this.server.registerTool('ui_show_error_message', 'Show error notification', {
type: 'object',
properties: {
message: { type: 'string', description: 'Error message to display' },
modal: { type: 'boolean', description: 'Show as modal dialog', default: false },
items: {
type: 'array',
items: { type: 'string' },
description: 'Action items to show'
},
},
required: ['message'],
}, this.showErrorMessage.bind(this));
// Show input box
this.server.registerTool('ui_show_input_box', 'Show input dialog', {
type: 'object',
properties: {
prompt: { type: 'string', description: 'Input prompt' },
placeholder: { type: 'string', description: 'Placeholder text' },
value: { type: 'string', description: 'Default value' },
password: { type: 'boolean', description: 'Hide input (password)', default: false },
validateInput: { type: 'string', description: 'Validation pattern (regex)' },
},
required: ['prompt'],
}, this.showInputBox.bind(this));
// Show quick pick
this.server.registerTool('ui_show_quick_pick', 'Show selection menu', {
type: 'object',
properties: {
items: {
type: 'array',
items: {
type: 'object',
properties: {
label: { type: 'string' },
description: { type: 'string' },
detail: { type: 'string' },
picked: { type: 'boolean' },
},
required: ['label'],
},
description: 'Items to choose from'
},
canPickMany: { type: 'boolean', description: 'Allow multiple selection', default: false },
placeholder: { type: 'string', description: 'Placeholder text' },
ignoreFocusOut: { type: 'boolean', description: 'Keep open when focus lost', default: false },
},
required: ['items'],
}, this.showQuickPick.bind(this));
// Show open dialog
this.server.registerTool('ui_show_open_dialog', 'Show file open dialog', {
type: 'object',
properties: {
canSelectFiles: { type: 'boolean', description: 'Allow file selection', default: true },
canSelectFolders: { type: 'boolean', description: 'Allow folder selection', default: false },
canSelectMany: { type: 'boolean', description: 'Allow multiple selection', default: false },
defaultUri: { type: 'string', description: 'Default URI to open' },
openLabel: { type: 'string', description: 'Open button label' },
filters: {
type: 'object',
description: 'File type filters',
additionalProperties: {
type: 'array',
items: { type: 'string' }
}
},
},
}, this.showOpenDialog.bind(this));
// Show save dialog
this.server.registerTool('ui_show_save_dialog', 'Show file save dialog', {
type: 'object',
properties: {
defaultUri: { type: 'string', description: 'Default URI to save' },
saveLabel: { type: 'string', description: 'Save button label' },
filters: {
type: 'object',
description: 'File type filters',
additionalProperties: {
type: 'array',
items: { type: 'string' }
}
},
},
}, this.showSaveDialog.bind(this));
// Set status bar message
this.server.registerTool('ui_set_status_bar_message', 'Set status bar text', {
type: 'object',
properties: {
message: { type: 'string', description: 'Status bar message' },
hideAfterTimeout: { type: 'number', description: 'Hide after milliseconds (optional)' },
},
required: ['message'],
}, this.setStatusBarMessage.bind(this));
// Create status bar item
this.server.registerTool('ui_create_status_bar_item', 'Create status bar item', {
type: 'object',
properties: {
id: { type: 'string', description: 'Unique identifier for the item' },
text: { type: 'string', description: 'Text to display' },
tooltip: { type: 'string', description: 'Tooltip text' },
command: { type: 'string', description: 'Command to execute on click' },
alignment: { type: 'string', description: 'Alignment (left/right)', default: 'left' },
priority: { type: 'number', description: 'Priority for ordering' },
color: { type: 'string', description: 'Text color' },
backgroundColor: { type: 'string', description: 'Background color' },
},
required: ['id', 'text'],
}, this.createStatusBarItem.bind(this));
// Show progress
this.server.registerTool('ui_show_progress', 'Show progress indicator', {
type: 'object',
properties: {
title: { type: 'string', description: 'Progress title' },
location: { type: 'string', description: 'Progress location (notification/window/source-control)', default: 'notification' },
cancellable: { type: 'boolean', description: 'Allow cancellation', default: false },
steps: {
type: 'array',
items: {
type: 'object',
properties: {
message: { type: 'string' },
increment: { type: 'number' },
},
required: ['message'],
},
description: 'Progress steps'
},
},
required: ['title'],
}, this.showProgress.bind(this));
// Update status bar item
this.server.registerTool('ui_update_status_bar_item', 'Update existing status bar item', {
type: 'object',
properties: {
id: { type: 'string', description: 'Status bar item ID' },
text: { type: 'string', description: 'New text' },
tooltip: { type: 'string', description: 'New tooltip' },
command: { type: 'string', description: 'New command' },
color: { type: 'string', description: 'New color' },
show: { type: 'boolean', description: 'Show/hide the item' },
},
required: ['id'],
}, this.updateStatusBarItem.bind(this));
// Remove status bar item
this.server.registerTool('ui_remove_status_bar_item', 'Remove status bar item', {
type: 'object',
properties: {
id: { type: 'string', description: 'Status bar item ID to remove' },
},
required: ['id'],
}, this.removeStatusBarItem.bind(this));
}
async showInformationMessage(args) {
try {
this.server.validateRequiredParams(args, ['message']);
const options = { modal: args.modal || false };
const result = await vscode.window.showInformationMessage(args.message, options, ...(args.items || []));
return this.server.createSuccessResponse({
selectedItem: result,
dismissed: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showWarningMessage(args) {
try {
this.server.validateRequiredParams(args, ['message']);
const options = { modal: args.modal || false };
const result = await vscode.window.showWarningMessage(args.message, options, ...(args.items || []));
return this.server.createSuccessResponse({
selectedItem: result,
dismissed: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showErrorMessage(args) {
try {
this.server.validateRequiredParams(args, ['message']);
const options = { modal: args.modal || false };
const result = await vscode.window.showErrorMessage(args.message, options, ...(args.items || []));
return this.server.createSuccessResponse({
selectedItem: result,
dismissed: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showInputBox(args) {
try {
this.server.validateRequiredParams(args, ['prompt']);
const options = {
prompt: args.prompt,
placeHolder: args.placeholder,
value: args.value,
password: args.password || false,
validateInput: args.validateInput ? (value) => {
const regex = new RegExp(args.validateInput);
return regex.test(value) ? null : 'Invalid input format';
} : undefined,
};
const result = await vscode.window.showInputBox(options);
return this.server.createSuccessResponse({
value: result,
cancelled: result === undefined
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showQuickPick(args) {
try {
this.server.validateRequiredParams(args, ['items']);
const quickPickItems = args.items.map(item => ({
label: item.label,
description: item.description,
detail: item.detail,
picked: item.picked,
}));
const options = {
canPickMany: args.canPickMany || false,
placeHolder: args.placeholder,
ignoreFocusOut: args.ignoreFocusOut || false,
};
const result = await vscode.window.showQuickPick(quickPickItems, options);
return this.server.createSuccessResponse({
selectedItems: Array.isArray(result) ? result : result ? [result] : [],
cancelled: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showOpenDialog(args) {
try {
const options = {
canSelectFiles: args.canSelectFiles !== false,
canSelectFolders: args.canSelectFolders || false,
canSelectMany: args.canSelectMany || false,
defaultUri: args.defaultUri ? vscode.Uri.parse(args.defaultUri) : undefined,
openLabel: args.openLabel,
filters: args.filters,
};
const result = await vscode.window.showOpenDialog(options);
return this.server.createSuccessResponse({
selectedUris: result ? result.map(uri => uri.toString()) : [],
cancelled: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showSaveDialog(args) {
try {
const options = {
defaultUri: args.defaultUri ? vscode.Uri.parse(args.defaultUri) : undefined,
saveLabel: args.saveLabel,
filters: args.filters,
};
const result = await vscode.window.showSaveDialog(options);
return this.server.createSuccessResponse({
selectedUri: result ? result.toString() : null,
cancelled: !result
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async setStatusBarMessage(args) {
try {
this.server.validateRequiredParams(args, ['message']);
if (args.hideAfterTimeout) {
vscode.window.setStatusBarMessage(args.message, args.hideAfterTimeout);
}
else {
vscode.window.setStatusBarMessage(args.message);
}
return this.server.createSuccessResponse({ success: true }, 'Status bar message set');
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async createStatusBarItem(args) {
try {
this.server.validateRequiredParams(args, ['id', 'text']);
const alignment = args.alignment === 'right' ? vscode.StatusBarAlignment.Right : vscode.StatusBarAlignment.Left;
const item = vscode.window.createStatusBarItem(alignment, args.priority);
item.text = args.text;
if (args.tooltip)
item.tooltip = args.tooltip;
if (args.command)
item.command = args.command;
if (args.color)
item.color = args.color;
if (args.backgroundColor)
item.backgroundColor = new vscode.ThemeColor(args.backgroundColor);
item.show();
this.statusBarItems.set(args.id, item);
return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' created`);
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async updateStatusBarItem(args) {
try {
this.server.validateRequiredParams(args, ['id']);
const item = this.statusBarItems.get(args.id);
if (!item) {
return this.server.createErrorResponse(`Status bar item '${args.id}' not found`);
}
if (args.text !== undefined)
item.text = args.text;
if (args.tooltip !== undefined)
item.tooltip = args.tooltip;
if (args.command !== undefined)
item.command = args.command;
if (args.color !== undefined)
item.color = args.color;
if (args.show !== undefined) {
if (args.show) {
item.show();
}
else {
item.hide();
}
}
return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' updated`);
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async removeStatusBarItem(args) {
try {
this.server.validateRequiredParams(args, ['id']);
const item = this.statusBarItems.get(args.id);
if (!item) {
return this.server.createErrorResponse(`Status bar item '${args.id}' not found`);
}
item.dispose();
this.statusBarItems.delete(args.id);
return this.server.createSuccessResponse({ success: true }, `Status bar item '${args.id}' removed`);
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
async showProgress(args) {
try {
this.server.validateRequiredParams(args, ['title']);
const locationMap = {
'notification': vscode.ProgressLocation.Notification,
'window': vscode.ProgressLocation.Window,
'source-control': vscode.ProgressLocation.SourceControl,
};
const location = locationMap[args.location || 'notification'] || vscode.ProgressLocation.Notification;
return new Promise((resolve) => {
vscode.window.withProgress({
location,
title: args.title,
cancellable: args.cancellable || false,
}, async (progress, token) => {
if (args.steps && args.steps.length > 0) {
for (const step of args.steps) {
if (token.isCancellationRequested) {
resolve(this.server.createSuccessResponse({ cancelled: true }, 'Progress cancelled'));
return;
}
progress.report({
message: step.message,
increment: step.increment,
});
// Small delay to show progress
await new Promise(resolve => setTimeout(resolve, 100));
}
}
resolve(this.server.createSuccessResponse({ success: true }, 'Progress completed'));
});
});
}
catch (error) {
return this.server.createErrorResponse(error);
}
}
dispose() {
for (const item of this.statusBarItems.values()) {
item.dispose();
}
this.statusBarItems.clear();
}
}
//# sourceMappingURL=uiTools.js.map