From a984da9a59135a10bf4c99b114e1a0ef48218e9b Mon Sep 17 00:00:00 2001 From: noiemany <51255434+compnew2006@users.noreply.github.com> Date: Sun, 11 Oct 2026 16:23:35 +0300 Subject: [PATCH 1/2] feat(webmcp): call the tools a page registers through WebMCP Add browser_webmcp_list and browser_webmcp_call. Pages that adopt WebMCP register tools with document.modelContext.registerTool() or
; agents can now list those tools and call them by name with an input object, instead of driving the page's UI. - Runner (extension/lib/webmcp-page.js) is stringified and evaluated in the page over CDP as an awaited expression (replMode does not unwrap a returned promise), and returns a JSON string. - Safety gates: consequentialHint tools and toolautosubmit forms need confirm:true; forms that wait for a user submit return DECLARATIVE_NEEDS_USER. Declarative forms are found in the light DOM, open and closed shadow roots and same-origin frames (DOM.performSearch); if that scan fails, calls fail closed (FORM_SCAN_FAILED). - Page-authored content is flagged untrustedContent by the handler, which also validates everything the page returns. - Timeouts abort the tool page-side; navigation during a call is a non-error status:"unknown". browser_shortcuts refuses a saved confirm:true. - npm run smoke:webmcp drives the real handlers against an isolated headless Chrome (15 checks); 629 unit tests pass. Built through specs/webmcp-support (spec, plan, independent review, tasks, implementation report, independent audit: PASS). Co-Authored-By: Claude Opus 5.5 --- README.md | 49 +- agent-config/AGENTS.md | 5 +- .../cursor/rules/browser-controller.mdc | 4 + .../skills/browser-automation/SKILL.md | 4 + extension/handlers/gif.js | 2 +- extension/handlers/webmcp.js | 397 +++++++++ extension/lib/protocol.js | 1 + extension/lib/router.js | 3 + extension/lib/webmcp-page.js | 399 +++++++++ llms.txt | 3 +- mcp-server/src/protocol.ts | 1 + mcp-server/src/tools/index.ts | 3 + mcp-server/src/tools/meta.ts | 4 + mcp-server/src/tools/shortcuts.ts | 18 + mcp-server/src/tools/webmcp.ts | 46 + package.json | 1 + scripts/smoke-webmcp.mjs | 315 +++++++ specs/webmcp-support/audit.md | 800 ++++++++++++++++++ specs/webmcp-support/implementation_report.md | 207 +++++ specs/webmcp-support/plan.md | 93 ++ specs/webmcp-support/review.md | 596 +++++++++++++ specs/webmcp-support/spec.md | 388 +++++++++ specs/webmcp-support/tasks.md | 218 +++++ tests/extension-webmcp.test.ts | 777 +++++++++++++++++ tests/fixtures/webmcp-demo.html | 152 ++++ tests/fixtures/webmcp-frame.html | 30 + tests/tools/registry.test.ts | 1 + tests/tools/shortcuts.test.ts | 24 + 28 files changed, 4532 insertions(+), 9 deletions(-) create mode 100644 extension/handlers/webmcp.js create mode 100644 extension/lib/webmcp-page.js create mode 100644 mcp-server/src/tools/webmcp.ts create mode 100644 scripts/smoke-webmcp.mjs create mode 100644 specs/webmcp-support/audit.md create mode 100644 specs/webmcp-support/implementation_report.md create mode 100644 specs/webmcp-support/plan.md create mode 100644 specs/webmcp-support/review.md create mode 100644 specs/webmcp-support/spec.md create mode 100644 specs/webmcp-support/tasks.md create mode 100644 tests/extension-webmcp.test.ts create mode 100644 tests/fixtures/webmcp-demo.html create mode 100644 tests/fixtures/webmcp-frame.html diff --git a/README.md b/README.md index 7402afa..a138985 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ It already has your browser open right there. It just can't see it. - **Versioned compatibility handshake.** The daemon and extension advertise an application-protocol version, build version, and capabilities before tool traffic is accepted. Explicitly incompatible protocol majors fail with an actionable error instead of producing unexplained timeouts; the build version is diagnostic and does not by itself make compatible peers fail. - **Real, trusted input.** Clicks, typing and key presses go through the Chrome DevTools Protocol, so the page sees `isTrusted` events, focus really moves, default actions run (Tab moves focus, Enter submits, arrows drive autocomplete menus) and focus/blur fire even while the window is in the background — legacy grids and lookup widgets behave as they do for a person. One debugger session per tab is reused and detached after 30 s idle (the yellow "being debugged" banner shows only while it is attached). Pass `trusted: false` for the old synthetic events with no banner; they are also the automatic fallback when the debugger can't attach. - **Batches.** `browser_batch` runs a list of tool calls in one round-trip and stops at the first failure — a click → type → Tab → wait → read sequence is one call instead of five. +- **WebMCP-aware.** On sites that expose their own actions through [WebMCP](https://github.com/webmachinelearning/webmcp), `browser_webmcp_list` / `browser_webmcp_call` call them directly instead of clicking through the UI — with confirmation gates for consequential tools and page output flagged as untrusted. - **Console-style JavaScript.** `browser_evaluate` accepts code as you'd type it in DevTools: top-level `await`, several statements, the last expression's value is returned, DOM nodes come back as readable descriptions — and page CSP doesn't block it. - **Refs that stay right.** Snapshot/find refs resolve through one shared page runtime: the registered element first, then the first *visible* selector match (across open and closed shadow roots and same-origin iframes), then a verified fallback that only re-binds when role, tag and name identify one element — an ambiguous match is reported as gone instead of clicked. Hidden duplicates are skipped. - **Native Chrome accessibility tree.** `browser_snapshot { source: "native" }` reads the tree Chrome itself computes (CDP `Accessibility.getFullAXTree`): exact roles, accessible names (`aria-labelledby`, `