Skip to main content

Tutorial: Who am I?

This tutorial will guide you through the process of setting up MCP Auth to authenticate users and retrieve their identity information from the authorization server.

After completing this tutorial, you will have:

  • ✅ A basic understanding of how to use MCP Auth to authenticate users.
  • ✅ A MCP server that offers a tool to retrieve user identity information.

Overview

The tutorial will involve the following components:

  • MCP server: A simple MCP server that uses MCP official SDKs to handle requests.
  • MCP inspector: A visual testing tool for MCP servers. It also acts as an OAuth / OIDC client to initiate the authorization flow and retrieve access tokens.
  • Authorization server: An OAuth 2.1 or OpenID Connect provider that manages user identities and issues access tokens.

Here's a high-level diagram of the interaction between these components:

Understand your authorization server

Retrieving user identity information

To complete this tutorial, your authorization server should offer an API to retrieve user identity information:

Logto is an OpenID Connect provider that supports the standard userinfo endpoint to retrieve user identity information.

To fetch an access token that can be used to access the userinfo endpoint, at least two scopes are required: openid and profile. You can continue reading as we'll cover the scope configuration later.

Dynamic Client Registration

Dynamic Client Registration is not required for this tutorial, but it can be useful if you want to automate the MCP client registration process with your authorization server. Check Is Dynamic Client Registration required? for more details.

Set up the MCP server

We will use the MCP official SDKs to create a MCP server with a whoami tool that retrieves user identity information from the authorization server.

Create a new project

mkdir mcp-server
cd mcp-server
uv init # Or use `pipenv` or `poetry` to create a new virtual environment

Install the MCP SDK and dependencies

pip install "mcp[cli]" starlette uvicorn

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

Create the MCP server

First, let's create an MCP server that implements a whoami tool.

Create a file named whoami.py and add the following code:

from mcp.server.fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount

mcp = FastMCP("WhoAmI")

@mcp.tool()
def whoami() -> dict[str, Any]:
    """A tool that returns the current user's information."""
    return {"error": "Not authenticated"}

app = Starlette(
    routes=[Mount('/', app=mcp.sse_app())]
)

Run the server with:

uvicorn whoami:app --host 0.0.0.0 --port 3001

Inspect the MCP server

Clone and run MCP inspector

Now that we have the MCP server running, we can use the MCP inspector to see if the whoami tool is available.

Due to the limit of the current implementation, we've forked the MCP inspector to make it more flexible and scalable for authentication and authorization. We've also submitted a pull request to the original repository to include our changes.

To run the MCP inspector, you can use the following command (Node.js is required):

git clone https://github.com/mcp-auth/inspector.git
cd inspector
npm install
npm run dev

Then, open your browser and navigate to http://localhost:6274/ (or other URL shown in the terminal) to access the MCP inspector.

Connect MCP inspector to the MCP server

Before we proceed, check the following configuration in MCP inspector:

  • Transport Type: Set to SSE.
  • URL: Set to the URL of your MCP server. In our case, it should be http://localhost:3001/sse.

Now you can click the "Connect" button to see if the MCP inspector can connect to the MCP server. If everything is okay, you should see the "Connected" status in the MCP inspector.

Checkpoint: Run the whoami tool

  1. In the top menu of the MCP inspector, click on the "Tools" tab.
  2. Click on the "List Tools" button.
  3. You should see the whoami tool listed on the page. Click on it to open the tool details.
  4. You should see the "Run Tool" button in the right side. Click on it to run the tool.
  5. You should see the tool result with the JSON response {"error": "Not authenticated"}.

MCP inspector first run

Integrate with your authorization server

To complete this section, there are several considerations to take into account:

The issuer URL of your authorization server

This is usually the base URL of your authorization server, such as https://auth.example.com. Some providers may have a path like https://example.logto.app/oidc, so make sure to check your provider's documentation.

How to retrieve the authorization server metadata
  • If your authorization server conforms to the OAuth 2.0 Authorization Server Metadata or OpenID Connect Discovery, you can use the MCP Auth built-in utilities to fetch the metadata automatically.
  • If your authorization server does not conform to these standards, you will need to manually specify the metadata URL or endpoints in the MCP server configuration. Check your provider's documentation for the specific endpoints.
How to register the MCP inspector as a client in your authorization server
  • If your authorization server supports Dynamic Client Registration, you can skip this step as the MCP inspector will automatically register itself as a client.
  • If your authorization server does not support Dynamic Client Registration, you will need to manually register the MCP inspector as a client in your authorization server.
How to retrieve user identity information and how to configure the authorization request parameters
  • For OpenID Connect providers: usually you need to request at least the openid and profile scopes when initiating the authorization flow. This will ensure that the access token returned by the authorization server contains the necessary scopes to access the userinfo endpoint to retrieve user identity information.

    Note: Some of the providers may not support the userinfo endpoint.

  • For OAuth 2.0 / OAuth 2.1 providers: check your provider's documentation to see how to retrieve user identity information using an access token and what parameters are required to fetch such access token when invoking the authorization flow.

While each provider may have its own specific requirements, the following steps will guide you through the process of integrating the MCP inspector and MCP server with provider-specific configurations.

Register MCP inspector as a client

Integrating with Logto is straightforward as it's an OpenID Connect provider that supports the standard userinfo endpoint to retrieve user identity information.

Since Logto does not support Dynamic Client Registration yet, you will need to manually register the MCP inspector as a client in your Logto tenant:

  1. Open your MCP inspector, click on the "OAuth Configuration" button. Copy the Redirect URL (auto-populated) value, which should be something like http://localhost:6274/oauth/callback.
  2. Sign in to Logto Console (or your self-hosted Logto Console).
  3. Navigate to the "Applications" tab, click on "Create application". In the bottom of the page, click on "Create app without framework".
  4. Fill in the application details, then click on "Create application":
    • Select an application type: Choose "Single-page application".
    • Application name: Enter a name for your application, e.g., "MCP Inspector".
  5. In the "Settings / Redirect URIs" section, paste the Redirect URL (auto-populated) value you copied from the MCP inspector. Then click on "Save changes" in the bottom bar.
  6. In the top card, you will see the "App ID" value. Copy it.
  7. Go back to the MCP inspector and paste the "App ID" value in the "OAuth Configuration" section under "Client ID".
  8. Enter the value {"scope": "openid profile email"} in the "Auth Params" field. This will ensure that the access token returned by Logto contains the necessary scopes to access the userinfo endpoint.

Set up MCP auth

In your MCP server project, you need to install the MCP Auth SDK and configure it to use your authorization server metadata.

First, install the mcpauth package:

pip install mcpauth

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

MCP Auth requires the authorization server metadata to be able to initialize. Depending on your provider:

The issuer URL can be found in your application details page in Logto Console, in the "Endpoints & Credentials / Issuer endpoint" section. It should look like https://my-project.logto.app/oidc.

Update the whoami.py to include the MCP Auth configuration:

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

auth_issuer = '<issuer-endpoint>'  # Replace with your issuer endpoint
auth_server_config = fetch_server_config(auth_issuer, type=AuthServerType.OIDC)
mcp_auth = MCPAuth(server=auth_server_config)

Now, we need to create a custom access token verifier that will fetch the user identity information from the authorization server using the access token provided by the MCP inspector.

import pydantic
import requests
from mcpauth.exceptions import (
    MCPAuthTokenVerificationException,
    MCPAuthTokenVerificationExceptionCode,
)
from mcpauth.types import AuthInfo

def verify_access_token(token: str) -> AuthInfo:
    """
    Verifies the provided Bearer token by fetching user information from the authorization server.
    If the token is valid, it returns an `AuthInfo` object containing the user's information.

    :param token: The Bearer token to received from the MCP inspector.
    """

    issuer = auth_server_config.metadata.issuer
    endpoint = auth_server_config.metadata.userinfo_endpoint # The provider should support the userinfo endpoint
    if not endpoint:
        raise ValueError(
            "Userinfo endpoint is not configured in the auth server metadata."
        )

    try:
        response = requests.get(
            endpoint,
            headers={"Authorization": f"Bearer {token}"}, # Standard Bearer token header
        )
        response.raise_for_status() # Ensure we raise an error for HTTP errors
        json = response.json() # Parse the JSON response
        return AuthInfo(
            token=token,
            subject=json.get("sub"), # 'sub' is a standard claim for the subject (user's ID)
            issuer=issuer, # Use the issuer from the metadata
            claims=json, # Include all claims (JSON fields) returned by the userinfo endpoint
        )
    # `AuthInfo` is a Pydantic model, so validation errors usually mean the response didn't match
    # the expected structure
    except pydantic.ValidationError as e:
        raise MCPAuthTokenVerificationException(
            MCPAuthTokenVerificationExceptionCode.INVALID_TOKEN,
            cause=e,
        )
    # Handle other exceptions that may occur during the request
    except Exception as e:
        raise MCPAuthTokenVerificationException(
            MCPAuthTokenVerificationExceptionCode.TOKEN_VERIFICATION_FAILED,
            cause=e,
        )

Update MCP server

We are almost done! It's time to update the MCP server to apply the MCP Auth route and middleware function, then make the whoami tool return the actual user identity information.

@mcp.tool()
def whoami() -> dict[str, Any]:
    """A tool that returns the current user's information."""
    return (
        mcp_auth.auth_info.claims
        if mcp_auth.auth_info # This will be populated by the Bearer auth middleware
        else {"error": "Not authenticated"}
    )

# ...

bearer_auth = Middleware(mcp_auth.bearer_auth_middleware(verify_access_token))
app = Starlette(
    routes=[
        # Add the metadata route (`/.well-known/oauth-authorization-server`)
        mcp_auth.metadata_route(),
        # Protect the MCP server with the Bearer auth middleware
        Mount('/', app=mcp.sse_app(), middleware=[bearer_auth]),
    ],
)

Checkpoint: Run the whoami tool with authentication

Restart your MCP server and open the MCP inspector in your browser. When you click the "Connect" button, you should be redirected to your authorization server's sign-in page.

Once you sign in and back to the MCP inspector, repeat the actions we did in the previous checkpoint to run the whoami tool. This time, you should see the user identity information returned by the authorization server.

MCP inspector whoami tool result

info

Check out the MCP Auth Python SDK repository for the complete code of the MCP server (OIDC version).

Closing notes

🎊 Congratulations! You have successfully completed the tutorial. Let's recap what we've done:

  • Setting up a basic MCP server with the whoami tool
  • Integrating the MCP server with an authorization server using MCP Auth
  • Configuring the MCP Inspector to authenticate users and retrieve their identity information

You may also want to explore some advanced topics, including:

Be sure to check out other tutorials and documentation to make the most of MCP Auth.