Skip to content

refactor: Extract shared remote MCP tool-call helper - #1291

Open
MQ37 wants to merge 7 commits into
masterfrom
refactor/dedupe-remote-mcp-call
Open

refactor: Extract shared remote MCP tool-call helper#1291
MQ37 wants to merge 7 commits into
masterfrom
refactor/dedupe-remote-mcp-call

Conversation

@MQ37

@MQ37 MQ37 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

What

Extracts withRemoteMcpClient() into src/mcp/remote_tool_call.ts: connect, hand the live client to a caller-supplied run(client) callback, always close, return a closed outcome union (connect-failed / aborted / error / success). Replaces duplicated connect/callTool/close try-catch-finally (including the same abort-race macrotask-yield workaround) in tool_dispatch.ts's ACTOR_MCP case and call_actor.ts's MCP passthrough. Each caller keeps its own callTool shape and response handling.

Why

Two copies of a non-obvious workaround drift the moment one is fixed and the other isn't.

One incidental behavior delta: the ACTOR_MCP _meta.progressToken gate now checks progressToken != null (previously only checked shouldForwardNotifications). Old code sent _meta: {} on the wire when a sync call had no progress token; new code omits _meta entirely. Same semantics for any spec-conformant server, confirmed via the SDK's request/serialization path.

Testing

pnpm run type-check / lint / format / check:agents clean. pnpm run test:unit: 97 files, 1457 passed, 1 skipped — includes 2 new tests for call_actor.ts's connect-failed/error outcomes.

connectMCPClient -> callTool -> close was duplicated in tool_dispatch.ts's
ACTOR_MCP case and call_actor.ts's MCP passthrough, including a copy-pasted
comment for an abort-race workaround. Extracted callRemoteMcpTool() into a
new src/mcp/remote_tool_call.ts (kept out of client.ts on purpose: tests
mock connectMCPClient via vi.spyOn on that module's namespace, which only
intercepts a genuine cross-module import, not a same-module direct call).

Pure refactor, no behavior change. Verified: type-check, lint, format,
check:agents clean; full unit suite green (96 files, 1415 passed, 1 skipped).
@github-actions github-actions Bot added the t-ai Issues owned by the AI team. label Aug 20, 2026
MQ37 added 2 commits August 20, 2026 15:46
Two JSDoc blocks in remote_tool_call.ts were multi-sentence where one
sufficed; tightened both and the matching AGENTS.md entry. No logic change.
…hrough outcomes

Verification (subagent) found two real gaps:

- tool_dispatch.ts's ACTOR_MCP case moved the 'Calling Actor-MCP' info log
  to fire unconditionally, including on a connect failure. Original code
  only logged it after a successful connect. Moved it into onConnected so
  it (and notification-handler setup) run in the same order and only on
  success, matching pre-extraction behavior exactly.
- call_actor.ts's handleMcpToolCall had no direct test for the
  'connect-failed' or non-abort 'error' outcomes (tool_dispatch.ts's
  ACTOR_MCP case already covered its own). Added both.

pnpm run type-check / lint / format / check:agents clean.
pnpm run test:unit: 96 files, 1417 passed, 1 skipped.
@github-actions github-actions Bot added the tested Temporary label used only programatically for some analytics. label Aug 20, 2026
@MQ37
MQ37 marked this pull request as draft August 20, 2026 14:06
MQ37 added 3 commits August 20, 2026 16:22
callRemoteMcpTool() owned callTool() itself (meta + onConnected hooks for
tool_dispatch.ts's notification forwarding). Replaced with
withRemoteMcpClient(), generic over a caller-supplied run(client) callback
that does the actual callTool — each caller already knows its own tool
name/args, no need for the helper to own that shape too. Net LOC: +76
across the branch vs +80 before (measured, not estimated) — the two are
close because callTool's own shape (schema/timeout/signal) has to live
somewhere; pushing it back to callers costs almost exactly what
centralizing it saved. Kept mainly for the simpler, symmetric interface
(one callback for both callers, no special-cased meta/onConnected split).

pnpm run type-check / lint / format / check:agents clean.
pnpm run test:unit: 96 files, 1417 passed, 1 skipped (unchanged).
@MQ37
MQ37 marked this pull request as ready for review August 21, 2026 09:35
@MQ37
MQ37 requested a review from jirispilka August 21, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants