Reference
Drive a page step by step through weles mcp instead of a browser library of your own.
weles mcp is a JSON-RPC 2.0 server on standard input and output (MCP protocol 2024-11-05). A caller opens a Weles browser, opens pages in it and drives them one operation at a time by the browserId and pageId the server hands out; this is how a product's journeys test a web page without importing Playwright.
Why it exists#
Browsers belong to Weles. A product whose tests need to click, fill, read and assert on a page, such as Probierz's web journeys, starts weles mcp and sends it tools/call requests; it never imports @playwright/test or launches an engine. The browser is the one AsyncNewBrowser starts inside the weles mcp process, with its fingerprint and init scripts.
One request per line on standard input: initialize, then tools/list or tools/call with params { name, arguments }. Every answer is one line on standard output: result.content[0].text holds the tool's answer as JSON text. Diagnostics go to standard error so standard output stays the protocol stream.
Reading and acting#
Every selector is a Playwright selector string: CSS, role=button[name="Start"], text=Continue or internal:label="Email". Operations act on the first element the selector matches.
weles_page_text { pageId, selector? } answers the visible text (body when no selector) as plain text, the one answer that is not JSON. weles_page_query { pageId, selector, attributes? } answers { count, visible, enabled, text, attributes } and, where they apply, checked and value; when nothing matches it answers count 0 with visible and enabled false. weles_page_wait { pageId, selector, state?: attached | detached | visible | hidden } returns when the element reaches that state.
weles_page_click, weles_page_fill { value }, weles_page_press { key }, weles_page_check { checked? } and weles_page_upload { files } act on the element. weles_page_evaluate { pageId, expression } evaluates a JavaScript expression in the page and answers its value as JSON text, so a string arrives quoted and undefined arrives as null; an expression that is a promise is awaited.
weles_page_screenshot { pageId, path?, fullPage?, type?: png | jpeg, quality? } writes the image to path or answers { mimeType, base64 }.
Network#
weles_page_route { pageId, pattern, status, contentType, body? } answers every request whose URL matches the glob with that response until weles_page_unroute { pageId, pattern }. weles_page_request { pageId, url, method?, headers?, body? } sends a request with the page's cookies and context headers and answers { url, status, ok, body }.
weles_page_events { pageId, clear? } answers { consoleErrors, failedRequests, responses: [{ url, status, method }] } recorded since the page opened or was last cleared; each list keeps its newest 500 entries.
A client writes one JSON-RPC request per line: initialize, then tools/call with the tool's name and arguments, for example weles_browser_start with {"browser":"chromium","os":"macos","headless":true}, weles_page_new with the browserId it answered, and weles_page_goto with the pageId and a url.
Refusals and diagnosis#
A failed call answers a JSON-RPC server error whose message names the argument that is missing or of the wrong type ("selector must be a non-empty string", "status is required"), an id the server never issued ("unknown pageId: page-9"), or carries the engine's own message when the element never reached the state or the navigation failed. An unknown tool answers "unknown tool: <name>"; a line that is not JSON answers a parse error; an unknown method answers method not found.