PrefectHQ/fastmcp · error · RuntimeError

No access token found. Ensure authentication is configured a

Error message

No access token found. Ensure authentication is configured and the request is authenticated.

What it means

The AccessToken dependency wraps get_access_token(), which returns the OAuth access token attached to the current authenticated MCP request. When no token is present, entering the context manager raises this RuntimeError. FastMCP throws it because returning None would silently hide misconfigured auth and lead to downstream NoneType errors.

Source

Thrown at fastmcp_slim/fastmcp/server/dependencies.py:1289

        await self._impl.increment(amount)

    async def set_message(self, message: str | None) -> None:
        """Update the progress status message."""
        assert self._impl is not None, "Progress must be used as a dependency"
        await self._impl.set_message(message)


# --- Access Token dependency ---


class _CurrentAccessToken(Dependency[AccessToken]):
    """Async context manager for AccessToken dependency."""

    async def __aenter__(self) -> AccessToken:
        token = get_access_token()

        if token is None:
            raise RuntimeError(
                "No access token found. Ensure authentication is configured "
                "and the request is authenticated."
            )
        return token

    async def __aexit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        traceback: TracebackType | None,
    ) -> None:
        pass


def CurrentAccessToken() -> AccessToken:
    """Get the current access token for the authenticated user.

    This dependency provides access to the AccessToken for the current

View on GitHub (pinned to 1f02114297)

Solutions

  1. Configure an auth provider on the FastMCP server (e.g. JWT/OAuth) and send a valid Authorization header with the request
  2. If the tool must work unauthenticated, make the token optional — use get_access_token() directly and handle None instead of the AccessToken dependency
  3. Check the transport: browser/HTTP clients must include the Bearer token; stdio/local clients won't have one
  4. In tests, inject a fake access token via FastMCP's test auth fixtures

Example fix

// before
async def my_tool(token: AccessToken) -> str:  # RuntimeError without auth
    return token.claims["sub"]
// after
from fastmcp.server.dependencies import get_access_token
async def my_tool() -> str:
    token = get_access_token()
    return token.claims["sub"] if token else "anonymous"
Defensive patterns

Strategy: try-catch

Validate before calling

from fastmcp.server.dependencies import get_access_token
token = get_access_token()
if token is None:
    # skip token-dependent logic or return anonymous result
    ...

Type guard

from fastmcp.server.dependencies import get_access_token
from mcp.server.auth.provider import AccessToken

def has_access_token() -> bool:
    return isinstance(get_access_token(), AccessToken)

Try / catch

try:
    async with AccessToken() as token:
        sub = token.claims['sub']
except RuntimeError as e:
    if 'No access token' in str(e):
        raise HTTPException(status_code=401) from e

Prevention

When it happens

Trigger: Entering `with AccessToken() as token:` in a request where authentication is not configured on the server, the transport delivered no Authorization header, or the call happens outside an authenticated request (tests, background tasks, unauthenticated transports like stdio without auth).

Common situations: Server deployed without an auth provider while tools declare AccessToken parameters; local stdio development where no auth is set up; expired/missing Bearer tokens; tests calling tools directly.

Understand the failure class

Related errors


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