CCloud Releases
Home
Following

Cloud Releases

Service catalogues and updates come from each provider's public product listing and announcements.

Explore

  • Home
  • Latest updates
  • Following

About

  • About
  • Contact
  • Privacy Policy
  • Terms of Use

Providers

  • Amazon Web Services
  • Microsoft Azure
  • Google Cloud
  • Cloudflare

Not affiliated with any cloud provider. Product names and logos belong to their owners.

  1. Providers
  2. ›Cloudflare
  3. ›Agents
  4. ›Update

Feature•Oct 1, 2026

The best way to do MCP auth just got better: Workers OAuth Provider goes v1, with a new split API and full support for MCP 2026-07-28

AgentsCloudflare · Developer platform

@cloudflare/workers-oauth-provider is now v1, with a new split API. One Worker acts as the authorization server: it signs users in and issues tokens. Your MCP server acts as the resource server, and can run in another Worker. It validates each token with the authorization server over a Service Binding, without crossing the public Internet.

  • It supports the MCP 2026-07-28 authorization specification, including Client ID Metadata Documents and issuer identification. It still works with older clients, including those using Dynamic Client Registration.
  • insufficientScope() gives you step-up authorization in one line.
  • The authorization server and the resource server can run in different Workers with different WAF and rate limiting rules.
  • One authorization server can issue tokens for many MCP servers.
  • A migration skill ships in the npm package so a coding agent can perform the upgrade.

The split API

import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope, } from "@cloudflare/workers-oauth-provider"; import { WorkerEntrypoint } from "cloudflare:workers"; // auth-server Worker: signs users in and issues tokens for both MCP servers. const authorizationServer = new OAuthAuthorizationServer({ issuer: "https://auth.example.com", resources: [ "https://calendar.example.com/mcp", "https://drive.example.com/mcp", ], scopesSupported: ["calendar:read", "calendar:write", "offline_access"], clientIdMetadataDocumentEnabled: true, }); export class AuthServer extends WorkerEntrypoint { fetch(request) { if (new URL(request.url).pathname === "/authorize") { return showConsent(request, this.env); } return authorizationServer.fetch(request, this.env, this.ctx); } validateToken(resource, token) { return authorizationServer.validateToken(resource, token, this.env); } } // calendar MCP Worker: checks tokens with AuthServer over a Service Binding. export const calendar = new OAuthResourceServer({ resourceMetadata: { resource: "https://calendar.example.com/mcp", authorization_servers: ["https://auth.example.com"], }, requiredScopes: ["calendar:read"], validateToken: (env) => env.AUTH_SERVER.validateToken, handler: { fetch(request, env, ctx) { if ( request.method === "POST" && !ctx.auth.scope.includes("calendar:write") ) { return insufficientScope(ctx.auth, ["calendar:read", "calendar:write"]); } return handleMcp(request, ctx.props); }, }, });

import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope, } from "@cloudflare/workers-oauth-provider"; import { WorkerEntrypoint } from "cloudflare:workers"; // auth-server Worker: signs users in and issues tokens for both MCP servers. const authorizationServer = new OAuthAuthorizationServer<Env>({ issuer: "https://auth.example.com", resources: [ "https://calendar.example.com/mcp", "https://drive.example.com/mcp", ], scopesSupported: ["calendar:read", "calendar:write", "offline_access"], clientIdMetadataDocumentEnabled: true, }); export class AuthServer extends WorkerEntrypoint<Env> { fetch(request: Request) { if (new URL(request.url).pathname === "/authorize") { return showConsent(request, this.env); } return authorizationServer.fetch(request, this.env, this.ctx); } validateToken(resource: string, token: string) { return authorizationServer.validateToken(resource, token, this.env); } } // calendar MCP Worker: checks tokens with AuthServer over a Service Binding. export const calendar = new OAuthResourceServer<Env, AuthProps>({ resourceMetadata: { resource: "https://calendar.example.com/mcp", authorization_servers: ["https://auth.example.com"], }, requiredScopes: ["calendar:read"], validateToken: (env) => env.AUTH_SERVER.validateToken, handler: { fetch(request, env, ctx) { if ( request.method === "POST" && !ctx.auth.scope.includes("calendar:write") ) { return insufficientScope(ctx.auth, ["calendar:read", "calendar:write"]); } return handleMcp(request, ctx.props); }, }, });

In the example, env.AUTH_SERVER.validateToken is that Service Binding call. The calendar Worker needs no KV namespace of its own.

{ "name": "calendar-mcp", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-10-14", "services": [ { "binding": "AUTH_SERVER", "service": "auth-server", "entrypoint": "AuthServer", }, ], }

name = "calendar-mcp" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-10-14" [[services]] binding = "AUTH_SERVER" service = "auth-server" entrypoint = "AuthServer"

OAuthResourceServer publishes the RFC 9728 protected resource metadata that MCP clients use to find your authorization server. It answers requests without a token with a 401 challenge that points to that metadata. It also rejects tokens issued for any other resource.

You can still use OAuthProvider as both the authorization server and the MCP server. For most 0.x deployments, the only required change is to add resourceMetadata: { resource }.

Other updates and helpers

  • Consent page and upstream sign-in helpers implement the MCP confused deputy protections.
  • Sliding refresh token expiry with refreshTokenIdleTTL.
  • Resumable KV cleanup with purgeExpiredData().
  • An internal reason on every error passed to onError.

Upgrade with the migration skill

Read the original announcement↗

More from Agents

All Agents updates →
  1. Cloudflare API MCP server sends Workers Issues as MCP Events

    Workers Issues provides built-in error monitoring for Cloudflare Workers. It detects production failures and groups related failures into issues without an SDK or application wrapper.

    Agents•Feature•Oct 13, 2026
  2. New persistent browser tool in the Agents SDK, with tabs and logins that last between turns

    The Cloudflare Agents SDK now provides a browserTool that gives your agent a Browser Run browser it can return to on later turns.

    Agents•Feature•Oct 13, 2026
  3. New web_fetch tool in the Agents SDK for reading webpages and documents, with automatic markdown conversion

    The Cloudflare Agents SDK now provides a web_fetch tool that reads webpages, PDFs, and supported Office documents, using Workers AI Markdown Conversion to turn them into text the model can read.

    Agents•Feature•Oct 12, 2026
  4. Run OpenCode 2.0 on Cloudflare with the Agents SDK

    The Agents SDK now supports OpenCode 2.0 through the experimental OpenCodeHarness. Run OpenCode inside a plain Durable Object, with sessions stored in SQLite and Lifecycle jobs that wake interrupted work after eviction.

    Agents•Feature•Oct 12, 2026
  5. New web_search tool in the Agents SDK, powered by the Cloudflare Web Search API

    The Cloudflare Agents SDK now provides a web_search tool that searches the public web through the Cloudflare Web Search API, powered by ceramic.ai, Exa, and Linkup.

    Agents•Feature•Oct 12, 2026