Skip to main content
Glama

Selenium MCP Server

actionTools.ts14.7 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StateManager } from '../utils/helpers.js'; import { ActionService } from '../services/actionService.js'; import { locatorSchema } from '../types/index.js'; import { z } from 'zod'; export function registerActionTools(server: McpServer, stateManager: StateManager) { server.tool( 'browser_hover', 'Hover over an element', { ...locatorSchema }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.hoverOverElement({ by, value, timeout }); return { content: [{ type: 'text', text: 'Hovered over element' }], }; } catch (e) { return { content: [ { type: 'text', text: `Error hovering over element: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_wait_for_element', 'Wait for an element to be present', { ...locatorSchema, timeout: z.number().describe('Timeout in milliseconds'), }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.waitForElement({ by, value, timeout }); return { content: [{ type: 'text', text: `Waited for element: ${value}` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error waiting for element: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_drag_and_drop', 'Perform drag and drop between two elements', { ...locatorSchema, targetBy: z .enum(['id', 'css', 'xpath', 'name', 'tag', 'class', 'link', 'partialLink']) .describe('Locator strategy to find target element'), targetValue: z.string().describe('Value for the target locator strategy'), }, async ({ by, value, targetBy, targetValue, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.dragAndDrop({ by, value, timeout }, { by: targetBy, value: targetValue, timeout }); return { content: [{ type: 'text', text: 'Drag and drop completed' }], }; } catch (e) { return { content: [ { type: 'text', text: `Error performing drag and drop: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_double_click', 'Perform double click on an element', { ...locatorSchema }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.doubleClickElement({ by, value, timeout }); return { content: [{ type: 'text', text: 'Double click performed' }], }; } catch (e) { return { content: [ { type: 'text', text: `Error performing double click: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_right_click', 'Perform right click (context click) on an element', { ...locatorSchema }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.rightClickElement({ by, value, timeout }); return { content: [{ type: 'text', text: 'Right click performed' }], }; } catch (e) { return { content: [ { type: 'text', text: `Error performing right click: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_select_dropdown_by_text', 'Select dropdown by visible text', { ...locatorSchema, text: z.string().describe('Visible text of the option to select'), }, async ({ by, value, text, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.selectDropdownByText({ by, value, text, timeout }); return { content: [{ type: 'text', text: `Selected dropdown option by text: ${text}` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error selecting dropdown option by text: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_select_dropdown_by_value', 'Select dropdown by value', { ...locatorSchema, value: z.string().describe('Value of the option to select'), }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.selectDropdownByValue({ by, value, timeout }); return { content: [ { type: 'text', text: `Selected dropdown option by value: ${value}`, }, ], }; } catch (e) { return { content: [ { type: 'text', text: `Error selecting dropdown option by value: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_key_press', 'Press a key on the keyboard', { key: z.string().describe("Key to press (e.g., 'Enter', 'Tab', 'a', etc.)"), }, async ({ key }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.pressKey(key); return { content: [{ type: 'text', text: `Key '${key}' pressed` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error pressing key: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_execute_script', 'Execute JavaScript in the context of the current page', { script: z.string().describe('JavaScript code to execute'), }, async ({ script }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); const result = await actionService.executeScript(script); return { content: [{ type: 'text', text: `Script executed successfully: ${result}` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error executing script: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_scroll_to_element', 'Scroll to an element', { ...locatorSchema }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollToElement({ by, value, timeout }); return { content: [{ type: 'text', text: `Scrolled to element` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling to element: ${(e as Error).message}`, }, ], }; } } ); server.tool('browser_scroll_to_top', 'Scroll to the top of the page', {}, async () => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollToTop(); return { content: [{ type: 'text', text: `Scrolled to top of the page` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling to top: ${(e as Error).message}`, }, ], }; } }); server.tool('browser_scroll_to_bottom', 'Scroll to the bottom of the page', {}, async () => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollToBottom(); return { content: [{ type: 'text', text: `Scrolled to bottom of the page` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling to bottom: ${(e as Error).message}`, }, ], }; } }); server.tool( 'browser_scroll_to_coordinates', 'Scroll to specific coordinates', { x: z.number().describe('X coordinate'), y: z.number().describe('Y coordinate'), }, async ({ x, y }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollToCoordinates(x, y); return { content: [{ type: 'text', text: `Scrolled to coordinates (${x}, ${y})` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling to coordinates: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_scroll_by_pixels', 'Scroll by a specific number of pixels', { x: z.number().describe('Number of pixels to scroll horizontally'), y: z.number().describe('Number of pixels to scroll vertically'), }, async ({ x, y }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollByPixels(x, y); return { content: [{ type: 'text', text: `Scrolled by pixels (${x}, ${y})` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling by pixels: ${(e as Error).message}`, }, ], }; } } ); server.tool('browser_select_checkbox', 'Select a checkbox', { ...locatorSchema }, async ({ by, value }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.selectCheckbox({ by, value }); return { content: [{ type: 'text', text: `Selected checkbox` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error selecting checkbox: ${(e as Error).message}`, }, ], }; } }); server.tool('browser_unselect_checkbox', 'Unselect a checkbox', { ...locatorSchema }, async ({ by, value }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.unselectCheckbox({ by, value }); return { content: [{ type: 'text', text: `Unselected checkbox` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error unselecting checkbox: ${(e as Error).message}`, }, ], }; } }); server.tool('browser_submit_form', 'Submit a form', { ...locatorSchema }, async ({ by, value }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.submitForm({ by, value }); return { content: [{ type: 'text', text: `Submitted form` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error submitting form: ${(e as Error).message}`, }, ], }; } }); server.tool('browser_focus_element', 'Focus on a specific element', { ...locatorSchema }, async ({ by, value }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.focusElement({ by, value }); return { content: [{ type: 'text', text: `Focused on element` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error focusing on element: ${(e as Error).message}`, }, ], }; } }); server.tool( 'browser_blur_element', 'Remove focus from a specific element', { ...locatorSchema }, async ({ by, value }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.blurElement({ by, value }); return { content: [{ type: 'text', text: `Removed focus from element` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error removing focus from element: ${(e as Error).message}`, }, ], }; } } ); server.tool( 'browser_screenshot', 'Take a screenshot of the current page', { outputPath: z .string() .optional() .describe('Optional path where to save the screenshot. If not provided, returns base64 data.'), }, async ({ outputPath }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); const screenshot = await actionService.takeScreenshot(); if (outputPath) { const fs = await import('fs/promises'); await fs.writeFile(outputPath, screenshot, 'base64'); return { content: [{ type: 'text', text: `Screenshot saved to ${outputPath}` }], }; } else { return { content: [ { type: 'text', text: 'Screenshot captured as base64:' }, { type: 'text', text: screenshot }, ], }; } } catch (e) { return { content: [ { type: 'text', text: `Error taking screenshot: ${(e as Error).message}`, }, ], }; } } ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pshivapr/selenium-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server