langchain-ai/deepagents · error · RuntimeError
No MCP OAuth provider matched {server_url!r}
Error message
No MCP OAuth provider matched {server_url!r} What it means
resolve_provider scans the internal OAuth provider registry and returns the first provider whose `matches(server_url)` is true; the generic provider is documented to always match. Raising here means the registry has no matching entry — effectively a broken/incomplete registry build rather than a user config problem.
Source
Thrown at libs/code/deepagents_code/mcp_providers/_registry.py:39
def resolve_provider(server_url: str) -> OAuthProvider:
"""Return the provider policy that owns `server_url`.
Args:
server_url: Remote MCP endpoint URL.
Returns:
The first matching `OAuthProvider`; falls back to `GenericProvider`.
Raises:
RuntimeError: If no provider matches (unreachable in practice since
`GenericProvider.matches` always returns `True`).
"""
for provider in _REGISTRY:
if provider.matches(server_url):
return provider
msg = f"No MCP OAuth provider matched {server_url!r}"
raise RuntimeError(msg)
View on GitHub (pinned to a1af029e6e)
Solutions
- Check whether _REGISTRY was modified/cleared in your session or test setup; restore the default registry including the generic fallback provider.
- Reinstall deepagents-code to restore the complete built-in registry.
- If you maintain a custom registry, ensure GenericProvider (whose matches() always returns True) is registered last.
- Verify the server_url is well-formed; a malformed URL combined with strict provider predicates can skip all specific providers.
Example fix
// before (test setup) _registry_override[:] = [GitHubProvider] // after _registry_override[:] = [GitHubProvider, GenericProvider()]
Defensive patterns
Strategy: fallback
Validate before calling
from deepagents_code.mcp_providers import _registry assert _registry._REGISTRY, "OAuth provider registry is empty"
Try / catch
try:
provider = resolve_provider(server_url)
except RuntimeError as exc:
if str(exc).startswith("No MCP OAuth provider matched"):
provider = GenericProvider() # fallback for custom registries
else:
raise Prevention
- Never clear or replace _REGISTRY without keeping a catch-all provider
- Register GenericProvider last so unknown URLs always match
- Smoke-test login against a non-standard server URL in CI
When it happens
Trigger: Calling resolve_provider (via build_oauth_provider or login) with a server_url when _REGISTRY is empty or its entries' matches() predicates all fail — i.e. the always-matching GenericProvider is missing from the registry.
Common situations: Test code monkeypatching/clearing _REGISTRY; custom builds that registered only specific providers (e.g. GitHub) and removed the generic fallback; plugin code that filtered the registry before login.
Related errors
- MCPReauthRequiredError({server_name})
- Authorization denied by provider: {err_code}{detail}
- Callback URL is missing the 'code' parameter.
- Device code request failed: HTTP {response.status_code} from
- Device code response from {device_code_url} is missing requi
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/379ddc28aaa5c931.
Report an issue: GitHub.