Safeguard
Developer Tools•

Why does a stdio MCP server skip OAuth and use environment credentials?

The MCP spec says stdio servers should not follow its OAuth flow and should read credentials from the environment. What that means for storing secrets.

Safeguard Security Team
3 min read

The MCP authorization spec says stdio servers should not follow its OAuth flow and should instead retrieve credentials from the environment. A stdio server is a local child process of the client, not a web service, so there is no HTTP request to challenge. That puts the weight on how you store and scope those secrets.

What the spec says

The authorization section states that authorization is optional. HTTP based transports should conform to the spec. Implementations using the stdio transport should not follow it and should retrieve credentials from the environment. Other transports must follow established security best practices for their protocol.

Why it works this way

OAuth in MCP runs over HTTP: a request without a token gets a 401, discovery metadata points to an authorization server, and a browser sign in follows. A stdio server speaks over standard input and output with the process that launched it. There is no web endpoint to challenge, and the trust boundary is the machine and the launching client.

The security guidance adds that using stdio limits access to just the client, which is why it recommends it for locally run servers.

What that moves onto you

ItemRisk if carelessBetter practice
API key in an environment variableVisible to other processes or in shell historyLoad from a vault or keychain at launch
Key written into a config fileCommitted to git or backed upReference a variable, keep the file clean
One key for many serversWide blast radiusOne narrow key per server
Long lived keyHard to revokeShort lived token where the service allows
Server inherits all variablesLeaks unrelated secretsPass only the variables it needs

Steps for a local server

  1. Create a dedicated credential for the server with the smallest scope that works.
  2. Inject it at launch from a secret store, not a file in the repository.
  3. Pass only the variables the server needs, not your full environment.
  4. Run the server in a sandbox so it cannot read other secrets on disk.
  5. Rotate the credential on a schedule and when a developer leaves.
  6. Log use of the credential at the service side.

When to prefer a remote server instead

If several people need the same tool, a remote HTTP server with OAuth gives you per user tokens, audience checks and revocation. Local stdio is simple, but each machine holds its own secret.

Safeguard includes agent identity and a free scan at https://gold.safeguard.sh/scan, plus policies, gates and guardrails for agent access.

Try it yourself

Follow the setup and notice where a credential would be supplied, then decide where you would store it so it stays out of the config file.

Click through it at your own pace, or open it full screen.

Quick check

Does stdio mean no authentication at all?

Not exactly. The server trusts the client that launched it, and it uses credentials from the environment to reach any outside service.

Should I put the key in the config file?

Avoid it. Reference an environment variable or secret store so the key does not end up in version control.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.