mcp-remote-auth-example
mcp-remote-auth-example
A minimal remote (Streamable HTTP) MCP server that is an OAuth 2.1 resource server — the shape the MCP authorization spec requires for remote servers. It shows the only auth code you actually own on your server:
Publishes Protected Resource Metadata at
/.well-known/oauth-protected-resource(RFC 9728).Rejects unauthenticated requests with
401+ aWWW-Authenticateheader pointing at that metadata (the discovery entry point).Validates every access token: signature, issuer, expiry, and audience (RFC 8707) — the check most walkthroughs skip.
You do not run your own OAuth server. In production you delete the local dev issuer and point the metadata at your IdP (Auth0, Okta, Keycloak, WorkOS, Entra). The dev issuer here exists only so the whole flow runs on your machine in one command.
Pinned to @modelcontextprotocol/sdk@1.29.0, TypeScript 5.9, jose 6.
One-command run
npm install
npm run demonpm run demo boots the server and walks the four wire behaviors, printing the real request/response for each:
Unauthenticated
POST /mcp→401+WWW-Authenticatereferencing the PRM URL.GET /.well-known/oauth-protected-resource→ the RFC 9728 document.A correctly audience-bound token →
initialize+tools/list+tools/call whoamisucceed.A token minted for a different resource →
401 invalid_token(the RFC 8707 audience check doing its job).
Tests
npm testSix guard tests cover the same behaviors plus expired and malformed tokens.
What's yours vs. what's the dev stand-in
File | Role | Keep in production? |
| The resource-server guard: PRM doc + token validation + audience check. | Yes — this is the code you own. |
| Remote MCP server (Streamable HTTP) with the guard in front. | Yes. |
| A tiny local dev authorization server so the demo runs offline. | No — delete and use your IdP. |
|
| Yes — set from env. |
Going to production
Delete
src/issuer.tsand the/jwksroute.Set
OAUTH_ISSUERto your IdP's issuer URL andMCP_RESOURCEto your server's public canonical URI.Your IdP already serves its own JWKS from its metadata;
src/auth.tsverifies against it unchanged.
License
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/unprototyped/mcp-remote-auth-example'
If you have feedback or need assistance with the MCP directory API, please join our Discord server