Announcing CIMD support for MCP Client registration
Learn more

Securing FastMCP with Scalekit: Remote OAuth Done Right

No items found.

If you’ve built anything that speaks the Model Context Protocol, you’ve almost certainly touched FastMCP.

It’s the most adopted Python framework for MCP servers — 20K+ stars, a healthy contributor base, and a release cadence that rivals many production frameworks.

It’s effectively FastAPI for MCP: typed tools, async I/O, auto-discovery, and a decorator-first developer experience.

As adoption has grown, FastMCP has become the default backbone for custom LLM integrations — powering internal copilots, AI assistants, and backend tools that expose domain-specific capabilities over the MCP spec.

With that kind of usage, the conversation quickly shifts from “how do I expose a tool?” to “how do I secure it?”

FastMCP’s Built-in Auth

FastMCP ships with three in-built auth options:

  • Bearer tokens — hard-coded secrets, easy for local dev.
  • JWT validation — lets you validate stateless tokens.
  • Full OAuth Server — a self-contained IdP, where FastMCP issues and manages tokens.

It’s a solid spread, but even the maintainers recommend caution:

“The vast majority of applications should use external identity providers instead.” — FastMCP Auth Guide

That’s not a hand-wave; it’s a boundary. FastMCP is in the tool-serving business, not the identity business.

Running an OAuth server means owning PKCE, JWK rotation, token introspection, and compliance — a full-time surface area.

For most production setups, that’s unnecessary.

What you actually need is an auth server that exists outside your MCP process — something purpose-built for issuing and validating OAuth 2.1 tokens.

That’s exactly why FastMCP introduced Remote OAuth.

Where Remote OAuth Fits

Think of FastMCP’s auth modes as a spectrum:

Mode
Description
Best For
Bearer / JWT
Simple static tokens; good for internal dev.
Local or test environments
Full OAuth Server
FastMCP hosts its own issuer and keys.
Self-contained or air-gapped installs
Remote OAuth
Delegates token issuance to an external IdP; server validates signatures and scopes.
Production environments

Remote OAuth keeps your authorization server independent — a key best practice in any distributed system.

Your MCP server becomes a resource server: it only validates JWTs and enforces scopes.

Everything else — user login, consent, client registration — is handled by your IdP.

This is the same pattern that drives every modern web API stack: microservices shouldn’t mint their own tokens.

They should validate tokens from a trusted source.

Why Scalekit Fits That Role

This is where Scalekit’s MCP Auth drops in naturally.

Scalekit is a standards-compliant OAuth 2.1 provider that already implements the same discovery and token endpoints FastMCP expects in its Remote OAuth flow.

So when you connect the two:

  • FastMCP acts as the resource server.
  • Scalekit acts as the authorization server.
  • Tokens, scopes, and validation all flow seamlessly.

That means:

  • No local user management.
  • No key rotation code.
  • No refresh token handling.
  • No re-implementing RFC 9126 on a Tuesday.

Scalekit handles OAuth 2.1 with Dynamic Client Registration (DCR), supports SSO via Google Workspace, Azure AD, and Okta, and exposes well-known JWKS and introspection endpoints.

FastMCP just points to those endpoints and validates every incoming bearer token automatically.

Setting It Up

Before wiring up any code, let’s connect the dots.

The Remote OAuth flow in FastMCP expects two things:

  1. An authorization server that exposes the standard OAuth discovery endpoints and issues JWT access tokens (that’s Scalekit), and
  2. An MCP resource server (your FastMCP instance) configured to validate those tokens and enforce scopes.

To make this concrete, we’ll use a simple Todo MCP server as our example.

It’s a minimal FastMCP app that exposes two tools — one for reading todos and one for writing them — secured by the scopes todo:read and todo:write.

The same pattern applies to any MCP toolset you build, whether it’s file sync, issue tracking, or internal dev automation.

Once you’ve registered your MCP server as a protected resource inside Scalekit, everything else becomes mechanical — a few environment variables, a provider import, and FastMCP does the validation automatically.

1. Register your MCP server in Scalekit

Tell Scalekit what your MCP server is and what scopes it enforces.

In the Scalekit dashboard:

  • Navigate to MCP Servers → Add New Server
  • Enter your local or public URL (e.g., http://localhost:3002/
  • Define scopes (todo:read and todo:write, etc).
  • Save and copy your Resourc

You’ll end up with something like:

SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com SCALEKIT_CLIENT_ID=skc_12345 SCALEKIT_RESOURCE_ID=res_67890 MCP_URL=http://localhost:3002/mcp

2. Add Scalekit Auth to FastMCP

Point your FastMCP app to Scalekit so it can validate tokens automatically.

from fastmcp import FastMCP from fastmcp.server.auth.providers.scalekit import ScalekitProvider import os auth = ScalekitProvider( environment_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), client_id=os.getenv("SCALEKIT_CLIENT_ID"), resource_id=os.getenv("SCALEKIT_RESOURCE_ID"), mcp_url=os.getenv("MCP_URL"), ) mcp = FastMCP(name="Todo Server", auth=auth) @mcp.tool def status() -> dict: return {"authenticated": True, "provider": "Scalekit"}

Then start your server:

uv run python server.py

FastMCP automatically validates tokens against Scalekit’s JWKS URL — no manual verification logic required.


3. Or configure via environment only

Prefer 12-factor style? You can declare the provider entirely through environment variables.

FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.scalekit.ScalekitProvider FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_ENVIRONMENT_URL=https://your-env.scalekit.com FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_CLIENT_ID=skc_123 FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_RESOURCE_ID=res_456 FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_MCP_URL=http://localhost:3002/mcp

Then your FastMCP entrypoint can be minimal:

from fastmcp import FastMCP mcp = FastMCP(name="Scalekit Protected Server") @mcp.tool def hello(): return {"message": "Authenticated via Scalekit!"}

That’s it — all validation, token introspection, and scope enforcement happen under the hood.

Example: Scoped Todo Tools

You can use the same pattern to protect individual MCP tools based on scopes.

from fastmcp.server.dependencies import get_access_token import uuid _TODOS = {} def require_scope(scope: str): token = get_access_token() if scope not in token.scopes: return {"error": f"Missing `{scope}` scope"} @mcp.tool def create_todo(title: str): if err := require_scope("todo:write"): return err tid = str(uuid.uuid4()) _TODOS[tid] = {"id": tid, "title": title, "done": False} return _TODOS[tid] @mcp.tool def list_todos(): if err := require_scope("todo:read"): return err return list(_TODOS.values())

Each incoming request carries a bearer token that includes the granted scopes.

FastMCP validates the token via Scalekit; your tools simply enforce scope logic.

Debugging and Inspection

Need to see what’s inside a token? Add a quick tool to inspect claims.

from fastmcp.server.context import request_ctx import jwt @mcp.tool def inspect_token(): ctx = request_ctx.get() auth = ctx.request.headers.get("authorization", "") token = auth.split(" ")[1] claims = jwt.decode(token, options={"verify_signature": False}) return claims

And for local debugging:

import logging logging.basicConfig(level=logging.DEBUG)

You’ll see validation events, discovery calls, and auth flow logs.

Best Practices

  • Keep your auth server separate. Your MCP server should only validate.
  • Use HTTPS in production; Remote OAuth won’t register otherwise.
  • Scope narrowly. Define granular permissions like todo:read, not admin*.
  • Rotate credentials regularly. Use Scalekit’s dashboard or your secret manager.
  • Log auth errors, but never tokens or secrets.

Why This Pattern Works

Remote OAuth gives you:

  • A clean separation between auth and app logic
  • Centralized security and SSO integration
  • Standards alignment with OAuth 2.1 and DCR
  • Zero auth boilerplate inside FastMCP

Scalekit just happens to make it frictionless — a single provider import, a few environment variables, and your FastMCP server behaves like any modern, secure resource API.

Further Reading

FAQs

Why should developers avoid building built-in OAuth in FastMCP?

While FastMCP offers an internal OAuth server, it requires managing complex security tasks like PKCE, JWK rotation, and token introspection. For production environments, maintainers recommend delegating identity management to specialized providers. This approach shifts the burden of compliance and maintenance away from your tool serving logic. Scalekit functions as an external authorization server, allowing your MCP server to focus exclusively on executing tools while maintaining a professional security posture.

What role does Scalekit play in the Remote OAuth flow?

Scalekit acts as the standards compliant OAuth 2.1 authorization server in this architecture. It handles user login, consent, and token issuance, while the FastMCP instance serves as the resource server. By using discovery endpoints and JWKS, Scalekit provides the necessary infrastructure for FastMCP to validate incoming bearer tokens automatically. This separation ensures that sensitive identity logic remains centralized and independent from the distributed MCP tool processes, adhering to modern microservices best practices.

How does Dynamic Client Registration benefit MCP server security?

Dynamic Client Registration allows for automated and secure onboarding of clients within the OAuth ecosystem. Scalekit utilizes this standard to simplify how MCP servers and clients interact without manual credential hardcoding. This reduces the risk of credential leakage and streamlines the management of multiple AI agents or apps. By automating registration, CISOs can ensure that every agent accessing backend tools is uniquely identified and authenticated according to current RFC 9126 standards.

Can FastMCP enforce granular permissions using OAuth scopes?

Yes, FastMCP can leverage OAuth scopes to implement fine grained authorization for specific tools. Developers define these scopes such as read or write permissions within the Scalekit dashboard. When an agent requests access, the resulting bearer token includes these claims. The MCP server then validates these scopes before executing a tool. This ensures that even authenticated users can only perform actions they are explicitly authorized for, providing a robust security layer for B2B applications.

Why is separation of auth and app logic critical?

Separating authentication from application logic is a fundamental architectural best practice for distributed systems. It prevents the MCP server from becoming a single point of failure for identity security. By delegating token issuance to Scalekit, you ensure that key rotation and user management are handled by a purpose built platform. This reduces the attack surface of your tool serving process and ensures that security updates to the identity provider do not require redeploying the entire MCP server.

How does Scalekit support enterprise SSO for AI agents?

Scalekit facilitates enterprise grade security by supporting SSO integrations with major providers like Google Workspace, Azure AD, and Okta. This allows organizations to manage access to their MCP servers using existing corporate identity directories. When an AI agent or developer attempts to access a protected tool, Scalekit handles the authentication flow against the enterprise IdP. This ensures that security policies such as multi factor authentication and user offboarding are automatically applied to all interactions with your AI tools.

What are the best practices for securing production MCP servers?

Production security requires several key layers starting with the use of HTTPS for all communications. You should utilize Remote OAuth to keep the authorization server independent and enforce granular scopes like read only access where possible. Regularly rotate credentials and avoid logging sensitive tokens or secrets. Additionally, utilize Scalekit to provide centralized monitoring of authentication events. By following these patterns, you align with OAuth 2.1 standards and ensure your AI infrastructure remains resilient and compliant.

How does FastMCP handle token validation via Scalekit?

FastMCP automates token validation by pointing to Scalekit discovery and JWKS endpoints. When a request arrives with a bearer token, the ScalekitProvider within FastMCP fetches the public keys to verify the signature. It also checks token expiration and required scopes without requiring manual verification logic from the developer. This seamless integration allows engineering teams to implement secure M2M and A2A authentication flows with minimal boilerplate, ensuring that every tool invocation is backed by a valid, verified identity.

Why choose Remote OAuth over simple JWT validation?

While simple JWT validation works for local testing, Remote OAuth provides a comprehensive security framework for production B2B environments. It supports dynamic workflows, better secret management, and centralized control over resource access. Remote OAuth allows for more sophisticated scenarios like token introspection and revocation, which are not possible with static JWTs. By delegating these responsibilities to Scalekit, engineering managers can ensure that their AI agents are operating within a secure, scalable, and standards compliant architecture that meets enterprise requirements.

Ready to secure your MCP Servers?
On this page
Share this article
Ready to secure your MCP Servers?

Acquire enterprise customers with zero upfront cost

Every feature unlocked. No hidden fees.
Start Free
$0
/ month
1 million Monthly Active Users
100 Monthly Active Organizations
1 SSO connection
1 SCIM connection
10K Connected Accounts
Unlimited Dev & Prod environments