>kitsune
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| KITSUNE_HOME | No | Data directory (0700) | ~/.kitsune |
| KITSUNE_TOKEN | No | Override the token in ~/.kitsune/token | |
| KITSUNE_WS_PORT | No | Extension WebSocket. Change WS_URL in extension/background/background.js too | 47652 |
| KITSUNE_HTTP_PORT | No | Bridge HTTP API | 47651 |
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 |
|---|---|
| browser_statusB | Check if Kitsune bridge and browser extension are connected. |
| browser_tabsB | List all open browser tabs with their IDs, titles, and URLs. |
| browser_page_infoB | Get current page URL, title, dimensions, and scroll position. Args: tab_id: Optional tab to target. Defaults to active tab. |
| browser_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 browser_page_text_by_tab_id — they do the same thing now. |
| browser_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 browser_tabs) Returns the full visible text content of the specified tab. |
| browser_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. |
| browser_domB | Get the accessibility tree of interactive elements on the page. Args: tab_id: Optional tab to target. Defaults to active tab. |
| browser_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 browser_switch_tab. |
| browser_navigateB | 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. raw: Bare image URLs (.jpg/.png/...) open inside a small local viewer page (image = #zlimg) so the extension can still script them. True opens the raw image. |
| browser_new_tabB | Open a new browser tab. Args: url: URL to open in the new tab (default: blank page) raw: Bare image URLs open inside a local viewer page (image = #zlimg) unless raw=True. |
| browser_close_tabA | Close a browser tab by its ID. Args: tab_id: The tab ID to close (get IDs from browser_tabs) force: Disarm "Leave page?" (beforeunload) prompts first - upload/editor pages otherwise hold the tab open and the close times out. |
| browser_switch_tabB | Switch focus to a specific browser tab. Args: tab_id: The tab ID to focus (get IDs from browser_tabs) |
| browser_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. |
| browser_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 browser_click unless a page specifically ignores synthetic clicks. Args: selector: CSS selector to click. If provided, Kitsune 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). |
| browser_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. |
| browser_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 Kitsune 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. |
| browser_fillB | 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. |
| browser_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. |
| browser_hoverB | 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. |
| browser_findB | 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. |
| browser_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. full: Results are capped at 8 MB (50 KB on extensions older than 2.1.0). full=True runs the code once and reads the result back in slices, so any size comes back complete. |
| browser_highlightB | 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. |
| browser_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. |
| browser_wait_for_resultB | 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. |
| browser_workflowsB | List available named Kitsune workflows from the bridge workflow directory. |
| browser_workflowB | Execute a named Kitsune workflow from the bridge workflow directory. Args: name: Workflow file name without .md variables: Optional template variables for the workflow |
| browser_cacheC | Control the Kitsune bridge response cache. Args: action: "clear", "status", or "ttl" seconds: TTL value when action is "ttl" |
| browser_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 browser_tabs but has no live content script — commands targeting it will hang or fail until it's reloaded. browser_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 browser_keep_alive for tabs you'll touch repeatedly. Args: tab_id: The tab ID to wake (get IDs from browser_tabs) |
| browser_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 browser_keep_alive with their IDs, drive them in parallel via browser_parallel or by passing tab_id to individual commands, then browser_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). |
| browser_keep_alive_stopB | Stop the keep-alive pinger for some or all tabs. Args: tab_ids: Tabs to stop pinging. Omit (or pass null) to stop all. |
| browser_reload_extensionA | Hot-reload the Kitsune 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. |
| browser_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 browser_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}] ] |
| browser_queryA | Extract multiple fields from every element matching a CSS selector. Much faster and cheaper than calling browser_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. |
| browser_htmlC | Return the outerHTML of a specific element. Cap 100KB. |
| browser_linksC | Return every anchor with href + text. Useful as a crawler primitive. |
| browser_imagesB | Return every with src, alt, and natural dimensions. |
| browser_metaC | Return all meta tags + link rels (canonical, RSS, icons, etc.). |
| browser_structured_dataC | Extract JSON-LD blocks, OpenGraph (og:*), and Twitter card meta. |
| browser_boundsC | Return getBoundingClientRect + viewport/page sizes for an element. |
| browser_computed_styleC | Return computed CSS for an element. Defaults to the layout-relevant set. |
| browser_readabilityB | Extract the main article on the page (title, byline, clean text). Heuristic: score candidate containers ( |
| browser_markdownC | Convert the page (or a selector subtree) to Markdown. Cap 80KB. |
| browser_iframesC | List all iframes with src + same-origin/accessible flags. |
| browser_explain_selectorB | Diagnose a CSS selector: match count, sample matches, suggestions for a more-specific selector if you got too many. |
| browser_select_optionA | Choose an in a . Default matches by value; pass
|
| browser_checkC | Set a checkbox or radio's checked state. |
| browser_focusC | Move focus to the matched element. |
| browser_blurC | Blur an element (or document.activeElement if no selector). |
| browser_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. |
| browser_double_clickC | Dispatch a synthetic double-click on the matched element. |
| browser_submit_formB | Submit a form. If selector is omitted, submits the first found. |
| browser_form_fillA | Fill many fields at once via fuzzy matching. Each key in Args: fields: {"email": "foo@bar", "Password": "...", "#submit-target": true} |
| browser_dragC | Synthetic drag-and-drop from one element to another (HTML5 drag events). |
| browser_click_and_wait_navigationA | Click an element, then wait for the resulting navigation to complete. Atomic operation — far more reliable than |
| browser_upload_fileA | Attach local file(s) to a page's upload control - no OS file dialog. The bridge reads the file from disk and streams it into the page, which builds real File objects and sets them on the (firing input + change). If the selector is a drop zone with no input inside, it fires dragenter/dragover/drop. Args: path: absolute file path, or a list of paths for multi-file inputs. selector: the file input, an element containing it, or a drop zone. Omit to use the first input[type=file] on the page. mode: "auto" (input if found, else drop), "input", or "drop". tab_id: target tab (default: active). Pass it for anything big - the upload streams in ~384 KB chunks and must keep hitting the same tab. Returns {ok, mode, files: [{name, size, type}], chunks, bytes, transport, seconds}. |
| browser_element_screenshotA | Screenshot a single element. Scrolls into view, captures, crops in the extension via OffscreenCanvas. Saves a PNG and returns its path (saved_to). Args: selector: CSS selector of the element tab_id: Optional tab to target. Defaults to active tab. save_to: Optional file path (default: ~/claude-zen-screenshots/element_.png) data_url: Also return the PNG data URL (large - only if you really need the bytes inline) scale: 1-4 output pixels per CSS pixel. 2 = genuinely sharper capture at twice the size (needs extension 2.1.1+; older extensions ignore it) |
| browser_full_page_screenshotA | Scroll-and-stitch screenshot covering the full document height (up to 30 viewports tall). Saves one PNG of the entire page and returns its path (saved_to). Args: tab_id: Optional tab to target. Defaults to active tab. save_to: Optional file path (default: ~/claude-zen-screenshots/fullpage_.png) data_url: Also return the PNG data URL (large) |
| browser_full_page_metricsB | Return document/viewport sizes + scroll position + devicePixelRatio. |
| browser_pin_tabC | Pin or unpin a tab. |
| browser_mute_tabC | Mute or unmute a tab. |
| browser_duplicate_tabC | Duplicate a tab. Returns the new tab id. |
| browser_reload_tabC | Reload a tab. Pass |
| browser_backC | Go back in history (browser back button). |
| browser_forwardC | Go forward in history. |
| browser_get_zoomB | Return the current zoom factor (1.0 = 100%). |
| browser_set_zoomB | Set zoom factor. 0.3 to 5.0 typical; 1.0 = 100%. |
| browser_windowsB | List all open browser windows with their tabs. |
| browser_create_windowC | Open a new browser window. Pass a URL to load it at start. |
| browser_close_windowB | Close a browser window by ID (from browser_windows). |
| browser_focus_windowC | Bring a browser window to the foreground. |
| browser_move_tabC | Move a tab to a position (and optionally to a different window). -1 = end. |
| browser_detach_tabC | Pop a tab out into its own new window. |
| browser_cookiesB | Cookie operations: "get", "set", "remove", "clear".
|
| browser_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. |
| browser_clipboardB | Read or write the system clipboard. Args: op: "read" or "write". text: Text to write when op="write". |
| browser_downloadsC | 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. |
| browser_clear_browsing_dataB | 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. |
| browser_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". |
| browser_capture_networkA | 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. |
| browser_wait_for_network_idleC | Wait until no new network resources have started for |
| browser_wait_for_urlC | Wait until the tab's URL matches a JS regex pattern. |
| browser_wait_for_titleB | Wait until document.title matches a JS regex pattern. |
| browser_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 browser_console_logs. |
| browser_console_logsA | Return buffered console logs from a tab (requires browser_watch_console first). |
| browser_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. |
| browser_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. |
| browser_tag_tabB | Give a tab a memorable name. Refer to it later via browser_resolve_tag. Names survive bridge restarts only if you re-tag — they live in memory. |
| browser_resolve_tagB | Look up the tab id for a tag set via browser_tag_tab. |
| browser_list_tagsB | List all tag → tab id mappings. |
| browser_untag_tabC | Remove a tag. |
| browser_tab_poolA | Maintain a warm pool of N tabs always ready to be acquired. Grows or shrinks to |
| browser_pool_acquireB | Check out a warm tab from the pool. Returns its tab_id. |
| browser_pool_releaseC | Return a tab to the pool for reuse. |
| browser_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. |
| browser_load_sessionC | Restore cookies + localStorage from a previously saved session. |
| browser_list_sessionsB | List saved sessions with their metadata. |
| browser_delete_sessionC | Delete a saved session file. |
| browser_healthB | Extended health/status: bridge version, ports, keep-alive list, pool state, tags, policy, sessions dir, audit/log sizes. |
| browser_logsC | Return recent bridge log lines (in-memory ring buffer). |
| browser_auditB | Return recent command audit entries: action, params (JS code stripped), success flag, error, duration. Useful for "what did the agent do?" reviews. |
| browser_schedulerA | Return bridge scheduler state for multi-agent/tab work. Shows active per-tab/global command scopes, pending WebSocket commands, and known tab locks. Useful when several agents are driving separate tabs. |
| browser_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." |
| browser_get_policyB | Return the active URL/readonly policy. |
| browser_retryA | Wrap any command in exponential-backoff retry. Args: command: A command dict (same shape as browser_batch entries). max_attempts: Total tries including the first. backoff_ms: Initial wait between attempts (doubles each retry). on_errors: Only retry if the error string contains one of these substrings. Default: retry on any error. |
| browser_wp_htmlA | Extract HTML widget content from a WordPress Elementor page. Navigates to the Elementor editor for the given page, waits for load, then extracts the innerHTML of all HTML widgets from the Elementor preview iframe. Returns clean HTML/CSS/JS content. The browser must already be logged into WP admin for this to work. Args: site_url: WordPress site URL (e.g. "https://thankyouexperiences.com") page_id: WordPress page/post ID (e.g. 5719 for Team page) |
| browser_batchA | Run multiple commands in a single request for speed. Each command is a dict with "action" and parameters. Add "tabId" to any command to target a specific tab instead of the active one. For true concurrency across tabs, prefer browser_parallel. Available actions: navigate, newTab, closeTab, switchTab, click, type, setEditableContent, fill, scroll, hover, find, js, pageInfo, pageText, screenshot, tabs, forms, dom, sleep, waitForElement, pageTextByTabId, wakeTab, parallel Args: commands: List of command dicts, e.g. [{"action": "navigate", "url": "..."}, {"action": "waitForElement", "selector": ".results", "timeout": 10000}, {"action": "pageText"}] |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 106 tools
Many tools overlap substantially: browser_page_text and browser_page_text_by_tab_id are explicitly documented as doing 'the same thing now', while browser_type, browser_fill, browser_set_editable_content, and browser_form_fill are four paths to entering text with subtle boundaries. Descriptions do help distinguish most cases (e.g. click vs trusted_click vs click_and_wait_navigation), but the sheer surface creates frequent ambiguity.
Nearly all tools use the browser_ prefix in snake_case, and verb_noun forms like browser_navigate, browser_close_tab, and browser_set_policy are predictable. However, a large minority are bare nouns with no verb (browser_health, browser_logs, browser_cookies, browser_forms, browser_html, browser_markdown), which slightly breaks the pattern.
106 tools is far beyond what any single agent can scan effectively, well past the 25+ threshold for a heavily overloaded surface. Many of these exist as niche one-offs (browser_wp_html, browser_reload_extension, browser_broadcast) that dilute discoverability of the core set.
The surface covers browser automation exhaustively: navigation, tabs, windows, cookies, storage, sessions, network interception/capture, screenshots, forms, JS execution, waiting primitives, policy, tagging, pooling, and diagnostics. It is hard to identify a meaningful missing operation for the stated domain.