Align capability key to SEP-2133 extensions format (#25)

Both SDKs now use Capabilities.Extensions with key
"io.modelcontextprotocol/interceptors". Previously C# used the short key
"interceptors" and Go used Capabilities.Experimental. SEP capability
example updated to match.

https://modelcontextprotocol.io/seps/2133-extensions

---------

Signed-off-by: Ukjae Jeong <jeongukjae@gmail.com>
This commit is contained in:
Ukjae Jeong 2026-07-06 10:29:21 +01:00 • committed by GitHub
commit 99bc7c9bb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 19 deletions

View file

@ -24,7 +24,7 @@ Status of this Go SDK implementation against the SEP-2624 interceptor proposal.
| Audit mode | `ModeAudit` records results without blocking; mutated payloads not propagated |
| Timeout & context | Per-interceptor timeouts via `InvokeParams.TimeoutMs`, chain-level context cancellation, `InvocationContext` with principal/traceId |
| Receiving direction (client → server) | All server-side method calls intercepted via `AddReceivingMiddleware` |
| Capability declaration | Interceptor metadata injected into `initialize` response via `Capabilities.Experimental` |
| Capability declaration | Interceptor metadata injected into `initialize` response via `Capabilities.Extensions` |
| First-party (in-process) deployment | `Server.LocalChain()` creates an in-memory transport `chain.Chain`; interceptors invoked via JSON-RPC even in-process |
| Third-party and hybrid deployment | Chain entries can point to any `*mcp.ClientSession` — local (in-memory), stdio, or HTTP transport |
| `json.RawMessage` payloads | Interceptor handlers receive `json.RawMessage` via `interceptor/invoke`, matching the SEP's JSON-level payload model |

View file

@ -50,7 +50,7 @@ behavior as remote interceptor servers.
During initialization, a lightweight middleware intercepts the `"initialize"`
response and injects interceptor metadata into
`Capabilities.Experimental["io.modelcontextprotocol/interceptors"]`. This
`Capabilities.Extensions["io.modelcontextprotocol/interceptors"]`. This
follows the same pattern as the variants extension
(`io.modelcontextprotocol/server-variants`).

View file

@ -15,7 +15,7 @@ import (
"github.com/modelcontextprotocol/ext-interceptors/go/sdk/interceptors/chain"
)
// extensionID is the capability key used in Capabilities.Experimental
// extensionID is the capability key used in Capabilities.Extensions
const extensionID = "io.modelcontextprotocol/interceptors"
// Option configures an Extension.
@ -163,8 +163,7 @@ func (e *Extension) initMiddleware() mcp.Middleware {
// enrichInitResult injects interceptor capability metadata into the
// InitializeResult, following the same pattern as the variants extension.
// The capability is declared under Capabilities.Experimental so it works
// without upstream go-sdk changes.
// The capability is declared under Capabilities.Extensions per SEP-2133.
func (e *Extension) enrichInitResult(result mcp.Result) (mcp.Result, error) {
initResult, ok := result.(*mcp.InitializeResult)
if !ok {
@ -174,8 +173,8 @@ func (e *Extension) enrichInitResult(result mcp.Result) (mcp.Result, error) {
if initResult.Capabilities == nil {
initResult.Capabilities = &mcp.ServerCapabilities{}
}
if initResult.Capabilities.Experimental == nil {
initResult.Capabilities.Experimental = make(map[string]any)
if initResult.Capabilities.Extensions == nil {
initResult.Capabilities.Extensions = make(map[string]any)
}
all := e.getInterceptors()
@ -193,7 +192,7 @@ func (e *Extension) enrichInitResult(result mcp.Result) (mcp.Result, error) {
events = append(events, ev)
}
initResult.Capabilities.Experimental[extensionID] = map[string]any{
initResult.Capabilities.Extensions[extensionID] = map[string]any{
"supportedEvents": events,
}