ZenLink MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| 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
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/JayQuan-McCleary/ZenLink-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server