Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Comments

Close side panel

SEP-2059: OAuth Device Flow for stdio MCP Servers#2059

Closed
SamMorrowDrums wants to merge 7 commits intomodelcontextprotocol:mainmodelcontextprotocol/modelcontextprotocol:mainfrom
SamMorrowDrums:sep-stdio-oauth-device-flowSamMorrowDrums/modelcontextprotocol:sep-stdio-oauth-device-flowCopy head branch name to clipboard
Closed

SEP-2059: OAuth Device Flow for stdio MCP Servers#2059
SamMorrowDrums wants to merge 7 commits intomodelcontextprotocol:mainmodelcontextprotocol/modelcontextprotocol:mainfrom
SamMorrowDrums:sep-stdio-oauth-device-flowSamMorrowDrums/modelcontextprotocol:sep-stdio-oauth-device-flowCopy head branch name to clipboard

Conversation

@SamMorrowDrums
Copy link
Contributor

@SamMorrowDrums SamMorrowDrums commented Jan 7, 2026

Summary

This SEP proposes a standardized mechanism for stdio-based MCP servers to perform OAuth authentication using the OAuth 2.0 Device Authorization Grant (RFC 8628).

Problem Statement

The current MCP Authorization specification explicitly states that stdio transport implementations "SHOULD NOT follow this specification, and instead retrieve credentials from the environment." This has led to widespread use of Personal Access Tokens (PATs) stored in plaintext configuration files, creating security and usability problems.

No existing SEP addresses this gap. The closest related work focuses on different concerns:

  • SEP-1036 (URL Mode Elicitation) - Third-party downstream authorization, not MCP server auth
  • SEP-991 (CIMD) - Client identity documents, which we reference for host passthrough
  • SEP-646 (Enterprise Managed Authorization) - Enterprise IdP for HTTP servers

Proposed Solution

  1. Ephemeral tokens: OAuth tokens issued at runtime, held in memory only
  2. Device flow via auth_login tool: Uses RFC 8628 for browserless OAuth
  3. tools/list_changed notifications: Dynamic tool registration after auth
  4. Lazy auth alternative: Auth triggered on first unauthenticated tool call via elicitation
  5. CIMD passthrough: Host apps can pass their identity to servers
  6. SDK-level implementation: Server authors opt-in; SDK handles complexity

Prior Art & Community Demand

Reference Description
github/github-mcp-server#132 "Non PAT auth method" - 23 upvotes requesting device flow
github/github-mcp-server#1649 Reference implementation proving feasibility
#205 "Treat MCP server as OAuth resource server" - 147 reactions
PR #887 SEP-1036 URL Mode Elicitation (merged) - provides primitives we leverage
PR #1296 SEP-991 CIMD (merged) - identity documents we reference

Demo

OAuth Device Flow Demo

Why This Needs a SEP

  1. Fills a transport-specific gap: No standard auth mechanism for stdio servers
  2. Uses RFC 8628: Device Authorization Grant not addressed elsewhere in MCP
  3. SDK-implementable: Designed for "auth for free" via SDK opt-in
  4. Ephemeral tokens: Different security model from stored credentials
  5. Lazy auth pattern: Novel approach using elicitation during tool calls

Why Not Host-Driven OAuth?

The host can't drive OAuth because it would need to know each server's authorization server:

  • GitHub MCP Server → github.com
  • Slack MCP Server → slack.com
  • Internal Server → corp.okta.com

This doesn't scale. CIMD solves the identity problem (host passes its identity URL), but the server must drive the OAuth flow because only it knows its authorization server.

Key Features

  • Servers start in unauthenticated mode with only auth_login tool (or all tools with lazy auth)
  • User completes OAuth in browser via device flow
  • Token held in memory, discarded on exit (ideal for docker run --rm)
  • Optional CIMD passthrough for host app identity
  • Backward compatible with existing PAT-based auth

Open Questions

  1. Should servers be able to trigger auth during initialize phase?
  2. Should lazy auth be the default SDK behavior?
  3. How should multi-account scenarios be handled?

Seeking Sponsor

This SEP is seeking a sponsor from the MCP core maintainers.


Status: Draft
Type: Standards Track
Author: @SamMorrowDrums

This SEP proposes a standardized mechanism for stdio-based MCP servers
to perform OAuth authentication using the OAuth 2.0 Device Authorization
Grant (RFC 8628).

Key features:
- Ephemeral tokens issued at runtime (no persistent storage)
- Device flow via tools, tools/list_changed, and URL elicitation
- Alternative lazy auth pattern (auth on first tool call)
- CIMD passthrough from host applications
- SDK-level implementation (server authors just opt-in)
- Scope challenge support for step-up authorization

Reference implementation: github/github-mcp-server#1649
@SamMorrowDrums SamMorrowDrums changed the title SEP-0000: OAuth Device Flow for stdio MCP Servers SEP-2059: OAuth Device Flow for stdio MCP Servers Jan 7, 2026
@localden
Copy link
Contributor

localden commented Jan 7, 2026

@SamMorrowDrums at a high level, I am curious why this is necessary in STDIO cases. A MCP server that runs locally has access to any authentication/authorization library - that is, if I run GitHub STDIO server, I can just use either a GitHub-specific auth library or rely on a generic OAuth implementation. When a tool is invoked, the tokens can be dynamically pulled from the cache, passed to the downstream API, and then if there is an error, the tool can trigger an interactive flow that is completely detached from what flow needs to be used here.

My worry here is that we're implementing a bunch of custom stuff for STDIO, and on top of that - it's Device Code Flow, which is highly phishable and likely not something we'd necessarily want to promote as the de-facto auth modality.

@SamMorrowDrums
Copy link
Contributor Author

That makes sense @localden mostly what I want is to move PAT users off hard coding tokens in stdio and I am not sure of a simple way to do it.

  • I don't like the idea of baking in an app and having the wrong client identity
  • I don't mind the host being responsible for token storage and negotiation

At minimum there needs to be a way to handle discovery and token delivery via stdio. If using CIMD wouldn't have to support device flow at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.