Skilllibrary mcp-auth-transports
Select and implement MCP transports (stdio, Streamable HTTP) and authentication (OAuth 2.1 for remote servers). Use when deciding between local vs remote MCP deployment, implementing OAuth flows for remote MCP servers, debugging transport-level connection issues, or adding auth to an existing MCP server.
git clone https://github.com/merceralex397-collab/skilllibrary
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/07-mcp/mcp-auth-transports" ~/.claude/skills/merceralex397-collab-skilllibrary-mcp-auth-transports && rm -rf "$T"
07-mcp/mcp-auth-transports/SKILL.mdPurpose
Guide transport selection and authentication implementation for MCP servers. MCP defines two transports (stdio, Streamable HTTP) and an OAuth 2.1-based auth flow for remote servers. This skill covers when to use each, how to implement them, and how to debug transport-level failures.
When to use this skill
- Deciding between stdio and Streamable HTTP transport for a new MCP server
- Adding OAuth 2.1 authentication to a remote MCP server
- Debugging transport-level connection failures (handshake, session, SSE stream drops)
- Migrating from the deprecated HTTP+SSE transport to Streamable HTTP
Do not use this skill when
- Building tool logic or resource schemas (not transport-level) → use
ormcp-tool-designmcp-resources-prompts - Setting up a first MCP server from scratch → use
get-started - Implementing application-level permissions/gating → use
mcp-security-permissions
Transport selection
Decision table
| Factor | stdio | Streamable HTTP |
|---|---|---|
| Deployment | Local process, launched by host | Remote server, shared across clients |
| Clients served | One (1:1 with host process) | Many (1:N) |
| Network overhead | None (IPC) | HTTP + optional SSE |
| Auth needed | No (inherit OS process permissions) | Yes (OAuth 2.1 recommended) |
| Session management | Implicit (process lifetime) | Explicit ( header) |
| Best for | CLI tools, desktop apps, dev environments | SaaS integrations, shared services, multi-tenant |
Default rule: Use stdio unless the server must be remote or serve multiple clients.
stdio transport
The client launches the server as a subprocess. Messages are newline-delimited JSON-RPC on stdin/stdout.
Client → stdin → Server (JSON-RPC request) Client ← stdout ← Server (JSON-RPC response) stderr → Server logging (not protocol)
Critical rules:
- Server MUST NOT write anything to stdout that is not a valid JSON-RPC message
- Server MUST NOT use
(Python) orprint()
(Node) to stdout — use stderrconsole.log() - Messages are delimited by newlines and MUST NOT contain embedded newlines
Streamable HTTP transport
The server exposes a single HTTP endpoint (e.g.,
https://example.com/mcp) supporting POST and GET.
Client → Server (POST): Each JSON-RPC message is a separate POST. Server responds with either
application/json or text/event-stream (SSE).
Server → Client (GET + SSE): Client opens SSE stream for server-initiated messages (notifications, requests).
Session management:
- Server MAY return
header in theMcp-Session-Id
responseinitialize - Client MUST include
on all subsequent requestsMcp-Session-Id - Server returns
when session expires; client must re-initialize404 - Client SHOULD send HTTP DELETE to terminate session cleanly
Security requirements for Streamable HTTP:
- MUST validate
header to prevent DNS rebindingOrigin - Local servers SHOULD bind to
, not127.0.0.10.0.0.0 - MUST implement authentication for production deployments
OAuth 2.1 authentication flow
MCP specifies OAuth 2.1 for remote server auth. The flow uses three standards:
- RFC 9728 — OAuth 2.0 Protected Resource Metadata (server advertises its auth server)
- RFC 8414 — OAuth 2.0 Authorization Server Metadata (client discovers endpoints)
- RFC 7591 — Dynamic Client Registration (client auto-registers without manual setup)
Flow sequence
1. Client → MCP Server: request without token 2. MCP Server → Client: 401 + WWW-Authenticate header (resource_metadata URL) 3. Client → MCP Server: GET /.well-known/oauth-protected-resource 4. MCP Server → Client: resource metadata with authorization_servers URL 5. Client → Auth Server: GET /.well-known/oauth-authorization-server 6. Auth Server → Client: server metadata (token endpoint, auth endpoint, etc.) 7. Client → Auth Server: Dynamic Client Registration (RFC 7591) if needed 8. Client ↔ Auth Server: OAuth 2.1 authorization code flow (with PKCE) 9. Auth Server → Client: access token 10. Client → MCP Server: MCP request + Bearer token
Implementation guidance
TypeScript server with Streamable HTTP:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import express from "express"; const app = express(); const server = new McpServer({ name: "my-remote-server", version: "1.0.0" }); // Register tools on server... app.post("/mcp", async (req, res) => { const transport = new StreamableHTTPServerTransport("/mcp"); await server.connect(transport); await transport.handleRequest(req, res); }); app.listen(3000);
For stdio transport (no auth needed): Credentials come from the environment (env vars, OS keychain, file-based tokens). Do NOT implement OAuth for stdio servers.
Decision rules
- stdio servers MUST NOT implement OAuth — credentials come from the host process environment
- Remote Streamable HTTP servers SHOULD implement OAuth 2.1 with PKCE
- MUST support Dynamic Client Registration (RFC 7591) unless the server has a known, fixed set of clients
- The deprecated HTTP+SSE transport (protocol version 2024-11-05) should be migrated to Streamable HTTP
- Always include
header on HTTP requests after initializationMCP-Protocol-Version
Output requirements
- Transport choice with rationale
- Auth implementation (OAuth flow or environment-based)
- Session management strategy (for Streamable HTTP)
- Security hardening checklist (Origin validation, binding, TLS)
Related skills
— application-level permissions and tool gatingmcp-security-permissions
— debugging transport-level issues with MCP Inspectormcp-inspector-debugging
— session isolation for multi-client Streamable HTTP serversmcp-multi-tenant-design
Failure handling
- If client gets 401 and cannot parse
, check the server implements RFC 9728 Protected Resource MetadataWWW-Authenticate - If SSE stream drops, client should reconnect with
header for resumabilityLast-Event-ID - If session returns 404, the session expired — client must send new
request without session IDinitialize - If
is missing from server response, the server is stateless — do not send session headersMcp-Session-Id