Here’s a dirty secret about MCP servers: almost nobody implements authentication. Not because they don’t want to—because it’s genuinely impossible.
Look at the “simple” auth examples in the official MCP repository. They’re 300+ lines of OAuth boilerplate, token validation, error handling, and security edge cases that would make a seasoned backend engineer weep. The message is clear: if you want auth, you’re on your own. Good luck figuring out PKCE flows, refresh token rotation, and session management while you’re trying to build your actual business logic.
We worked with our partners at WorkOS to change that.
FastMCP 2.11 introduces our first major step into enterprise-ready authentication, reducing those 300 lines to essentially a one-liner. It also includes a completely rewritten OpenAPI parser, delivering on the promise of using REST APIs as a thoughtful starting point for MCP servers.
Give us a star on GitHub or check out the updated docs at gofastmcp.com.
Authentication: The Problem Nobody Talks About
I’ve spent months watching developers in the MCP community hit the same wall. They build a brilliant MCP server with amazing tools and resources. They’re ready to deploy to production. Then they ask: “How do I add authentication?”
Silence.
Production-grade auth is a specialized domain. OAuth 2.1, JWT validation, PKCE—these are table stakes for handling user data, and getting them wrong can sink your application. Developers have been forced to choose: ship without auth (unacceptable) or spend weeks becoming security experts (a distraction, to say the least).
Enter WorkOS: DCR-Compliant Auth as a Service
Our partnership with WorkOS emerged from a simple observation: the best auth is auth you don’t have to implement yourself. WorkOS AuthKit provides enterprise-grade authentication that is fully compliant with the MCP specification’s requirement for Dynamic Client Registration (DCR).
Working together, we’ve built authentication directly into FastMCP’s core. The result is plug-and-play auth that doesn’t require you to become a security expert overnight:
from fastmcp import FastMCPfrom fastmcp.server.auth.providers.workos import AuthKitProvider
mcp = FastMCP( name="SecureServer", auth=AuthKitProvider( authkit_domain="your_authkit_domain", base_url="http://localhost:8000", # your server's URL ))
@mcp.tooldef sensitive_operation(): """This tool now requires authentication.""" return "Only authenticated users can call this"
Behind this simple interface, FastMCP handles token validation, user session management, and all the OAuth complexity, cleanly rejecting unauthorized requests before they reach your business logic.
For teams that need custom authentication flows, we’ve also introduced the TokenVerifier
protocol—a clean interface for implementing your own auth logic while still leveraging FastMCP’s built-in security patterns.
OpenAPI: The Redemption Arc
A few months ago, I wrote a post titled “Stop Converting Your REST APIs to MCP”. I stand by that advice—blindly wrapping a massive REST API will poison your agent with context pollution and atomic operations.
But I was being a little tongue-in-cheek. The truth is, REST APIs are fantastic starting points for MCP servers. They provide working endpoints, real business logic, and documented interfaces. The problem was never the APIs themselves—it was our tooling for converting them thoughtfully.
FastMCP 2.11 includes a completely rewritten OpenAPI parser that addresses the core issues:
Performance: The new parser uses single-pass schema processing with optimized memory usage. What used to take minutes now takes seconds, even for massive specs.
Maintainability: The old parser had become a maintenance nightmare with edge cases and special handling scattered throughout. The new architecture is clean, extensible, and actually understandable.
Thoughtful Defaults: Instead of blindly converting every endpoint, the new parser makes intelligent decisions about what tools make sense for agents, while still giving you full control to customize the conversion.
The new parser is experimental and disabled by default, but you can enable it with:
export FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER=1
We’re being thoughtful about the rollout because we know teams depend on the existing behavior. But early testing shows dramatic improvements in both performance and output quality.
Context State: Memory for Your Tools
One more thing: FastMCP 2.11 introduces persistent state management across tool calls. This seemingly simple feature unlocks powerful new patterns for multi-step agent workflows:
from fastmcp import FastMCP, Context
mcp = FastMCP()
@mcp.tooldef start_analysis(ctx: Context, dataset_id: str): """Begin analyzing a dataset.""" ctx.state["analysis_id"] = f"analysis_{dataset_id}" ctx.state["progress"] = 0 return f"Started analysis {ctx.state['analysis_id']}"
@mcp.tooldef check_analysis_progress(ctx: Context): """Check the progress of the current analysis.""" if "analysis_id" not in ctx.state: return "No analysis in progress" return f"Analysis {ctx.state['analysis_id']} is {ctx.state['progress']}% complete"
The state persists across tool calls within the same session, giving your agents memory and the ability to maintain context across complex, multi-step operations. Note that state is only persisted for the duration of the session on the in-memory context object!
Happy engineering!