extension_eval
Evaluate an expression in a running extension context.
Quick start
Evaluate chrome.runtime.id in the background and in the popup
Asked to evaluate an expression, the agent starts the session with eval on and reads the value back.
How the agent uses it
Start the session with allowEval:true (extension_dev), which writes a 0600 session token; without that token every route of this tool, the debug port included, answers eval-disabled. Context defaults to 'background', except on a Chromium MV3 session (the default template) where it defaults to 'page', the active tab; pass context:'background' to evaluate in the service worker, which on Chromium goes over the debug port. Debug-port evaluates run with a user gesture, so gesture-gated APIs (permissions.request, sidePanel.open) can succeed here and still fail when the extension's own code calls them. For content and page, pass url to pick the tab, or omit both url and tab for the active tab; a numeric tab only disambiguates. Extension surfaces (popup, options, sidebar, devtools) and override pages (newtab, history, bookmarks) need no tab id but must already be open: open one with extension_open first, because a closed one returns an explicit error. On a Chromium MV3 session those pages, and context:'page' with a chrome-extension:// url, evaluate over CDP, the inspector path the extension page CSP does not govern; elsewhere they evaluate over the in-bundle relay. On Firefox a document whose content security policy forbids eval (the extension's own pages, or a site's) is evaluated over the debugger protocol instead, which takes one expression; a page inside the extension that is no declared surface (pages/*) is reached the same way by context:'page' and its moz-extension:// url once a tab shows it. Call extension_dom_snapshot with listTabs:true to enumerate {tabId, url, title}.
Page text in the answer
Part of this tool's answer is text a web page or the extension wrote. The server fences it between <untrusted-data-ID> and </untrusted-data-ID> with a fresh random ID per call, named in untrusted.boundary. A fence is a signal to the model, not a gate: pair it with --no-ship when the agent reads pages you do not trust. See Server flags and telemetry.
Reference
| Group | local, on by default |
| Tier | Act |
| Needs | a session started with allowEval: true on extension_dev |
| Read only | no |
| Destructive | yes |
| Idempotent | no |
| Reaches the open web | yes |
Inputs
| Input | Type | Required | Default | What it does |
|---|---|---|---|---|
projectPath | string | yes | Extension project root (needs a live dev session) | |
expression | string | yes | JavaScript expression to evaluate in the target context | |
context | "background" | "popup" | "options" | "sidebar" | "devtools" | "newtab" | "history" | "bookmarks" | "content" | "page" | no | Where to evaluate. Default background, except Chromium MV3 sessions default to page (the active tab). | |
url | string | no | content/page: pick the tab by url (match pattern, then substring). Preferred over tab. | |
tab | number | no | Numeric chrome.tabs id, only to disambiguate when several tabs match. | |
browser | string | no | Session browser; defaults to this project's live session | |
timeout | number | no | Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port. |
When it fails
- The call is refused because no session is live. Start one with
extension_devorextension_startand call again. - Eval is refused. Eval is the one gate that stays off. Start the session with
allowEval: trueonextension_dev. - The answer depends on the network. This tool reaches the open web, so a refusal can be the network, not the project.
Next
- MCP server: install, the two groups and the session gates
- Install in your client
extension_open: Open an extension surface, or replay an event, in a running session.extension_reload: Reload a running extension's background context, or a tab.extension_storage: Read or write chrome.storage in a running extension.