Skip to content
Scalekit Docs
Go to Dashboard

OAuth authorization server for MCP servers

Secure your Model Context Protocol (MCP) servers with Scalekit’s drop-in OAuth 2.1 authorization solution

Scalekit provides a production-ready OAuth 2.1 authorization server that implements the MCP authorization specification. This guide shows you how to integrate OAuth-based authentication and authorization into your MCP server with minimal code changes.

Why use Scalekit OAuth for MCP servers?

  • Identity-scoped access: Restrict each token to a specific user or agent.
  • Granular permissions: Control exactly which tools and data each client can access using fine-grained scopes.
  • OAuth 2.1 compliance: Rely on a modern, secure, and widely adopted authorization standard.
  • Comprehensive audit trails: Track who accessed what, when, and with which permissions.

For a deeper explanation of why an OAuth layer is essential for remote MCP servers, read the MCP authorization overview.

The Scalekit OAuth authorization server and your MCP server work together to secure access and enforce permissions.

Scalekit OAuth authorization server

Acts as the identity provider for your MCP server. It:

  • Authenticates users and agents
  • Issues access tokens with fine-grained scopes
  • Manages OAuth 2.1 flows (authorization code, client credentials)
  • Supports dynamic client registration for easy onboarding

Your MCP server

Validates incoming access tokens and enforces the permissions encoded in each token. Only requests with valid, authorized tokens are allowed.

This separation of responsibilities ensures a clear boundary: Scalekit handles identity and token issuance, while your MCP server focuses on business logic of executing the actual tool calls.

Before you begin, ensure you have:

  1. Access to your Scalekit account and the API credentials. If you don’t have a Scalekit account yet, you can signup here.

  2. Installed Scalekit SDK into your project

    Terminal window
    npm install @scalekit/sdk
    import { Scalekit } from '@scalekit-sdk/node';
    const scalekit = new Scalekit(
    '<SCALEKIT_ENVIRONMENT_URL>',
    '<SCALEKIT_CLIENT_ID>',
    '<SCALEKIT_CLIENT_SECRET>',
    );

In the Scalekit dashboard, navigate to MCP servers and click Add MCP server. Configure your server with the following settings:

MCP server registration

Basic configuration:

  • Server name: A display name that users will see during authorization (e.g., “My AI Assistant”)
  • Resource identifier: Your MCP server’s unique identifier, typically your server’s URL (e.g., https://mcp.mycompany.com). Access tokens minted by Scalekit will have the resource identifier as aud claim.

Access control settings:

  • Allow dynamic client registration — Enables MCP clients to register automatically without manual approval. For security reasons, Scalekit ensures that any client that registers via DCR has to implement PKCE-based OAuth 2.1 flow to prevent authorization code interception attacks.

Token configuration:

  • Access token lifetime: Recommended 300-3600 seconds (5 minutes to 1 hour)

Authentication Provider:

  • Use Scalekit: If you are already using Scalekit to power authentication for your other resources like web application, mobile application, API etc, you can continue to use Scalekit as the authentication provider for your MCP server too.

  • Use your own authentication provider: If you are using any other authentication provider like Microsoft Entra, Google Workspace, AWS Cognito, Auth0, Keycloak etc, you can configure Scalekit to integrate with your existing auth system to validate user identity.

Step 2: Implement resource metadata discovery

Section titled “Step 2: Implement resource metadata discovery”

Once you have added your MCP server in the Scalekit dashboard, you will be presented with the protected resource metadata information that you can copy directly from the Scalekit Dashboard and implement in your MCP Server.

MCP clients discover your authorization server through the OAuth 2.0 protected resource metadata endpoint.

Resource Metadata Information

Below is the code sample to implement resource metadata discovery in your MCP Server:

// Required: OAuth Protected Resource Metadata endpoint
// Copy the actual well-known endpoint and the corresponding metadata from the Scalekit dashboard. What is shown here is just a sample
app.get('/.well-known/oauth-protected-resource', (req, res) => {
res.json({
"authorization_servers": [
"https://your-company.scalekit.com/resources/res_82829009141891595"
],
"bearer_methods_supported": [
"header"
],
"resource": "https://mcp.mycompany.com",
"resource_documentation": "https://mcp.mycompany.com/docs",
"scopes_supported": ["weather:read", "weather:write"]
});
});

Description of the OAuth Protected Resource Metadata:

FieldDescription
resourceThe identifier of the resource server. This is the unique identifier of your MCP Server. Every token that Scalekit issues will have this value as aud claim.
authorization_serversA list of authorization servers that are trusted by the resource server. MCP Clients use this information to discover more about the authorization server capability by fetching the authorization server.
bearer_methods_supportedA list of methods that are supported for bearer tokens. MCP Clients send the OAuth token as Authorization: Bearer <token> header.
resource_documentationA URL to the documentation of the resource server.
scopes_supportedA list of scopes that are supported by the resource server. MCP Clients use this information to determine which scopes that they would like the token for as part of the OAuth authorize request.

Step 3: Validate Bearer Token in your MCP Server

Section titled “Step 3: Validate Bearer Token in your MCP Server”

Your MCP server needs to validate whether all the incoming requests have a valid access token. Below is a sample middleware implementation if you are using expressjs for implementing your MCP Server.

You can use Scalekit SDKs (across Node.js, Java, GoLang, Python) to determine whether the token is valid or not and whether the token has appropriate claim values like aud, iss, exp, iat, scope etc.

import { Scalekit, TokenValidationOptions } from '@scalekit-sdk/node';
import { NextFunction, Request, Response } from 'express';
const scalekit = new Scalekit('<SCALEKIT_ENVIRONMENT_URL>', '<SCALEKIT_CLIENT_ID>', '<SCALEKIT_CLIENT_SECRET>');
// your resource id that you configure in the scalekit dashboard
const RESOURCE_ID = `https://your-mcp-server.com`;
// your resource metadata endpoint that you can copy from the scalekit dashboard
const resource_metadata_endpoint = `https://your-mcp-server.com/.well-known/oauth-protected-resource`;
export const WWWHeader = {HeaderKey: 'WWW-Authenticate',HeaderValue: `Bearer realm="OAuth", resource_metadata="${resource_metadata_endpoint}"`}
export async function authMiddleware(req: Request, res: Response, next: NextFunction) {
try {
// Allow public access to well-known endpoints
if (req.path.includes('.well-known')) {
return next();
}
// Apply authentication to all MCP requests
const authHeader = req.headers['authorization'];
const token = authHeader?.startsWith('Bearer ')? authHeader.split('Bearer ')[1]?.trim(): null;
if (!token) {
throw new Error('Missing or invalid Bearer token');
}
await scalekit.validateToken(token, { audience: [RESOURCE_ID] });
next();
} catch (err) {
return res.status(401).set(WWWHeader.HeaderKey, WWWHeader.HeaderValue).end();
}
}
// Apply to all MCP endpoints
app.use('/', authMiddleware);

Step 4: (Optional) Implement Scope-based authorization at the tool execution level

Section titled “Step 4: (Optional) Implement Scope-based authorization at the tool execution level”

Implement scope validation at the MCP tool execution level to ensure that the tool is only executed if the user has authorized the MCP client for the required scope.

try{
await scalekit.validateToken(token, { audience: [RESOURCE_ID], requiredScopes: [scope] });
} catch(error){
return res.status(403).json({
error: 'insufficient_scope',
error_description: `Required scope: ${scope}`,
scope: scope
});
}

Download our sample MCP Server: We have put together a simple MCP server that you can check out and run it locally to test the end to end functionality of a working MCP server complete with authentication and authorization. You can download and execute a sample MCP server implementation from GitHub.