Self-host: Managed OAuth on the Access application is cleared by every deploy, breaking MCP auth
Self-hosted MCP requires Managed OAuth on the Cloudflare Access application — docs/SELF_HOSTING_CLOUDFLARE_OPERATIONS.md documents enabling it by hand in the Zero Trust dashboard. That setting does not survive the next pnpm deploy:selfhost.
What happens
- Deploy a self-host stage, enable Managed OAuth in the dashboard, connect an MCP client — works.
- Run
pnpm deploy:selfhostagain (a routine version update). oauth_configurationis back tonulland every MCP client fails with:
Unexpected content type: text/htmlThat "HTML" is the Access login page. Nothing points at the toggle that a deploy silently switched off, possibly days earlier.
Cause
emailAccessGate (alchemy.access.ts:75-80) declares only type, name, domain and policies on Cloudflare.Access.Application. Alchemy's reconcile performs a PUT-style update whose body is assembled by buildMutableBody (node_modules/alchemy/lib/Cloudflare/Access/Application.js:402) from declared props only, so oauth_configuration is omitted from the request and Cloudflare clears it.
Alchemy's Access.Application resource does not expose an oauthConfiguration prop at all, so it cannot currently be declared.
Possible fix
The underlying client already supports it: @distilled.cloud/cloudflare/zero-trust accepts oauthConfiguration (zero-trust.ts:2538, serialised to oauth_configuration at :2996). alchemy.run.ts already imports and calls that client directly for other Zero Trust work (listOrganizationsForAccount, createOrganizationForAccount), so the self-host stack could apply the OAuth configuration after the application resource resolves — making the setting declarative and self-healing on every deploy instead of a manual step that deploys undo.
Gating it behind an env flag (default off) would keep the behaviour opt-in for deployments that don't use MCP.
Environment
- Self-host on Cloudflare,
AUTH_MODE=cloudflare_access, Workers Free plan - alchemy
2.0.0-beta.61, OpenSEO0.1.7 - Access application provisioned by the deploy (not hand-managed via
TEAM_DOMAIN/POLICY_AUD)
Related: #47 (same area — self-host MCP behind Access Managed OAuth).
Source: every-app/open-seo