clickElementTool.ts•2.68 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { By } from 'selenium-webdriver';
import { getWebDriver } from "../services/seleniumService.js";
const ClickElementInputSchema = z.object({
selector: z.string().min(1, { message: "CSS selector cannot be empty." }),
});
type ClickElementInput = z.infer<typeof ClickElementInputSchema>;
const ClickElementOutputSchema = z.object({
success: z.boolean(),
message: z.string(),
});
export function registerClickElementTool(server: McpServer): void {
const description = "Finds the first element matching the CSS selector and clicks it.";
server.tool(
'selenium_clickElement',
description,
ClickElementInputSchema.shape,
async (params: ClickElementInput) => {
const driver = getWebDriver();
try {
console.log(`Finding element to click with selector: ${params.selector}`);
const element = await driver.findElement(By.css(params.selector));
if (!(await element.isDisplayed()) || !(await element.isEnabled())) {
throw new Error(`Element found but is not interactable (visible and enabled): ${params.selector}`);
}
const tagName = await element.getTagName();
console.log(`Clicking element <${tagName}> with selector: ${params.selector}`);
await element.click();
console.log(`Successfully clicked element: ${params.selector}`);
return {
content: [
{
type: "text",
text: `Successfully clicked element <${tagName}> matching selector: ${params.selector}`,
},
]
};
} catch (error: any) {
if (error.name === 'NoSuchElementError') {
console.error(`Element not found to click: ${params.selector}`);
throw new Error(`Element not found to click: ${params.selector}`);
} else if (error.name === 'ElementClickInterceptedError') {
console.error(`Click intercepted for element: ${params.selector}. Another element is obscuring it.`);
throw new Error(`Click intercepted for element: ${params.selector}. Another element may be obscuring it.`);
} else if (error.name === 'ElementNotInteractableError') {
console.error(`Element not interactable: ${params.selector}. It might be hidden or disabled.`);
throw new Error(`Element not interactable: ${params.selector}.`);
} else {
console.error(`Error clicking element ${params.selector}:`, error);
throw new Error(`Failed to click element. Error: ${error.message || 'Unknown error'}`);
}
}
}
);
}