mcp-go. Both serve Streamable HTTP, and both are resource servers — they verify a bearer token but do not implement an OAuth authorization server or dynamic client registration. That’s the defining fact for MCP Manager: with Go you connect via the token-in-header or pre-registration modes, with any DCR handled by a separate authorization server. This page covers that path; the frameworks’ own docs are authoritative.
Start with Building Your Own MCP
Server
for the requirements and the auth-mode
decision tree. This page is the Go
layer on top.
Serve Streamable HTTP
Both frameworks expose Streamable HTTP as anhttp.Handler:
- Official Go SDK:
mcp.NewStreamableHTTPHandler(getServer, opts)returns a handler serving a single MCP endpoint. See the repo and theauthpackage. - mcp-go:
server.NewStreamableHTTPServer(mcpServer, server.WithEndpointPath("/mcp")), with options likeWithStatefulandWithStreamableHTTPCORS. See the repo.
Illustrative — see the framework docs
Authenticate as a resource server
Neither framework issues tokens or registers clients — they validate tokens an external authorization server issued, and advertise that authorization server through RFC 9728 metadata.- Official Go SDK: wrap your handler with
auth.RequireBearerToken(verifier, opts)(it returns401with aWWW-Authenticatepointing at your metadata) and serveauth.ProtectedResourceMetadataHandler(...). - mcp-go: serve
server.NewProtectedResourceMetadataHandler(...)at/.well-known/oauth-protected-resource; do token validation in your own middleware.
| You want | How, in Go |
|---|---|
| Token in a header | Validate an API key / bearer token in middleware. Simplest; one shared identity unless you scope tokens per user |
| OAuth pre-registration | Run an external authorization server (your IdP), advertise it via RFC 9728, and give MCP Manager a Client ID + Secret for it |
/register endpoint to expose. If you need DCR, put a DCR-capable authorization server in front and let the Go server validate its tokens.
MCP Manager compatibility checklist
Streamable HTTP at a fixed path
Serve
NewStreamableHTTPHandler (Go
SDK) or NewStreamableHTTPServer
(mcp-go) at a stable path; not an
SSE-only endpoint.Stateless or sticky on multi-instance
Stateful sessions live in process
memory — run stateless or enable
sticky sessions behind a load
balancer.
Choose token or pre-registration
Validate a header token (simplest),
or stand up an external
authorization server and connect MCP
Manager with pre-registration.
Go gotchas
No dynamic client registration
No dynamic client registration
Neither framework can be an authorization server, so DCR must live elsewhere. Don’t expect MCP Manager’s automatic OAuth path to find a
registration_endpoint on the Go server itself — use token or pre-registration. See the auth modes.Sessions held in memory
Sessions held in memory
Stateful Streamable HTTP sessions are
per-process. Behind a load balancer
without sticky routing, follow-up
requests can miss their session — run
stateless or pin sessions.
Audience must match your public URL
Audience must match your public URL
Your token verifier should validate the audience against your canonical public URL (no trailing slash), or valid tokens get rejected with
401.Further reading
Official Go SDK
The Streamable HTTP handler and the
auth package for bearer verification.mcp-go
The community framework, its
Streamable HTTP server, and
protected-resource metadata.
Authentication & Identity
MCP Manager’s token-in-header and
pre-registration modes in depth.
Building Your Own MCP Server
The cross-framework requirements, decision tree, and troubleshooting catalog.
.png?fit=max&auto=format&n=gKqTvJPtsRi2bLNx&q=85&s=8abbce3efb590630de2102c43d32aadf)
.png?fit=max&auto=format&n=Dy9YsIECUbR9JZiT&q=85&s=a1f404cd7f7aeb1727c89d81137ae1ac)