mcp__Claude_in_Chrome__navigate silently denies non-pre-approved domains — no user-facing approval path exists anywhere
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When Claude Code Desktop's mcp__Claude_in_Chrome__navigate tool is called with a domain not in the session's seeded turnApprovedDomains set, the extension silently denies the request with { allowed: false, needsPrompt: false }. No approval prompt surfaces anywhere in the product. No toast, no side-panel control, no UI of any kind.
This breaks any workflow involving per-branch preview URLs (Vercel, Netlify, Cloudflare Pages, Render, etc.) where the target hostname is unique per PR and cannot be known at session start.
The UI scaffolding for the fix already exists at claude.ai/settings/browser-extension — Anthropic has shipped the block-list half of the permission model (blockedUrlPatterns) but not the allow-list half (which would be the UI counterpart to the extension's existing turnApprovedDomains / permissionStorage).
What Should Happen?
One or more of the following:
- An allow-list UI at
claude.ai/settings/browser-extensionsymmetric to the existing block-list, with wildcard support (*.vercel.app,*.netlify.app,*.pages.dev,*.onrender.com). - 2. Gate 1 should fall through to
{ needsPrompt: true }in interactive sessions instead of{ allowed: false, needsPrompt: false }— so the user at least gets a visible approval dialog. - 3. An MCP tool the agent can call to request additional domains mid-session, triggering a user-confirmation prompt in Claude Code Desktop.
- 4. An allow-list key in the extension's
managed_schema.jsonalongsideblockedUrlPatterns.
Error Messages/Logs
Tool call response from mcp__Claude_in_Chrome__navigate:
"Navigation to this domain is not allowed"
No stack trace. No additional detail. The error is returned synchronously with no user-facing prompt or notification of any kind.
Steps to Reproduce
- Open Claude Code Desktop (v1.2773.0.0, Windows 11 MSIX) with the Claude in Chrome integration active (extension v1.0.68).
- Start a new conversation. Ask Claude to navigate to a Vercel PR preview URL, e.g.: "Go to https://tenefly-bicjcd639-mensahb89s-projects.vercel.app and tell me what you see."
- 3. Claude Code Desktop activates
follow_a_planpermission mode and seedsturnApprovedDomainswith the project's known domains (e.g.,["www.tenefly.com"]) via IPC:{ subtype: "set_permission_mode", mode: "follow_a_plan", allowed_domains: ["www.tenefly.com"] }. - 4. Claude calls
mcp__Claude_in_Chrome__navigatewith the preview URL. - 5. Result: Tool returns
"Navigation to this domain is not allowed". No prompt appears anywhere — not in Claude Code Desktop, not in the Chrome extension popup, not as a toast or notification.
Root cause (traced to extension source):
In fcoeoabgfenejglbffodgkkbkcdhcgfn/1.0.68_0/assets/PermissionManager-WI3FAKQw.js, checkPermission() runs:
// Gate 1 — fires before persistent storage and before the prompt fallback
if (r && this.turnApprovedDomains.size > 0 && !this.isTurnApprovedDomain(r))
return { allowed: false, needsPrompt: false };
When turnApprovedDomains is non-empty, this gate hard-denies any unlisted domain with needsPrompt: false, bypassing both the persistent permissionStorage lookup and the user-approval prompt fallback.
Every path verified as non-working:
- Editing
CLAUDE.md"Browser access" section — not consulted by host plan seeding - - Brand-new session with preview URL in the first user message — hostname still not in
turnApprovedDomains - - - Clicking the Claude in Chrome extension icon — no per-domain approval UI in v1.0.68
- - - - Chrome managed policy (
managed_schema.json) — exposes onlyblockedUrlPatternsandforceLoginOrgUUID; no allow-list key - - - - -
claude.ai/settings/browser-extension— full audit performed; exposes only a block-list (binary on/off + blocked sites list). "Default for all sites" dropdown has exactly two options: "Allow extension" and "Block extension". No allow-list, no wildcard field - - - - - - Claude Code Desktop CLI (
claude --help) — only--chrome/--no-chrome - - - - - - - All Claude Code Desktop config files — no browser-domain settings
- - - - - - - - Editing the extension's
permissionStorageLevelDB — irrelevant because Gate 1 fires before that store is consulted - - - - - - - - -
/org/settingson claude.ai — redirects to homepage (individual Pro account); no org admin console
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
1.2773.0.0 (Claude Code Desktop, Windows MSIX). Claude in Chrome extension v1.0.68.
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
Why this hurts
Per-PR preview deployments are table stakes for modern web dev. Our team ships UI changes behind feature flags and needs to visually verify on a Vercel preview URL before merge. Preview hostnames are unique per branch — there is no way to pre-list them at session start.
Viable workarounds attempted:
- Patching the extension file locally — Chrome hashes extension files and can silently reinstall from cache or flag the extension as corrupted (disabling the whole integration). Not viable.
- - DevTools monkey-patching the running service worker — MV3 service workers idle-kill after ~30 seconds; the patch is lost on restart. Not viable for tasks longer than a few minutes.
- - - Merging without preview verification — defeats the verification gate entirely.
Why the fix is low-effort
The backend already fully exists:
turnApprovedDomains(in-memory Set) andpermissionStorage(LevelDB) are already implemented in the extension- - The
set_permission_modeIPC path already accepts anallowed_domainsarray - - -
claude.ai/settings/browser-extensionalready has the UI scaffold (block-list side)
Shipping the allow-list side is finishing what's half-built, not net-new infrastructure. Adding wildcard support (*.vercel.app) would unblock all PR preview workflows with a single entry.
Suggested fix preference order
- Add allow-list UI to
claude.ai/settings/browser-extensionwith wildcard support — symmetric to the existing block-list - 2. Change Gate 1 from
{ allowed: false, needsPrompt: false }to{ allowed: false, needsPrompt: true }in interactive sessions — at minimum gives the user a visible approval path - 3. Expose an MCP tool for the agent to request additional domains mid-session with user confirmation
- 4. Add an allow-list key to
managed_schema.jsonalongsideblockedUrlPatterns
Happy to test patches on a preview build and provide additional repro data.
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
{ allowed: false, needsPrompt: false }is the worst possible combination here because it creates a silent policy wall with no recovery path.That means the system has enough logic to deny the action, but not enough product surface to explain the denial or let the user authorize the new domain. For preview-URL workflows that is especially damaging because ephemeral per-branch hostnames are normal, not exceptional.
So the real bug is not only "cannot navigate to some domains." It is that the permission model is half-implemented:
That turns a dynamic browser tool into a static allowlist tool, which breaks many legitimate dev workflows.
The most important fix is the interactive fallback you suggest: when the session is interactive and the domain is not pre-approved, the extension should surface a real approval request instead of returning a silent denial. Even before a full allow-list UI ships, that would restore operator control.
More broadly, this is another hidden-boundary problem. Users cannot trust tool capabilities if policy denials happen invisibly and indistinguishably from tool flakiness.
I reproduced the error identically on MS Edge with the same v1.0.69 extension installed (deviceId different, error identical: permission_required: subdomain.ourinternalwebsite.com). Confirms the regression is in the extension build, not platform-specific to Chrome.
Same issue on macOS — 3+ weeks blocked
Symptom:
This has persisted for 3+ weeks and completely blocks multi-site workflows. Please prioritize.
Confirming this is still a problem
+1, same issue here.
Symptoms mcp__Claude_in_Chrome__navigate (and tabs_create_mcp followed by navigate) returns "Navigation to this domain is not allowed" on every domain tested (google.com, infomaniak.com, example.com) — not site-specific.
"Your approved sites" stays empty Checked Claude in Chrome settings → Authorizations → "Vos sites approuvés" ("Your approved sites"): list is empty, and no approval prompt ever renders in the browser or in the side panel to populate it.
Troubleshooting already tried (no effect)
Restarted Chrome
Uninstalled/reinstalled the Claude in Chrome extension with different permissions
Switched browser entirely: Chrome → Brave, same error
Full computer restart
Extension version: 1.0.77
Notable detail Navigation worked once, early in the session (google.com/search?q=... succeeded). After opening the extension's own settings page ("Vos sites approuvés"), every subsequent navigation attempt — including to google.com again — started failing with the same error, and never recovered despite all the troubleshooting above.
Environment
OS: Windows 11 Pro
Browsers tested: Chrome, Brave
Driven via: Claude Code (agent), MCP tools
Diagnosis from Claude Code:
Title: claude-in-chrome navigate silently locks to first domain of a conversation, shadowing the saved approved-sites allowlist
Environment
Summary
Once any domain is approved during a conversation, mcp__claude-in-chrome__navigate hard-denies every other domain — even domains that are explicitly ALLOW in the extension's persisted permissionStorage (the "approved sites" UI list). No permission prompt is offered, so there's no recovery within the conversation. Effect: the first domain navigated in a conversation becomes the only usable domain for the rest of that conversation.
Root cause (from assets/mcpPermissions-CJK8I7C7.js)
// checkPermission():
if (n && this.turnApprovedDomains.size > 0 && !this.isTurnApprovedDomain(n))
return { allowed: false, needsPrompt: false }; // ← hard deny, no prompt
...
if (!this.forcePrompt && this.isTurnApprovedDomain(i))
return { allowed: true, needsPrompt: false };
await this.loadPermissions(); // permissionStorage only checked here (unreachable once locked)
turnApprovedDomains is an exclusive in-session lock set via setTurnApprovedDomains(). Once non-empty, the short-circuit returns needsPrompt:false, so (a) permissionStorage is never consulted, and (b) no prompt is raised to approve the new domain. The caller (navigate) then returns:
{ error: "Navigation to this domain is not allowed", errorCode: "navigate_permission_denied" }
Repro
Observed invariants while debugging
Expected
When turnApprovedDomains is non-empty and a different domain is requested, either (a) fall through to permissionStorage and allow if ALLOW, or (b) return needsPrompt:true so the user can approve the additional domain. The persisted approved-sites list should not be silently shadowed.
Secondary bug
Reloading the extension's service worker (chrome.runtime.reload() from its DevTools) crashed Chrome — suggests the SW init path throws/loops under some state.
Workaround
One external domain per conversation, navigated first; start a fresh conversation to use a different domain.
Corroborating report on macOS, with the org-policy layer explicitly ruled out.
Setup: Claude Desktop driving
mcp__claude-in-chrome__navigatethrough the Claude in Chrome extension. macOS, single local browser connected. The account is the organization Owner.Trace (matches @rajatrocks's "locks to the first domain of the conversation"):
navigateto a second domain (www.printful.com) returnedNavigation to this domain is not allowed, with no prompt anywhere (no toast, no side-panel control, no dialog).Ruled out, so this is clearly not a config or policy problem:
claude.ai-> Settings -> Claude in Chrome shows "Default for all sites = Allow extension" ("works everywhere except sites you block below") with an empty blocklist..claude/settings.local.jsonhas no domain restriction; the chrome MCP tools are permitted generally.navigatepath is locked.So even on a fully-permissive Owner account, MCP navigation hard-locks to the first domain approved in the conversation and denies all others with
{allowed:false, needsPrompt:false}. Starting a fresh conversation and navigating to the desired domain first confirms it (that domain then works and the previous one is locked out). The mid-session approval prompt, or the agent-callable request-domain tool proposed in the original post, would resolve this.Additional data point from Windows 11 that narrows the trigger, plus a workaround not yet mentioned in this thread.
The session lock is seeded by answering "Always allow" on the session's first browser navigate permission prompt.
Environment: Claude desktop app 1.18286.0 (MSIX), Claude Code CLI 2.1.197 (entrypoint: claude-desktop), extension v1.0.79, Chrome stable, Windows 11 Home.
browser:navigateprompt in a session is answered "Always allow": that domain becomes the only usable domain for the rest of the session. Every other domain — including example.com and wikipedia.org — returnsNavigation to this domain is not allowedwithneedsPrompt:false. The desktop app's main.log confirms no permission request is even emitted after the first one.So the most trusting answer ("Always allow") produces the most restricted session, while "Allow once" preserves full multi-domain functionality. Workaround for anyone hitting this: always answer "Allow once" on browser permission prompts.
One more observation: a second machine on the same account with the same app + extension versions never exhibits the lock. The affected machine started showing it immediately after the desktop app was reset/reinstalled on 2026-07-02 — possibly a staged rollout / flag difference on the client side that enables the
follow_a_planseeding described in the OP.Follow-up — the machine-to-machine difference from my previous comment is now explained, and it's much simpler than the staged-rollout theory I speculated about.
The lock only engages when the Claude Code session's permission mode is the default "approve" mode. In auto-accept mode the lock never engages — and switching the mode mid-session releases an already-locked session immediately.
Decisive test (Windows 11, desktop app 1.18286.0, extension v1.0.80): a session that had been hard-locked to github.com for days (mail.google.com / railway.app / example.com all returning
Navigation to this domain is not allowed) was unlocked by nothing more than switching the session's permission mode from "approve edits" (default) to "auto". Same session, same extension, no restart — immediately after the switch, example.com, mail.google.com and railway.app all navigated (and screenshotted) fine.This also resolves my earlier "second machine never exhibits the lock" observation: that machine habitually runs in auto mode — no rollout/flag difference required. And the machine that "suddenly broke" had been reset, which reverted its permission mode to the default.
Practical guidance for anyone hitting this:
The underlying bug from the OP is still present in extension v1.0.80 (Gate 1 hard-deny with
needsPrompt:falseis unchanged inmcpPermissions-*.js) — approve mode still silently denies unlisted domains with no approval path.Same bug, +1 — with a repro matrix that isolates it to the MCP bridge's internal allowlist
Environment: Claude in Chrome v1.0.80, Chrome on Ubuntu (also reproduced identically with the extension in Edge on Windows 11). Driven from Claude Code via the claude-in-chrome MCP tools.
Setup (everything a user can configure is maxed out):
What works:
site-b.example.comwith no issue (so the extension itself has full access to the site).site-a.example.com— a domain that got approved at some point in the past, proving the MCP bridge allowlist exists and is honored.What's broken — MCP tools refuse
site-b.example.comin every form:navigate→Navigation to this domain is not allowed(instant, no approval prompt anywhere — not in the browser, not in the side panel, not in the Claude Code client)computer(screenshot) on an already-open tab for that domain, moved into the MCP tab group →Permission denied for this action on this domainThings that do NOT register a domain for the MCP bridge (all tried):
Expected: either MCP calls to a new domain trigger the site-approval prompt (like the side panel gets), or the Options page's "Your approved sites" list is manually editable. Currently there is no path whatsoever for a user to grant the MCP bridge a new domain, while domains approved earlier (mechanism unknown) keep working — which matches #58464 and #61611.
Adding another data point with a fairly complete repro / isolation trail (Windows 10, Claude Code desktop app + Claude in Chrome extension).
What happened
list_connected_browsersshows a new deviceId, and every page-level action is now rejected:navigate→ "Navigation to this domain is not allowed" (all domains — even example.com, so not site-specific)computer(screenshot) → "Permission denied for this action on this domain"tabs_context_mcp,tabs_create_mcp,list_connected_browsers).Key observations
So approvals appear to be keyed to the connection/device identity: reloading the extension rotates the deviceId, orphans all prior approvals, and the re-approval prompt for external (Claude Code) connections never triggers — leaving no recovery path other than abandoning the extension for that workflow.
Happy to provide logs or run diagnostics if useful.
Corroborating from a different angle: the same root problem (unique-per-deploy origin defeats a per-origin trust model) also surfaces as a visible, unavoidable-per-visit prompt — 'Allow Claude to act on [URL]?' with Deny/Always allow/Allow once — rather than a silent deny, on a Cloudflare Pages preview URL (
<hash>.<project>.pages.dev). Possibly a different tool/code path thanmcp__Claude_in_Chrome__navigate, but the underlying gap (no wildcard/pattern pre-auth for auto-generated preview domains) is the same, so a fix should cover both manifestations.