Secure your Model Context Protocol (MCP) servers with Scalekit's drop-in OAuth 2.1 authorization solution and protect your AI integrations
This guide shows you how to add production-ready OAuth 2.1 authorization to your Model Context Protocol (MCP) server using Scalekit. You’ll learn how to secure your MCP server so that only authenticated and authorized users can access your tools through AI hosts like Claude Desktop, Cursor, or VS Code.
MCP servers expose tools that AI hosts can discover and execute to interact with your resources. For example:
A sales team member could use Claude Desktop to view customer information, update records, or set follow-up reminders
A developer could use VS Code or Cursor with a GitHub MCP server to perform everyday GitHub actions through chat
An autonomous agent could use an MCP server to perform actions such as look up the account details in a CRM system
When you build MCP servers, multiple AI hosts may need to discover and use your server to interact with your resources. Scalekit handles the complex authentication and authorization for you, so you can focus on building better tools and improving functionality.
To get started, make sure you have your Scalekit account and API credentials ready. If you haven’t created a Scalekit account yet, you can sign up and get a free account.
Use the Scalekit dashboard to register your MCP server and configure MCP hosts (or AI agents following the MCP client protocol) to use Scalekit as the authorization server. The Scalekit SDK validates tokens after users have been authenticated and authorized to access your MCP server.
Add MCP server to get drop-in OAuth2.1 authorization server
In the Scalekit dashboard, go to MCP servers and select Add MCP server.
Provide a name for your MCP server to help you identify it easily. This name appears on the Consent page that MCP hosts display to users when authorizing access to your MCP server.
Enable dynamic client registration for MCP hosts. This allows MCP hosts to automatically register with Scalekit (and your authorization server), eliminating the need for manual registration and making it easier for users to adopt your MCP server secur.
Enable Client ID Metadata Document (CIMD) to allow your authorization server to fetch client metadata from MCP hosts and authorize them automatically.
Click Save to register the server.
Note: If your MCP server is intended for use by public MCP clients such as Claude, Cursor, or VS Code, it is recommended to keep both DCR and CIMD enabled. Clients that support CIMD will use the CIMD flow, while clients that do not yet support CIMD can fall back to Dynamic Client Registration. This ensures your MCP server remains compatible with the widest range of MCP clients while preserving a smooth authorization experience.
Advanced settings
Server URL: Your MCP server’s unique identifier, typically your server’s URL (e.g., https://mcp.yourapp.com). This is an optional field. If not provided, Scalekit will use the generated resource_id as the resource identifier. If provided, access tokens minted by Scalekit will have the resource identifier as aud claim along with the Scalekit generated resource_id.
Scopes: Define the permissions your MCP server needs, such as todo:read or todo:write. These scopes are pre-approved when users authenticate to use your MCP server, streamlining the authorization process.
Let MCP clients discover your OAuth2.1 authorization server
MCP protocol directs any MCP client to discover your OAuth2.1 authorization server by calling a public endpoint on your MCP server. This endpoint is called .well-known/oauth-protected-resource and your MCP server must host this endpoint.
Copy the resource metadata JSON from Dashboard > MCP Servers > Your server > Metadata JSON and implement it in your .well-known/oauth-protected-resource endpoint. The authorization_servers field contains your Scalekit resource identifier, which clients use to initiate the OAuth flow.
Your MCP server should validate that all incoming requests contain a valid access token. Leverage Scalekit SDKs to validate tokens and verify essential claims such as aud (audience), iss (issuer), exp (expiration), iat (issued at), and scope (permissions).
// Initialize Scalekit client with environment credentials
4
// Reference installation guide for client setup details
5
constscalekit=newScalekit(
6
process.env.SCALEKIT_ENVIRONMENT_URL,
7
process.env.SCALEKIT_CLIENT_ID,
8
process.env.SCALEKIT_CLIENT_SECRET
9
);
10
11
// Resource configuration
12
// Get these values from Scalekit dashboard > MCP servers > Your server
13
// For FastMCP: Use base URL with trailing slash (e.g., https://mcp.example.com/)
14
constRESOURCE_ID='https://your-mcp-server.com';// If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard.
from scalekit.common.scalekit import TokenValidationOptions
3
import os
4
5
# Initialize Scalekit client with environment credentials
6
# Reference installation guide for client setup details
7
scalekit_client =ScalekitClient(
8
env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
9
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
10
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET")
11
)
12
13
# Resource configuration
14
# Get these values from Scalekit dashboard > MCP servers > Your server
15
# For FastMCP: Use base URL with trailing slash (e.g., https://mcp.example.com/)
16
RESOURCE_ID="https://your-mcp-server.com"# If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard.
raiseValueError("Missing or invalid Bearer token")
Validate the token against your configured resource audience to ensure it was issued for your specific MCP server. The resource identifier must match the Server URL you registered earlier.
constRESOURCE_ID='https://your-mcp-server.com';// If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard.
// Security: Allow public access to well-known endpoints for metadata discovery
// This enables MCP clients to discover your OAuth configuration
if (req.path.includes('.well-known')) {
returnnext();
}
// Extract Bearer token from Authorization header
constauthHeader=req.headers['authorization'];
consttoken=authHeader?.startsWith('Bearer ')
?authHeader.split('Bearer ')[1]?.trim()
:null;
if (!token) {
thrownewError('Missing or invalid Bearer token');
}
// Security: Validate token against configured resource audience
awaitscalekit.validateToken(token, {
audience: [RESOURCE_ID]
});
next();
} catch (err) {
// Return proper OAuth 2.0 error response with WWW-Authenticate header
returnres
.status(401)
.set(WWWHeader.HeaderKey,WWWHeader.HeaderValue)
.end();
}
}
// Apply authentication middleware to all MCP endpoints
app.use('/',authMiddleware);
from scalekit import ScalekitClient
from scalekit.common.scalekit import TokenValidationOptions
from fastapi import Request, HTTPException, status
from fastapi.responses import Response
import os
scalekit_client =ScalekitClient(
env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET")
)
RESOURCE_ID="https://your-mcp-server.com"# If no Server URL is set in Scalekit, use the autogenerated resource ID (e.g., res_123456789) from your dashboard.
Add scope validation at the MCP tool execution level to ensure tools are only executed when the user has authorized the MCP client with the required permissions. This provides fine-grained access control and follows the principle of least privilege.
Beyond the OAuth 2.1 authorization you’ve implemented, you can enable additional authentication methods that work seamlessly with your MCP server’s token validation:
Enable organizations to authenticate through their identity providers (Okta, Azure AD, Google Workspace). Your MCP server continues validating tokens the same way, while Scalekit handles:
Centralized access control through existing enterprise identity systems
Single sign-on experience for organization members
Allow users to authenticate via Google, GitHub, Microsoft, and other social providers. Your existing token validation logic remains unchanged while providing:
Quick onboarding for individual users
Familiar authentication experience
Reduced friction for personal and small team use cases
These authentication methods require no changes to your MCP server implementation—you continue validating tokens exactly as shown in the previous steps.
Bring your own auth allows you to use your own authentication system to authenticate users to your MCP server.
Your MCP server now has production-ready OAuth 2.1 authorization! You’ve successfully implemented a secure authorization flow that protects your MCP tools and ensures only authenticated users can access them through AI hosts.
Try the demo: Download and run our sample MCP server with authentication already configured to see the complete integration in action.
In summary,
Scalekit OAuth authorization server
Acts as the identity provider for your MCP server.
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.