langchain-ai/deepagents · error · ValueError
Server '{server_name}' uses stdio transport; 'auth: oauth' i
Error message
Server '{server_name}' uses stdio transport; 'auth: oauth' is only valid for http/sse transports. What it means
`auth: oauth` performs browser-based OAuth and only makes sense for remote transports (http/sse) that can redirect through an authorization flow. stdio servers are local subprocesses with no HTTP surface, so `_validate_server_config` raises this ValueError when `auth: oauth` is combined with a stdio server.
Source
Thrown at libs/code/deepagents_code/mcp_tools.py:948
f"Server '{server_name}' has unsupported transport type '{server_type}'. "
"Supported types: stdio, sse, http"
)
raise ValueError(error_msg)
auth = server_config.get("auth")
if auth is not None:
if auth != "oauth":
msg = (
f"Server '{server_name}' has unsupported auth value "
f"{auth!r}. Only 'oauth' is supported."
)
raise ValueError(msg)
if server_type == "stdio":
msg = (
f"Server '{server_name}' uses stdio transport; "
"'auth: oauth' is only valid for http/sse transports."
)
raise ValueError(msg)
header_names = {name.lower() for name in (server_config.get("headers") or {})}
if "authorization" in header_names:
msg = (
f"Server '{server_name}' cannot combine 'auth: oauth' "
"with an 'Authorization' header."
)
raise ValueError(msg)
_validate_tool_filter_fields(server_name, server_config)
def _validate_tool_filter_fields(
server_name: str,
server_config: dict[str, Any],
) -> None:
"""Validate optional `allowedTools` / `disabledTools` fields.
Both fields, when present, must be non-empty lists of strings. SettingView on GitHub (pinned to a1af029e6e)
Solutions
- Remove the `auth` field from the stdio server entry.
- If OAuth is genuinely needed, the server must be remote: set `"type": "http"` or `"sse"` with a `url` and keep `auth: oauth`.
- Pass credentials to a local stdio server via `env` (e.g. {"API_KEY": "..."}) per the server's own requirements.
- Validate the corrected entry with `resolve_and_load_mcp_tools` before reloading.
Example fix
// before
{"local": {"type": "stdio", "command": "npx", "args": ["-y", "mcp-server"], "auth": "oauth"}}
// after
{"local": {"type": "stdio", "command": "npx", "args": ["-y", "mcp-server"], "env": {"API_KEY": "..."}}} Defensive patterns
Strategy: validation
Validate before calling
def validate_auth_transport(name: str, cfg: dict) -> None:
if cfg.get("type", "stdio") == "stdio" and cfg.get("auth") is not None:
raise ValueError(f"Server '{name}' uses stdio transport; 'auth: oauth' is only valid for http/sse transports.") Type guard
def auth_matches_transport(cfg: dict) -> bool:
stype = cfg.get("type", "stdio")
auth = cfg.get("auth")
return auth is None or (auth == "oauth" and stype in ("http", "sse")) Try / catch
try:
tools = resolve_and_load_mcp_tools(config)
except ValueError as e:
if "only valid for http/sse transports" in str(e):
name = extract_server_name(str(e))
config["servers"][name].pop("auth", None) # stdio servers manage their own auth
tools = resolve_and_load_mcp_tools(config)
else:
raise Prevention
- OAuth applies only to remote (http/sse) servers; never add `auth` to stdio entries.
- Give local stdio servers credentials via `env` per the server's own requirements.
- When converting a remote entry to a local command, strip auth fields in the same edit.
- Avoid blanket config merges that copy `auth` onto every server.
When it happens
Trigger: A server entry resolving to type `stdio` includes `"auth": "oauth"`, e.g. `{"type": "stdio", "command": "npx", "args": [...], "auth": "oauth"}`, validated through `select_server`, `resolve_and_load_mcp_tools`, or the config validators.
Common situations: Copy-pasting a remote-server entry (which used oauth) and converting it to a local command without dropping `auth`; adding auth globally to all servers in a config; misunderstanding that stdio servers handle their own auth via env vars/secrets.
Related errors
- Server '{server_name}' has unsupported auth value {auth!r}.
- Server '{server_name}' cannot combine 'auth: oauth' with an
- Server '{server_name}' uses {transport!r} transport; OAuth l
- {str(exc)}
- {prefix}.args must be a list, got {type(args).__name__}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/c3bf68332d402f30.
Report an issue: GitHub.