> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorization for Your MCP Server

> Learn how to protect your MCP server by requiring access tokens from authorized clients.

export const DownloadQuickstartButton = ({category, framework, label = "Download Sample"}) => {
  const [isDownloading, setIsDownloading] = useState(false);
  const githubRepo = 'auth0-samples/auth0-ai-samples';
  const filename = `${category}-${framework}-sample.zip`;
  const downloadSample = () => {
    setIsDownloading(true);
    const downloadUrl = `https://github.com/${githubRepo}/releases/latest/download/${filename}`;
    window.open(downloadUrl, '_blank');
    setTimeout(() => setIsDownloading(false), 1000);
  };
  return <div className="download-button-container">
      <button onClick={downloadSample} disabled={isDownloading} className={`download-button ${isDownloading ? 'downloading' : ''}`} aria-label={`Download ${category} ${framework} sample code`}>
        {isDownloading ? <>
            <svg className="download-spinner" width="16" height="16" viewBox="0 0 24 24" fill="none">
              <circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="2" fill="none" strokeDasharray="31.416" strokeDashoffset="31.416">
                <animate attributeName="stroke-dasharray" dur="2s" values="0 31.416;15.708 15.708;0 31.416" repeatCount="indefinite" />
                <animate attributeName="stroke-dashoffset" dur="2s" values="0;-15.708;-31.416" repeatCount="indefinite" />
              </circle>
            </svg>
            Downloading...
          </> : <>
            <Icon icon="download" color="white" />
            {label}
          </>}
      </button>
    </div>;
};

Authorization controls access to your MCP server so that only trusted clients can use its resources. In this quickstart, you'll learn how to secure your MCP server by requiring and validating client access tokens.

When an MCP client makes a request on behalf of a user, it must include a valid access token issued by Auth0. Your MCP server verifies this token and determines which tools and resources the client can access based on the user's permissions.

By the end of this quickstart, you will have an MCP server that:

* Requires access tokens for all incoming requests
* Validates OAuth 2.0 access tokens from authorized clients
* Enforces role-based access control to manage tool permissions

## Prerequisites

<AccordionGroup>
  <Accordion title="1. Create or log in to your Auth0 account">
    To continue with this quickstart, you need to have an [Auth0 account](https://auth0.com/signup).
  </Accordion>

  <Accordion title="2. Enable the Resource Parameter Compatibility Profile and Include Issuer in Authorization Responses">
    To use the `resource` parameter in your access tokens and the `iss` claim to identify your authorization server, you need to enable two toggles in the [Auth0 Dashboard](https://manage.auth0.com/dashboard/):

    1. Navigate to **Settings** on the left sidebar.
    2. Select [**Advanced**](https://manage.auth0.com/dashboard/#/tenant/advanced) in the top right corner.
    3. Scroll down to the **Settings** section and enable the following toggles:
       * **Resource Parameter Compatibility Profile**: Enables support for the `resource` parameter in authorization requests, allowing access tokens to be scoped to a specific API.
       * **Include Issuer in Authorization Responses**: Includes the `iss` parameter identifying the authorization server in authorization responses, helping clients defend against mix-up attacks.
  </Accordion>

  <Accordion title="3. Install the Auth0 CLI">
    This guide uses [Auth0 CLI](https://auth0.github.io/auth0-cli/) to configure an Auth0 tenant for secure MCP tool access.

    1. Follow the [Auth0 CLI installation instructions](https://auth0.github.io/auth0-cli/).
    2. Log in to your account with the Auth0 CLI:

    ```shell wrap lines theme={null}
    auth0 login --scopes "read:client_grants,create:client_grants,delete:client_grants,read:clients,create:clients,update:clients,read:resource_servers,create:resource_servers,update:resource_servers,read:roles,create:roles,update:roles,update:tenant_settings,read:connections,update:connections"
    ```

    Confirm you are in the correct tenant by double-checking the tenant domain in the terminal, or run the command below:

    ```shell theme={null}
    auth0 tenants list
    ```

    If more than one tenant is configured, the default tenant will be indicated by an arrow.
  </Accordion>

  <Accordion title="4. Install jq">
    To simplify the process of interacting with the Auth0 CLI, we recommend installing [jq](https://jqlang.org/download/). This will allow you to easily parse JSON responses from the CLI.

    <Tabs>
      <Tab title="macOS">
        <CodeBlock language="shell">brew install jq</CodeBlock>
      </Tab>

      <Tab title="Linux">
        <CodeBlock language="shell">sudo apt-get install jq</CodeBlock>
      </Tab>

      <Tab title="Windows">
        <CodeBlock language="shell">choco install jq</CodeBlock>
      </Tab>
    </Tabs>
  </Accordion>
</AccordionGroup>

## Configure tenant settings

<AccordionGroup>
  <Accordion title="1. Promote the connection to a domain-level connection">
    To allow third-party clients like MCP Inspector to use a connection such as a username-and-password database or a social connection, you need to promote the connection to a domain-level connection. [Learn more about configuring third-party applications](https://auth0.com/docs/get-started/applications/third-party-applications/configure-third-party-applications).

    <Steps>
      <Step title="List Your Connection">
        List your connections to get their IDs

        ```shell theme={null}
        auth0 api get connections
        ```
      </Step>

      <Step title="Choose Your Connections">
        From the list, identify which connections you want to use for the MCP server and copy the ID.

        * For the username-and-password database, look for the connection with the strategy `auth0`.
        * For the Google social connection, look for the connection with the strategy `google-oauth2`.
      </Step>

      <Step title="Upgrade the Connection to Domain-Level">
        For each of those specific connection IDs, run the following command to mark it as a domain-level connection. Replace `YOUR_CONNECTION_ID` with the actual ID (e.g., `con_XXXXXXXXXXXXXXXX`).

        ```shell wrap lines theme={null}
        auth0 api patch connections/YOUR_CONNECTION_ID --data '{"is_domain_connection": true}'
        ```
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="2. Create roles">
    The sample application in this quickstart is prepared to show different tools depending on the role of a given user. For example, a Tool Administrator will have access to different tools than a Tool User.

    Let's create roles that allow you to control which users can access which tools.

    For each role you need (e.g., "Tool Administrator", "Tool User"), run the create command as below.

    ```shell wrap lines theme={null}
    # Example for an admin role
    auth0 roles create --name "Tool Administrator" --description "Grants access to all MCP tools"

    # Example for a basic user role
    auth0 roles create --name "Tool User" --description "Grants access to basic MCP tools"
    ```

    Save the IDs from the output (they start with `rol_`), as you'll need them in a later step to assign permissions and users to these roles.
  </Accordion>

  <Accordion title="3. Assign roles to users">
    Find users and assign them to the roles. You can search by their email address:

    ```shell wrap lines theme={null}
    auth0 users search --query "email:\"example@google.com\""
    ```

    Copy the user ID (`USERID`) from the last command's output, then assign the role to the user:

    ```shell wrap lines theme={null}
    auth0 users roles assign "USER_ID_HERE" --roles "YOUR_ROLE_ID_HERE"
    ```
  </Accordion>
</AccordionGroup>

## Create an API to represent your MCP server

An MCP server is treated just like any other [API](https://auth0.com/docs/get-started/apis) in your Auth0 tenant, which means you can use the same access control, scoping, and authorization features. The API (also known as a Resource Server) represents your protected MCP Server.

Run the following command to [create an API](https://auth0.com/docs/get-started/auth0-overview/set-up-apis) in Auth0:

```shell wrap lines theme={null}
auth0 api post resource-servers --data '{
  "identifier": "http://localhost:3001/",
  "name": "MCP Tools API",
  "signing_alg": "RS256",
  "token_dialect": "rfc9068_profile_authz",
  "enforce_policies": true,
  "scopes": [
    {"value": "tool:whoami", "description": "Access the WhoAmI tool"},
    {"value": "tool:greet", "description": "Access the Greeting tool"}
  ]
}'
```

Note that `rfc9068_profile_authz` is used as the [token dialect](https://auth0.com/docs/get-started/apis/enable-role-based-access-control-for-apis#token-dialect-options) to include the `permissions` claim in the access token, which can be useful for the API to check user permissions without making additional calls.

For more details on protecting APIs with Auth0, check our [quickstarts](https://auth0.com/docs/quickstarts#backend%2Fapi).

<Accordion title="Assign permissions to roles">
  After creating the API and roles, assign the API permissions to the roles.

  ```shell wrap lines theme={null}
  # Example for admin role (all scopes)
  auth0 roles permissions add YOUR_ADMIN_ROLE_ID --api-id "http://localhost:3001/" --permissions "tool:whoami,tool:greet"

  # Example for user role (one scope)
  auth0 roles permissions add YOUR_USER_ROLE_ID --api-id "http://localhost:3001/" --permissions "tool:whoami"
  ```

  Replace `YOUR_ADMIN_ROLE_ID` and `YOUR_USER_ROLE_ID` with the role IDs you saved when creating the roles.
</Accordion>

## Sample app

<Tabs>
  <Tab title="Javascript" icon="js">
    <Tabs>
      <Tab title="Use sample app (recommended)">
        Start by downloading the sample app for this quickstart. The sample includes a FastMCP MCP server with an Auth0 integration in JavaScript.

        <DownloadQuickstartButton category="auth-for-mcp" framework="fastmcp-mcp-js" />

        Once downloaded, extract the files and open the project in your preferred IDE.
      </Tab>

      <Tab title="Clone GitHub repository">
        Clone the repository and navigate to the sample app folder which includes a FastMCP MCP server with an Auth0 integration in JavaScript.

        ```shell wrap lines theme={null}
        git clone https://github.com/auth0-samples/auth0-ai-samples.git
        cd auth0-ai-samples/auth-for-mcp/fastmcp-mcp-js
        ```

        Once cloned, open the project in your preferred IDE.
      </Tab>
    </Tabs>

    ## Install packages

    Ensure you have npm installed or follow the instructions to [install npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) in its documentation. In the `fastmcp-mcp-js` directory, install the required packages:

    ```shell theme={null}
    npm install
    ```

    ## Create your environment file

    In the `fastmcp-mcp-js` directory, run the following command to create a new `.env` file populated with all the required environment variables:

    ```shell wrap lines theme={null}
    DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') \
    && touch .env \
    && echo "AUTH0_DOMAIN=${DOMAIN}" > .env \
    && echo "AUTH0_AUDIENCE=http://localhost:3001/" >> .env \
    && echo "PORT=3001" >> .env \
    && echo "MCP_SERVER_URL=http://localhost:3001/" >> .env \
    && echo ".env file created with your Auth0 details:" \
    && cat .env
    ```

    ## Run your MCP server

    Run this command to start your server:

    ```shell theme={null}
    npm run start
    ```
  </Tab>

  <Tab title="Python" icon="python">
    <Tabs>
      <Tab title="Use sample app (recommended)">
        Start by downloading the sample app for this quickstart. The sample includes a FastMCP MCP server with an Auth0 integration in Python.

        <DownloadQuickstartButton category="auth-for-mcp" framework="fastmcp-mcp-python" />

        Once downloaded, extract the files and open the project in your preferred IDE.
      </Tab>

      <Tab title="Clone GitHub repository">
        Clone the repository and navigate to the sample app folder which includes a FastMCP MCP server with an Auth0 integration in Python.

        ```shell wrap lines theme={null}
        git clone https://github.com/auth0-samples/auth0-ai-samples.git
        cd auth0-ai-samples/auth-for-mcp/fastmcp-mcp-python
        ```

        Once cloned, open the project in your preferred IDE.
      </Tab>
    </Tabs>

    ## Install packages

    Ensure you have poetry installed or follow the instructions to [install poetry](https://python-poetry.org/docs/) in its documentation. In the `fastmcp-mcp-python` directory, install the required packages:

    ```shell theme={null}
    poetry install
    ```

    ## Create your environment file

    In the `fastmcp-mcp-python` directory, run the following command to create a new `.env` file populated with all the required environment variables:

    ```shell wrap lines theme={null}
    DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') \
    && touch .env \
    && echo "AUTH0_DOMAIN=${DOMAIN}" > .env \
    && echo "AUTH0_AUDIENCE=http://localhost:3001/" >> .env \
    && echo "PORT=3001" >> .env \
    && echo "MCP_SERVER_URL=http://localhost:3001/" >> .env \
    && echo ".env file created with your Auth0 details:" \
    && cat .env
    ```

    ## Run your MCP server

    Run this command to start your server:

    ```shell theme={null}
    poetry run python -m src.server
    ```
  </Tab>
</Tabs>

## Testing your MCP server

Now that your MCP server is up and running, you can test it by using tools like [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector).

<Card title="Learn how to test your Auth0-powered MCP server" href="/ai/docs/mcp/guides/test-your-mcp-server-with-mcp-inspector" icon="book" iconType="solid" horizontal />

## Next steps

* To set up first-party tool calling, complete the [Call Your APIs on a User's Behalf](./call-your-apis-on-users-behalf) quickstart.
