HTTP + OAuth Server
A Delta-MCP server over Streamable HTTP running as a full OAuth 2.1 resource server: it serves the RFC 9728 PRM document, validates bearer tokens (audience + expiry + signature), and emits spec-compliant WWW-Authenticate challenges.
Self-contained — generates an RSA keypair at boot and verifies RS256 tokens against it, standing in for a real authorization server’s JWKS. Zero external dependencies.
Run
npx tsx examples/http-oauth-server/index.tsThe server prints curl commands for the full discovery dance.
Flow
1. POST /mcp (no token) → 401 WWW-Authenticate: ... resource_metadata=...2. GET /.well-known/oauth-protected-resource → 200 { resource, authorization_servers, ... }3. POST /mcp Authorization: Bearer <valid> → 2004. POST /mcp Authorization: Bearer <wrong aud> → 401 error="invalid_token" (RFC 8707)Production
Replace verifySignature with a JWKS-backed verifier pointed at your real authorization server:
import { createRemoteJWKSet, jwtVerify } from "jose";
const jwks = createRemoteJWKSet( new URL("https://auth.example.com/.well-known/jwks.json"));
server.startHttp({ port: 3000, oauth: { resourceUrl: "https://mcp.example.com", authorizationServers: ["https://auth.example.com"], verifySignature: async (token) => { try { await jwtVerify(token, jwks, { audience: "https://mcp.example.com" }); return true; } catch { return false; } }, },});Delta-MCP still enforces audience + expiry independently; verifySignature adds the cryptographic proof.
See also
- OAuth 2.1 — how it works
- Filesystem server for a simpler HTTP server without auth