`connect_resource` took one resource, so item N+1 was only created after the
model saw item N's answer and called again. Combined with a Person Server that
started a pending's consent clock at creation, a request made while another was
waiting could expire before the person ever saw it — beta 2026-09-11, a Gmail
connect created behind two others was never surfaced and timed out, then
succeeded immediately when retried alone.
The tool now takes a LIST and starts every item inside one call, so the PS
queues them in order and the wallet can show a depth. The remaining budget goes
on polling the items still waiting, head first; each item answers for itself,
and a repeat call with the same items resumes the live pendings instead of
creating a second set. Only the head interaction is surfaced — the PS shows its
queue one at a time.
Native prompts now branch on era AND on what the client declared, which are not
the same gate. On 2026-07-28 an elicitation rides an `input_required` result and
the SDK refuses it with -32021 unless the client declared `elicitation.url`, so
this checks first rather than trading a link for an error. On a 2025-era
connection the SDK rethrows UrlElicitationRequiredError (-32042) with no gate of
its own, and clients that implement -32042 handle it even when they
under-declare — Claude Code 2.1.268 ships the retry loop while declaring a bare
`elicitation:{}`, which is why every connect today degrades to text. Form mode
is not attempted: same gate, and it is not what form mode is for.
New connect-resources.test.ts drives the registered tool through a real
McpServer over InMemoryTransport — the tool handlers had no coverage, and the
smoke test only checked names. It asserts both items are POSTed before the call
answers, that a repeat call does not re-POST, and that a connection-less item
never reaches the PS. 45 passing, typecheck clean.
Claude-Session: https://claude.ai/code/session_01LSCbiJc1MkXpEADe4ywZNf
Co-authored-by: dickhardt <dick.hardt@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>