## Summary
`unionCapabilities` merges `Experimental` map entries from inner variant
servers but skips the `Extensions` field entirely. This means any
extension registered via `ServerCapabilities.AddExtension()` on an inner
server (e.g. `io.modelcontextprotocol/skills`) is silently dropped from
the front proxy's `InitializeResult`.
- Add the same first-wins merge logic for `Extensions` that already
exists for `Experimental`
- Bump `go-sdk` to v1.4.1 which introduced the `Extensions` field on
`ServerCapabilities`
- Add unit test for `unionCapabilities` extensions merging
- Add integration test verifying extensions survive the variant path
end-to-end
## Test plan
- [x] `TestUnionCapabilities_MergesExtensions` — verifies first-wins
merge semantics for extensions
- [x] `TestIntegration_ExtensionsAdvertised` — verifies extensions
registered on inner servers appear in the client's `InitializeResult`
- [x] All existing tests pass (27/27)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Builds on the types and architecture from the previous PR to deliver a
working variant-aware MCP
server that routes requests to inner mcp.Server instances based on
per-request _meta variant selection,
enabling a single MCP endpoint to serve multiple tool/resource/prompt
variants simultaneously.
```go
// Create standard mcp.Server instances — one per variant
codeReviewServer := mcp.NewServer(&mcp.Implementation{Name:
"devplatform", Version: "v1.0.0"}, nil)
mcp.AddTool(codeReviewServer, &mcp.Tool{Name: "list_pull_requests",
...}, handler)
mcp.AddTool(codeReviewServer, &mcp.Tool{Name: "get_diff", ...}, handler)
pmServer := mcp.NewServer(&mcp.Implementation{Name: "devplatform",
Version: "v1.0.0"}, nil)
mcp.AddTool(pmServer, &mcp.Tool{Name: "list_issues", ...}, handler)
mcp.AddTool(pmServer, &mcp.Tool{Name: "create_issue", ...}, handler)
// Register them as variants on a single server
vs := variants.NewServer(&mcp.Implementation{Name: "devplatform",
Version: "v1.0.0"}).
WithVariant(variants.ServerVariant{
ID: "code-review",
Description: "PR and code review operations",
Status: variants.Stable,
}, codeReviewServer, 0).
WithVariant(variants.ServerVariant{
ID: "project-management",
Description: "Issue and project tracking operations",
Status: variants.Stable,
}, pmServer, 1)
// Future: register variants backed by remote MCP servers
// WithHTTPVariant(v, mcpServer, priority) — variant backed by an
mcp.Server exposed over HTTP
// WithRemoteVariant(v, "https://...", priority) — variant backed by a
remote MCP endpoint
// Serve over HTTP for multiple concurrent clients
handler := variants.NewStreamableHTTPHandler(vs, nil)
http.ListenAndServe(":8080", handler)
// Or serve over stdio for single-client use:
// vs.Run(ctx, &mcp.StdioTransport{})
```
Key additions
- Backend abstraction (inMemoryBackend) — creates in-memory transport pairs between the variant server and
inner mcp.Server instances, with notification forwarding for progress and logging events.
- Request dispatcher (dispatch.go) — handles routing for tools/list, tools/call, resources/list,
resources/read, resources/subscribe, prompts/list, prompts/get, and completion/complete methods.
Implements variant-scoped cursor wrapping to correctly paginate across multiple inner servers.
- Session middleware (session.go) — manages per-session inner connections in stateful mode and shared
connections in stateless HTTP mode, ensuring proper lifecycle management.
- Initialize enrichment — injects availableVariants into the server's capabilities response so clients can
discover which variants are available.
- Capability discovery — merges inner server capabilities via union to present a unified capability set to
clients.
- NewStreamableHTTPHandler — provides an HTTP handler for multi-client serving over Streamable HTTP
transport.
- Integration tests (server_test.go, 458 lines) — covers end-to-end variant selection, backward
compatibility (no variant specified), HTTP transport, and stateless modes.
- Examples — stdio-based (examples/server/variants/main.go) and HTTP-based
(examples/server/variants-http/main.go) example servers demonstrating the API.
- README — rewritten with API documentation and architecture diagrams.
TODO (subsequent PRs):
- Unit Testing
- More integration tests
Signed-off-by: Kurt Degiorgio <kdegiorgio@bloomberg.net>
Defines the core types and API for server variants extension, laying
groundwork for multi-variant server implementation. Server.Run() is not
yet implemented but architecture is designed and documented.
- Add Server type with variant registration
- Implement default priority-based ranking
- Define ServerVariant, VariantHints, and related types per SEP spec
- Add comprehensive example demonstrating intended multi-variant usage
- Document implementation plan for Server.Run() dispatch architecture
Next PRs:
- Unit Tests
- Implementation for Server.Run
- Conformance Testing
Signed-off-by: Kurt Degiorgio <kdegiorgio@bloomberg.net>