Claude in Chrome: bridge handler missing tabId type coercion causes all tab-interacting tools to timeout
Bug Description
All Claude in Chrome tools that require a tabId parameter (navigate, read_page, computer, javascript_tool, etc.) timeout after 120 seconds when called from Claude Code CLI. Tools that don't require tabId (tabs_context_mcp, tabs_create_mcp) work correctly (~45ms response time).
Root Cause
The Chrome extension (v1.0.52) has two code paths for receiving tool calls, and only one handles type coercion correctly.
Native messaging handler (service-worker.ts) — WORKS:
const n = a.args?.tabId;
const r = "number" == typeof n ? n : "string" == typeof n && parseInt(n, 10) || void 0;
Bridge handler (mcpPermissions module) — BROKEN:
const u = i.tabId; // raw value from JSON args — arrives as STRING from Claude Code MCP
if (void 0 !== u) try { await chrome.tabs.get(u) } catch { return }
// ^^^^^^^^
// Silent return with no tool_result sent back → 120s timeout on Claude Code side
Claude Code's MCP framework serializes all tool parameters as strings (confirmed in debug logs: "tabId":"1914017989" instead of "tabId":1914017989).
In Manifest V3 strict argument parsing, chrome.tabs.get("1914017989") (string) throws a type error because it expects an integer. The catch { return } silently drops the request without sending any tool_result message back through the bridge, causing Claude Code to wait until the 120-second timeout.
Fix
Add the same type coercion to the bridge handler that already exists in the native messaging handler:
// Before:
const u = i.tabId;
// After:
const u = "number" == typeof i.tabId ? i.tabId : "string" == typeof i.tabId ? parseInt(i.tabId, 10) : void 0;
Also ensure i.tabId is updated with the coerced value before passing to Pr(), so downstream functions like J.getTabForMcp() also receive the correct type.
Environment
- Claude Code v2.1.44
- Chrome extension v1.0.52 (
fcoeoabgfenejglbffodgkkbkcdhcgfn) - Chrome 144.0.7559.135
- macOS Darwin 24.6.0
Steps to Reproduce
- Run
claude --chrome - Connect to Chrome with the Claude extension installed
- Call
tabs_context_mcp→ works (no tabId in args) - Call
navigatewith a valid tabId → 120s timeout (tabId arrives as string)
Debug Log Evidence
[Claude in Chrome] Sending tool_call: navigate (4e2bc4a8)
[120 seconds pass, no bridge response]
[Claude in Chrome] Tool call timeout: navigate (4e2bc4a8) after 120000ms, pending calls: 0
The bridge handler receives the tool_call but chrome.tabs.get(stringTabId) throws, and catch { return } silently drops it.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗