Chrome MCP: Extension doesn't reconnect after native messaging host disconnect
Description
The Claude Chrome extension (v1.0.47) does not attempt to reconnect when the native messaging host disconnects. Once the connection drops — which happens silently during normal usage (sleep/wake, process restart, etc.) — the MCP tools stop working entirely. The only fix is to manually close and reopen the browser tab group or restart Chrome.
This is a significant reliability issue for long-running Claude Code sessions that use browser automation via MCP.
Steps to Reproduce
- Start a Claude Code session with Chrome MCP tools (
mcp__claude-in-chrome__*) - Use browser automation normally (navigate, screenshot, click, etc.)
- Wait for native host disconnect (triggers on macOS sleep/wake, or kill/restart the
chrome-native-hostprocess) - Attempt any MCP tool call — it fails silently or returns an error
- Extension shows no indication that it's disconnected and makes no attempt to reconnect
Expected Behavior
The extension should automatically attempt to reconnect to the native messaging host with exponential backoff, similar to how WebSocket clients handle disconnects. A periodic health check should also detect silent disconnects.
Actual Behavior
The onDisconnect handler in the service worker clears internal state (port = null, connected = false) but never calls the connection function again. The connection remains broken until the user manually intervenes.
Workaround
I patched the extension's service worker to add:
- Auto-reconnect with exponential backoff on
port.onDisconnect:
- Delays: 3s → 6s → 12s → 24s → ... → 60s max
- Resets attempt counter on successful reconnect
- Skips reconnect if error is "native messaging host not found" (not installed)
- 30-second health check interval to catch silent disconnects:
- If
port === nulland native host is known to be installed, attempt reconnect - Runs independently of the disconnect handler
Example pattern (simplified from the minified service worker):
// On disconnect — add reconnect with exponential backoff
port.onDisconnect.addListener(() => {
const error = chrome.runtime.lastError?.message;
port = null;
connected = false;
// Don't retry if host isn't installed
if (error?.includes("native messaging host not found")) return;
const attempt = self.__reconnectAttempt || 0;
self.__reconnectAttempt = attempt + 1;
const delay = Math.min(3000 * Math.pow(2, attempt), 60000);
setTimeout(() => {
connectToNativeHost().then(success => {
if (success) self.__reconnectAttempt = 0;
});
}, delay);
});
// Health check — catch silent disconnects
setInterval(() => {
if (!port && nativeHostInstalled) {
connectToNativeHost();
}
}, 30000);
Environment
- macOS 15.3 (Darwin 25.2.0)
- Chrome (latest)
- Claude Chrome Extension v1.0.47
- Claude Code CLI (latest)
Additional Context
A secondary issue we encountered (now resolved) was a native messaging host conflict between Claude Desktop and Claude Code. Both registered host configs in ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/:
com.anthropic.claude_browser_extension.json→ Claude Desktopcom.anthropic.claude_code_browser_extension.json→ Claude Code
The extension tried Desktop's host first, and when it failed (Desktop wasn't running), the connection broke with no fallback. Renaming Desktop's config to .bak resolved this. It appears the naming has since been separated, but users who installed both products before the fix may still have stale configs causing conflicts.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗