Most auth samples stop at logging the user in. This one carries roles from Asgardeo into tool listing, so a user without the `manager` role never sees the reportees tool at all — a cleaner failure mode than an authorised call that returns an error. Two setup steps catch people out: the callback URL has to be added to the Asgardeo application twice, once for `http://localhost:8788/callback` and again for the deployed Worker URL, and Cursor needs `mcp-remote` in front because it does not do MCP authentication itself.
A working sample of an authenticated remote MCP server. It runs on Cloudflare Workers and sits between two OAuth roles at once: an OAuth server to your MCP clients, and an OAuth/OIDC client to your Asgardeo organization.
- Login before tool use: connecting a client redirects the user to Asgardeo and back
- Role-scoped tool visibility — every authenticated user gets `userInfo`, while `getDirectReportees` appears only for users holding the `manager` role, and stays invisible to everyone else
- A deployable path end to end: `npm run dev` locally on `http://localhost:8788`, then `npx wrangler@latest deploy` to a workers.dev URL
- SSE transport, testable from the MCP Inspector or the Cloudflare Workers AI LLM Playground
An Asgardeo account and a Cloudflare account, plus Node.js version 18.x or higher. In Asgardeo, register a Traditional Web Application over OpenID Connect and note the client id, the client secret and your organization name. Locally these go in a `.dev.vars` file as `ASGARDEO_CLIENT_ID`, `ASGARDEO_CLIENT_SECRET`, `ASGARDEO_BASE_URL` and `ASGARDEO_SCOPE`; for deployment they are set as Wrangler secrets along with a `COOKIE_ENCRYPTION_KEY`. You also create a KV namespace bound as `OAUTH_KV` and paste its id into `wrangler.jsonc`.
