Claude Preview MCP: Add preview_navigate tool to fix unreliable page navigation

Resolved 💬 2 comments Opened Mar 7, 2026 by cricker-synamedia Closed Apr 5, 2026

Problem

When the preview dev server restarts (via preview_stop + preview_start), the browser tab loses its connection and lands on chrome-error://chromewebdata/. There is no reliable way to navigate the tab back to the dev server URL.

The current workaround is using preview_eval to run window.location.href = 'http://localhost:...' on the chrome-error page, but this is unreliable because:

  1. JS execution on chrome-error:// is restricted - window.location assignments sometimes work but often the page context resets between calls
  2. Race conditions - subsequent preview_eval calls frequently find the page has reverted to chrome-error:// because the navigation had not completed
  3. DOM queries fail silently - document.querySelectorAll('select') returns results in one call, then returns empty in the next because the page context was lost mid-navigation

This makes the preview workflow fragile. A typical recovery sequence requires 3-5 attempts of preview_eval + preview_screenshot before the page stabilizes.

Proposed Solution

Add a preview_navigate tool that uses the browser's native navigation API (e.g., Playwright's page.goto() or CDP's Page.navigate) rather than injecting JS into the current page context.

preview_navigate(serverId: string, url?: string)
  • url defaults to the server's localhost URL if omitted
  • Uses native browser navigation, not JS eval
  • Waits for the page to reach a loaded state before returning

This would complement the existing preview_eval tool, which is great for in-page debugging but not suited for navigation from error states.

Current Workaround

  • Avoid preview_stop when possible (rely on preview_start reusing running servers)
  • Use window.location.replace() via preview_eval and take a preview_screenshot between every eval call to force a render wait
  • Retry navigation multiple times until it sticks

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗