Skip to content

refactor(mcp): split MCPClientManager into a thin facade and three controllers - #2759

Closed
mattzcarey wants to merge 1 commit into
fix/mcp-reauth-holesfrom
refactor/mcp-client-controllers
Closed

mattzcarey wants to merge 1 commit into
fix/mcp-reauth-holesfrom
refactor/mcp-client-controllers

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

MCPClientManager is now a thin facade over three controllers, with no behaviour change. It was a 2,600-line class holding every decision; now it holds the public API and the Lifecycle hooks and delegates each call to the module that owns that kind of decision. index.ts only re-exports.

Stacked on #2758, part of the work on #2658. Every review on this stack found its bugs in the gaps between methods of that one class: a failure path that forgot to record, a link shown again after being redeemed, an addMcpServer() that undid a recorded failure. With each kind of decision in one file, those gaps are easy to see. Dependencies point one way, top to bottom:

File Owns
manager.ts Public API and Lifecycle hooks (onStart, onRequest, onJob)
servers.ts Each server's life: register, connect, discover, restore, settle, reconnect, close, remove, migrate. afterFailure is the one place that decides retry or stop.
authorization.ts Links and OAuth: entering authenticating (round limit, spent links), callbacks, request recovery, link expiry, provider creation
status.ts The transitions both share: stop with a recorded failure, ready, save the session
jobs.ts The durable connect and auth-expiry jobs and the reconnect policy. It schedules, moves and cancels, and decides nothing.
elicitation.ts, legacy-connect.ts, types.ts, context.ts Elicitation handlers, the deprecated connect(), the public types, and the one context object the controllers share

Other changes:

  • three copies of the OAuth provider setup (register, restore, rebuilding from a stored row) are one createProvider()
  • reconnect-policy.ts is folded into jobs.ts
  • types and constants the stack exported but only used internally are no longer exported
  • servers.ts reaches connectToServer() and discoverIfConnected() through the manager, so subclass overrides and test spies still see internal calls
  • one test that built a manager with Object.create(MCPClientManager.prototype) now constructs a real one

The generated .d.ts for agents/mcp/client exports the same names, and MCPClientManager has the same public members. pnpm run check and the full agents suite (4,614 tests) pass unchanged, including the MCP integration tests.


Devin Review

@changeset-bot

changeset-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: c5edcb9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@agent-think

agent-think Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

✅ agents import sizes: no significant changes (9f933622 → c5edcb97, workflow run)

@pkg-pr-new

pkg-pr-new Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2759

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2759

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2759

hono-agents

npm i https://pkg.pr.new/hono-agents@2759

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2759

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2759

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2759

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2759

commit: c5edcb9

@mattzcarey
mattzcarey force-pushed the refactor/mcp-client-controllers branch from 0daff73 to a3a7e91 Compare October 29, 2026 11:52
devin-ai-integration[bot]

This comment was marked as resolved.

@mattzcarey
mattzcarey added this pull request to stack #2750 October 29, 2026 18:57
@mattzcarey
mattzcarey force-pushed the refactor/mcp-client-controllers branch from a3a7e91 to f822df1 Compare October 29, 2026 18:58
…ntrollers

MCPClientManager was a 2,600-line class holding every decision. It is now
the public API and the Lifecycle hooks only, delegating to:

- servers.ts: each server's connection life, with afterFailure as the one
  place that decides retry or stop
- authorization.ts: links, OAuth callbacks, request recovery, link expiry,
  provider creation (one createProvider instead of three copies)
- jobs.ts: the durable jobs and reconnect policy (reconnect-policy.ts folded
  in); schedules, moves and cancels, decides nothing
- status.ts: the shared stop / ready / save-session transitions

Dependencies point one way. The public exports and MCPClientManager's public
members are unchanged; index.ts only re-exports. Unused exports in the stack's
modules are no longer exported.
@mattzcarey

Copy link
Copy Markdown
Member Author

Replaced by #2782 (MCP client changes) and #2783 (examples).

@mattzcarey mattzcarey closed this Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant