{"name":"browser","version":"1.0.0","description":"Remote isolated browser and web intelligence service with Scrapling anti-bot extraction.","transport":{"type":"streamable-http","url":"/mcp","authentication":{"type":"bearer"}},"transports":[{"type":"streamable-http","url":"/mcp","authentication":{"type":"bearer"}},{"type":"sse","url":"/sse","authentication":{"type":"bearer"}}],"capabilities":{"tools":true},"instructions":"You have access to a remote browser. You can control it like a real user: navigate to pages, click buttons, fill forms, read content, take screenshots, and more.\n\nQUICK START - How to use this browser:\n1. Call browser_navigate with a URL to open a page (returns a screenshot automatically)\n2. Use browser_click, browser_type, browser_select to interact with the page like a user would\n3. Use browser_extract to read text/data from the page, or browser_screenshot to see it visually\n4. The browser keeps its state between calls - cookies, sessions, and tabs all persist\n\nCOMMON WORKFLOWS:\n- Search: navigate to site -> type in search box (pressEnter: true) -> extract results\n- Fill a form: navigate -> type into fields -> select dropdowns -> click submit\n- Read content: navigate -> extract text with CSS selectors -> scroll down -> extract more\n- Test a flow: navigate -> interact step by step -> screenshot to verify each step\n- Monitor APIs: enable network logging -> navigate -> list captured XHR requests\n- Keyboard: browser_press_key for shortcuts (Ctrl+S, Cmd+K) and navigation (Enter, Tab, Escape)\n- Dropdowns/menus: browser_hover to reveal CSS :hover states, flyouts, and tooltips\n\nTIPS:\n- browser_navigate returns a screenshot automatically - look at it to understand the page layout\n- Use text= prefix to click by visible text: browser_click({selector: \"text=Sign In\"})\n- Use pressEnter: true with browser_type to submit search forms\n- Use browser_wait if a page needs time to load dynamic content\n- Use browser_evaluate to run any JavaScript for complex logic\n- Use browser_navigate_back / browser_navigate_forward for history navigation\n- Multiple tabs are supported via browser_tabs\n\nREALTIME / VISION-DRIVEN CONTROL (observe → drive → inspect):\nYou can drive the browser the way a human does — by LOOKING at the screen and\nacting at pixel coordinates, with no CSS selector. This is how vision-first\nagents operate:\n- OBSERVE: browser_observe({stream:true}) returns the latest frame of the page\n  PLUS a /sessions/:id/stream WebSocket URL that pushes live JPEG frames in real\n  time. Watch the page change as you act. Works headed OR headless (captured via\n  CDP, independent of any display).\n- DRIVE BY COORDINATES: browser_click_at({x,y}), browser_mouse_move({x,y}),\n  browser_mouse_button({action:\"down\"|\"up\"}), browser_type_at({x,y,text}).\n  Coordinates are in the same pixel space as the observe frame — see a button,\n  click its center. Enables Claude-computer-use / OmniParser-style flows.\n- INSPECT: browser_cdp({method:\"Performance.getMetrics\"}) runs ANY CDP method\n  (Page.captureSnapshot for full DOM, Tracing.start/stop for perf traces,\n  Network.*, Emulation.*) for deep inspection — always available, in-process.\n- EXTERNAL ATTACH: browser_cdp_endpoint({sessionId}) returns the CDP wsEndpoint\n  (ws://127.0.0.1:<port>/devtools/browser/<id>, localhost-bound on purpose — CDP\n  has no auth) so you can drive the browser with your own Playwright via\n  connectOverCDP. Reach it from another machine over an SSH tunnel\n  (ssh -i <key> -L <port>:127.0.0.1:<port> -N <host>), then connectOverCDP the\n  wsEndpoint as-is. Returns {enabled:false} when the host hasn't set EXPOSE_CDP=true.\n\nPARALLEL & ISOLATED SESSIONS:\n- By default all your calls share one \"default\" browser session per API key — fine for\n  sequential work, but two concurrent flows on it fight over the same tabs.\n- For PARALLEL or independent work, call browser_create_session to get a sessionId, then\n  pass that sessionId to every tool call for that flow. Each session is a fully isolated\n  BrowserContext (own cookies/login/tabs), and the server load-balances sessions across a\n  POOL of Chromium processes — so N independent scrapes/logins run concurrently without\n  sharing state or contending for one browser.\n- Persist logins per session: browser_session_save({key,sessionId}) /\n  browser_session_load({key,sessionId}). Call browser_close_session({sessionId}) when done.\n\nINFRASTRUCTURE:\n- docker_stats (admin-only) returns host CPU (% + cores), memory\n  (total/used/available), disk per mount, container counts, and cumulative\n  network byte totals. Useful to understand host capacity.\n\nADVANCED BROWSER TOOLS:\nFor operations not covered by the basic tools, use these:\n- browser_evaluate runs JavaScript inside the isolated page. Host-side\n  browser_run_code is disabled by default and is only exposed to admins when\n  ENABLE_UNSAFE_RUN_CODE=true.\n- browser_wait_response: Block until a network response matching a URL pattern\n  arrives (returns headers + body). Use after triggering a click/type that\n  fires an XHR you need to read.\n- browser_download: Capture files downloaded by the page. list/wait/get/clear.\n- browser_frame: Operate inside an iframe by url/name/index (click, type,\n  extract, evaluate, press_key, hover).\n- browser_console: Capture JS console messages (enable -> do actions -> list).\n- browser_accessibility: Get the page's ARIA/accessibility tree.\n- browser_get_text: Extract visible text as plain or markdown format.\n- browser_drag_and_drop: Drag from one element to another.\n- browser_file_upload: Set files on a <input type=\"file\"> element.\n- browser_handle_dialog: Accept/dismiss the next alert/confirm/prompt.\n- browser_get_cookies / browser_set_cookies: Read/write browser cookies.\n- browser_clear_session: Wipe cookies, localStorage, sessionStorage.\n\nPROXY ROTATION (anti-blocking):\nEach Decodo proxy port maps to a different residential IP. The server rotates\nports round-robin across the configured range (default 10001-10025) to avoid\nblocking. All callers may use browser_proxy({action:\"status\"}) to inspect the\ncurrent port. Only admin-scoped callers may rotate or update global settings.\n\nSESSION PERSISTENCE (cross-connection):\nCookies held in memory vanish when your MCP connection drops — including HttpOnly\nauth cookies that you can't read via JavaScript. To survive restarts, snapshot the\nbrowser state and reload it later.\n\n- browser_session_save({key}): Save the current browser context (cookies + localStorage +\n  sessionStorage, including HttpOnly cookies) under a label you choose. Keyed per\n  API key — other keys can't see your saved sessions.\n- browser_session_load({key}): Replace the current browser context with one\n  seeded from saved state. Use at the start of a new connection to skip login.\n  Closes your current pages; next tool call opens a fresh page already authenticated.\n- browser_session_list: List saved session keys with size and timestamp.\n- browser_session_delete({key}): Delete a saved session.","tools":[{"name":"browser_restart","description":"Close this token's sessions and start a fresh isolated session."},{"name":"browser_navigate","description":"Navigate to a URL and return title, final URL, status, and screenshot."},{"name":"browser_screenshot","description":"Capture the viewport, full page, or a selected element."},{"name":"browser_click","description":"Click an element selected by CSS, XPath, or visible text."},{"name":"browser_type","description":"Type text into an input or textarea."},{"name":"browser_select","description":"Select option values in a select element."},{"name":"browser_scroll","description":"Scroll the page or a selected scrollable element."},{"name":"browser_press_key","description":"Press a keyboard key or shortcut."},{"name":"browser_hover","description":"Hover over a selected element."},{"name":"browser_navigate_back","description":"Go back in browser history."},{"name":"browser_navigate_forward","description":"Go forward in browser history."},{"name":"browser_extract","description":"Extract text, HTML, attributes, or values from selected elements."},{"name":"browser_observe","description":"Get a current page frame and optionally its live WebSocket stream URL."},{"name":"browser_click_at","description":"Click at an absolute screenshot coordinate."},{"name":"browser_mouse_move","description":"Move the mouse to an absolute screenshot coordinate."},{"name":"browser_mouse_button","description":"Press or release a mouse button at the current position."},{"name":"browser_type_at","description":"Click a screenshot coordinate, then type text."},{"name":"browser_cdp","description":"Run an allowed Chrome DevTools Protocol method on the active page."},{"name":"browser_cdp_endpoint","description":"Return the localhost-only external CDP endpoint when explicitly enabled."},{"name":"browser_evaluate","description":"Execute bounded JavaScript inside the page; a timeout recycles the context."},{"name":"browser_network","description":"Capture and inspect network traffic (XHR, fetch, documents, etc.) — including request/response bodies and headers. Workflow: 1) action:'enable' BEFORE navigating, 2) navigate/interact, 3) action:'list' to browse (headers + metadata by default, add includeBodies:true for inline bodies), 4) action:'get' with an id to pull one entry's full body. Text bodies (JSON, HTML, text/*) are returned as UTF-8 strings; binary bodies come back base64 (responseBodyBase64:true). Each body is truncated at 128 KB per request and per response; the truncated flag tells you. Filter by URL literal substring, HTTP method, resource type, or status code."},{"name":"browser_wait","description":"Wait for a condition before proceeding. Use this when a page loads content dynamically (SPAs, AJAX) and you need to wait before extracting/clicking. Types: 'selector' waits for an element to appear, 'networkidle' waits for all network requests to finish, 'navigation' waits for a page navigation, 'function' waits for custom JS to return true, 'timeout' is a simple delay. Example: {type: 'selector', value: '.results-loaded'}, {type: 'networkidle'}."},{"name":"browser_tabs","description":"Manage multiple browser tabs. Use 'list' to see all open tabs, 'open' to open a new tab with a URL, 'switch' to change the active tab, 'close' to close a tab. Each tab has its own page state. Useful for comparing pages side by side or opening links without losing your place."},{"name":"browser_pdf","description":"Export the current page as a PDF document. Returns base64-encoded PDF and sizeBytes. Optionally save to a file path on disk. Supports paper sizes, orientation, margins, and background printing. Example: {format: 'A4', landscape: false, margin: {top: '2cm', bottom: '2cm'}}."},{"name":"browser_console","description":"Capture console messages from the page. Supports enable/disable/list/clear actions with optional filtering by type (log, warn, error, info, debug) or text pattern. Useful for debugging JS errors, logging, and SPA diagnostics."},{"name":"browser_accessibility","description":"Get the browser's accessibility tree for the current page. Returns the full ARIA tree with roles, names, values, and children. Useful for accessibility auditing or extracting content the way a screen reader sees it."},{"name":"browser_get_text","description":"Extract readable text content from the page as plain text or markdown. Skips hidden elements (display:none, visibility:hidden) and non-content tags (script, style, svg). Use format='markdown' for heading-aware extraction, or format='readable' to skip nav/footer/header noise."},{"name":"browser_drag_and_drop","description":"Drag from a source element to a target element. Use for drag-and-drop file uploads, reordering lists, or kanban-style moves."},{"name":"browser_file_upload","description":"Set files on a <input type='file'> element. Does NOT open the OS file picker — sets files directly on the input element. Provide absolute paths to files on the server filesystem."},{"name":"browser_handle_dialog","description":"Handle the next browser dialog (alert, confirm, or prompt). Must be called BEFORE the action that triggers the dialog. Waits for the dialog to appear, then accepts or dismisses it."},{"name":"browser_get_cookies","description":"Get cookies from the browser context. Returns name, value, domain, path, expires, httpOnly, secure, and sameSite for each cookie. Optionally filter by URL(s)."},{"name":"browser_set_cookies","description":"Add cookies to the browser context. Cookies persist across pages and will be saved when the session closes. Use to inject auth tokens, session IDs, or bypass consent banners."},{"name":"browser_create_session","description":"Create a new isolated browser session — a separate BrowserContext (own cookies, localStorage, tabs) placed on its own Chromium process from a server-side POOL. Returns a sessionId to pass to every other browser tool via the 'sessionId' parameter. This is how you run TRULY PARALLEL browser work: each sessionId is fully isolated and load-balanced across the pool, so concurrent sessions don't share state or contend for one process. A crashed pool browser only affects its own sessions (they auto-recover on a healthy one). Sessions are scoped to your API key. Omit sessionId on calls to use a shared default session."},{"name":"browser_close_session","description":"Close an isolated browser session created with browser_create_session. Frees the BrowserContext and all its pages. Requires sessionId parameter."},{"name":"browser_clear_session","description":"Clear all session state: cookies, localStorage, and sessionStorage. Use to start fresh without closing the browser. Useful for testing logged-out states or clearing stale data."},{"name":"browser_wait_response","description":"Block until a network response whose URL contains the given literal substring arrives, then return it with headers and body. Useful after an action triggers an XHR/fetch. Body is UTF-8 text for text/JSON/XML content types, otherwise base64. Truncates at 128 KB. Throws on timeout."},{"name":"browser_download","description":"Capture files downloaded by the page (Playwright 'download' events). Downloads are auto-captured as soon as they fire — call 'list' to see what's been captured, 'wait' to block for the next one, 'get' to retrieve a file's content (base64) by id, 'clear' to flush. Use after clicking a download link/button. Files are saved to disk on the server; 'get' reads them back."},{"name":"browser_frame","description":"Operate inside an iframe. Select the frame by a literal URL substring, exact name, or zero-based index (main frame is 0). Then run click/type/extract/evaluate/press_key/hover inside that frame. Use 'list' first to discover frames."},{"name":"browser_proxy","description":"Inspect Decodo proxy status. Admin-scoped callers may also rotate the global port or update global proxy settings. Ordinary callers cannot mutate proxy state."},{"name":"browser_session_save","description":"Snapshot the current browser context (cookies — including HttpOnly — plus localStorage, sessionStorage, IndexedDB origins, and the non-secret proxy-port pin) to persistent storage under a label you choose. Restores preserve proxy IP continuity by default. Saved state is scoped to your API key."},{"name":"browser_session_load","description":"Restore a previously saved browser context (from browser_session_save) into the current session. Replaces the active BrowserContext and preserves the saved proxy port by default so IP-bound auth cookies remain valid. Set useCurrentProxy only for an intentional operator-directed IP change."},{"name":"browser_session_list","description":"List saved session keys for the current API key. Returns each key's byte size and last-saved timestamp."},{"name":"browser_session_delete","description":"Delete a saved browser session by key. Returns deleted:true on success, deleted:false if no such key."},{"name":"docker_stats","description":"Get Docker resource usage statistics. Returns CPU, memory, and network usage for all running containers. Useful for monitoring system resources and debugging performance issues."},{"name":"scrapling_open_session","description":"[Scrapling sidecar] Open a persistent browser session that can be reused across multiple `session_fetch` calls.\nThis avoids the overhead of launching a new browser for each request. Sessions hold the browser-level\nconfiguration only; per-request options are passed to `session_fetch` on each call."},{"name":"scrapling_open_request_session","description":"[Scrapling sidecar] Open a persistent HTTP requests session (no browser) that can be reused across multiple\n`session_make_request` calls, keeping cookies, connections, and the browser fingerprint between requests.\nThe session holds this configuration only; per-request options are passed to `session_make_request` on each call.\nIt shares `close_session`/`list_sessions` with the browser sessions and shows there as a 'static' session."},{"name":"scrapling_close_session","description":"[Scrapling sidecar] Close a persistent session and free its resources."},{"name":"scrapling_list_sessions","description":"[Scrapling sidecar] List all active sessions with their details, including the effective settings each one was created with."},{"name":"scrapling_make_request","description":"[Scrapling sidecar] Make an HTTP request to a URL with any method (GET, POST, PUT, DELETE) and return a structured output of the result.\nOnly suitable for low-mid protection levels."},{"name":"scrapling_bulk_get","description":"[Scrapling sidecar] Make GET HTTP request to a group of URLs and for each URL, return a structured output of the result.\nOnly suitable for low-mid protection levels."},{"name":"scrapling_fetch","description":"[Scrapling sidecar] Use playwright to open a browser to fetch a URL and return a structured output of the result.\nOnly suitable for low-mid protection levels."},{"name":"scrapling_bulk_fetch","description":"[Scrapling sidecar] Use playwright to open a browser, then fetch a group of URLs at the same time, and for each page return a structured output of the result.\nOnly suitable for low-mid protection levels."},{"name":"scrapling_stealthy_fetch","description":"[Scrapling sidecar] Use the stealthy fetcher to fetch a URL and return a structured output of the result.\nThe only fetcher suitable for high-protection websites."},{"name":"scrapling_bulk_stealthy_fetch","description":"[Scrapling sidecar] Use the stealthy fetcher to fetch a group of URLs at the same time, and for each page return a structured output of the result.\nThe only fetcher suitable for high-protection websites."},{"name":"scrapling_session_fetch","description":"[Scrapling sidecar] Fetch a URL through a browser session previously opened with `open_session` and return a structured output of the result.\nThe session (dynamic or stealthy) holds the browser-level configuration; every option here applies to this request only, with the defaults shown."},{"name":"scrapling_session_make_request","description":"[Scrapling sidecar] Make an HTTP request with any method (GET, POST, PUT, DELETE) through a requests session previously opened\nwith `open_request_session`, keeping its cookies, connections, and browser fingerprint across calls. The session\nholds the impersonation and proxy configuration; every option here applies to this request only, with the defaults shown."},{"name":"scrapling_screenshot","description":"[Scrapling sidecar] Capture a screenshot of a web page using an existing browser session and return it as an image.\nA browser session must be opened first with `open_session` (either `dynamic` or `stealthy`); the session ID is then passed here."}]}