---
schema: rendered-html/v1
title: "Multiple Auth Sources - FastMCP"
source_url: https://gofastmcp.com/servers/auth/multi-auth
generated_at: 2026-06-11T19:39:14.154246+00:00
---




[FastMCP home page![light logo](images/gofastmcp__com__servers__auth__multi-auth__wordmark.avif)![dark logo](images/gofastmcp__com__servers__auth__multi-auth__wordmark-white.avif)](gofastmcp__com.md)







Authentication

Multiple Auth Sources









  - Authentication

    - [Overview](gofastmcp__com__servers__auth__authentication.md)
    - [Token Verification](gofastmcp__com__servers__auth__token-verification.md)
    - [Remote OAuth](gofastmcp__com__servers__auth__remote-oauth.md)
    - [OAuth Proxy](gofastmcp__com__servers__auth__oauth-proxy.md)
    - [OIDC Proxy](gofastmcp__com__servers__auth__oidc-proxy.md)
    - [Full OAuth Server](gofastmcp__com__servers__auth__full-oauth-server.md)
    - [Multiple Auth Sources](/servers/auth/multi-auth)
  - [Authorization

    NEW](gofastmcp__com__servers__authorization.md)














- [Understanding MultiAuth](#understanding-multiauth)
- [Verification Order](#verification-order)
- [Verifiers Only](#verifiers-only)
- [API Reference](#api-reference)
  - [MultiAuth](#multiauth)

Authentication

# Multiple Auth Sources


Accept tokens from multiple authentication sources with a single server.


New in version `3.1.0`
Production servers often need to accept tokens from multiple authentication sources. An interactive application might authenticate through an OAuth proxy, while a backend service sends machine-to-machine JWT tokens directly. `MultiAuth` composes these sources into a single `auth` provider so every valid token is accepted regardless of where it was issued.

## [​](#understanding-multiauth) Understanding MultiAuth

`MultiAuth` wraps an optional auth server (like `OAuthProxy`) together with one or more token verifiers (like `JWTVerifier`). When a request arrives with a bearer token, `MultiAuth` tries each source in order and accepts the first successful verification.
The auth server, if provided, is tried first. It owns all OAuth routes and metadata — the verifiers contribute only token verification logic. This keeps the MCP discovery surface clean: one set of routes, one set of metadata, multiple verification paths.

from fastmcp.server.auth import MultiAuth, OAuthProxy
from fastmcp.server.auth.providers.jwt import JWTVerifier

auth = MultiAuth(
    server=OAuthProxy(
        issuer_url="https://login.example.com/...",
        client_id="my-app",
        client_secret="secret",
        base_url="https://my-server.com",
    verifiers=[
        JWTVerifier(
            jwks_uri="https://internal-issuer.example.com/.well-known/jwks.json",
            issuer="https://internal-issuer.example.com",
            audience="my-mcp-server",

mcp = FastMCP("My Server", auth=auth)

Interactive MCP clients authenticate through the OAuth proxy as usual. Backend services skip OAuth entirely and send a JWT signed by the internal issuer. Both paths are validated, and the first match wins.

## [​](#verification-order) Verification Order

`MultiAuth` checks sources in a deterministic order:

1. **Server** (if provided) — the full auth provider’s `verify_token` runs first
2. **Verifiers** — each `TokenVerifier` is tried in list order

The first source that returns a valid `AccessToken` wins. If every source returns `None`, the request receives a 401 response.
This ordering means the server acts as the “primary” authentication path, with verifiers as fallbacks for tokens the server doesn’t recognize.

## [​](#verifiers-only) Verifiers Only

You don’t always need a full OAuth server. If your server only needs to accept tokens from multiple issuers, pass verifiers without a server:

from fastmcp.server.auth import MultiAuth
from fastmcp.server.auth.providers.jwt import JWTVerifier, StaticTokenVerifier

auth = MultiAuth(
    verifiers=[
        JWTVerifier(
            jwks_uri="https://issuer-a.example.com/.well-known/jwks.json",
            issuer="https://issuer-a.example.com",
            audience="my-server",
        JWTVerifier(
            jwks_uri="https://issuer-b.example.com/.well-known/jwks.json",
            issuer="https://issuer-b.example.com",
            audience="my-server",

mcp = FastMCP("Multi-Issuer Server", auth=auth)

Without a server, no OAuth routes or metadata are served. This is appropriate for internal systems where clients already know how to obtain tokens.

## [​](#api-reference) API Reference

### [​](#multiauth) MultiAuth

| Parameter | Type | Description |
| --- | --- | --- |
| `server` | `AuthProvider | None` | Optional auth provider that owns routes and OAuth metadata. Also tried first for token verification. |
| `verifiers` | `list[TokenVerifier] | TokenVerifier` | One or more token verifiers tried after the server. |
| `base_url` | `str | None` | Override the base URL. Defaults to the server’s `base_url`. |
| `required_scopes` | `list[str] | None` | Override required scopes. Defaults to the server’s scopes. |

[Full OAuth Server

Previous](gofastmcp__com__servers__auth__full-oauth-server.md)[Authorization

Next](gofastmcp__com__servers__authorization.md)






