PreviewContext blocks legitimate http://localhost URLs in desktop app 1.6608.0 — preview pane and screenshot pipeline both fail
Environment
- Claude Code desktop app: 1.6608.0 (latest available as of 2026-05-08)
- macOS: 26.3.1 (build 25D2128)
claudeCLI: 2.1.77
Summary
In the desktop app, the in-chat preview pane refuses to load http://localhost:PORT/... links with the error:
"Link to localhost was blocked. Preview only supports localhost URLs."
The hostname in the link is literally localhost — not 127.0.0.1, not 0.0.0.0, not a LAN IP — so the error message is self-contradicting. The same underlying block also breaks the screenshot pipeline used by visual-review skills (e.g. frontend-design), so any agent flow that depends on preview_start + preview_screenshot against a local web build fails end-to-end. Manually opening the same URL in Safari works fine, so it isn't a server, port, or network issue. Started ~7 days ago, coinciding with a recent app update.
Repro
- Use any flow that produces a
http://localhost:PORT/...link in chat (e.g. an agent that spins up a static HTML preview, or a frontend-design / visual-review skill that callspreview_screenshot). - Either click the link, or wait for the screenshot step to run.
- Observe the error in the preview pane and/or
Preview not found for server ...in the screenshot tool result.
Expected: the localhost URL loads in the preview pane and the screenshot is captured.
Actual: navigation is blocked; the preview process is killed (SIGTERM, code: 143); subsequent screenshot calls fail with Preview not found for server ....
Evidence (from ~/Library/Logs/Claude/main.log)
[Preview] Server ready (HTTP responding) { serverId: '...' }
[PreviewContext] Load failed, retry { ... }
[PreviewContext] Blocked navigation to { url: 'http://localhost:8775/the-crisis/westminster.html' }
[Preview] Timeout waiting for load { serverId: '...' }
[Preview] Process exited { serverId: '...', code: 143 }
[Preview] capturePreviewScreenshot failed:
PreviewError: Preview not found for server ...
at Object.capturePreviewScreenshot (/Applications/Claude.app/Contents/Resources/app.asar/.vite/build/index.js:2582:6617)
The Preview MCP itself is healthy — it spawns processes and the server responds on its port. The failure is at the PreviewContext navigation-allowlist layer: it is rejecting URLs whose host is localhost. Both user-visible symptoms (clicked-link block, failed screenshots) trace back to this single check.
Hypothesis
Regression in PreviewContext's navigation allowlist in build 1.6608.0 — possibly a stricter URL parse that no longer recognises localhost as a permitted host, or a check that runs before the allowlist resolves the host.
Impact
Blocks all in-app visual-review flows (frontend-design and similar skills cannot capture screenshots), and breaks the click-to-preview affordance for any localhost link an agent surfaces. Workaround for clicked links is opening them in Safari; there is no user-side workaround for the screenshot pipeline.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗