Skip to content

Compose alternate-result filters with typed server handlers#1718

Open
onatozmenn wants to merge 1 commit into
modelcontextprotocol:mainfrom
onatozmenn:feat/composable-server-extensions
Open

Compose alternate-result filters with typed server handlers#1718
onatozmenn wants to merge 1 commit into
modelcontextprotocol:mainfrom
onatozmenn:feat/composable-server-extensions

Conversation

@onatozmenn

@onatozmenn onatozmenn commented Jul 20, 2026

Copy link
Copy Markdown

Alternate-result handlers currently replace the normal typed server pipeline. For Tasks, that means enabling task support can bypass ordinary tool filters such as validation, telemetry, and ASP.NET authorization.

This PR lets extension-owned alternate results wrap the existing pipeline instead:

  • Adds an experimental, method-keyed AddAlternateResultFilter API.
  • Moves Tasks to that API and runs ordinary filters once, before the tool body, with MatchedPrimitive set.
  • Gives background task execution its own async DI scope so scoped filters and tool dependencies stay alive.
  • Keeps CallToolWithAlternateHandler as the explicit replacement API and reports incompatible registrations at startup.

This covers the alternate-result composition part of #1704. Custom RPC registration and subscription grants remain follow-up work.

How Has This Been Tested?

  • Full solution build for netstandard2.0, net8.0, net9.0, and net10.0: no warnings or errors.
  • Core net10 suite: 2,296 passed, 5 skipped.
  • ASP.NET net10 suite (excluding external conformance/OAuth fixtures): 284 passed, 30 skipped.
  • Focused alternate/filter/task tests: 73 passed on net10 and 13 passed on both net8 and net9.
  • Tasks + authorization integration: 2 passed on each of net8, net9, and net10.
  • dotnet format whitespace --verify-no-changes and git diff --check pass.

Breaking Changes

No stable API break. The new API is experimental. Registering both an explicit CallToolWithAlternateHandler and a method-keyed alternate-result filter now fails at startup because the explicit handler is a full replacement.

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

Tasks is the first consumer, using tools/call. Tests also cover prompts/get and prompts/list to make sure the registration is not tool-specific.

Signed-off-by: onatozmenn <onatozmen44@gmail.com>
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