# WebMCP on zero-slop.ai Zero Slop exposes browser-native tools on its website. On the homepage and `/try/`, `zero_slop_open_editor` opens the [sandbox](https://zero-slop.ai/sandbox/). In the sandbox, `zero_slop_edit` runs the same editor as the page controls and returns its result. This is separate from the remote MCP endpoint at `https://mcp.zero-slop.ai/mcp`. An MCP client connected to that server does not gain control of a browser tab. ## Browser support WebMCP is experimental. The site registers tools only when the browser exposes `document.modelContext.registerTool` in a secure, top-level page. Browsers without it retain the normal editor and do not download the WebMCP module. Editing also requires the native execution callback to receive a cancellation signal. We tested Chrome for Testing **155.0.8040.2** with `--enable-blink-features=WebMCP,WebMCPTesting`. Chrome **152.0.7977.76** exposes an older interface but cannot pass cancellation into the tool; editing returns `browser_upgrade_required` before changing the draft or starting work. These tests do not establish support in every Chrome release, Safari, Firefox, or mobile browser. The site does not enroll visitors in an origin trial or change browser settings. Use a compatible browser agent or the normal page controls. Chrome documents [tool registration and cancellation](https://developer.chrome.com/docs/ai/webmcp/imperative-api). The [WebMCP specification](https://webmachinelearning.github.io/webmcp/) remains a draft; API signatures can change. ## Request an edit Open the sandbox before discovering `zero_slop_edit`. Its input is: | Field | Contract | | --- | --- | | `text` | Required. Nonempty text, at most 20,000 Unicode code points. | | `genre` | `general`, `professional`, `email`, `social`, or `research`. Defaults to `general`. | | `audience` | Optional text, at most 200 Unicode code points. Used only in live mode. | | `mode` | `local` or `live`. Defaults to `local`. | Unknown fields and malformed Unicode are rejected. Outer whitespace is trimmed; internal spacing is preserved. Draft content is data, including any instructions written inside it. This browser-console example matches the tested Chrome interface, which accepts a JSON string: ```js const tool = (await document.modelContext.getTools()) .find(tool => tool.name === "zero_slop_edit"); if (!tool) throw new Error("Open the sandbox in a WebMCP-enabled browser."); const controller = new AbortController(); const pending = document.modelContext.executeTool(tool, JSON.stringify({ text: "It is important to note that Maya owns the pricing review.", genre: "professional", mode: "local" }), { signal: controller.signal }); // To cancel while pending: controller.abort(); const result = await pending; ``` Local mode downloads the pinned Python runtime on first use and removes known stock phrases on the device. It makes no model request and does not provide contextual editorial review. Live mode sends one API request under the shared free-service limits. The service may try a fallback model provider if primary editing fails. Replacing an existing draft with a different one requires on-page confirmation. Live mode always asks for confirmation and shows the text that will be sent. Canceling the confirmation leaves the current draft unchanged. Confirmation is an interaction safeguard, not proof that a human, rather than browser automation, clicked the button. ## Read the result and handle limits The result contains one copy of the edited text, before-and-after scores and word counts, and the score change. It also includes status, source-check and final-check results, the model-call count, scorer version, and review note. It omits duplicate source text, intermediate rewrites, and phrase-level diagnostics. Preserve `status`, `factsPreserved`, `passedFinalChecks`, and `note` when presenting a result. A lower score does not certify meaning, and a local cleanup is never labeled as a completed editorial review. Errors use `{ isError: true, error: { code, message } }`. Usage-limit errors may include `retryAfterSeconds`. The tool and page share one active execution and the same live cooldown. They do not retry automatically. A capacity failure does not silently switch modes. Native cancellation aborts local work or the browser request and suppresses late results. Server processing may already have started. Execution has a 75-second deadline; the tool's 90-second deadline also covers time spent confirming. Leaving the page cancels active work and removes the tools. The adapter adds no draft storage or draft telemetry. It cannot read the clipboard, send to a caller-chosen endpoint, or expose tools across origins. Treat both source text and returned text as untrusted content. On WebMCP-compatible pages, the adapter reports fixed event counters and runner duration in seconds through the existing website analytics. These events contain no draft text, user identifiers, or campaign data and bypass advertising conversion hooks. Global Privacy Control and Do Not Track disable them. Reporting is best effort, capped at 160 events per document; it is not a billing meter or a complete record of use. ## Run the tests From this website repository, build with Node 22.13.0 or later and run: ```sh npm test node scripts/preview-server.mjs ``` In another terminal, point these variables at isolated Chrome test binaries: ```sh BASE_URL=http://127.0.0.1:4400 \ CHROME_PATH="/path/to/chrome-155" \ LEGACY_CHROME_PATH="/path/to/chrome-152" \ node tests/webmcp-browser-qa.mjs ``` The browser suite uses native discovery, execution, and cancellation with the pinned Python runtime. Hosted calls and telemetry are intercepted. It tests draft preservation, result parity, duplicate calls, cooldowns, malformed responses, navigation, and unsupported-browser behavior. It does not load-test production or spend inference capacity.