Skip to main content
Glama

Playwright MCP Server

by BhanuTJ93
interaction.ts7.81 kB
import { BrowserToolBase } from './base.js'; import { ToolContext, ToolResponse, createSuccessResponse, createErrorResponse } from '../common/types.js'; import { setGlobalPage } from '../../toolHandler.js'; /** * Tool for clicking elements on the page */ export class ClickTool extends BrowserToolBase { /** * Execute the click tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { await page.click(args.selector); return createSuccessResponse(`Clicked element: ${args.selector}`); }); } } /** * Tool for clicking a link and switching to the new tab */ export class ClickAndSwitchTabTool extends BrowserToolBase { /** * Execute the click and switch tab tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { // Listen for a new tab to open const [newPage] = await Promise.all([ //context.browser.waitForEvent('page'), // Wait for a new page (tab) to open page.context().waitForEvent('page'),// Wait for a new page (tab) to open page.click(args.selector), // Click the link that opens the new tab ]); // Wait for the new page to load await newPage.waitForLoadState('domcontentloaded'); // Switch control to the new tab setGlobalPage(newPage); //page= newPage; // Update the current page to the new tab //context.page = newPage; //context.page.bringToFront(); // Bring the new tab to the front return createSuccessResponse(`Clicked link and switched to new tab: ${newPage.url()}`); //return createSuccessResponse(`Clicked link and switched to new tab: ${context.page.url()}`); }); } } /** * Tool for clicking elements inside iframes */ export class IframeClickTool extends BrowserToolBase { /** * Execute the iframe click tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { const frame = page.frameLocator(args.iframeSelector); if (!frame) { return createErrorResponse(`Iframe not found: ${args.iframeSelector}`); } await frame.locator(args.selector).click(); return createSuccessResponse(`Clicked element ${args.selector} inside iframe ${args.iframeSelector}`); }); } } /** * Tool for filling elements inside iframes */ export class IframeFillTool extends BrowserToolBase { /** * Execute the iframe fill tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { const frame = page.frameLocator(args.iframeSelector); if (!frame) { return createErrorResponse(`Iframe not found: ${args.iframeSelector}`); } await frame.locator(args.selector).fill(args.value); return createSuccessResponse(`Filled element ${args.selector} inside iframe ${args.iframeSelector} with: ${args.value}`); }); } } /** * Tool for filling form fields */ export class FillTool extends BrowserToolBase { /** * Execute the fill tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { await page.waitForSelector(args.selector); await page.fill(args.selector, args.value); return createSuccessResponse(`Filled ${args.selector} with: ${args.value}`); }); } } /** * Tool for selecting options from dropdown menus */ export class SelectTool extends BrowserToolBase { /** * Execute the select tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { await page.waitForSelector(args.selector); await page.selectOption(args.selector, args.value); return createSuccessResponse(`Selected ${args.selector} with: ${args.value}`); }); } } /** * Tool for hovering over elements */ export class HoverTool extends BrowserToolBase { /** * Execute the hover tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { await page.waitForSelector(args.selector); await page.hover(args.selector); return createSuccessResponse(`Hovered ${args.selector}`); }); } } /** * Tool for executing JavaScript in the browser */ export class EvaluateTool extends BrowserToolBase { /** * Execute the evaluate tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { const result = await page.evaluate(args.script); // Convert result to string for display let resultStr: string; try { resultStr = JSON.stringify(result, null, 2); } catch (error) { resultStr = String(result); } return createSuccessResponse([ `Executed JavaScript:`, `${args.script}`, `Result:`, `${resultStr}` ]); }); } } /** * Tool for dragging elements on the page */ export class DragTool extends BrowserToolBase { /** * Execute the drag tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { const sourceElement = await page.waitForSelector(args.sourceSelector); const targetElement = await page.waitForSelector(args.targetSelector); const sourceBound = await sourceElement.boundingBox(); const targetBound = await targetElement.boundingBox(); if (!sourceBound || !targetBound) { return createErrorResponse("Could not get element positions for drag operation"); } await page.mouse.move( sourceBound.x + sourceBound.width / 2, sourceBound.y + sourceBound.height / 2 ); await page.mouse.down(); await page.mouse.move( targetBound.x + targetBound.width / 2, targetBound.y + targetBound.height / 2 ); await page.mouse.up(); return createSuccessResponse(`Dragged element from ${args.sourceSelector} to ${args.targetSelector}`); }); } } /** * Tool for pressing keyboard keys */ export class PressKeyTool extends BrowserToolBase { /** * Execute the key press tool */ async execute(args: any, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { if (args.selector) { await page.waitForSelector(args.selector); await page.focus(args.selector); } await page.keyboard.press(args.key); return createSuccessResponse(`Pressed key: ${args.key}`); }); } } /** * Tool for switching browser tabs */ // export class SwitchTabTool extends BrowserToolBase { // /** // * Switch the tab to the specified index // */ // async execute(args: any, context: ToolContext): Promise<ToolResponse> { // return this.safeExecute(context, async (page) => { // const tabs = await browser.page; // // Validate the tab index // const tabIndex = Number(args.index); // if (isNaN(tabIndex)) { // return createErrorResponse(`Invalid tab index: ${args.index}. It must be a number.`); // } // if (tabIndex >= 0 && tabIndex < tabs.length) { // await tabs[tabIndex].bringToFront(); // return createSuccessResponse(`Switched to tab with index ${tabIndex}`); // } else { // return createErrorResponse( // `Tab index out of range: ${tabIndex}. Available tabs: 0 to ${tabs.length - 1}.` // ); // } // }); // } // }

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/BhanuTJ93/MCP'

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