Skip to content

Commit

Permalink
Merge pull request #72 from executeautomation/main
Browse files Browse the repository at this point in the history
Added Hover and Select Capability in Puppeteer MCP Server
  • Loading branch information
dsp-ant authored Nov 27, 2024
2 parents def7549 + 2385870 commit 5a279e5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 5 deletions.
11 changes: 11 additions & 0 deletions src/puppeteer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@ A Model Context Protocol server that provides browser automation capabilities us
- Click elements on the page
- Input: `selector` (string): CSS selector for element to click

- **puppeteer_hover**
- Hover elements on the page
- Input: `selector` (string): CSS selector for element to hover

- **puppeteer_fill**
- Fill out input fields
- Inputs:
- `selector` (string): CSS selector for input field
- `value` (string): Value to fill

- **puppeteer_select**
- Select an element with SELECT tag
- Inputs:
- `selector` (string): CSS selector for element to select
- `value` (string): Value to select

- **puppeteer_evaluate**
- Execute JavaScript in the browser console
- Input: `script` (string): JavaScript code to execute
Expand Down Expand Up @@ -64,6 +74,7 @@ Here's the Claude Desktop configuration to use the Puppeter server:
}
}
}
```

## License

Expand Down
83 changes: 78 additions & 5 deletions src/puppeteer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,29 @@ const TOOLS: Tool[] = [
required: ["selector", "value"],
},
},
{
name: "puppeteer_select",
description: "Select an element on the page with Select tag",
inputSchema: {
type: "object",
properties: {
selector: { type: "string", description: "CSS selector for element to select" },
value: { type: "string", description: "Value to select" },
},
required: ["selector", "value"],
},
},
{
name: "puppeteer_hover",
description: "Hover an element on the page",
inputSchema: {
type: "object",
properties: {
selector: { type: "string", description: "CSS selector for element to hover" },
},
required: ["selector"],
},
},
{
name: "puppeteer_evaluate",
description: "Execute JavaScript in the browser console",
Expand All @@ -88,7 +111,7 @@ async function ensureBrowser() {
browser = await puppeteer.launch({ headless: false });
const pages = await browser.pages();
page = pages[0];

page.on("console", (msg) => {
const logEntry = `[${msg.type()}] ${msg.text()}`;
consoleLogs.push(logEntry);
Expand Down Expand Up @@ -122,7 +145,7 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
const height = args.height ?? 600;
await page.setViewport({ width, height });

const screenshot = await (args.selector ?
const screenshot = await (args.selector ?
(await page.$(args.selector))?.screenshot({ encoding: "base64" }) :
page.screenshot({ encoding: "base64", fullPage: false }));

Expand Down Expand Up @@ -210,12 +233,62 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
};
}

case "puppeteer_select":
try {
await page.waitForSelector(args.selector);
await page.select(args.selector, args.value);
return {
toolResult: {
content: [{
type: "text",
text: `Selected ${args.selector} with: ${args.value}`,
}],
isError: false,
},
};
} catch (error) {
return {
toolResult: {
content: [{
type: "text",
text: `Failed to select ${args.selector}: ${(error as Error).message}`,
}],
isError: true,
},
};
}

case "puppeteer_hover":
try {
await page.waitForSelector(args.selector);
await page.hover(args.selector);
return {
toolResult: {
content: [{
type: "text",
text: `Hovered ${args.selector}`,
}],
isError: false,
},
};
} catch (error) {
return {
toolResult: {
content: [{
type: "text",
text: `Failed to hover ${args.selector}: ${(error as Error).message}`,
}],
isError: true,
},
};
}

case "puppeteer_evaluate":
try {
const result = await page.evaluate((script) => {
const logs: string[] = [];
const originalConsole = { ...console };

['log', 'info', 'warn', 'error'].forEach(method => {
(console as any)[method] = (...args: any[]) => {
logs.push(`[${method}] ${args.join(' ')}`);
Expand Down Expand Up @@ -301,7 +374,7 @@ server.setRequestHandler(ListResourcesRequestSchema, async () => ({

server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri.toString();

if (uri === "console://logs") {
return {
contents: [{
Expand Down Expand Up @@ -333,7 +406,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: TOOLS,
}));

server.setRequestHandler(CallToolRequestSchema, async (request) =>
server.setRequestHandler(CallToolRequestSchema, async (request) =>
handleToolCall(request.params.name, request.params.arguments ?? {})
);

Expand Down

0 comments on commit 5a279e5

Please sign in to comment.