execute-code
Execute custom JavaScript code using Playwright to interact with web pages, retrieve page data, and perform automated browser actions for testing and automation workflows.
Instructions
Execute custom Playwright JS code against the current page
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The Playwright code to execute. Must be an async function declaration that takes a page parameter. Example: async function run(page) { console.log(await page.title()); return await page.title(); } Returns an object with: - result: The return value from your function - logs: Array of console logs from execution - errors: Array of any errors encountered Example response: {"result": "Google", "logs": ["[log] Google"], "errors": []} |
Implementation Reference
- src/mcp/index.ts:190-229 (registration)Registration of the 'execute-code' MCP tool, including input schema, description, and handler function that logs usage and delegates execution to secureEvalAsync helper.server.tool( 'execute-code', 'Execute custom Playwright JS code against the current page', { code: z.string().describe(`The Playwright code to execute. Must be an async function declaration that takes a page parameter. Example: async function run(page) { console.log(await page.title()); return await page.title(); } Returns an object with: - result: The return value from your function - logs: Array of console logs from execution - errors: Array of any errors encountered Example response: {"result": "Google", "logs": ["[log] Google"], "errors": []}`) }, async ({ code }) => { posthogServer.capture({ distinctId: getUserId(), event: 'execute_code', properties: { codeLength: code.length, }, }); const result = await secureEvalAsync(page, code); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) // Pretty print the JSON } ] }; } )
- src/mcp/index.ts:210-229 (handler)The MCP tool handler function for 'execute-code'. Captures analytics, executes the code via secureEvalAsync, and returns the result as pretty-printed JSON text content.async ({ code }) => { posthogServer.capture({ distinctId: getUserId(), event: 'execute_code', properties: { codeLength: code.length, }, }); const result = await secureEvalAsync(page, code); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) // Pretty print the JSON } ] }; } )
- src/mcp/index.ts:193-209 (schema)Input schema for the 'execute-code' tool using Zod, defining the 'code' string parameter with detailed usage instructions and examples.{ code: z.string().describe(`The Playwright code to execute. Must be an async function declaration that takes a page parameter. Example: async function run(page) { console.log(await page.title()); return await page.title(); } Returns an object with: - result: The return value from your function - logs: Array of console logs from execution - errors: Array of any errors encountered Example response: {"result": "Google", "logs": ["[log] Google"], "errors": []}`) },
- src/mcp/eval.ts:6-97 (helper)Supporting utility function that securely executes the provided async Playwright code in a Node.js vm sandbox. Injects the page object, overrides console to capture logs/errors, wraps code to call run(page), and returns structured result with result/logs/errors.export const secureEvalAsync = async (page: Page, code: string, context = {}) => { // Set default options const timeout = 20000; const filename = 'eval.js'; let logs: string[] = []; let errors: string[] = []; // Code should already be a function declaration // Just need to execute it with page argument const wrappedCode = ` ${code} run(page); `; // Create restricted sandbox with provided context const sandbox = { // Core async essentials Promise, setTimeout, clearTimeout, setImmediate, clearImmediate, // Pass page object to sandbox page, // Capture all console methods console: { log: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); logs.push(`[log] ${msg}`); }, error: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); errors.push(`[error] ${msg}`); }, warn: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); logs.push(`[warn] ${msg}`); }, info: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); logs.push(`[info] ${msg}`); }, debug: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); logs.push(`[debug] ${msg}`); }, trace: (...args: any[]) => { const msg = args.map(arg => String(arg)).join(' '); logs.push(`[trace] ${msg}`); } }, // User-provided context ...context, // Explicitly block access to sensitive globals process: undefined, global: undefined, require: undefined, __dirname: undefined, __filename: undefined, Buffer: undefined }; try { // Create context and script const vmContext = vm.createContext(sandbox); const script = new vm.Script(wrappedCode, { filename }); // Execute and await result const result = script.runInContext(vmContext); const awaitedResult = await result; return { result: awaitedResult, logs, errors }; } catch (error: any) { return { error: true, message: error.message, stack: error.stack, logs, errors }; } }