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

# MCP Auth

> Let your users connect to MCP servers through Nango

MCP Auth lets your application authorize end users to access external MCP servers, such as Notion MCP, Linear MCP, or HubSpot MCP, so you can call those servers’ tools on behalf of each user.

Nango handles OAuth with the MCP provider and stores the tokens. You can then use the connection to call the MCP server via Nango’s [proxy](https://nango.dev/docs/reference/backend/http-api/proxy/post.md).

## Two ways to use MCP Auth

| Type | Use case | Examples |
| - | - | - |
| **Catalog MCP servers** | Official MCP servers listed in [Nango's catalog](https://nango.dev/api-integrations?category=mcp) | [HubSpot (MCP)](https://nango.dev/docs/api-integrations/hubspot-mcp.md), [Notion MCP](https://nango.dev/docs/api-integrations/notion-mcp.md), [Linear MCP](https://nango.dev/docs/api-integrations/linear-mcp.md) |
| **Generic MCP Server OAuth2** | Let your users connect any server that supports the [MCP Protocol](https://modelcontextprotocol.io/specification/draft). | Custom servers |

If you are missing a catalog MCP server you can [request it](https://nango.dev/docs/integrations/contribute-or-request-api.md).

## How to use it

### Catalog MCP servers

1. **Create the integration**\
   In the Nango UI: [Integrations](https://app.nango.dev/dev/integrations) → *Configure New Integration* → choose the MCP provider (e.g. *HubSpot (MCP)*, *Notion MCP*).\
   Some providers, for example HubSpot MCP, require you to [register an MCP auth app](https://nango.dev/docs/api-integrations/hubspot-mcp/how-to-register-your-own-hubspot-mcp-api-oauth-app) and add **Client ID** and **Client Secret** in Nango. But most support dynamic client registrations: You can just enable them on Nango, and Nango registers a client for you in the background.

   > [accordion] For agents
   >
   > Create the integration with the API. MCP providers use the `MCP_OAUTH2` credentials type. Nango supports three client registration modes, set per provider in the catalog:
   >
   > | Mode | Who registers the client | `client_id`/`client_secret` in requests |
   > | - | - | - |
   > | **static** | You, on the provider's developer portal | Required on create, editable on update |
   > | **dynamic** (DCR) | Nango, automatically, via the MCP server's dynamic client registration endpoint | Omit entirely — Nango manages them |
   > | **cimd** (Client ID Metadata Document) | Nango, by publishing a metadata document the provider fetches at connect time | Omit entirely — Nango manages them. Requires your Nango instance to be reachable at a public HTTPS URL (always true on Nango Cloud; a self-hosted instance must set `NANGO_SERVER_URL` to a public `https://` URL) |
   >
   > > [tab] cURL (static — client registered with the provider)
   > >
   > > ```bash theme={null}
   > > curl --request POST \
   > >   --url https://api.nango.dev/integrations \
   > >   --header 'Authorization: Bearer <NANGO-API-KEY>' \
   > >   --header 'Content-Type: application/json' \
   > >   --data '{
   > >     "unique_key": "<INTEGRATION-ID>",
   > >     "provider": "<PROVIDER>",
   > >     "credentials": {
   > >       "type": "MCP_OAUTH2",
   > >       "client_id": "<CLIENT-ID>",
   > >       "client_secret": "<CLIENT-SECRET>"
   > >     }
   > >   }'
   > > ```
   >
   > > [tab] cURL (dynamic or cimd)
   > >
   > > ```bash theme={null}
   > > curl --request POST \
   > >   --url https://api.nango.dev/integrations \
   > >   --header 'Authorization: Bearer <NANGO-API-KEY>' \
   > >   --header 'Content-Type: application/json' \
   > >   --data '{
   > >     "unique_key": "<INTEGRATION-ID>",
   > >     "provider": "<PROVIDER>"
   > >   }'
   > > ```
   > >
   > > Nango registers (or publishes) the OAuth client automatically — omit `credentials` entirely.
   >
   > **Read it back** — [Get an integration](https://nango.dev/docs/reference/backend/http-api/integration/get.md) with `?include=credentials` to see the stored `client_id`/`client_secret`/`scopes` (requires the `environment:integrations:read_credentials` scope):
   >
   > ```bash theme={null}
   > curl --request GET \
   >   --url 'https://api.nango.dev/integrations/<INTEGRATION-ID>?include=credentials' \
   >   --header 'Authorization: Bearer <NANGO-API-KEY>'
   > ```
   >
   > For `dynamic` and `cimd` providers, `client_secret` and `scopes` can come back empty (`""`) or `null` right after creation — the MCP server's registration response doesn't always issue a client secret (a public-client registration is common for DCR), and scopes are only set when you explicitly configure them. That's expected, not a sign the registration failed. Scopes can be set or changed via the update endpoint in any mode, including `dynamic` and `cimd` — only `client_id`/`client_secret` are restricted to `static` providers.
   >
   > [List all integrations](https://nango.dev/docs/reference/backend/http-api/integration/list.md) works the same as for any other provider:
   >
   > ```bash theme={null}
   > curl --request GET \
   >   --url https://api.nango.dev/integrations \
   >   --header 'Authorization: Bearer <NANGO-API-KEY>'
   > ```
   >
   > **Update** — rotate credentials or change scopes with the same `MCP_OAUTH2` credentials shape. `client_id`/`client_secret` can only be set for `static` providers; Nango rejects the request if you try to set them on a `dynamic` or `cimd` integration, since it manages those itself:
   >
   > ```bash theme={null}
   > curl --request PATCH \
   >   --url https://api.nango.dev/integrations/<INTEGRATION-ID> \
   >   --header 'Authorization: Bearer <NANGO-API-KEY>' \
   >   --header 'Content-Type: application/json' \
   >   --data '{
   >     "credentials": {
   >       "type": "MCP_OAUTH2",
   >       "client_secret": "<NEW-CLIENT-SECRET>",
   >       "scopes": "<SCOPE-1>,<SCOPE-2>"
   >     }
   >   }'
   > ```
   >
   > **Delete** — same as any other integration:
   >
   > ```bash theme={null}
   > curl --request DELETE \
   >   --url https://api.nango.dev/integrations/<INTEGRATION-ID> \
   >   --header 'Authorization: Bearer <NANGO-API-KEY>'
   > ```
   >
   > For all fields and response shapes, see [Create](https://nango.dev/docs/reference/backend/http-api/integration/create.md), [Get](https://nango.dev/docs/reference/backend/http-api/integration/get.md), [List](https://nango.dev/docs/reference/backend/http-api/integration/list.md), [Update](https://nango.dev/docs/reference/backend/http-api/integration/update.md), and [Delete an integration](https://nango.dev/docs/reference/backend/http-api/integration/delete.md).

2. **Run the same auth flow as standard OAuth**
   * Backend: [create a Connect session](https://nango.dev/docs/guides/auth/auth-guide.md#generate-session-token) with `allowed_integrations: ['<integration-id>']` (e.g. `hubspot-mcp`, `notion-mcp`).
   * Frontend: [open the Connect UI](https://nango.dev/docs/guides/auth/auth-guide.md#trigger-auth-flow) with the session token.
   * Backend: [persist the connection ID](https://nango.dev/docs/guides/auth/auth-guide.md#save-connection-id-from-webhook) from the auth webhook or Connect UI callback.

3. **Call the MCP server**\
   Use the stored `connection_id` and integration id (e.g. `hubspot-mcp`) with the [Proxy API](https://nango.dev/docs/reference/backend/http-api/proxy/post.md) (JSON-RPC `tools/call`, etc.).

### Generic MCP Server OAuth2

1. **Create a generic MCP integration**\
   [Integrations](https://app.nango.dev/dev/integrations) → *Configure New Integration* → *MCP Server OAuth2 (Generic)*. Optionally set **OAuth Client Name**, **URI**, and **Logo URI** (used in dynamic client registration with the MCP server).

2. **Same Connect session + Connect UI flow**\
   As above: backend creates a session with `allowed_integrations: ['mcp-generic']` (or your custom integration id), frontend opens Connect UI with that token, backend stores the connection ID.

3. **End user supplies the MCP server URL**\
   When the user starts the connection, the Connect UI prompts for **MCP Server URL** (e.g. `https://mcp.notion.com/mcp`). Nango automatically discovers the OAuth endpoints from the server and walks the user through the OAuth connection flow.

4. **Call the MCP server**\
   Same as pre-built: use the connection with the [Proxy API](https://nango.dev/docs/reference/backend/http-api/proxy/post.md). The connection is tied to the MCP server URL the user entered.

> [!NOTE]
>
> Our generic MCP provider currently only works with MCP servers that support automatic client registration (DCR, or CIMD).

## End user experience

* **Catalog MCP servers**\
  User sees a list of supported MCP servers in your app → clicks connect → is redirected to the provider’s OAuth page (e.g. HubSpot or Notion) → signs in and approves → connection is created in Nango

* **MCP Generic**\
  User clicks connect → sees a form asking for the MCP Server URL → submits → is redirected to that MCP server’s OAuth page → signs in and approves → connection is created in Nango

In both cases, your app only needs to open the Connect UI and pass the session token. Nango handles the rest.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.