feat: MCP Browser v3.1.1 - 56+ tools, visual overlays, fixes
- Added 9 new tools: visual overlay, highlight, toast, drag-drop, etc. - Fixed evaluateJS to support function arguments - Fixed hover for non-visible elements - Fixed storage operations with try/catch - Added 10 new wait tools: clickable, element visible, text - Fixed tool name mapping in server.js for MCP protocol - Updated README with 60+ tools documentation - Version bump to 3.1.1
This commit is contained in:
@@ -27,6 +27,7 @@ const tools = {
|
||||
goForward: require('./tools/goForward'),
|
||||
reload: require('./tools/reload'),
|
||||
evaluateJS: require('./tools/evaluateJS'),
|
||||
evaluateJs: require('./tools/evaluateJS'),
|
||||
waitForURL: require('./tools/waitForURL'),
|
||||
newTab: require('./tools/newTab'),
|
||||
switchTab: require('./tools/switchTab'),
|
||||
@@ -49,10 +50,19 @@ const tools = {
|
||||
blockResources: require('./tools/blockResources'),
|
||||
uploadFile: require('./tools/uploadFile'),
|
||||
getPerformanceMetrics: require('./tools/getPerformanceMetrics'),
|
||||
wait: require('./tools/wait')
|
||||
wait: require('./tools/wait'),
|
||||
enableVisualOverlay: require('./tools/enableVisualOverlay'),
|
||||
showToast: require('./tools/showToast'),
|
||||
highlightElement: require('./tools/highlightElement'),
|
||||
dragAndDrop: require('./tools/dragAndDrop'),
|
||||
annotatedScreenshot: require('./tools/annotatedScreenshot'),
|
||||
getInputValues: require('./tools/getInputValues'),
|
||||
waitForClickable: require('./tools/waitForClickable'),
|
||||
waitForElementVisible: require('./tools/waitForElementVisible'),
|
||||
waitForText: require('./tools/waitForText')
|
||||
};
|
||||
|
||||
const server = new Server({ name: 'browser', version: '3.0.0' }, { capabilities: { tools: {} } });
|
||||
const server = new Server({ name: 'browser', version: '3.1.1' }, { capabilities: { tools: {} } });
|
||||
|
||||
const toolSchemas = [
|
||||
{ name: 'open_url', description: 'Abre uma URL no navegador', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL para abrir' }, waitUntil: { type: 'string', enum: ['domcontentloaded', 'load', 'networkidle'] } }, required: ['url'] } },
|
||||
@@ -101,14 +111,79 @@ const toolSchemas = [
|
||||
{ name: 'block_resources', description: 'Bloqueia recursos', inputSchema: { type: 'object', properties: { types: { type: 'array', items: { type: 'string' } } }, required: ['types'] } },
|
||||
{ name: 'upload_file', description: 'Upload de arquivo', inputSchema: { type: 'object', properties: { selector: { type: 'string' }, filePaths: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }] } }, required: ['selector', 'filePaths'] } },
|
||||
{ name: 'get_performance_metrics', description: 'Métricas de performance', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'wait', description: 'Aguarda ms', inputSchema: { type: 'object', properties: { ms: { type: 'number' } }, required: ['ms'] } }
|
||||
{ name: 'wait', description: 'Aguarda ms', inputSchema: { type: 'object', properties: { ms: { type: 'number' } }, required: ['ms'] } },
|
||||
{ name: 'enable_visual_overlay', description: 'Ativa cursor customizado e indicadores visuais de rolagem', inputSchema: { type: 'object', properties: {} } },
|
||||
{ name: 'show_toast', description: 'Mostra notificação toast na página', inputSchema: { type: 'object', properties: { message: { type: 'string' }, duration: { type: 'number' } } } },
|
||||
{ name: 'highlight_element', description: 'Destaca elemento com animação visual', inputSchema: { type: 'object', properties: { selector: { type: 'string' }, color: { type: 'string' }, duration: { type: 'number' } }, required: ['selector'] } },
|
||||
{ name: 'drag_and_drop', description: 'Arrasta e solta elemento', inputSchema: { type: 'object', properties: { sourceSelector: { type: 'string' }, targetSelector: { type: 'string' } }, required: ['sourceSelector', 'targetSelector'] } },
|
||||
{ name: 'annotated_screenshot', description: 'Screenshot com elementos destacados', inputSchema: { type: 'object', properties: { fullPage: { type: 'boolean' }, path: { type: 'string' }, highlight: { oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }] } } } },
|
||||
{ name: 'get_input_values', description: 'Obtém valores de todos os inputs', inputSchema: { type: 'object', properties: { selector: { type: 'string' } } } },
|
||||
{ name: 'wait_for_clickable', description: 'Espera elemento ser clicável', inputSchema: { type: 'object', properties: { selector: { type: 'string' }, timeout: { type: 'number' } }, required: ['selector'] } },
|
||||
{ name: 'wait_for_element_visible', description: 'Espera elemento visível', inputSchema: { type: 'object', properties: { selector: { type: 'string' }, timeout: { type: 'number' }, state: { type: 'string', enum: ['attached', 'detached', 'visible', 'hidden'] } }, required: ['selector'] } },
|
||||
{ name: 'wait_for_text', description: 'Espera texto aparecer na página', inputSchema: { type: 'object', properties: { text: { type: 'string' }, timeout: { type: 'number' } }, required: ['text'] } }
|
||||
];
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: toolSchemas }));
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
const { name, arguments: args } = request.params;
|
||||
const tool = tools[name.replace(/-/g, '').replace(/_([a-z])/g, (_, c) => c.toUpperCase())] || tools[name];
|
||||
let toolName = name.replace(/-/g, '').replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
||||
|
||||
// Debug log
|
||||
console.error('[MCP] Request:', name, '→ Converted:', toolName);
|
||||
|
||||
const nameMap = {
|
||||
// camelCase sem underscores
|
||||
'geturl': 'getURL',
|
||||
'gethtml': 'getHTML',
|
||||
'goback': 'goBack',
|
||||
'goforward': 'goForward',
|
||||
'newtab': 'newTab',
|
||||
'switchtab': 'switchTab',
|
||||
'listtabs': 'listTabs',
|
||||
'closetab': 'closeTab',
|
||||
'setviewport': 'setViewport',
|
||||
'emulatedevice': 'emulateDevice',
|
||||
'waitforurl': 'waitForURL',
|
||||
'waitforselector': 'waitForSelector',
|
||||
'getcookies': 'getCookies',
|
||||
'setcookies': 'setCookies',
|
||||
'clearcookies': 'clearCookies',
|
||||
'getstorage': 'getStorage',
|
||||
'setstorage': 'setStorage',
|
||||
'clearstorage': 'clearStorage',
|
||||
'getnetworklogs': 'getNetworkLogs',
|
||||
'blockresources': 'blockResources',
|
||||
'getperformancemetrics': 'getPerformanceMetrics',
|
||||
'waitfortimeout': 'waitForTimeout',
|
||||
'enablevisualoverlay': 'enableVisualOverlay',
|
||||
'showtoast': 'showToast',
|
||||
'highlightelement': 'highlightElement',
|
||||
'draganddrop': 'dragAndDrop',
|
||||
'annotatedscreenshot': 'annotatedScreenshot',
|
||||
'getinputvalues': 'getInputValues',
|
||||
'waitforclickable': 'waitForClickable',
|
||||
'waitforelementvisible': 'waitForElementVisible',
|
||||
'waitfortext': 'waitForText',
|
||||
'fillformauto': 'fillFormAuto',
|
||||
'agentflow': 'agentFlow',
|
||||
'agentflowv2': 'agentFlowV2',
|
||||
'smartclick': 'smartClick',
|
||||
'smarttype': 'smartType',
|
||||
'smartwaitnavigation': 'smartWaitNavigation',
|
||||
'getbuttons': 'getButtons',
|
||||
'getforms': 'getForms',
|
||||
'extractelements': 'extractElements',
|
||||
'gettext': 'getText',
|
||||
'getlinks': 'getLinks',
|
||||
'openurl': 'openUrl',
|
||||
'closebrowser': 'closeBrowser',
|
||||
'gettitle': 'getTitle'
|
||||
};
|
||||
|
||||
if (nameMap[toolName]) toolName = nameMap[toolName];
|
||||
|
||||
const tool = tools[toolName] || tools[name];
|
||||
if (!tool) throw new Error(`Tool "${name}" não encontrada`);
|
||||
try {
|
||||
const result = await tool(args || {});
|
||||
|
||||
Reference in New Issue
Block a user