pypi fastmcp 4.0.0b1
v4.0.0b1: Fourgone Conclusion

latest releases: 4.2.0a1, 4.1.4, 3.4.11...
3 months ago

FastMCP 4 makes stateful MCP applications work on the sessionless 2026-07-28 protocol while one deployment continues serving handshake-era clients. Tools can ask follow-up questions across requests, preserve authenticated user state, and move long-running work into background tasks without sticky sessions or a continuously connected client.

The engine underneath changed completely. MCP Python SDK v2 rewrote the protocol layer end to end — protocol types moved into a standalone mcp_types package (still importable as mcp.types), model fields use snake_case in Python, and the server request-handling model was replaced. FastMCP absorbs nearly all of it, so most FastMCP 3 servers upgrade untouched.

🌐 Every protocol era — modern and handshake-era clients are served simultaneously, negotiated per connection. Modern requests can be handled by any replica behind an ordinary load balancer.

💬 Interactive tools — tools ask follow-up questions across complete request-response rounds. Shared request-state keys let any replica resume the next round after load balancing or a worker restart.

💾 State without a session — UserSession and SessionId give tools explicit per-user state on a protocol that deliberately has none (SEP-2567), stored server-side and keyed to the authenticated user.

⏳ Background tasks — the io.modelcontextprotocol/tasks extension (SEP-2663), shipped in the new fastmcp-tasks package on the same Docket engine FastMCP 3 used. @mcp.tool(task=True) is still the whole authoring surface.

🧩 Server extensions — add_extension() turns capability-negotiated protocol features (SEP-2133) into a supported plugin surface instead of surgery on core.

🔐 Enterprise auth — complete server-side identity assertion (SEP-990), plus require_roles, incremental-authorization step-up challenges (SEP-2350), DCR application_type (SEP-837), and routable transport headers for gateways (SEP-2243).

⌨️ Argument completion — a @mcp.completion handler answers autocomplete for prompt arguments and resource-template parameters, and can narrow suggestions using the arguments already supplied.

Breaking changes. Server-initiated sampling and roots are removed from the server API: both pushed a request down a live connection, which the sessionless protocol no longer has, and a method that only works against old clients is a trap. Elicitation continues in a request-shaped form, and generation belongs in your server — call an LLM directly. The 3.x-era compatibility shims are also gone. The upgrade guide walks through every change.

Install the beta by pinning it explicitly:

uv add "fastmcp==4.0.0b1"

This is a beta released for testing ahead of 4.0. Pin an exact version and expect sharp edges.

What's Changed

New Features 🎉

  • Migrate to MCP Python SDK v2 by @jlowin in #4437
  • Teach fastmcp.Client the modern protocol: mode negotiation, MRTR driver, response cache by @jlowin in #4450
  • Forward-port Hugging Face auth provider by @jlowin in #4475
  • Add server-side identity assertion (SEP-990 ID-JAG) by @jlowin in #4483
  • Add guard-mode multi-round-trip tools (SEP-2322) by @jlowin in #4544
  • Add FastMCP-native server extension API (SEP-2133) by @jlowin in #4602
  • Add stateless session state (UserSession / SessionId) by @jlowin in #4604
  • Add background tasks via the io.modelcontextprotocol/tasks extension (SEP-2663) by @jlowin in #4603

Breaking Changes ⚠️

  • Emit one SERVER span per request and adopt spec-correct error codes by @jlowin in #4445
  • Remove 3.x deprecated module shims and dead parameters by @jlowin in #4447
  • Remove 3.0-deprecated FastMCP server methods by @jlowin in #4451
  • Remove 3.x deprecated parameters and object-mode decorators by @jlowin in #4453
  • Migrate to MCP SDK v2.0.0b2 (httpx2) by @jlowin in #4503
  • Fix typos by @szepeviktor in #4498
  • Stop proxies from validating backend results or mutating shared transports by @jlowin in #4552
  • Surface resource, prompt, and proxy errors on the modern protocol by @jlowin in #4579
  • Negotiate the best mutual protocol era by default by @jlowin in #4572
  • Remove server-initiated sampling and roots from the server API by @jlowin in #4648
  • Remove 3.x-era compatibility shims by @jlowin in #4661

Enhancements ✨

  • Deprecate ctx.sample and add clear errors for push features on 2026 connections by @jlowin in #4448
  • Add server-level cache hints (SEP-2549) by @jlowin in #4464
  • Add KeyValueResponseCacheStore for distributed client response caching by @jlowin in #4479
  • Test lifespan fires once per process over HTTP by @jlowin in #4480
  • Add telemetry off-switch and mcp.protocol.version span attribute by @jlowin in #4481
  • Trace client task management requests by @jlowin in #4525
  • Stabilize upgraded ty checks by @jlowin in #4526
  • Improve DescopeProvider scope discovery and well-known URL support by @gaokevin1 in #4489
  • Add examples/ to the ty static-analysis gate by @jlowin in #4466
  • Expose telemetry attributes on span start by @zzstoatzz in #4487
  • Fix-issue-4284 : Add Auth0MCPProvider for Auth0 Auth for MCP by @vijaydeepsinha in #4411
  • Run FastMCP middleware for every inbound message by @jlowin in #4553
  • Add 'prs welcome' label to waive the PR assignment gate by @jlowin in #4557
  • Rename martian workflows to marvin by @jlowin in #4558
  • Bump pinned Claude models to current versions by @jlowin in #4561
  • Make the unit suite fast: in-process HTTP tests, no real sleeps, parallel Windows CI by @jlowin in #4554
  • Mirror the frontend's protocol era on a proxy's backend connection by @jlowin in #4573
  • Drop forked client protocol helpers in favor of the SDK's by @jlowin in #4574
  • Bring the v4 developer notes up to date with what shipped by @jlowin in #4581
  • Trim fastmcp.types to FastMCP-unique types by @jlowin in #4584
  • Let a server answer argument-completion requests by @jlowin in #4582
  • Add machine-to-machine client authentication by @jlowin in #4583
  • Expose era-neutral client server metadata by @zzstoatzz in #4599
  • Support routable transport headers for gateways (SEP-2243) by @jlowin in #4622
  • Emit scope step-up challenges for incremental authorization (SEP-2350) by @jlowin in #4623
  • Honor OAuth application_type in DCR (SEP-837) by @jlowin in #4621
  • Drop stale label-noting instructions from CLAUDE.md by @jlowin in #4654
  • Add require_roles auth check by @jlowin in #4656
  • Add valid_scopes parameter to OIDC proxy valid scopes by @Educg550 in #4660
  • feat: Add telemetry interop mode for FastMCP by @strawgate in #4046
  • Note that review comment threads should get an acknowledgement by @jlowin in #4678
  • Soften the review-comment reply guidance by @jlowin in #4683
  • Resolve review threads on fix, reply on decline by @jlowin in #4685
  • Move to the stable MCP Python SDK 2.0.0 by @jlowin in #4655

Security 🔒

  • Drive the FastMCP lifespan through the SDK session manager by @jlowin in #4446
  • Route skill file access through SDK path-security primitives by @jlowin in #4449
  • Screen templated resource parameters for path traversal by default by @jlowin in #4482
  • [codex] Add OAuthProxy RFC 9207 issuer responses by @jlowin in #4438
  • Apply app visibility where no host can by @jlowin in #4692

Fixes 🐞

  • Capture SharedContext for task-enabled Docket servers by @jlowin in #4443
  • Fix stale mcp.types imports in examples by @jlowin in #4452
  • Forward-port HTTP host guard compatibility by @jlowin in #4474
  • Fix Azure scope fallback by @zzstoatzz in #4469
  • fix(server): omit ScalarElicitationType wrapper title from elicitation schemas by @syf2211 in #4502
  • Skip unsupported JWKS keys instead of failing the whole key set (#4515) by @earfman in #4517
  • Don't mutate the caller's schema in compress_schema by @winklemad in #4492
  • Forward upstream instructions through create_proxy by @verdie-g in #4512
  • Serialize deep object query parameters by @jlowin in #4523
  • Reject positional-only tool parameters by @jlowin in #4524
  • Clarify PR-reopen flow and fix label-race that broke auto-reopen by @jlowin in #4518
  • Clean up disconnected task sessions by @jlowin in #4519
  • Handle expired OAuth client registrations by @jlowin in #4520
  • Fix OAuth request annotation after httpx2 migration by @jlowin in #4534
  • Fix docs banner contrast by @jlowin in #4522
  • Preserve component metadata in response cache by @jlowin in #4521
  • Clean up task sessions on connection exit by @jlowin in #4535
  • Include scopes in auth challenges by @jlowin in #4527
  • Make examples/ actually trigger the ty gate by @jlowin in #4541
  • Add subject field to AccessToken initialization by @piaudonn in #4267
  • Restore Mintlify's fixed banner positioning by @jlowin in #4542
  • Fix #4292: SSRF guard breaks OAuth/JWKS fetches behind a corporate HTTP proxy by @endofcake in #4412
  • Preserve telemetry attributes when a sampler does not forward them by @jlowin in #4539
  • Speed up the unit test suite, and fix the task-notification race it surfaced by @jlowin in #4550
  • Fix label triage applying no labels, and make blocked tool calls fail by @jlowin in #4555
  • Fix AI workflow allowlists being destroyed by tokenization by @jlowin in #4560
  • Make transformed tool required order deterministic by @Kludex in #4564
  • Stop gather() from creating coroutines it may never schedule by @jlowin in #4559
  • Restore upgraded dependency checks by @zzstoatzz in #4576
  • Fix skill frontmatter parsing with UTF-8 BOM by @hxaxd in #4533
  • Fix File helper extension handling by @VectorPeak in #4531
  • Fix percent-encoded skill file names unreadable in resources mode by @jlowin in #4590
  • Fix flaky stdio crash-recovery tests by @jlowin in #4594
  • Bridge camelCase ToolAnnotations reads by @zzstoatzz in #4597
  • Preserve raw CallToolResult tool returns by @LarryHu0217 in #4587
  • Advertise only supported token endpoint auth methods in OAuthProxy metadata by @jlowin in #4608
  • Fix OAuth proxy override typing by @zzstoatzz in #4612
  • Pin burner-redis below the Windows-crashing 0.1.7 release by @jlowin in #4618
  • fix : canonical mime type mapping from formats to remove inconsistency #4627 by @Aman071106 in #4628
  • fix: accept callable roots handlers by @ShuyingZhang in #4639
  • Pass the MCP conformance suite's draft and pending scenarios by @jlowin in #4650
  • Use issuer_url for OAuth issuer identity by @jlowin in #4652
  • Fix the ty failure blocking upgrade checks on main by @jlowin in #4657
  • Bind CIMD assertion audience to the advertised token endpoint by @jlowin in #4659
  • Record effective scopes on the OAuth transaction by @jlowin in #4670
  • Copy schemas iteratively so deep nesting still compresses by @jlowin in #4671
  • Fix OpenAPI allOf reference fields by @hxaxd in #4653
  • Flatten OpenAPI discriminator subtypes into request bodies by @jlowin in #4677
  • Let maintenance releases publish without fastmcp-tasks by @jlowin in #4676
  • Read CLI-scanned MCP config files as UTF-8 explicitly by @jlowin in #4690
  • Late-bind app tool names so UIs survive composition by @jlowin in #4682

Docs 📚

  • Docs: forward-port v3.4.4 changelog entries by @jlowin in #4476
  • Document icon theme support by @jlowin in #4537
  • Add missing 4.0.0 version badge to Path Security docs by @jlowin in #4540
  • Align server component docs by @strawgate in #4260
  • Align CLI, deployment, and config docs by @strawgate in #4259
  • Align client, Apps, and integration docs by @strawgate in #4261
  • Fix stale MRTR/elicitation framing in client and upgrade docs by @jlowin in #4551
  • docs: quote pip extras install examples by @RachGranville in #4568
  • Document Windows CI parallelism and the subprocess_heavy marker by @jlowin in #4575
  • Document v3->v4 removals and add upgrade-reality tests by @jlowin in #4585
  • Archive v3 docs and publish v4 as the primary version by @jlowin in #4613
  • Document targeted v4 prerelease installation by @zzstoatzz in #4598
  • Fix stale Mac/Windows-vs-Linux OAuth key/storage docs by @jlowin in #4617
  • v4 docs quality pass: stale task/era claims, broken links, polish by @jlowin in #4619
  • whats-new: add the argument completion capability by @jlowin in #4620
  • docs: fix ProxyProvider docstring example calling nonexistent with_namespace() by @andrew-stelmach-fleet in #4633
  • Unpublish v4 development notes; prep docs for beta 1 by @jlowin in #4644
  • Expand the FAQ for the v4 transition by @jlowin in #4649
  • Document the issuer_url identity change for upgraders by @jlowin in #4658
  • Cover require_roles in the v4 highlights by @jlowin in #4666
  • Fix FAQ: sampling/roots/elicitation legacy-mode advice, SessionProvider registration by @jlowin in #4672
  • Audit v4 docs: fix missing version badges, fill whats-new gaps by @jlowin in #4668
  • Docs: add v3.4.5 changelog entries to main by @jlowin in #4674
  • Split the SDK upgrade guides by SDK version by @jlowin in #4684
  • Add v4.0.0b1 changelog and updates entries by @jlowin in #4681

Dependencies 📦

  • chore(deps): bump mcp from 1.26.0 to 1.27.2 in /examples/testing_demo in the uv group across 1 directory by @dependabot[bot] in #4514
  • chore(deps): bump actions/setup-node from 6 to 7 by @dependabot[bot] in #4546
  • Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #4640
  • Bump actions/setup-python from 6 to 7 by @dependabot[bot] in #4641
  • chore(deps): bump mcp from 1.27.2 to 1.28.1 in /examples/testing_demo in the uv group across 1 directory by @dependabot[bot] in #4614

Other Changes 🦾

  • Test: HTTP lifespan fires once per process across sessions by @jlowin in #4470

New Contributors

Full Changelog: v3.4.5...v4.0.0b1

Don't miss a new fastmcp release

NewReleases is sending notifications on new releases.