Skip to content

Expose actual inbound-processing completion for reusable transport admission - #3024

Draft
servrox wants to merge 2 commits into
modelcontextprotocol:mainfrom
servrox:codex/inbound-request-lifecycle
Draft

servrox wants to merge 2 commits into
modelcontextprotocol:mainfrom
servrox:codex/inbound-request-lifecycle

Conversation

@servrox

@servrox servrox commented Oct 14, 2026 •

Copy link
Copy Markdown

Transport adapters cannot safely return reusable admission credits from responses or cancellation alone: handlers, response writes and SDK cleanup may still be running. This adds local MessageExtraInfo.onMessageProcessed metadata, preserved through the official stdio entry, and a public stdio capability marker. Completion joins ordinary handlers/writes/controller cleanup, asynchronous inbound-response validation, opening/error paths, and subscription ACK/teardown/started notification deliveries.

Draft proposal for #3020; maintainer acceptance is still pending. The metadata is never serialized and does not attest remote effects or application work outside returned promises. No alternate MCP transport or protocol implementation is introduced.

Validation:

  • Core: 1,533 tests passed. Server: 585 passed; the explicit duration test is skipped in the normal suite.
  • Client: 995 passed; three unchanged stdio fixture cases fail because NixOS has no /usr/bin/tee. No system workaround was installed.
  • A separate 601.56-second run processed successful asynchronous tools in both protocol generations through the official StdioServerTransport framing and Node Writable callbacks, reusing eight IDs only after completion. Controlled in-memory streams do not attest OS pipes or remote delivery. The callback-only correction preserves this ordinary write boundary; four focused actual-source regressions separately cover close, early error, destroyed output and end without drain.
  • Affected core/server/client typechecks and changed-source lint/format passed. Independent read-only lifecycle review findings were corrected and rechecked with no remaining findings in that scope.

Official stdio send now waits for the actual chunk callback even when write() accepts the chunk immediately. Failure and close cannot return an unfinished write credit. Independent review reproduced and closed both missing-event hangs.

The new changeset and documentation describe the local completion boundary. This is a source proposal, not released SDK support or downstream production qualification.

@changeset-bot

changeset-bot Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fdd1ffb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server Minor
@modelcontextprotocol/client Minor
@modelcontextprotocol/codemod Minor
@modelcontextprotocol/core Minor
@modelcontextprotocol/server-legacy Minor
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

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

@pkg-pr-new

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

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@3024

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@3024

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@3024

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@3024

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@3024

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@3024

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@3024

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@3024

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@3024

commit: fdd1ffb

@claude claude Bot added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Oct 15, 2026

@karaaslanz karaaslanz left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Exact-source review of draft HEAD fdd1ffb9baef3d93c996224d164d5b2ebaf4db7f. Found a reproducible post-close write race introduced by async outbound interception.

Location: packages/server/src/server/serveStdio.ts, StdioConnectionChannel.send (approx. lines 184?197). It checks this._closed before await this._outboundIntercept?.(message), but not again afterwards. modernOutboundIntercept is now async, introducing an await boundary even for ordinary responses where interception returns undefined. If the channel is closed/discarded during the await, the continuation still forwards the message to the shared wire after close() finished.

Exact-source reproduction: fetched serveStdio.ts from the PR head (blob 4f6d5fc7928b93269c149d25691428022e82c153), transformed the actual StdioConnectionChannel class with Node 24 TypeScript-strip, instantiated it using a deferred async interceptor and a counting fake wire. Sequence:

  1. Start channel.send({jsonrpc:'2.0', id:7, result:{ok:true}}); interceptor awaits.
  2. await channel.close().
  3. Resolve the interceptor with undefined; then await the pending send.
  4. Observed WIRE_WRITES_AFTER_CLOSE = 1.

No repo files changed. This is a deterministic exact-source isolated test, not a full stdio integration suite.

Narrow fix and regression gate: check this._closed again after awaiting interception, before this._wire.send. Add a deferred-interceptor test that closes the channel between the two steps and verifies zero writes to the shared wire. This prevents discarded connection instances from emitting late messages. I did not review the broader admission-completion design end to end.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants