Development Choices

OAuth or API key headers for an MCP server

Author
Joseph Trasatti Member of technical staff
Published
Section
MCP
Length
5 min read3 sources cited

Use OAuth for a remote MCP server on a workstation with a browser: it binds one product environment per connection and keeps no secret in your config file. Use header authentication — one cloudinary-url header, or three — for headless CI, containers, or one machine serving several environments at once.

Two ways to hand a credential to a remote MCP server

A remote MCP server runs on the vendor’s infrastructure, so the credential has to travel with the connection rather than sitting in the environment of a process your client launched. Cloudinary publishes remote endpoints for asset management, environment config, structured metadata, analysis and MediaFlows, and its MCP server documentation lists the auth mode each one accepts (checked 2026-08-18). Two mechanisms are on offer, and three things decide between them: where the secret ends up, whether a browser is reachable, and how many product environments one machine needs at once.

OAuth is the default on the remote servers. Connecting opens a browser login, you authenticate against Cloudinary directly, you pick a product environment, and the connection is bound to that environment. No secret is typed anywhere along the way — the client ends up holding a token the flow issued to it, not an account credential you pasted.

Header authentication sends the credential on every request. It accepts either a single cloudinary-url header carrying the full credential string, or three separate headers for the cloud name, the API key and the API secret. The MediaFlows MCP server names that trio cld-cloud-name, cld-api-key and cld-secret (checked 2026-08-18); the mechanics of wiring it up are covered in configuring the MediaFlows MCP server.

Where the secret ends up

This is the difference people skip past. A header-authenticated server is configured in a client config file, and that file holds a long-lived secret in plaintext. That is a materially different exposure from an OAuth token kept in the client’s own store — not because one is stored and the other is not, but because of what the artifact is. The header credential is a reusable account secret: anything that reads the file can act as your product environment, from anywhere, until you rotate it. The OAuth token was issued to one client for one product environment.

The exposure surface is the ordinary one for a plaintext file: it is readable by every process running as you, it gets picked up by dotfile sync, it appears in a screen share, and it survives in git history if the config lives in a repo. MCP client config files as a credential surface goes into the specific paths and the habits that leak them.

OAuth is not free of storage risk — the token still lands on disk in most clients. The claim is narrower than safer: the blast radius of one leaked file is smaller, and it is scoped to a single product environment by construction.

Whether a browser is reachable

OAuth is unusable where no browser is reachable, and the reason is structural rather than an implementation gap. RFC 6749’s authorization code grant routes the resource owner through a user-agent: something has to render the login page and receive the redirect that carries the code back. A CI runner or a container has no user-agent to route through, and neither does a remote box you reached over SSH.

That is the normal reason headless environments fall back to API keys. A header credential is just bytes on a request, so it works identically whether a human is present or not. The MCP specification defines authorization for HTTP transports and leaves locally-launched stdio servers to take credentials from their environment, which is why the same fallback shows up whenever a server moves out of an interactive session — see remote versus local MCP servers for where each form lands.

The practical consequence: if the same server has to be reachable from your laptop and from CI, you are not choosing one mechanism. You are running OAuth interactively and header auth in the pipeline, with two configs to keep in step.

How many product environments one machine can hold

An OAuth flow selects a single product environment per connection. That is the point of the browser step — you choose, and the binding is fixed. It also means one connection can never straddle two environments, which is a real safety property when staging and production sit side by side in the same client.

Only header auth lets one machine hold credentials for several product environments at once, because each configured server entry carries its own credential string. Anyone who works across environments in a single session — an agency running several clients, or a developer moving assets between staging and production — needs that, and OAuth does not offer it. The cost is that the machine now holds several long-lived secrets in plaintext instead of one, so the exposure from the previous section scales with the number of environments.

CriterionOAuthHeader auth
Standing on Cloudinary remote serversdefaultopt-in
What is storedtoken in the client’s own store, nothing typedlong-lived secret, plaintext in config
Shapebrowser login, environment chosen in the flowone cloudinary-url header, or three headers
Headless CI or containerunusable, no browser to reachworks unchanged
Product environments per machineone per connectionseveral at once

Which to pick when

Pick OAuth if the client runs on a workstation with a browser and you work in one product environment at a time. It is the default, it keeps a long-lived secret out of your config file, and the environment binding is explicit rather than a string you might mistype into the wrong entry.

Pick header auth if the client runs headless — CI, a container, a build agent, a remote box over SSH. There is no browser for the redirect, so this is not a preference, it is the only mechanism that functions. Treat the credential like any other pipeline secret: injected at run time, not committed.

Pick header auth if one machine must hold several product environments at once. It is the only option that does, and the multi-client or staging-plus-production case is common enough that this decides it outright.

The case worth naming as a mistake: header auth on an interactive workstation, in a single environment, chosen because pasting a credential string was faster than clicking through a login. That takes the plaintext-secret exposure without buying either thing header auth exists for. If you are already at a browser and already in one environment, the default is the default for a reason.

Sources

  1. its MCP server documentation lists the auth mode each one accepts cloudinary.com
  2. RFC 6749's authorization code grant datatracker.ietf.org
  3. MCP specification modelcontextprotocol.io

See also