Skip to content

Conversation

@ahammednibras8
Copy link

This PR implements a request-lifecycle middleware system for McpServer (fixes
#1238), enabling cross-cutting concerns (logging, authentication, error
handling) to be applied consistently across all Tools, Resources, and Prompts
using a standard "Onion Model".

Motivation and Context

Currently, developers must manually wrap every single tool handler to add logic
like logging or auth checks. This is repetitive and prone to security errors
(forgetting one handler).

This change introduces server.use(), allowing centralized middleware
registration that applies to the entire server lifecycle. It solves the need for
reliable, cross-cutting logic execution without boilerplate.

How Has This Been Tested?

  • Automated Tests: Added packages/server/test/server/mcpServer.test.ts
    covering:
    • Execution Order (FIFO)
    • Short-circuiting (Auth patterns)
    • Error propagation (Upstream & Downstream)
    • Async timing & Double-next safety
  • Manual Verification: Created an LLM-connected battle test server to verify
    real-time logging middleware.
  • Regressions: pnpm test passed (348 tests) and pnpm typecheck passed
    (strict typing).

Breaking Changes

No. This is a strictly additive change.

  • Existing code continues to work exactly as before (Zero-Behavior Default).
  • The internal _executeRequest path is optimized to have negligible overhead
    if no middleware is registered.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to
    change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Design Decision: server.use() freezes the middleware stack upon server
connection (start). This prevents race conditions where middleware might be
added mid-request, ensuring deterministic behavior.

Example Usage:

server.use(async (context, next) => {
  console.log(`[${Date.now()}] ${context.request.method}`);
  try {
    await next(); // Execute next middleware/handler
  } catch (err) {
    console.error("Error intercepted:", err);
    throw err;
  }
});

@ahammednibras8 ahammednibras8 requested a review from a team as a code owner December 28, 2025 14:49
@changeset-bot
Copy link

changeset-bot bot commented Dec 28, 2025

⚠️ No Changeset found

Latest commit: 3890516

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 28, 2025

Open in StackBlitz

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1345
npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1345

commit: 3890516

@ahammednibras8 ahammednibras8 changed the title Feature/1238 mcp server middleware Middleware Support for McpServer (Fixes #1238) Dec 28, 2025
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