diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 366c21ea4..a6d0744ed 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -1,6 +1,6 @@ -# Chrome DevTools MCP Tool Reference (~6962 cl100k_base tokens) +# Chrome DevTools MCP Tool Reference (~7107 cl100k_base tokens) - **[Input automation](#input-automation)** (9 tools) - [`click`](#click) @@ -317,8 +317,10 @@ ### `evaluate_script` -**Description:** Evaluate a JavaScript function inside the currently selected page. Returns the response as JSON, -so returned values have to be JSON-serializable. +**Description:** Evaluate a JavaScript function inside the currently selected page or frame. Returns the response as JSON, +so returned values have to be JSON-serializable. The function runs in the current page context only; do not use it to navigate to other pages. +Use [`navigate_page`](#navigate_page) or [`new_page`](#new_page) for navigation, then run [`evaluate_script`](#evaluate_script) again after the new page loads. When querying the DOM, use standard browser APIs +and valid native CSS selectors only. Uids from [`take_snapshot`](#take_snapshot) are not DOM attributes; pass them via the args parameter when you need the referenced elements. **Parameters:** @@ -331,8 +333,9 @@ so returned values have to be JSON-serializable. Example with arguments: `(el) => { return el.innerText; }` + Use only standard DOM APIs and valid native CSS selectors inside the function. Do not use snapshot uids in querySelector calls, and do not change window.location here to navigate across pages. -- **args** (array) _(optional)_: An optional list of arguments to pass to the function. +- **args** (array) _(optional)_: An optional list of element uids from [`take_snapshot`](#take_snapshot). These are resolved to real element handles and passed as function arguments; they are not available as DOM attributes in the page. --- diff --git a/skills/chrome-devtools/SKILL.md b/skills/chrome-devtools/SKILL.md index 9b9fbce46..ff4f6c31d 100644 --- a/skills/chrome-devtools/SKILL.md +++ b/skills/chrome-devtools/SKILL.md @@ -11,6 +11,10 @@ description: Uses Chrome DevTools via MCP for efficient debugging, troubleshooti **Element interaction**: Use `take_snapshot` to get page structure with element `uid`s. Each element has a unique `uid` for interaction. If an element isn't found, take a fresh snapshot - the element may have been removed or the page changed. +**Snapshot uid scope**: `uid`s from `take_snapshot` are MCP references, not DOM attributes. Do not use them in `querySelector()` or other selector strings. When a script needs one of those elements, pass the `uid` through `evaluate_script` args so the tool resolves it to a real element handle. + +**Script scope**: `evaluate_script` runs in the currently selected page or frame only. Do not try to navigate by setting `window.location` inside the evaluated function. Use `navigate_page` or `new_page`, wait for the destination page, then run another `evaluate_script`. + ## Workflow Patterns ### Before interacting with a page @@ -30,7 +34,7 @@ description: Uses Chrome DevTools via MCP for efficient debugging, troubleshooti - **Automation/interaction**: `take_snapshot` (text-based, faster, better for automation) - **Visual inspection**: `take_screenshot` (when user needs to see visual state) -- **Additional details**: `evaluate_script` for data not in accessibility tree +- **Additional details**: `evaluate_script` for data not in accessibility tree. Use valid native DOM APIs/selectors only; avoid library-specific pseudo-classes like `:contains(...)`. ### Parallel execution diff --git a/src/bin/cliDefinitions.ts b/src/bin/cliDefinitions.ts index aef789af3..ca8da840a 100644 --- a/src/bin/cliDefinitions.ts +++ b/src/bin/cliDefinitions.ts @@ -139,20 +139,21 @@ export const commands: Commands = { }, evaluate_script: { description: - 'Evaluate a JavaScript function inside the currently selected page. Returns the response as JSON,\nso returned values have to be JSON-serializable.', + 'Evaluate a JavaScript function inside the currently selected page or frame. Returns the response as JSON,\nso returned values have to be JSON-serializable. The function runs in the current page context only; do not use it to navigate to other pages.\nUse navigate_page or new_page for navigation, then run evaluate_script again after the new page loads. When querying the DOM, use standard browser APIs\nand valid native CSS selectors only. Uids from take_snapshot are not DOM attributes; pass them via the args parameter when you need the referenced elements.', category: 'Debugging', args: { function: { name: 'function', type: 'string', description: - 'A JavaScript function declaration to be executed by the tool in the currently selected page.\nExample without arguments: `() => {\n return document.title\n}` or `async () => {\n return await fetch("example.com")\n}`.\nExample with arguments: `(el) => {\n return el.innerText;\n}`\n', + 'A JavaScript function declaration to be executed by the tool in the currently selected page.\nExample without arguments: `() => {\n return document.title\n}` or `async () => {\n return await fetch("example.com")\n}`.\nExample with arguments: `(el) => {\n return el.innerText;\n}`\nUse only standard DOM APIs and valid native CSS selectors inside the function. Do not use snapshot uids in querySelector calls, and do not change window.location here to navigate across pages.\n', required: true, }, args: { name: 'args', type: 'array', - description: 'An optional list of arguments to pass to the function.', + description: + 'An optional list of element uids from take_snapshot. These are resolved to real element handles and passed as function arguments; they are not available as DOM attributes in the page.', required: false, }, }, diff --git a/src/tools/script.ts b/src/tools/script.ts index 725628bcd..c91c99721 100644 --- a/src/tools/script.ts +++ b/src/tools/script.ts @@ -17,8 +17,10 @@ export type Evaluatable = Page | Frame | WebWorker; export const evaluateScript = defineTool(cliArgs => { return { name: 'evaluate_script', - description: `Evaluate a JavaScript function inside the currently selected page. Returns the response as JSON, -so returned values have to be JSON-serializable.`, + description: `Evaluate a JavaScript function inside the currently selected page or frame. Returns the response as JSON, +so returned values have to be JSON-serializable. The function runs in the current page context only; do not use it to navigate to other pages. +Use navigate_page or new_page for navigation, then run evaluate_script again after the new page loads. When querying the DOM, use standard browser APIs +and valid native CSS selectors only. Uids from take_snapshot are not DOM attributes; pass them via the args parameter when you need the referenced elements.`, annotations: { category: ToolCategory.DEBUGGING, readOnlyHint: false, @@ -34,6 +36,7 @@ Example without arguments: \`() => { Example with arguments: \`(el) => { return el.innerText; }\` +Use only standard DOM APIs and valid native CSS selectors inside the function. Do not use snapshot uids in querySelector calls, and do not change window.location here to navigate across pages. `, ), args: zod @@ -45,7 +48,9 @@ Example with arguments: \`(el) => { ), ) .optional() - .describe(`An optional list of arguments to pass to the function.`), + .describe( + `An optional list of element uids from take_snapshot. These are resolved to real element handles and passed as function arguments; they are not available as DOM attributes in the page.`, + ), ...(cliArgs?.experimentalPageIdRouting ? pageIdSchema : {}), ...(cliArgs?.categoryExtensions ? {