Skip to main content
To add OAuth authentication to your MCP server, you need to have an Identity Provider (IdP) that manages your users identities. Depending on your IdP, you can be in one of the 4 following cases:

Using an OAuth 2.1 compatible Identity Providers (IdP)

If you’re already using an OAuth 2.1 identity provider with Dynamic Client Registration (DCR), you simply need to configure your MCP server to advertise your IdP through OAuth metadata endpoints. The easiest way to do so is to rely on existing SDK helpers to provide such configuration on your server:
import { mcpAuthMetadataRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";

//...

app.use(
  mcpAuthMetadataRouter({
    oauthMetadata: {
      authorization_endpoint: "https://my-idp.com/oauth2/authorize",
      token_endpoint: "https://my-idp.com/oauth2/token",
      registration_endpoint: "https://my-idp.com/oauth2/register",
      response_types_supported: ["code"],
      code_challenge_methods_supported: ["S256"],
      token_endpoint_auth_methods_supported: ["client_secret_post"],
      issuer: "http://localhost:3000",
    },
    resourceServerUrl: new URL("http://localhost:3000"),
  })
);

const authMiddleware = requireBearerAuth({
  verifier: {
    verifyAccessToken: async (token) => {
      // Generic jwtDecode for JWT auth token or any IDP custom verification method

      return { token, clientId: "clientId", scopes: [], expiresAt: Date.now()/1000 + 600 }
    }
  }
});

app.post("/mcp", authMiddleware, async (req: Request, res: Response) => {});
app.get("/mcp", authMiddleware, async (req: Request, res: Response) => {});
app.delete("/mcp", authMiddleware, async (req: Request, res: Response) => {});

app.listen(3000);
Configuring your MCP server to use an existing Identity Provider (IdP) with OAuth requires knowledge of a the different oauth endpoint URLs. We have curated a list of endpoints for the most used IdPs here.
After deploying a new version of your MCP server on Alpic with such a configuration, you should see your server as Protected in the Settings tab of your project page. This will confirm that your MCP server is protected by OAuth.
We made Alpic to be fully compatible with your local server code. If your authentication code runs locally, it should work on Alpic. In the example above, you should keep the localhost URL for the resource server when your deploy to Alpic.

Using an OAuth 2.0 compatible Identity Provider (IdP) with no DCR

If you’re not using an OAuth 2.1 IdP with DCR, you can rely on Alpic’s Dynamic Client Registration proxy to handle the complexity associated with multiple OAuth clients registering to use your IdP. In order to leverage Alpic’s DCR proxy feature, you should configure your MCP server to advertise your IdP through OAuth metadata endpoints without mentioning a registration_endpoint property. The easiest way to do so is to rely on existing SDK helpers to provide such configuration on your server:
import { mcpAuthMetadataRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";

//...

app.use(
  mcpAuthMetadataRouter({
    oauthMetadata: {
      authorization_endpoint: "https://my-idp.com/oauth2/authorize",
      token_endpoint: "https://my-idp.com/oauth2/token",
      response_types_supported: ["code"],
      code_challenge_methods_supported: ["S256"],
      token_endpoint_auth_methods_supported: ["client_secret_post"],
      issuer: "http://localhost:3000",
    },
    resourceServerUrl: new URL("http://localhost:3000"),
  })
);

const authMiddleware = requireBearerAuth({
  verifier: {
    verifyAccessToken: async (token) => {
      // Generic jwtDecode for JWT auth token or any IDP custom verification method

      return { token, clientId: "clientId", scopes: [], expiresAt: Date.now()/1000 + 600 }
    }
  }
});

app.post("/mcp", authMiddleware, async (req: Request, res: Response) => {});
app.get("/mcp", authMiddleware, async (req: Request, res: Response) => {});
app.delete("/mcp", authMiddleware, async (req: Request, res: Response) => {});

app.listen(3000);
After deploying a new version of your MCP server on Alpic with such a configuration, check that your server is detected as Protected in the Settings tab of your project page. If that’s the case, you will see an option to activate Alpic DCR. In order to activate DCR, you should create a single OAuth client on your IdP. This client will be the one proxied by Alpic for every request users make to identify on your MCP server. Make sure to choose a generic enough name in case it’s displayed during the authentication process. The callback URL to use for this client is specified by Alpic when activating DCR. Please fill-in the activation form with newly created OAuth client ID, client secret and scopes to complete the DCR proxy setup.

Using and IdP without OAuth support

In the case you have an internal identity management system, or are using an identity management system that doesn’t support Oauth, you can use providers that take care of Oauth and DCR flow for you while keeping your identity system. Here are some providers supporting the MCP use-case: Once you have configured your MCP Oauth 2.1 workflow with that provider, you can use the examples above to integrate it into your MCP server.

Building from scratch

If you don’t have any identity system, you can build yours, or rely on one of the many Identiy Managment Systems out there. You can check our OAuth providers list to see which of them is supporting OAuth 2.1 with DCR or not.