Releases: jlowin/fastmcp
'Tis a Gift to Be Sample
FastMCP 2.14.1 adds support for sampling with tools (SEP-1577). This exciting new feature lets servers pass tools to ctx.sample(), enabling agentic workflows where the server borrows the client's LLM and controls tool execution automatically. Pass any callable as a tool and FastMCP handles the loop: calling the LLM, executing tools, and feeding results back until a final response is produced. For fine-grained control, ctx.sample_step() makes a single LLM call and returns a SampleStep, letting you inspect tool calls, add custom logic, or build your own execution loop. Structured output via result_type returns validated Pydantic models instead of raw text. This release also adds AnthropicSamplingHandler alongside the existing OpenAI handler (newly promoted out of the experimental module), so clients and servers can provide sampling capability across major providers with ease.
What's Changed
New Features π
Enhancements π§
- Add Python 3.13 to Ubuntu CI tests by @jlowin in #2606
- Remove legacy _task_capable_initialize() workaround by @jlowin in #2612
- Consolidate session state reset logic and improve cancellation cleanup by @jlowin in #2615
- Unify SamplingHandler and promote OpenAI handler by @jlowin in #2616
- Add tool_names parameter to mount() for name overrides by @jlowin in #2619
- Adopt streamable_http_client API from MCP SDK by @jlowin in #2620
- Deprecate exclude_args in favor of Depends() by @jlowin in #2621
Fixes π
- fix: prompt tasks returning mcp.types.PromptMessage now work by @chrisguidry in #2603
- Use WindowsSelectorEventLoopPolicy to fix Windows test warnings by @jlowin in #2607
- Clean up cancelled connection startup by @shawnthapa in #2614
- Consolidate sampling examples and fix tool_choice bug by @jlowin in #2618
Docs π
Dependencies π¦
- chore: bump pydocket to >=0.15.5 by @chrisguidry in #2605
New Contributors
- @shawnthapa made their first contribution in #2614
Full Changelog: v2.14.0...v2.14.1
v2.14.0: Task and You Shall Receive
FastMCP 2.14 begins adopting the MCP 2025-11-25 specification, headlined by protocol-native background tasks that let long-running operations report progress without blocking clients. This release also graduates the OpenAPI parser to standard, adds first-class support for several new spec features, and removes deprecated APIs accumulated across the 2.x series.
Background Tasks (SEP-1686)
Long-running operations (like tool calls) normally block MCP clients until they complete. The new MCP background task protocol (SEP-1686) lets clients start operations, track progress, and retrieve results without blocking. For FastMCP users, taking advantage of this new functionality is as easy as adding task=True to any async decorator. Under the hood, it's powered by Docket, the enterprise task scheduler at the heart of Prefect Cloud that handles millions of concurrent tasks every day.
from fastmcp import FastMCP
from fastmcp.dependencies import Progress
mcp = FastMCP("MyServer")
@mcp.tool(task=True)
async def train_model(dataset: str, progress: Progress = Progress()) -> str:
await progress.set_total(100)
for epoch in range(100):
# ... training work ...
await progress.increment()
return "Model trained successfully"Clients that call this tool in task-augmented mode (for FastMCP clients, that merely means another task=True!) receive a task ID immediately, poll for progress updates, and fetch results when ready. Background tasks work out-of-the-box with an in-memory backend, and users can optionally provide a Redis URL for persistence, horizontal scaling, and single-digit millisecond task pickup latency. When using Redis, users can also add additional Docket workers to scale out their task processing.
Read the docs here!
OpenAPI Parser Promotion
The experimental OpenAPI parser graduates to standard. The new architecture delivers improved performance through single-pass schema processing and cleaner internal abstractions. Existing code works unchanged; users of the experimental module should update their imports.
MCP 2025-11-25 Spec Support
This release begins adopting the MCP 2025-11-25 specification. Beyond the core SDK updates, FastMCP adds first-class developer experiences for:
- SEP-1686: Background tasks with progress tracking
- SEP-1699: SSE polling and event resumability, with full
AsyncKeyValuesupport - SEP-1330: Multi-select enum elicitation schemas
- SEP-1034: Default values for elicitation schemas
- SEP-986: Tool name validation at registration time
As the MCP SDK continues to adopt more of the specification, FastMCP will add corresponding high-level APIs.
Breaking Changes & Cleanup
This release removes deprecated APIs accumulated across the 2.x series: BearerAuthProvider, Context.get_http_request(), the dependencies parameter, legacy resource prefix formats, and several deprecated methods. The upgrade guide provides migration paths for each.
What's Changed
New Features π
- Switch to new OpenAPI parser as default by @jlowin in #2513
- [2.14] SEP-1686 tasks by @chrisguidry in #2378
Enhancements π§
- Expose InitializeResult to middleware by @jlowin in #2516
- [2.14] Update for MCP SDK auth changes by @chrisguidry in #2507
- Validate tool names at registration time (SEP-986) by @jlowin in #2540
- Deflake GitHub MCP remote integration tests by @chrisguidry in #2543
- Add SEP-1034 default values support for elicitation by @jlowin in #2545
- Improve rate limit detection for integration tests by @chrisguidry in #2550
- Reduce Marvin Test Failure noise by @strawgate in #2553
- [SEP-1686] Raise ValueError when sync functions have task=True by @jlowin in #2554
- refactor: move task attribute to function-based variants only [SEP-1686] by @jlowin in #2560
- Fix type errors for ty 0.0.1-alpha.31 upgrade by @jlowin in #2561
- Add regression tests for functools.wraps + Context (#2524) by @jlowin in #2566
- Update VersionBadge to use Mintlify native Badge component by @jlowin in #2571
- Add TaskConfig for SEP-1686 execution modes by @jlowin in #2570
- Add execution field to base Tool class by @chrisguidry in #2576
- SEP-1699: Add SSE polling support with EventStore by @jlowin in #2564
- SEP-1330 enum schema support by @jlowin in #2549
- Expose get_session_id callback by @mathewjhan in #2486
- Remove TaskConfig and client from root exports by @jlowin in #2580
- Remove overly restrictive MIME type validation from Resource by @jlowin in #2585
- feat: handle error from the initialize middleware by @tonyxwz in #2531
- Remove tests/test_examples.py by @jlowin in #2593
Fixes π
- Fix RFC 8414 path-aware authorization server metadata discovery by @jlowin in #2533
- Make fastapi.cli a runnable package by @paulo-raca in #2532
- Move TokenHandler to OAuthProvider for consistent OAuth error codes by @jlowin in #2538
- Update FastMCP server documentation link by @sskim91 in #2529
- Fix: Include signature modification in create_function_without_params by @AidanAllchin in #2563
- add client kwargs to proxy clients and meta to proxy tool calls by @cegersdoerfer in #2520
- Prefix Docket function names to avoid collisions in multi-mount setups by @chrisguidry in #2575
- Fix OAuth client to preserve full URL path for metadata discovery by @jlowin in #2577
- Do not run windows tests in parallel by @jlowin in #2579
- Fix proxy tool result meta attribute forwarding by @dherrman in #2526
- Fix nested server mount routing for 3+ levels deep by @jlowin in #2586
- Add smart fallback for missing access token expiry by @jlowin in #2587
- fix: preserve exception propagation through transport cleanup by @jlowin in #2591
Breaking Changes π«
- Remove enable_docket setting; Docket is now always on by @chrisguidry in #2558
- Forbid task execution through proxies, add mount/proxy task tests by @chrisguidry in #2574
- Remove enable_tasks setting, enable task protocol by default by @chrisguidry in #2578
- Remove deprecated
from fastmcp.settings import settingsby @jlowin in #2581 - Remove deprecated mount/import argument order and separator params by @jlowin in #2582
- 2.14 deprecation removals by @jlowin in #2329
Note that #2329 includes the following PRs:- Remove deprecated FASTMCP_SERVER_ environment variable prefix by @jlowin in #2330
- Remove deprecated Context.get_http_request method by @jlowin in #2332
- Remove fastmcp.Image top-level import (deprecated 2.8.1) by @jlowin in #2334
- Remove deprecated client parameter from FastMCPProxy by @jlowin in #2333
- Remove deprecated run_streamable_http_async method by @jlowin in #2338
- Remove deprecated sse_app method by @jlowin in #2337
- Remove deprecated run_sse_async method by @jlowin in #2335
- Remove deprecated streamable_http_app method by @jlowin in #2336
- Remove deprecated dependencies parameter (fixes #2177) by @jlowin in #2340
- Remove output_schema=False support (deprecated 2.11.4) by @jlowin in #2339
- Remove deprecated BearerAuthProvider module by @jlowin in #2341
...
v2.13.3: Pin-ish Line
MCP SDK 1.23 introduced some changes related to the 11/25/25 MCP protocol update that break some patches/workarounds that FastMCP had implemented previously. In particular, OAuth changes in the new protocol changed some implementation details that FastMCP patched; as such 1.23 is not necessarily a breaking SDK change but it is "breaking" for certain FastMCP behaviors.
As a precaution, this release pins mcp<1.23. FastMCP 2.14 will introduce 11/25/25 support (and require mcp>=1.23).
v2.13.2: Refreshing Changes
FastMCP 2.13.2 polishes the authentication stack with fixes for token refresh, scope handling, and multi-instance deployments. Discord joins the growing roster of built-in OAuth providers, Azure and Google token handling gets more reliable, and proxy classes now properly forward icons and titles. This release also adds CSP customization for consent screens and fixes an edge case where $defs could mutate during tool transforms.
Welcome to 7 new contributors who made their first FastMCP contributions in this release!
What's Changed
New Features π
Enhancements π§
- Bump actions/checkout from 4 to 5 by @dependabot[bot] in #2433
- feat: Made Changes to DescopeProvider to Support New Well Known URLs by @gaokevin1 in #2392
- Scalekit provider updates by @AkshayParihar33 in #2413
- Add consent_csp_policy parameter for CSP customization by @jlowin in #2484
- Add icons support to proxy classes by @jlowin in #2502
Fixes π
- Add refresh token support defaults to GoogleProvider by @jlowin in #2438
- Fix exclude_args with non-serializable types by @jlowin in #2440
- Fix Azure OAuth token refresh with unprefixed scopes by @Neet-Nestor in #2462
- fix: prevent $defs mutation in Tool.from_tool transforms by @jtanningbed in #2493
- Add
titleattribute toProxyTool,ProxyResource, β¦ by @CNSeniorious000 in #2497 - Fix OAuth proxy refresh token storage for multi-instance deployments by @jlowin in #2483
- Fix get_access_token() returning stale token after OAuth refresh by @jlowin in #2505
- Fix version badges for icons and website_url; add Discord example by @jlowin in #2509
- Fix Azure provider OIDC scope handling by @jlowin in #2506
Docs π
- Update http.mdx by @Shengshenlan in #2446
- Fix version number in VersionBadge: change 2.14.0 to 2.13.0 by @ShaikAyesha17 in #2491
- Add Discord OAuth integration documentation by @jlowin in #2508
Dependencies π¦
- Bump actions/setup-python from 5 to 6 by @dependabot[bot] in #2432
- Bump py-key-value-aio to 0.3.0 by @strawgate in #2437
- Bump actions/checkout from 5 to 6 by @dependabot[bot] in #2474
Other Changes π¦Ύ
New Contributors
- @Neet-Nestor made their first contribution in #2462
- @Shengshenlan made their first contribution in #2446
- @gaokevin1 made their first contribution in #2392
- @ShaikAyesha17 made their first contribution in #2491
- @jtanningbed made their first contribution in #2493
- @CNSeniorious000 made their first contribution in #2497
- @Aisha630 made their first contribution in #2428
Full Changelog: v2.13.1...v2.13.2
v2.13.1: Heavy Meta
FastMCP 2.13.1 introduces meta parameter support for ToolResult (#2283), letting tools return metadata alongside results to enable new use cases such as OpenAI's Apps SDK. It also supports client-sent meta (#2206) as well as improved OAuth capabilities and custom token verifiers (including the new DebugTokenVerifier) and an OCI authentication provider. A large list of enhancements and bugfixes round out the release.
Note that #2422 excludes MCP SDK 1.21.1 as a permitted dependency version due to a bug that fails FastMCP integration tests.
What's Changed
Enhancements π§
- Cleanly render auth errors from OAuth Proxy by @jlowin in #2268
- Add custom token verifier support to OIDCProxy by @jlowin in #2279
- Supporting Multiple Issuers For JWTVerifier Oauth Workflow by @mhassaninmsft in #2233
- Switch to
logger.exceptionforfastmcp run/inspectby @jakekaplan in #2294 - Add base_authority parameter to AzureProvider for Azure Government support by @jlowin in #2306
- Add DebugTokenVerifier with custom sync/async validation by @jlowin in #2296
- Added to_data_uri method for Image class. by @Hyperclaw79 in #2227
- Remove test warnings by @jlowin in #2331
- Mark flaky Windows test for retry by @jlowin in #2344
- Add meta support to ToolResult by @BrandonShar in #2283
- switch from pre-commit to prek by @zzstoatzz in #2309
- Add manual initialization control to Client by @jlowin in #2355
- Pin Cyclopts to v4.0.0 + compliance note by @jlowin in #2354
- Switch marvin to prek from pre-commit by @strawgate in #2361
- Add meta to call tool by @aiorga-sherpas in #2206
- feat: add algorithm configuration to Supabase auth provider by @cemalkilic in #2376
- chore(typos): fix additional typos by @pstoeckle in #2396
- Martian triage for test failures by @strawgate in #2407
- OCI Provider with Docs by @kiranthakkar in #2389
Fixes π
- Fix OAuth token storage documentation by @jlowin in #2272
- fix(docs): correct the key_value repo link by @JonZeolla in #2276
- Remove trailing slashes from MCP endpoint URLs by @jlowin in #2277
- Fix py-key-value-aio minimum version to 0.2.8 by @jlowin in #2288
- Fix Chrome CSP blocking OAuth consent form with custom protocol redirects by @jlowin in #2305
- Add OIDCProxy to auth module exports by @jlowin in #2308
- Require uvicorn>=0.35 for websockets-sansio support by @jlowin in #2307
- Fix query-only resource templates not matching URIs without query strings by @joshuadavidthomas in #2323
- Security: Update authlib to 1.6.5 (CVE-2025-61920) by @ColeMurray in #2347
- Security: Validate Cursor deeplink URLs and use safer Windows API by @ColeMurray in #2348
- fix: on_initialize is not using request params but the whole request by @Maxi91f in #2357
- Fix OAuth metadata endpoint URLs when base_url differs from issuer_url by @jlowin in #2353
- Fix Windows test timeouts from SQLite locking by @jlowin in #2368
- Fix: URL-encode server name in Cursor deeplinks by @jlowin in #2369
- Fix get_http_headers() returning empty dict in on_initialize middleware by @jlowin in #2370
- Allow OAuth instance to use the same httpx factory as the Transport by @guschnwg in #2324
- Fix consent form action for subpath mounting by @jlowin in #2382
- Fix Windows test timeout and restore parallel testing by @jlowin in #2383
- Fix duplicate keyword argument error in configure_logging by @strawgate in #2381
- Update CSP to allow data URI images on OAuth screens by @lawrence-law in #2405
- fix: upstream token cache expires when refresh expires by @wipash in #2410
- fix(oauth_proxy): π add extra_token_params as kwargs in refreshβ¦ by @EdenTrainorCDL in #2387
- fix(OpenAPIParser): Fix missing $defs for response schemas in experimental OpenAPI parser by @ChristophNetsch in #2398
- docs: fix run_server_async documentation by @jlowin in #2423
- Fix self-referencing types not being recognized as object schemas by @jlowin in #2424
- Simplify _is_object_schema helper by @jlowin in #2426
Docs π
- Update Azure sidebar title to include Entra ID by @jlowin in #2266
- Improve OAuth client token storage security documentation by @jlowin in #2270
- Add note about docs version by @jlowin in #2271
- π Add docstrings to
enhancement/support-jwt-multiple-issuersby @coderabbitai[bot] in #2282 - Add maturity warnings for py-key-value backends by @strawgate in #2311
- Improve ToolResult and structured output documentation by @jlowin in #2349
- Document client meta parameter by @jlowin in #2367
- docs: clarify pytest-asyncio dependency and asyncio mode configuration by @strawgate in #2399
Dependencies π¦
Other Changes π¦Ύ
- Replace openapi-core with jsonschema-path by @jlowin in #2291
- Fix lowest-direct dependency tests to actually test minimum versions by @Copilot in #2295
- Add version badge for DebugTokenVerifier by @jlowin in #2390
- Handle request_context availability during MCP initialization by @jlowin in #2400
- Exclude MCP SDK 1.21.1 and add scope validation to InMemoryOAuthProvider by @jlowin in #2422
New Contributors
- @JonZeolla made their first contribution in #2276
- @mhassaninmsft made their first contribution in #2233
- @coderabbitai[bot] made their first contribution in #2282
- @jakekaplan made their first contribution in #2294
- @joshuadavidthomas made their first contribution in #2323
- @Hyperclaw79 made their first contribution in #2227
- @ColeMurray made their first contribution in #2347
- @BrandonShar made their first contribution in #2283
- @aiorga-sherpas made their first contribution in #2206
- @guschnwg made their first contribution in #2324
- @cemalkilic made their first contribution in #2376
- @pstoeckle made their first contribution in #2396
- @lawrence-law made their first contribution in #2405
- @wipash made their first contribution in #2410
- @EdenTrainorCDL made their first contribution in #2387
- @ChristophNetsch made their first contribution in #2398
- @kiranthakkar made their first contribution in #2389
Full Changelog: v2.13.0.1...v2.13.1
v2.13.0.2: Cache Me If You Can
Bugfixes
This release includes two critical dependency fixes:
v2.13.0.1: Cache Me If You Can
This release includes an important bugfix for 2.13.0 that affects how the Azure OAuth provider handles scopes.
What's Changed
Enhancements π§
- Add "High Value" Ruff Rules by @strawgate in #2255
Fixes π
Other Changes π¦Ύ
- Add CI test job for lowest-direct dependency resolution by @Copilot in #2261
New Contributors
- @Copilot made their first contribution in #2261
Full Changelog: v2.13.0...v2.13.0.1
v2.13.0: Cache Me If You Can
FastMCP 2.13.0 "Cache Me If You Can" represents a fundamental maturation of the framework. After months of community feedback on authentication and state management, this release delivers the infrastructure FastMCP needs to handle production workloads: persistent storage, response caching, and pragmatic OAuth improvements that reflect real-world deployment challenges.
πΎ Pluggable storage backends bring persistent state to FastMCP servers. Built on py-key-value-aio, a new library from FastMCP maintainer Bill Easton (@strawgate), the storage layer provides encrypted disk storage by default, platform-aware token management, and a simple key-value interface for application state. We're excited to bring this elegantly designed library into the FastMCP ecosystem - it's both powerful and remarkably easy to use, including wrappers to add encryption, TTLs, caching, and more to backends ranging from Elasticsearch, Redis, DynamoDB, filesystem, in-memory, and more! OAuth providers now automatically persist tokens across restarts, and developers can store arbitrary state without reaching for external databases. This foundation enables long-running sessions, cached credentials, and stateful applications built on MCP.
π OAuth maturity brings months of production learnings into the framework. The new consent screen prevents confused deputy and authorization bypass attacks discovered in earlier versions while providing a clean UX with customizable branding. The OAuth proxy now issues its own tokens with automatic key derivation from client secrets, and RFC 7662 token introspection support enables enterprise auth flows. Path prefix mounting enables OAuth-protected servers to integrate into existing web applications under custom paths like /api, and MCP 1.17+ compliance with RFC 9728 ensures protocol compatibility. Combined with improved error handling and platform-aware token storage, OAuth is now production-ready and security-hardened for serious applications.
FastMCP now supports out-of-the-box authentication with:
- WorkOS and AuthKit
- GitHub
- Azure (Entra ID)
- AWS Cognito
- Auth0
- Descope
- Scalekit
- JWTs
- RFC 7662 token introspection
β‘ Response Caching Middleware dramatically improves performance for expensive operations. Cache tool and resource responses with configurable TTLs, reducing redundant API calls and speeding up repeated queries.
π Server lifespans provide proper initialization and cleanup hooks that run once per server instance instead of per client session. This fixes a long-standing source of confusion in the MCP SDK and enables proper resource management for database connections, background tasks, and other server-level state. Note: this is a breaking behavioral change if you were using the lifespan parameter.
β¨ Developer experience improvements include Pydantic input validation for better type safety, icon support for richer UX, RFC 6570 query parameters for resource templates, improved Context API methods (list_resources, list_prompts, get_prompt), and async file/directory resources.
This release includes contributions from 20 new contributors and represents the largest feature set in a while. Thank you to everyone who tested preview builds and filed issues - your feedback shaped these improvements!
What's Changed
New Features π
- Add RFC 6570 query parameter support to resource templates by @jlowin in #1971
- Add Storage to FastMCP and switch OAuth to use it by @strawgate in #1913
- Add Pydantic-compatible input validation by @jlowin in #2073
- Add RFC 7662 token introspection provider by @jlowin in #2074
- Add Response Caching Middleware by @strawgate in #1845
- Support mounting OAuth-protected servers under path prefixes by @jlowin in #2119
- OAuth proxy issues its own tokens by @jlowin in #2109
- Implement icon support by @jlowin in #2121
- Add ToolInjectionMiddleware + Tools for Read/List Resource/Prompt for Client Compat by @strawgate in #2142
Enhancements π§
- Add Scalekit Provider for Enterprise Authentication by @AkshayParihar33 in #1927
- Add AuthKit DCR example by @jlowin in #1935
- Remove redirect path for authkit example by @jlowin in #1938
- feat: Follow OAuth 2.1 spec requirements on auth failures by @tcarac in #1923
- Refactor OAuth 2.1 error handling with TokenHandler subclass by @jlowin in #1948
- Expand timeouts by @jlowin in #1954
- Upgrade GitHub workflows to claude-code-action@v1 by @jlowin in #1956
- Add --model claude-sonnet-4-5-20250929 to all workflows by @jlowin in #1963
- Improve env vars for marvin by @jlowin in #1972
- Add Any annotations to args and kwargs by @strawgate in #1994
- Mark GitHub Integration tests as flaky by @strawgate in #2000
- Internal refactor of MCP handlers by @jlowin in #2005
- Support
initializerequests in middleware by @jlowin in #1546 - Updates to Logging Middleware by @strawgate in #1974
- add supabase-auth by @aaazzam in #1997
- Allow direct instantiation of Prompt and Resource classes by @jlowin in #2031
- Support customizable env file location by @jlowin in #2036
- Improve Tracebacks for narrow terminals by @jlowin in #1939
- Refactor mounting logic from managers to server by @jlowin in #2069
- feat: expose errlog on stdio transport by @mpuhacz in #1991
- feat: Add title, annotations and meta to mixin decorators by @AnkeshThakur in #2033
- Add warnings regarding memory store by @strawgate in #2052
- Also push client messages (info/warn/debug) to server debug log by @strawgate in #2063
- feat: add azp claim by @roee-hersh in #1945
- bump kv dependency to 0.2.2 by @strawgate in #2089
- Add auto-close workflow for issues needing MRE by @jlowin in #2100
- Add client_storage property to aws provider by @rparme in #2107
- Update version badge for azure auth docs by @jlowin in #2120
- Disable parallel test execution on Windows by @jlowin in #2128
- Support custom server name, icons, and link in OAuth Proxy consent page by @jlowin in #2135
- Replace subprocess tests with in-process async servers by @jlowin in #2006
- Progress replacing asyncio with anyio by @jlowin in #2143
- Update CLI logo by @jlowin in #2159
- Change auth init log to debug by @jlowin in #2160
- allow non write users for marvin flows by @jlowin in #2161
- Redesign OAuth consent screen for better UX by @jlowin in #2170
- Allow authorization consent screen to be disabled by @jlowin in #2172
- example: update server init usage by @zzstoatzz in #2200
- Update smart home example again by @zzstoatzz in #2201
- Use platformdirs for settings.home by @jlowin in #2213
- Add platform-aware OAuth token persistence by @jlowin in #2218
- Update CLI logo by @jlowin in #2220
- Improve OAuth error messages with custom handlers and middleware by @jlowin in #2221
- Fix martian concurrency controls and dedupe issues mcp servers by @strawgate in #2240
- Use abstract types for FastMCP class instantiation by @strawgate in #2219
- Derive
jwt_signing_keyfrom Client Secret, default to Encrypted Disk Store by @strawgate in https://github.com/jlowin/fast...
v2.13.0rc3
Release candidate 3 for 2.13.0
v2.13.0rc2
Release candidate 2 for 2.13.0