Public Browser
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CHROME_PATH | No | Path to Chrome binary (overrides auto-detection) | |
| SILBERCUE_CHROME_PORT | No | CDP debugging port | 9222 |
| PUBLIC_BROWSER_PROFILE | No | Chrome profile name or path to use | |
| PUBLIC_BROWSER_TELEMETRY | No | Opt-in: upload anonymised Cortex patterns to the community endpoint | |
| SILBERCUE_CHROME_PROFILE | No | Chrome user profile directory (auto-launch only) | |
| SILBERCUE_CHROME_HEADLESS | No | Opt-in headless mode for CI/server environments | false |
| SILBERCUE_CHROME_AUTO_LAUNCH | No | Auto-launch Chrome if no running instance found | true |
| PUBLIC_BROWSER_TELEMETRY_ENDPOINT | No | Override the telemetry collection endpoint (must be HTTPS) | https://cortex.public-browser.dev/v1/patterns |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| virtual_deskA | PRIMARY orientation tool — call first in every new session, after reconnect, or when unsure. Lists all tabs with IDs, URLs, state. Use returned IDs to navigate to an existing tab instead of opening duplicates. Cheap, call liberally. |
| view_pageA | The way to see what is on the page. Call this after navigate/click/switch_tab — not capture_image. Returns text content + stable element refs (e.g. 'e5') for click/type/fill_form. Also use this to read visible text, check errors, find buttons. Default filter:'interactive' shows actionable elements; for paragraphs/table cells call view_page(ref: 'eN', filter: 'all'). Collapsed containers show as |
| clickA | Click an element by ref, CSS selector, or viewport coordinates. Dispatches real CDP mouse events (mouseMoved/mousePressed/mouseReleased). For canvas or pixel-precise targets, use x+y coordinates instead of ref. If the click opens a new tab, the response reports it automatically. The response already includes the DOM diff (NEW/REMOVED/CHANGED lines) — inspect those changes for success/failure signals instead of following up with evaluate to re-check state. If click fails with a stale-ref error, call view_page for fresh refs and retry. Avoid evaluate(querySelector + .click()) as default recovery — it bypasses the CDP pointer chain and hides real bugs. (Legitimate exception: explicitly testing synthetic JS event plumbing.) |
| typeA | Type text into an input field identified by ref or CSS selector. For multiple fields in the same form, prefer fill_form — it handles text inputs, , checkbox, and radio in one round-trip and is more reliable than N separate type calls. For special keys (Enter, Escape, Tab, arrows) or shortcuts (Ctrl+K), use press_key instead. On stale-ref errors, call view_page for fresh refs and retry. Avoid evaluate(element.value = ...) as default data-entry recovery — it bypasses framework listeners (React, Vue) and masks real failures. (Legitimate exception: tests explicitly targeting synthetic event plumbing.) |
| fill_formA | Fill a complete form with one call — the preferred way to submit any form with 2+ fields. Each field needs ref or CSS selector plus value. Supports text inputs, (by value or visible label), checkboxes (boolean), and radio buttons. Use this INSTEAD of multiple type calls or evaluate-setting select.value: one round-trip, partial errors do not abort, each field reports its own status. On per-field errors, call view_page and retry the failing fields — DO NOT escape to evaluate(querySelector) to patch individual fields; it bypasses framework state management (React, Vue) and hides real bugs. |
| press_keyA | Press a keyboard key or shortcut. Optionally focus an element first via ref/selector. Use for Enter, Escape, Tab, arrows, shortcuts (Ctrl+K). |
| scrollA | Scroll the page, a container, or an element into view. Returns position and content-growth tracking (scrollHeight grew by Npx — useful for detecting lazy-loaded content). Do NOT scroll with evaluate(window.scrollTo/scrollBy) — scroll handles position tracking and settle timing automatically. Use container_ref/container_selector + direction to scroll inside a specific container. |
| dragA | Drag an element via native CDP mouse events (mousePressed → interpolated mouseMoved with buttons:1 → mouseReleased). Works for CSS-driven drag: slider thumbs, resize handles, text selection, mouse-based reorder lists (e.g. SortableJS in mouse mode). NOT suitable for HTML5 Drag&Drop API (draggable=true elements with dragstart/drop listeners, React DnD HTML5Backend, Vuedraggable, ng2-dnd) — that path needs Input.dispatchDragEvent which this tool does not implement. Parameters: from_ref/from_selector OR from_x+from_y as source, to_ref/to_selector OR to_x+to_y as target. |
| navigateA | Navigate the ACTIVE tab to a URL (or action:'back' to go back, action:'reload' to refresh current page — all element refs become stale after reload). Waits for settle. WARNING: overwrites the user's active tab — always call virtual_desk FIRST to check what's open. First call per session is auto-redirected to virtual_desk. |
| switch_tabA | Open a new tab, switch to an existing tab by ID (from virtual_desk), or close a tab. Prefer 'open' over navigate when you don't want to touch the user's active tab. After switching, refs from the previous tab are invalid — call view_page FIRST to get fresh refs before click/type/fill_form. DO NOT try to reuse old refs via evaluate(querySelector) as a shortcut. |
| tab_statusA | Active tab's cached URL/title/ready/errors for quick sanity checks mid-workflow ('did my click navigate?'). For tab discovery: use virtual_desk. For page content: use view_page. |
| wait_forB | Wait for a condition: element visible, network idle, or JS expression true |
| observeA | Watch an element for changes over time — use this INSTEAD of writing MutationObserver/setInterval/setTimeout code in evaluate. Two modes: (1) collect — watch for 'duration' ms, return all text/attribute changes (e.g. collect 3 values that appear one after another). (2) until — wait for a condition, then optionally click immediately (e.g. click Capture when counter hits 8). Use click_first to trigger the action that causes changes (observer is set up BEFORE the click, so nothing is missed). |
| capture_imageA | Pixel-level visual screenshot (WebP, max 800px, <100KB). Do NOT call this to see what is on the page — call view_page instead (10-30x cheaper, returns text + refs you can click). capture_image cannot drive click/type and cannot read text. The ONLY valid uses: (1) canvas/chart content that has no DOM text, (2) pixel-level animation or rendering comparison, (3) the user explicitly asks for a screenshot. If you are unsure, use view_page. |
| dom_snapshotA | Structured layout data: bounding boxes, computed styles, paint order, colors. Refs match view_page. Use ONLY for spatial questions view_page cannot answer (is A above B? what color?). For element discovery or text: use view_page. For pure visual verification: use capture_image. |
| handle_dialogA | Configure browser dialog handling (alerts, confirms, prompts). Pre-configure BEFORE triggering actions that may show dialogs. Replaces evaluate-based workarounds (window.alert = ...) — handle_dialog uses CDP Page.javascriptDialogOpening and works even when the dialog blocks all JS. |
| file_uploadA | Upload file(s) to a file input element. Provide ref or CSS selector to identify the , and absolute path(s) to the file(s). |
| console_logsA | Retrieve collected browser console logs. Filter by level (info/warning/error/debug) and/or regex pattern. Optionally clear the buffer after reading. |
| network_monitorA | Monitor network requests via CDP. Workflow: start → trigger action → get(pattern: 'api'). Use INSTEAD of evaluate-based fetch interceptors (window.fetch = ..., XMLHttpRequest.prototype.open = ...) — network_monitor captures all requests including those initiated by the page itself. |
| downloadA | Check status of file downloads or list all downloaded files in this session. Downloads happen automatically when you click download links or navigate to files (PDFs, CSVs, etc.) — you do NOT need to call this tool to trigger downloads. Use this tool to:
|
| configure_sessionA | View/set session defaults for recurring parameters (tab, timeout, etc.). Without params: show current defaults and auto-promote suggestions. With autoPromote: true: apply all suggestions. Use profile param BEFORE any browser interaction to launch Chrome with a named profile. |
| run_planA | Execute a sequential plan of tool steps server-side. Supports variables ($varName), conditions (if), saveAs, error strategies (abort/continue/capture_image), suspend/resume. Parallel tab execution via parallel: [{ tab, steps }]. |
| batch_evaluateA | Visit multiple URLs sequentially and evaluate the same JavaScript expression on each page. Use for controlled batch checks across known pages when view_page/run_plan would be too chatty. Not for normal page reading, clicking, or form work. |
| set_page_dataA | Write a large payload (>1 MB) to window.__pb_data[key] in the page, bypassing the CDP 1 MB-per-message limit via server-side chunking. Use when: passing big base64 images / JSON / fixtures to a debug hook (window.__yourHook(data)), stubbing fetch responses with large bodies, or feeding binary data to a custom drop-zone. Sources: inline (pass |
| evaluateA | Execute JavaScript in the browser page context. Good uses: computation, style mutations (.style.X = ..., classList.add), shadow-root traversal, in-page fetch(), app-specific side effects no dedicated tool covers. Bad uses: (1) automatic recovery after a click/type/fill_form failure — call view_page for fresh refs and retry instead; (2) scrolling — use scroll via run_plan (returns position + content growth); (3) element discovery (querySelector/getElementById/innerText) — prefer view_page or fill_form. Scope is shared between calls — top-level const/let/class are auto-wrapped in IIFE. If/else blocks may return undefined — use ternary (a ? b : c) or explicit return. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Silbercue/public-browser'
If you have feedback or need assistance with the MCP directory API, please join our Discord server