PrefectHQ/fastmcp · error · RuntimeError

EntraOBOToken requires an AzureProvider as the auth provider

Error message

EntraOBOToken requires an AzureProvider as the auth provider. Current provider: {type(server.auth).__name__}

What it means

After obtaining the access token, EntraOBOToken locates the server's auth provider with _find_azure_provider to perform the OBO exchange. If the server's auth provider is not an AzureProvider (or doesn't wrap one), the OBO exchange can't be performed, so it raises RuntimeError naming the actual provider type.

Source

Thrown at fastmcp_slim/fastmcp/server/auth/providers/azure.py:858

    def __init__(self, scopes: list[str]):
        self.scopes = scopes

    async def __aenter__(self) -> str:
        _require_azure_identity("EntraOBOToken")

        from fastmcp.server.dependencies import get_access_token, get_server

        access_token = get_access_token()
        if access_token is None:
            raise RuntimeError(
                "No access token available. Cannot perform OBO exchange."
            )

        server = get_server()
        azure_provider = _find_azure_provider(server.auth)
        if azure_provider is None:
            raise RuntimeError(
                "EntraOBOToken requires an AzureProvider as the auth provider. "
                f"Current provider: {type(server.auth).__name__}"
            )

        credential = await azure_provider.get_obo_credential(
            user_assertion=access_token.token,
        )

        result = await credential.get_token(*self.scopes)
        return result.token


def EntraOBOToken(scopes: list[str]) -> str:
    """Exchange the user's Entra token for a downstream API token via OBO.

    This dependency performs a Microsoft Entra On-Behalf-Of (OBO) token exchange,
    allowing your MCP server to call downstream APIs (like Microsoft Graph) on
    behalf of the authenticated user.

View on GitHub (pinned to 1f02114297)

Solutions

  1. Set the server's auth to AzureProvider(...): FastMCP(..., auth=AzureProvider(...)).
  2. Remove or gate EntraOBOToken usage in tools when running against non-Azure auth.
  3. If you wrap AzureProvider in a custom provider, make it discoverable by _find_azure_provider or call azure_provider.get_obo_credential directly.

Example fix

// before
mcp = FastMCP(name="app", auth=GitHubProvider(client_id=cid, client_secret=sec))
// after
mcp = FastMCP(name="app", auth=AzureProvider(client_id=cid, client_secret=sec, tenant_id=tid))
Defensive patterns

Strategy: type-guard

Validate before calling

from fastmcp.server.auth.providers.azure import AzureProvider, _find_azure_provider
from fastmcp.server.dependencies import get_server
if _find_azure_provider(get_server().auth) is None:
    raise RuntimeError("Server auth must be (or wrap) AzureProvider for EntraOBOToken")

Type guard

def server_uses_azure(auth) -> bool:
    from fastmcp.server.auth.providers.azure import _find_azure_provider
    return _find_azure_provider(auth) is not None

Try / catch

try:
    async with EntraOBOToken(scopes=["api"]) as t:
        ...
except RuntimeError as e:
    if "requires an AzureProvider" in str(e):
        logger.error(f"Wrong auth provider configured: {e}")
    raise

Prevention

When it happens

Trigger: Using EntraOBOToken on a server whose auth is, e.g., JWTVerifier, GoogleProvider, GitHubProvider, or any non-Azure AuthProvider.

Common situations: Copy-pasting EntraOBOToken sample code into a project that uses a different identity provider; switching the server's auth provider during migration and leaving OBO token usage in tools; wrapping AzureProvider in a custom AuthProvider that _find_azure_provider doesn't recognize.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/df5d203a97d1dad9. Report an issue: GitHub.