Skip to content

Release Notes - v0.12.0

Release Date: 2026-08-09

Overview

This release adds a protocol-agnostic external token verifier seam to mcp/oauth2, letting an MCP server run as a pure OAuth resource server against tokens issued by an external authorization server (an enterprise IdP, or an ID-JAG / MCP Enterprise-Managed Authorization deployment) instead of the built-in authorization server. No breaking changes.

Installation

go get github.com/plexusone/omniskill@v0.12.0

Requires Go 1.26+ and MCP Go SDK v1.7.0+.

Highlights

  • External resource-server mode - HTTPServerOptions.ExternalAuth validates externally-issued bearer tokens instead of running a local authorization server
  • Delegation chains - TokenInfo.Actor carries an RFC 8693 act delegation chain (e.g. orchestrator-acting-for-worker) into request context
  • RFC 9728 metadata - protected resource metadata advertises the external authorization servers and the correct WWW-Authenticate challenge on 401s

What's New

External Token Verifier (mcp/oauth2)

TokenVerifier is a small interface that lets any protocol-specific verifier (JWT/JWKS, introspection, etc.) plug into the server without mcp/oauth2 taking on that dependency:

type TokenVerifier interface {
    VerifyToken(ctx context.Context, token string) (*TokenInfo, error)
}

Adapters such as github.com/aistandardsio/agent-protocols/adapters/omniskill supply ID-JAG-aware implementations; a plain function can also be adapted with TokenVerifierFunc.

ExternalBearerMiddleware(verifier, resourceMetadataURL) wraps a handler so that requests are authenticated against the verifier, storing the resulting TokenInfo in context, and unauthenticated/invalid requests get a WWW-Authenticate: Bearer resource_metadata="..." challenge per the MCP authorization spec.

ExternalProtectedResourceMetadataHandler serves RFC 9728 protected resource metadata listing the external authorization servers, mounted at /.well-known/oauth-protected-resource.

Resource-Server Mode on ServeHTTP (mcp/server)

HTTPServerOptions.ExternalAuth runs the server as a pure resource server — only the protected resource metadata endpoint is mounted, no local authorization server endpoints:

rt.ServeHTTP(ctx, &runtime.HTTPServerOptions{
    Addr: ":8080",
    ExternalAuth: &runtime.ExternalAuthOptions{
        Verifier:             myJWTVerifier, // implements oauth2.TokenVerifier
        AuthorizationServers: []string{"https://idp.example.com"},
    },
})

ExternalAuth is mutually exclusive with OAuth and OAuth2; Verifier and AuthorizationServers are required and validated at ServeHTTP call time.

Delegation Chains and Extra Claims (mcp/oauth2)

TokenInfo gains two fields populated by external verifiers:

  • Actor []string - the delegation chain acting on behalf of Subject, outermost actor first (from nested act claims, RFC 8693). Read it from a request with oauth2.GetActorFromContext(ctx).
  • Claims map[string]any - additional claims from the external token, for use in custom policy decisions (e.g. with ToolAuthorizer).

Both are empty/nil for tokens issued by the built-in authorization server.

Dependencies

No dependency changes.

Contributors

  • John Wang
  • Claude Opus 4.8