# Cloudflare Access Access sits in front of the public hostname. It is a gate for browsers, not a replacement for MCP OAuth. Official reference: - [Self-hosted Access applications](https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-apps/) - [Path-based policies](https://developers.cloudflare.com/cloudflare-one/policies/access/) ## Protect humans, bypass machines Create a self-hosted Access application for the Tunnel hostname. Split paths: **Bypass** (MCP and OAuth machine traffic): - `/mcp` - `/token` - `/revoke` - `/.well-known` - `/health` **Allow** (your identity provider — email, GitHub, or whatever you already use): - `/authorize` - `/` `/authorize` is the page where you approve a client. Access should require you before that form is reachable from the public internet. The LAN origin is trusted and does not need Access. `/health` stays on the bypass list so a NAS health check or uptime probe can reach it without a browser session. ## Access is not MCP OAuth A user who passes Access can load `/authorize` and approve a client. The MCP client still needs a CIMD OAuth grant with PKCE. Do not treat an Access session cookie as permission to call `/mcp`. ## Service tokens Kody cannot send Cloudflare Access service-token header pairs (`CF-Access-Client-Id` / `CF-Access-Client-Secret`) when it talks to a remote MCP server. Prefer the OAuth shape this starter already implements: Access protects the human approve step; `/mcp` and `/token` stay on Bypass and require the MCP bearer. Do not put Access in "Service Auth" on `/mcp` and then paste one Access service token into several Kody accounts. That shares one credential across identities. ## One grant per Kody account Each Kody account that connects to this server completes its own authorize step and receives its own access and refresh tokens. Do not copy a bearer from one account into another.