ZenLink MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| zen_statusA | Check if ZenLink bridge and browser extension are connected. |
| zen_tabsA | List all open browser tabs with their IDs, titles, and URLs. |
| zen_page_infoA | Get current page URL, title, dimensions, and scroll position. Args: tab_id: Optional tab to target. Defaults to active tab. |
| zen_page_textA | Extract all readable text from the current page. Args: tab_id: Optional tab to target. Defaults to active tab. For non-active tabs, prefer this with tab_id over zen_page_text_by_tab_id — they do the same thing now. |
| zen_page_text_by_tab_idA | Get page text from a specific tab by ID without switching to it. Args: tab_id: The tab ID to read from (get IDs from zen_tabs) Returns the full visible text content of the specified tab. |
| zen_formsB | Get all form fields on the current page with their labels and values. Args: tab_id: Optional tab to target. Defaults to active tab. |
| zen_domA | Get the accessibility tree of interactive elements on the page. Args: tab_id: Optional tab to target. Defaults to active tab. |
| zen_screenshotA | Capture a screenshot of the current page. Returns the saved file path. Note: screenshots are inherently visual and capture the active tab of the focused window. To screenshot a specific tab, switch to it first with zen_switch_tab. |
| zen_navigateA | Navigate the active tab to a URL. Args: url: The URL to navigate to (e.g. "https://example.com") tab_id: Optional tab to navigate. Defaults to active tab. |
| zen_new_tabB | Open a new browser tab. Args: url: URL to open in the new tab (default: blank page) |
| zen_close_tabB | Close a browser tab by its ID. Args: tab_id: The tab ID to close (get IDs from zen_tabs) |
| zen_switch_tabA | Switch focus to a specific browser tab. Args: tab_id: The tab ID to focus (get IDs from zen_tabs) |
| zen_clickB | Click an element on the page by CSS selector or coordinates. Args: selector: CSS selector to click (e.g. "#submit", ".btn-primary") x: X coordinate (used if selector is empty) y: Y coordinate (used if selector is empty) tab_id: Optional tab to target. Defaults to active tab. |
| zen_trusted_clickA | Click using the real OS mouse pointer for pages that reject synthetic DOM events. This is slower and moves the user's cursor, so prefer zen_click unless a page specifically ignores synthetic clicks. Args: selector: CSS selector to click. If provided, ZenLink clicks its center. x: X coordinate, used if selector is empty. y: Y coordinate, used if selector is empty. coordinate_space: "viewport" for browser viewport coords or "screen" for desktop coords. focus: Whether to try to foreground the browser first. Defaults to false. tab_id: Optional tab to resolve the selector against (viewport coords only). |
| zen_typeB | Type text into an input field. Args: selector: CSS selector of the input element text: Text to type clear: Whether to clear existing text first tab_id: Optional tab to target. Defaults to active tab. |
| zen_set_editable_contentA | Set text or HTML in a contenteditable editor, input, or textarea in one fast operation. Use this for rich editors such as Gmail compose bodies where typing long text is slow. Args: selector: CSS selector or ZenLink ref for the editable element value: Text or HTML to place into the editor format: "text" for plain text or "html" for trusted HTML clear: Whether to replace existing content instead of appending tab_id: Optional tab to target. Defaults to active tab. |
| zen_fillA | Set a form field's value directly (faster than typing). Args: selector: CSS selector of the input/select element value: Value to set tab_id: Optional tab to target. Defaults to active tab. |
| zen_scrollB | Scroll the page. Args: direction: Scroll direction - "up", "down", "left", or "right" amount: Pixels to scroll tab_id: Optional tab to target. Defaults to active tab. |
| zen_hoverA | Hover over an element on the page. Args: selector: CSS selector of the element to hover over tab_id: Optional tab to target. Defaults to active tab. |
| zen_findA | Find elements on the page using natural language description. Args: query: What to find (e.g. "login button", "search bar", "email input") tab_id: Optional tab to target. Defaults to active tab. |
| zen_jsB | Execute JavaScript in the current page context. Args: code: JavaScript code to run (e.g. "document.title" or "document.querySelectorAll('a').length") tab_id: Optional tab to target. Defaults to active tab. |
| zen_highlightA | Highlight an element on the page with a visual overlay. Args: selector: CSS selector of the element to highlight tab_id: Optional tab to target. Defaults to active tab. |
| zen_wait_for_elementA | Wait for a CSS selector to appear and become visible on the page. Returns immediately when the element is found, rather than sleeping a fixed duration. Use this instead of sleep when waiting for dynamic/JS-rendered content. Args: selector: CSS selector to wait for (e.g. ".tracking-events", "#results", "[data-loaded]") timeout: Maximum time to wait in milliseconds (default: 10000 = 10s) poll_interval: How often to check in milliseconds (default: 200ms) tab_id: Optional tab to target. Defaults to active tab. |
| zen_wait_for_resultA | Poll a JavaScript expression until it returns a non-empty result. Args: code: JavaScript expression to evaluate repeatedly timeout: Maximum time to wait in milliseconds poll_interval: How often to check in milliseconds tab_id: Optional tab to target. Defaults to active tab. |
| zen_workflowsA | List available named ZenLink workflows from the bridge workflow directory. |
| zen_workflowB | Execute a named ZenLink workflow from the bridge workflow directory. Args: name: Workflow file name without .md variables: Optional template variables for the workflow |
| zen_cacheB | Control the ZenLink bridge response cache. Args: action: "clear", "status", or "ttl" seconds: TTL value when action is "ttl" |
| zen_wake_tabA | Revive a tab that Zen's Tab Unloader may have discarded. Zen aggressively unloads inactive tabs to save RAM. An unloaded tab still appears in zen_tabs but has no live content script — commands targeting it will hang or fail until it's reloaded. zen_wake_tab is idempotent: if the tab is already alive it returns immediately; otherwise it reloads the tab and waits for the page to finish loading. Use before targeting a tab that might have been idle for a while. Prefer zen_keep_alive for tabs you'll touch repeatedly. Args: tab_id: The tab ID to wake (get IDs from zen_tabs) |
| zen_keep_aliveA | Keep tabs warm so Zen's Tab Unloader won't discard them mid-workflow. Starts a background pinger in the bridge that fires a no-op JS evaluation at each listed tab on the given interval. Any script access resets Zen's idle timer, so the tabs stay loaded. Replaces any existing keep-alive for the same tabs (use a new interval to change cadence). Use this at the start of parallel multi-tab work: open your tabs, call zen_keep_alive with their IDs, drive them in parallel via zen_parallel or by passing tab_id to individual commands, then zen_keep_alive_stop when done. The pinger auto-stops if the bridge restarts. Args: tab_ids: Tab IDs to keep loaded. interval_seconds: How often to ping each tab. Minimum 10s, default 60s. Should be well under Zen's unloader timeout (commonly 20+ minutes). |
| zen_keep_alive_stopA | Stop the keep-alive pinger for some or all tabs. Args: tab_ids: Tabs to stop pinging. Omit (or pass null) to stop all. |
| zen_reload_extensionA | Hot-reload the ZenLink extension in the browser. Use this after editing the extension source to pick up changes without
going through Note: only works once you're already on a version of the extension that has this action handler. The very first install of that version requires the usual about:addons toggle. |
| zen_parallelA | Run command sequences in parallel — typically one sequence per tab. Each inner list is a sequence that runs serially; all sequences run concurrently. Commands that target a specific tab (navigate, switchTab, or any tab-aware action) MUST include "tabId" inside the parallel batch to avoid race conditions over the active tab. Returns a list of result lists, one per input sequence. Args: sequences: List of command sequences. Each command is a dict with "action" and parameters — same shape as zen_batch commands. Example for driving two tabs at once: [ [{"action": "navigate", "url": "...", "tabId": 12}, {"action": "waitForElement", "selector": "h1", "tabId": 12}, {"action": "pageText", "tabId": 12}], [{"action": "navigate", "url": "...", "tabId": 13}, {"action": "waitForElement", "selector": "h1", "tabId": 13}, {"action": "pageText", "tabId": 13}] ] |
| zen_queryA | Extract multiple fields from every element matching a CSS selector. Much faster and cheaper than calling zen_js per element. The default
fields cover the common ones (text, href, value, src, alt, id, name);
pass Args: selector: CSS selector. fields: Field names to extract per element. Defaults to a useful set. limit: Max elements to return (capped at 500). tab_id: Optional tab; defaults to active. |
| zen_htmlB | Return the outerHTML of a specific element. Cap 100KB. |
| zen_linksB | Return every anchor with href + text. Useful as a crawler primitive. |
| zen_imagesC | Return every with src, alt, and natural dimensions. |
| zen_metaC | Return all meta tags + link rels (canonical, RSS, icons, etc.). |
| zen_structured_dataC | Extract JSON-LD blocks, OpenGraph (og:*), and Twitter card meta. |
| zen_boundsB | Return getBoundingClientRect + viewport/page sizes for an element. |
| zen_computed_styleC | Return computed CSS for an element. Defaults to the layout-relevant set. |
| zen_readabilityA | Extract the main article on the page (title, byline, clean text). Heuristic: score candidate containers ( |
| zen_markdownC | Convert the page (or a selector subtree) to Markdown. Cap 80KB. |
| zen_iframesC | List all iframes with src + same-origin/accessible flags. |
| zen_explain_selectorA | Diagnose a CSS selector: match count, sample matches, suggestions for a more-specific selector if you got too many. |
| zen_select_optionB | Choose an in a . Default matches by value; pass
|
| zen_checkC | Set a checkbox or radio's checked state. |
| zen_focusC | Move focus to the matched element. |
| zen_blurB | Blur an element (or document.activeElement if no selector). |
| zen_keypressA | Dispatch a synthetic keyboard event. Use modifiers like
Args: key: Key name, e.g. "Enter", "Tab", "Escape", "ArrowDown", "a". selector: Optional element to target. Defaults to document.activeElement. modifiers: {"ctrl"|"shift"|"alt"|"meta": True}. text: If set, also insert this text into editable targets. |
| zen_double_clickC | Dispatch a synthetic double-click on the matched element. |
| zen_submit_formA | Submit a form. If selector is omitted, submits the first found. |
| zen_form_fillA | Fill many fields at once via fuzzy matching. Each key in Args: fields: {"email": "foo@bar", "Password": "...", "#submit-target": true} |
| zen_dragC | Synthetic drag-and-drop from one element to another (HTML5 drag events). |
| zen_click_and_wait_navigationA | Click an element, then wait for the resulting navigation to complete. Atomic operation — far more reliable than |
| zen_element_screenshotA | Screenshot a single element. Scrolls into view, captures, crops in the extension via OffscreenCanvas. Returns a PNG data URL. |
| zen_full_page_screenshotB | Scroll-and-stitch screenshot covering the full document height (up to 30 viewports tall). Returns one PNG data URL of the entire page. |
| zen_full_page_metricsC | Return document/viewport sizes + scroll position + devicePixelRatio. |
| zen_pin_tabC | Pin or unpin a tab. |
| zen_mute_tabC | Mute or unmute a tab. |
| zen_duplicate_tabB | Duplicate a tab. Returns the new tab id. |
| zen_reload_tabA | Reload a tab. Pass |
| zen_backC | Go back in history (browser back button). |
| zen_forwardC | Go forward in history. |
| zen_get_zoomC | Return the current zoom factor (1.0 = 100%). |
| zen_set_zoomB | Set zoom factor. 0.3 to 5.0 typical; 1.0 = 100%. |
| zen_windowsA | List all open browser windows with their tabs. |
| zen_create_windowA | Open a new browser window. Pass a URL to load it at start. |
| zen_close_windowA | Close a browser window by ID (from zen_windows). |
| zen_focus_windowC | Bring a browser window to the foreground. |
| zen_move_tabB | Move a tab to a position (and optionally to a different window). -1 = end. |
| zen_detach_tabC | Pop a tab out into its own new window. |
| zen_cookiesA | Cookie operations: "get", "set", "remove", "clear".
|
| zen_storageA | localStorage / sessionStorage ops. Args: kind: "local" or "session". op: "get" | "set" | "remove" | "clear" | "list" | "snapshot" | "restore". key: Required for get/set/remove. value: For set, the string value. For restore, a dict of key→value. tab_id: Tab to run against. Storage is per-origin, so prefer driving it on a tab already at the right origin. |
| zen_clipboardA | Read or write the system clipboard. Args: op: "read" or "write". text: Text to write when op="write". |
| zen_downloadsB | Downloads operations. Args: op: "download" | "list" | "cancel". url: For "download", the URL to fetch. filename: Optional output filename. query: For "list", a downloads.search query dict. |
| zen_clear_browsing_dataA | Clear browsing data of the given types. Args: types: Which to clear. Subset of ["cache","cookies","history", "localStorage","passwords","downloads"]. Default = all of those. since_ms: Only data created since this epoch-ms timestamp. |
| zen_interceptA | Block, log, or redirect HTTP requests by URL regex. Useful to suppress analytics/ads during agent runs (3–10× page speed-up) or to log what an SPA actually fetches. Args: op: "add" | "clear" | "list" | "log" | "clearLog". patterns: For "add", regex patterns to match against request URLs. effect: For "add", "block" (cancel request) or "redirect". |
| zen_capture_networkB | Capture network requests via the page's PerformanceObserver. Args: op: "start" begins capturing fresh, "stop" pauses, "read" returns the buffer (default), "clear" empties it. since: When reading, only return entries with startTime >= since (ms). tab_id: Optional tab; defaults to active. |
| zen_wait_for_network_idleC | Wait until no new network resources have started for |
| zen_wait_for_urlC | Wait until the tab's URL matches a JS regex pattern. |
| zen_wait_for_titleC | Wait until document.title matches a JS regex pattern. |
| zen_watch_consoleA | Toggle console capture on a tab. Once enabled, browser console messages (log/info/warn/error/debug + window errors) are buffered up to 500 entries; retrieve via zen_console_logs. |
| zen_console_logsA | Return buffered console logs from a tab (requires zen_watch_console first). |
| zen_broadcastA | Fire the same command at every listed tab in parallel. Each tab gets the command with its own tabId injected. Returns per-tab results keyed by tab id. Args: tab_ids: Tabs to target. command: Command dict, e.g. {"action": "pageInfo"} or {"action": "getReadability"}. timeout: Per-tab timeout in seconds. |
| zen_sync_barrierA | Block until a JS predicate returns truthy on every listed tab. Replaces hand-rolled "wait for everything to be ready" loops. Args: tab_ids: Tabs to monitor. predicate: JS expression that returns truthy when the tab is ready, e.g. "!!document.querySelector('.results')". timeout: Overall timeout in ms. poll_interval: Per-poll interval in ms. |
| zen_tag_tabA | Give a tab a memorable name. Refer to it later via zen_resolve_tag. Names survive bridge restarts only if you re-tag — they live in memory. |
| zen_resolve_tagC | Look up the tab id for a tag set via zen_tag_tab. |
| zen_list_tagsB | List all tag → tab id mappings. |
| zen_untag_tabC | Remove a tag. |
| zen_tab_poolA | Maintain a warm pool of N tabs always ready to be acquired. Grows or shrinks to |
| zen_pool_acquireA | Check out a warm tab from the pool. Returns its tab_id. |
| zen_pool_releaseC | Return a tab to the pool for reuse. |
| zen_save_sessionA | Snapshot cookies (and per-origin localStorage if urls given) to disk. Use case: log into a service interactively once, save the session, then have parallel agents load it for authenticated work. Args: name: A label for the session (becomes filename under ~/claude-zen-sessions/). urls: Origins whose cookies + localStorage to snapshot. Each gets opened briefly in a temp tab so localStorage can be read. |
| zen_load_sessionA | Restore cookies + localStorage from a previously saved session. |
| zen_list_sessionsB | List saved sessions with their metadata. |
| zen_delete_sessionC | Delete a saved session file. |
| zen_healthB | Extended health/status: bridge version, ports, keep-alive list, pool state, tags, policy, sessions dir, audit/log sizes. |
| zen_logsB | Return recent bridge log lines (in-memory ring buffer). |
| zen_auditA | Return recent command audit entries: action, params (JS code stripped), success flag, error, duration. Useful for "what did the agent do?" reviews. |
| zen_set_policyA | Set URL allow/deny regex lists and/or read-only mode. Read-only mode blocks write actions (click/type/navigate/cookies set/etc.) while still allowing read ops. Useful for "let the agent observe only." |
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
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/JayQuan-McCleary/ZenLink-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server