Skip to main content

Get started

Choose a compatible OAuth 2.1 or OpenID Connect provider

MCP specification has some specific requirements for authorization:

While the last two are not mandatory, the first one is necessary to ensure a secure and compliant implementation.

note

In the new MCP draft, RFC 8414 will be mandated for authorization servers (providers). We'll update the documentation once the new draft is finalized.

You can check the MCP-compatible provider list to see if your provider is supported.

Install MCP Auth SDK

MCP Auth is available for both Python and TypeScript. Let us know if you need support for another language or framework!

pip install mcpauth

Or any other package manager you prefer, such as pipenv or poetry.

Init MCP Auth

The first step is to initialize the MCP Auth instance with your provider's authorization server metadata. If your provider conforms one of:

You can use the built-in function to fetch the metadata and initialize the MCP Auth instance:

from mcpauth import MCPAuth
from mcpauth.config import AuthServerType
from mcpauth.utils import fetch_server_config

mcp_auth = MCPAuth(
    server=fetch_server_config(
      '<auth-server-url>',
      type=AuthServerType.OIDC # or AuthServerType.OAUTH
    )
)

If you need to manually specify the metadata URL or endpoints, check Other ways to initialize MCP Auth.

Mount the metadata endpoint

To conform to the current MCP specification, MCP Auth mounts the OAuth 2.0 Authorization Server Metadata endpoint (/.well-known/oauth-authorization-server) to your MCP server:

from starlette.applications import Starlette

app = Starlette(routes=[
    mcp_auth.metadata_route(),
])

The URLs in the metadata are kept as-is, so the role of authorization server is fully delegated to the provider. You can test the metadata endpoint by visiting /.well-known/oauth-authorization-server in your MCP server.

Why only the metadata endpoint?

You may see the official SDKs provide an auth router that mounts authorization endpoints like /authorize, /token, etc. Here is why we don't do that:

  1. Mounting only the metadata endpoint allows you to leverage the full capabilities of your provider without "reinventing the wheel" and injecting unnecessary complexity into your MCP server.
  2. There's also an ongoing effort to shift the MCP server's role to a resource server and requires OAuth 2.0 Protected Resource Metadata (RFC 9728). Which means that the MCP server will not handle any authorization logic anymore (including the metadata endpoint), but only serve as a resource server that relies on the provider for authentication and authorization.
note

We will update MCP Auth to support the new MCP specification when it is finalized. In the meantime, you can use the current version which is compatible with the current specification.

Use the Bearer auth middleware

Once the MCP Auth instance is initialized, you can apply the Bearer auth middleware to protect your MCP routes:

from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.routing import Mount
from mcpauth import MCPAuth
from mcp.server.fastmcp import FastMCP

mcp = FastMCP()
mcp_auth = MCPAuth(
  # Initialize with your auth server config
)
bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt", required_scopes=["read", "write"]
)

app = Starlette(routes=[
    mcp_auth.metadata_route(),
    Mount(
        "/",
        app=mcp.sse_app(),
        middleware=[Middleware(bearer_auth)],
    ),
])

In the example above, we specified the jwt token type and required the read and write scopes. It will automatically validate the JWT (JSON Web Token) and populate an object with the authenticated user's information.

info

Didn't hear about JWT (JSON Web Token) before? Don't worry, you can keep reading the documentation and we'll explain it when needed. You can also check Auth Wiki for a quick introduction.

For more information on the Bearer auth configuration, check the Configure Bearer auth.

Retrieve the auth info in your MCP implementation

Once the Bearer auth middleware is applied, you can access the authenticated user's (or identity's) information in your MCP implementation:

MCP Auth will store the authenticated user's information in a context variable after successful authentication once the Bearer auth middleware is applied. You can access it in your MCP tool handlers like this:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP()
mcp_auth = MCPAuth(
  # Initialize with your auth server config
)

@mcp.tool()
def add(a: int, b: int):
    """
    A tool that adds two numbers.
    The authenticated user's information will be available in the context.
    """
    auth_info = mcp_auth.auth_info # Access the auth info in the current context
    if auth_info:
        print(f"Authenticated user: {auth_info.claims}")
    return a + b

Next steps

Continue reading to learn an end-to-end example of how to integrate MCP Auth with your MCP server, and how to handle the auth flow in MCP clients.