Retries browser and Linear MCP tool calls twice when the connection dropped before the call ran.

hooks/register.ts 39 lines1import type { Register } from 'claude-code'
2
3const RETRIES = 2
4const PAUSE_MS = 1500
5
6const FLAKY = /^mcp__(claude-in-chrome|Claude_Browser|claude_ai_Linear|plugin_linear_linear)__/
7
8// Only errors that mean the call never reached the tool: a retry cannot repeat a write.
9const DROPPED =
10 /not connected|ECONNREFUSED|socket hang up|connection (closed|refused)|extension (is not|not|was) (connected|running|available)|no (browser|extension) (connected|available)|MCP error -32000/i
11
12export const register: Register = on => {
13 on('tool.call', async ($, e, next) => {
14 const tool = String(e.tool)
15 let ran = await next(e)
16
17 if (!FLAKY.test(tool)) {
18 return ran
19 }
20
21 for (let attempt = 1; attempt <= RETRIES; attempt += 1) {
22 const hasDropped = ran.deny === undefined && ran.isError === true && DROPPED.test(ran.text ?? '')
23
24 if (!hasDropped || next.signal.aborted) {
25 return ran
26 }
27
28 await $.clock.sleep(PAUSE_MS)
29 ran = await next(e)
30
31 if (ran.deny === undefined && ran.isError !== true) {
32 $.ui.toast(`retry-flaky: ${tool.split('__')[1]} recovered on retry ${attempt}`)
33 }
34 }
35
36 return ran
37 })
38}
39