Move to remote HTTP safely

Authenticate and authorize requests

Protect a remote server by validating who sent a token, who it is for, when it expires, and what it permits.

8 minute lesson

~~~

Authentication establishes who the caller is. Authorization decides what that caller may do.

For remote HTTP, an MCP server acts as an OAuth resource server. The HTTP layer must verify the bearer token before MCP dispatch. createMcpHandler() does not derive trusted identity from the request header.

The v2 SDK provides a web-standard gate:

import { requireBearerAuth } from '@modelcontextprotocol/server'

const gate = requireBearerAuth({
  verifier,
  requiredScopes: ['notes:read'],
  resourceMetadataUrl
})

async function fetchMcp(request: Request) {
  const auth = await gate(request)
  if (auth instanceof Response) return auth

  return handler.fetch(request, { authInfo: auth })
}

The omitted verifier must validate the token’s signature or introspection result, issuer, audience, expiry, and revocation status. The SDK gate checks the bearer shape, expiry, and required scopes around that verifier.

Audience is critical. Reject a valid token minted for another service. If the MCP server calls a downstream API, obtain a separate token for that API. Passing the caller’s token through creates a confused-deputy boundary.

Return 401 when the token is missing or invalid. Return 403 when the identity is valid but lacks the required scope. Advertise protected resource metadata so compatible clients can discover the authorization server.

Use HTTPS. Keep tokens out of URLs, source code, analytics, tool results, and logs.

The course dataset may be public only because every note is practice data. Replace it with private notes and authorization becomes a release blocker, not a later improvement.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →