Files
PaperClipAI/server
DottaandClaude Opus 5 0aaf6ddbea fix(server): harden the pinned remote MCP transport's failure paths
Pinning to `approved[0]` alone dropped the failover `fetch` gave a
multi-homed host, so one dead A record took the whole connection down.
Walk the approved addresses in resolution order instead — but only for
addresses that are unreachable. A peer that answers from an unapproved
address is the rebinding defence firing, not a reachability problem, so
it still fails closed on the first try rather than being retried past.

Also close the gaps the response deadline left behind:

- a connect timeout used to leak the half-open socket, since nothing
  above that point owned it yet;
- both deadlines threw bare `Error`s, so callers that switch on the
  guard's error codes saw a timeout as an unclassified failure — they
  now carry `remote_http_response_timeout`;
- a finished response left an armed socket timer behind; and
- the default deadline drops from undici's 300 s to 30 s, which is
  already generous for metadata discovery, a token exchange or a
  JSON-RPC round trip. `tools/call` owns a caller-set budget an operator
  can raise to 60 s, so it passes `responseTimeoutMs` explicitly rather
  than being truncated by the tighter default.

Covers each with a regression test, including a peer that dribbles
header bytes forever — the case that rules out `req.setTimeout`, whose
idle clock such a peer can reset indefinitely.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 21:20:02 +00:00
..