Speakeasy Logo
Skip to Content

Build MCP servers with external OAuth

When building production MCP servers, you often need to protect sensitive endpoints with OAuth authentication. This guide shows you how to build an MCP server with external OAuth authentication. We’ll use FusionAuth as an example, but you can use any OAuth 2.0 provider you have set up (such as Auth0, Okta, Keycloak, or your own OAuth server).

We’ll build an enhanced version of the Push Advisor API from earlier guides, adding OAuth-protected endpoints that demonstrate real-world authentication patterns.

:::tip[Already have OAuth set up?] If you already have an API with OAuth authentication and just want to configure Gram to use it, you can skip directly to Configuring Gram to use OAuth. :::

:::note[Live demo available] You can test the complete OAuth implementation at https://gram-oauth.abdulbaaridavids04.workers.dev  with a working login page, protected endpoints, and OAuth discovery metadata. :::

What we’ll build

In this guide, we’ll:

  • First, set up an API with both public and OAuth-protected endpoints
  • Next, configure an external OAuth provider (we’ll use FusionAuth as an example)
  • Then create a manual login flow for token testing
  • Finally, integrate with Gram’s OAuth configuration and test protected endpoints in the playground

Setting up the project

First, we’ll start with extending the Push Advisor API  with an OAuth-protected endpoint:

We’ve added a deploy-history endpoint that requires OAuth authentication. We’ve also added a login endpoint that provides a manual login page for token generation.

Configuring your OAuth provider

Before we implement OAuth protection in our API, we need to set up an OAuth provider. In this example, we’ll use FusionAuth, but the same principles apply to any OAuth 2.0 compliant provider like Auth0, Okta, Keycloak, or your own implementation.

Application setup

First, we’ll set up our OAuth provider to work with our API. These steps are similar across different OAuth providers:

  1. Create Application: In your OAuth provider’s admin panel, create a new application/client named “Push Advisor API”

  2. OAuth Configuration:

    • Enable Authorization Code grant type
    • Set redirect URLs:

OAuth Application Settings (FusionAuth example)

  1. Get Credentials: Note the Client ID and Client Secret for your configuration

API configuration

Now we can configure our OAuth provider settings in the API. Replace these values with your actual OAuth provider’s configuration:

Next, we’ll implement the OAuth protection within the API. We’ll add middleware that validates OAuth tokens against our external provider.

Protected endpoint implementation

Next, we’ll implement endpoints that require authentication:

OAuth discovery endpoint

We’ll also need to implement the OAuth discovery endpoint required by the MCP specification:

Manual login page

For testing purposes, we’ll create a basic login page for token generation:

API Login Page

Defining OAuth in the OpenAPI document

Next, we’ll document our OAuth configuration in the OpenAPI document, you can read more about how Gram uses the OpenAPI document here.

Configuring Gram to use OAuth

Now we’ll configure Gram to work with our external OAuth server. After uploading the OpenAPI document, and creating a new toolset, go to the toolset settings page and click Connect OAuth.

:::note[Note] You’ll need to make your toolset public to use OAuth. :::

In the OAuth configuration page, choose External Server instead of OAuth Proxy and enter the server slug as well as the metadata for your OAuth server.

Gram OAuth Server Configuration

The OAuth Authorization Server Metadata is a JSON object that describes the OAuth server. It’s used by Gram to discover the OAuth server’s capabilities.

You can read more about the OAuth Authorization Server Metadata here .

:::tip[Using different OAuth providers] The metadata format is standardized across OAuth providers. Most providers offer a discovery endpoint (like /.well-known/openid-configuration) that returns this metadata automatically. Check your OAuth provider’s documentation for their specific discovery URL or metadata format. :::

Testing in Gram playground

Finally, let’s test everything in the Gram playground.

After uploading our OpenAPI document and creating a toolset, we’ll go to the playground to test it. When we ask the AI agent to get deployment history, it will automatically detect that OAuth authentication is required:

Gram Playground Testing

Notice how the environment variables section shows PUSH_ADVISOR_OAUTH_ACCESS_TOKEN is <EMPTY>, and the agent tells us exactly what we need to do to authenticate. The agent can also discover the OAuth requirements automatically by calling the discovery endpoint.

we can see that an OAuth access token is required but not yet provided:

Gram Access Token Required

:::note[Note] In the Gram playground, you need to manually add OAuth tokens to environment variables for testing. In a proper MCP client implementation, the OAuth flow would be handled automatically by the client, including token refresh and management. :::

Getting an OAuth token

To test our protected endpoints, we need to get a valid OAuth token. Here’s how a user would get an OAuth token:

  1. Visit the login page: First, we go to the /login page provided by the API to start the authentication process

API Login Page

  1. Redirect to OAuth Provider: Click “Login with OAuth Provider” which redirects to your OAuth provider’s login screen (in this example, FusionAuth):

OAuth Provider Login Screen (FusionAuth example)

  1. Complete authentication: After logging in, your OAuth provider redirects back to our API with an authorization code

  2. Get the access token: Copy the access token from the success page

OAuth Token Success

Adding the token to Gram

Now we can add our OAuth token to the Authentication environment variables in Gram:

Gram Playground OAuth Token

Once we’ve added a valid OAuth token, we can test the protected endpoints in the playground:

Gram OAuth Complete

Troubleshooting

OAuth is a complex topic, and there are many ways to configure it. Here are some common issues and how to troubleshoot them.

Common issues

Invalid redirect URI: Ensure all redirect URLs are configured in your OAuth provider

Token validation fails: Check that your client credentials are correct and the OAuth provider is accessible

CORS issues: Include proper CORS headers for browser-based OAuth flows

Scope mismatches: Verify that requested scopes match what’s configured in your OAuth provider

Last updated on