Mirror of https://github.com/modelcontextprotocol/experimental-ext-variants — Status: Experimental. This repository provides a multi-language reference implementation of the variants proposal for the Model Context Protocol (MCP), as described in SEP-2053.
  • Go 98.6%
  • Python 0.6%
  • TypeScript 0.6%
  • JavaScript 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Steven Chen e5e8f117e8
variants: redirect inner server sending methods to fix dropping notifications in stateless mode (#7)
Registers a sending middleware on each inner server that intercepts all
outgoing messages and routes them through the front session using a
session-swapped request wrapper. Replaces the previous proxy client
handler approach which dropped log messages in stateless mode.

## Motivation and Context
Tool handlers in variant servers use req.Session (the inner session) to
send notifications. Previously, log messages were silently dropped in
stateless mode because the inner session is not aware of the front
session.
This change injects the sendingMethodHandler from the frontSession into
the context and adds a sending middleware to redirect all sending
requests to the frontSession handler directly.
A few considerations in this implementation:
* Having frontSession in the context allows notifications to be sent to
the correct frontSession, when the same backend session could be used by
multiple front sessions.
* This solution will work for synchronous notifications that happen
within the same context (progress, log, sampling, elicitation) but not
working for asynchronous notifications (tool list changed, resource
updated etc), because asynchronous notifications are sent with a new
context.
* All the operations before the sending method will still happen in the
backend. Most notable impact is in stateless mode, requests from one
client could change the log level for other clients. For this reason, I
default the logging level to debug for now.
* This implementation relies on the MCP Go SDK sendingMethodHandler
taking a generic `Request` not one that tied to specific function. Based
on the current SDK implementation this is unlikely to change.
* The same generic method forwarding mechanism could work for receiving
methods too, but with some caveat. That can be addressed in separate PR.

## How Has This Been Tested?
TestNotificationDelivery — verifies progress and log messages arrive at
the front clients with multiple clients making concurrent request.

New tests added for context preservation that was added in
https://github.com/modelcontextprotocol/experimental-ext-variants/pull/6.
Context preservation is required to make the notification forwarding
work anyway. Since we use the context to carry frontSession handler to
the backend session.

All existing tests pass

## Breaking Changes
None. Tool handlers continue to use req.Session normally.

## Types of changes
Bug fix (non-breaking change which fixes an issue)
2026-03-23 15:39:57 +00:00
.github/workflows Merge pull request #1 from modelcontextprotocol/chore/scaffolding 2026-01-27 20:10:28 +00:00
conformance Merge pull request #1 from modelcontextprotocol/chore/scaffolding 2026-01-27 20:10:28 +00:00
go/sdk variants: redirect inner server sending methods to fix dropping notifications in stateless mode (#7) 2026-03-23 15:39:57 +00:00
python/sdk Merge pull request #1 from modelcontextprotocol/chore/scaffolding 2026-01-27 20:10:28 +00:00
typescript/sdk Merge pull request #1 from modelcontextprotocol/chore/scaffolding 2026-01-27 20:10:28 +00:00
.gitignore Merge pull request #1 from modelcontextprotocol/chore/scaffolding 2026-01-27 20:10:28 +00:00
LICENSE Initial commit 2026-01-26 10:54:20 +00:00
README.md Add example servers for SEP-2053 variant patterns (#4) 2026-03-01 12:42:43 +05:30

MCP Variants (Experimental Extension)

Status: Experimental. This work is for prototyping and feedback only, and is not an accepted or official MCP extension.

This repository provides a multi-language reference implementation of the variants proposal for the Model Context Protocol (MCP), as described in SEP-2053.

Implementations

Language Directory Package Status
Go go/sdk/ github.com/modelcontextprotocol/experimental-ext-variants/go/sdk Planned
Python python/sdk/ mcp-ext-variants Planned
TypeScript typescript/sdk/ @ext-modelcontextprotocol/variants Planned

Examples (Go)

The Go implementation includes runnable example servers under go/sdk/examples/server/:

model-optimized/

Same tools, different descriptions per LLM family.

https://github.com/user-attachments/assets/5bb60cd2-291f-4940-abfe-f53852d35470

github/

Different tool sets per variant with custom ranking.

https://github.com/user-attachments/assets/d770ac55-e988-4d89-bdf8-bcb3cf1e2e53

research/

Context budget management via description verbosity.

trading/

API versioning, lifecycle statuses, and deprecation info.

variants-stdio/

Minimal single-variant setup.

CI/CD

This monorepo uses path-based CI workflows to efficiently test only what changes:

How It Works

  1. Language-specific workflows (python.yml, go.yml, typescript.yml)

    • Only trigger when their language directory or workflow file changes
    • Run all tests, linting, and checks for that language
  2. Status check workflow (status-check.yml)

    • Runs on every PR to verify required checks passed
    • Determines what needs to pass based on which files changed
    • This is the only required check in branch protection

Examples

  • Change python/sdk/file.py → Only Python CI runs → PR requires Python checks to pass
  • Change both Go and TypeScript files → Both CIs run → PR requires both to pass
  • Change only README.md → No language CIs run → PR can merge immediately

Forcing All Checks

To run all language checks regardless of changed files:

  • In a PR: Comment /test all (only works for repo owners/members/collaborators)
  • Manually: Use GitHub Actions UI or CLI to trigger individual workflows

Adding New Required Checks

  1. Add your check to the appropriate language workflow (e.g., python.yml):

    python-security-scan:
      name: "Security Scan"
      runs-on: ubuntu-latest
      steps:
        - name: Run security checks
          run: # your commands here
    
  2. Update the status check in .github/workflows/status-check.yml:

    const requiredChecks = {
      python: [
        'Python CI / Linting',
        'Python CI / Unit Tests (3.10)',
        // ... existing checks ...
        'Python CI / Security Scan'  // ← Add your new check
      ],
    
  3. Submit PR - Your new check is now required for all relevant changes!

License

Apache License 2.0 - See LICENSE file for details

Resources