NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #400 most downloaded on PyPI
The fast, Pythonic way to build MCP servers and clients.
Last release today
04 Oct 2026
Ships fairly regularly
a new release about every 1 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
129 releases · first in 2024
One column per month.
rate_limiting: deprecate a burst_capacity below 1 by @zzstoatzz and @sclfcz in #5296
This release contains important security and bug fixes. All users are encouraged to upgrade. Thanks to our 10 contributors, including 6 first-time contributors.
Full Changelog: v4.0.10...v4.0.11
Task-enabled tools now work behind search transforms and CodeMode: they're registered with the task backend even when hidden, and a tool, resource, or
Task-enabled tools now work behind search transforms and CodeMode: they're registered with the task backend even when hidden, and a tool, resource, or prompt that calls one through ctx.fastmcp.call_tool() (including the search call_tool proxy and CodeMode's execute) now gets its result instead of an empty task receipt.
Full Changelog: v4.0.9...v4.0.10
ResourceTemplate now keeps its compiled URI pattern for its own lifetime while the shared cache is bounded again, preventing dynamic proxies from grow
ResourceTemplate now keeps its compiled URI pattern for its own lifetime while
the shared cache is bounded again, preventing dynamic proxies from growing
process memory without restoring the 4,096-template performance cliff.
Full Changelog: v4.0.8...v4.0.9
Completion goes back to its 4.0.5 behavior. The visibility check added in 4.0.6 and reworked in 4.0.7 simulated list requests through middleware, and
Completion goes back to its 4.0.5 behavior. The visibility check added in 4.0.6 and reworked in 4.0.7 simulated list requests through middleware, and in 4.0.7 that could let a response cache serve hidden prompts to other clients. New tests pin both problems, and withholding suggestions for hidden references will return with a proper design. Resource template patterns are now cached without a size limit, so servers with thousands of templates read fast again, and OAuthProxy revokes the upstream refresh token instead of sending its own token upstream.
Full Changelog: v4.0.7...v4.0.8
Fixes two regressions from 4.0.6. The completion visibility check runs only the list-specific middleware hooks, so rate limits, logging, and metrics s
Fixes two regressions from 4.0.6. The completion visibility check runs only the list-specific middleware hooks, so rate limits, logging, and metrics see a single request per completion again. Resource template patterns are cached, which makes template reads faster than in 4.0.5.
Full Changelog: v4.0.6...v4.0.7
Resource templates now match what clients actually send: literals raw or percent-encoded, and list query parameters exploded or comma-joined. A Client
Resource templates now match what clients actually send: literals raw or percent-encoded, and list query parameters exploded or comma-joined. A Client whose exit is cancelled releases its session instead of leaking it, completion no longer answers for prompts and templates the caller can't see, and JSON schemas with float or oversized length limits load instead of failing. The auth fixes cache OIDC discovery and keep Google tokens out of request URLs.
get_schema by @zzstoatzz in #4970Full Changelog: v4.0.5...v4.0.6
Tool parameters declared strict with Field(strict=True) , StrictInt , or a strict model config are honored again, on both direct calls and task submis
Tool parameters declared strict with Field(strict=True), StrictInt, or a strict model config are honored again, on both direct calls and task submission. Since the SDK v2 migration the server's lax default overrode them and silently coerced values.
Full Changelog: v4.0.4...v4.0.5
OpenAPI request bodies get most of the attention in this patch: multipart string arrays are sent as repeated fields, whole-body arguments no longer cl
OpenAPI request bodies get most of the attention in this patch: multipart string arrays are sent as repeated fields, whole-body arguments no longer clobber same-named HTTP parameters, dictionary bodies and raw content types survive intact, and JSON scalar bodies are encoded. On the auth side, OAuthProxy rejects ID-JAG tokens unless identity assertion is configured and refuses non-positive upstream token expiries. Clients now follow empty pagination cursors and servers reject malformed ones.
Full Changelog: v4.0.3...v4.0.4
Multi-server clients with legacy-only backends now avoid unnecessary startup retries, and tools returning unconstrained sequences no longer send image
Multi-server clients with legacy-only backends now avoid unnecessary startup retries, and tools returning unconstrained sequences no longer send images twice. This patch also fixes task timing values rejected by strict clients and cleans up unfinished Monty callbacks when execution ends.
Full Changelog: v4.0.2...v4.0.3
ClientGroup is now importable from the package root, from fastmcp import ClientGroup , with the same lazy export and install hint as Client , so integ
ClientGroup is now importable from the package root, from fastmcp import ClientGroup, with the same lazy export and install hint as Client, so integrations no longer couple to FastMCP's internal module layout.
Full Changelog: v4.0.1...v4.0.2
ClientGroup now reference-counts its context the way Client does, so entering a connected group from a nested block or a concurrent task reuses the ex
ClientGroup now reference-counts its context the way Client does, so entering a connected group from a nested block or a concurrent task reuses the existing connections instead of raising. Adapters written against Client's reentrancy can hold a ClientGroup the same way.
Full Changelog: v4.0.0...v4.0.1
Breaking changes: server-initiated sampling and roots are removed (no live connection exists to call back into mid-request), ctx.elicit() is old-proto…
FastMCP 4 is stable. Five betas, five weeks, 23 contributors, and more than 80 pull requests later — the new protocol engine held up under real gateways, agent frameworks, and production servers, and most FastMCP 3 applications upgrade without code changes.
This is the FastMCP release for the new MCP. On July 28, MCP released the 2026-07-28 protocol revision and the rewritten Python SDK v2 shipped the same day. FastMCP 4 is built on both: modern requests are sessionless and self-contained, so any replica behind an ordinary load balancer can answer them, and one FastMCP 4 deployment negotiates the best protocol version per connection — new clients get the new protocol, old clients keep working, and Client(url) does the same negotiation from the other side.
The new protocol's capabilities come through FastMCP's usual high-level surfaces:
@mcp.tool(task=True)) run outside the request path via the io.modelcontextprotocol/tasks extension, shipped in the optional fastmcp-tasks package on the same Docket engine as FastMCP 3.add_extension(): a negotiated capability, additive request methods, tool-call interception, and a lifespan. Tasks are built this way, outside core.Mcp-Method/Mcp-Name routing headers so gateways can route without parsing JSON-RPC.The framework grew alongside the protocol: dependency injection can bind a dependency to arguments of the call it serves (Depends(get_account, user_id=CallArgument("owner"))) while keeping it out of the tool schema, and ClientGroup manages one client per server with collision-checked namespacing — each member negotiating its own protocol version.
The beta period motivated a bunch of correctness work. Most of it was auth: hardened OAuth consent flows, issuer validation, and JWT verification, plus proxies that strip cookies and connection-owned headers at trust boundaries. The rest was durability and compatibility — encrypted task snapshots, serialized event-store writes, response caching handling empty results, errors, and versioned components, and dozens of smaller fixes from CodeMode to Python 3.14 compat.
Breaking changes: server-initiated sampling and roots are removed (no live connection exists to call back into mid-request), ctx.elicit() is old-protocol-only, FastMCP 3's deprecated APIs are gone, MCP model fields are snake_case (with a warning compatibility bridge for the old names), and background tasks moved to fastmcp-tasks. Passing a bare string like Client("server.py") to run local code is deprecated in favor of Path, for removal in FastMCP 5.
The upgrade guide covers every change and includes a copyable prompt for auditing an application with a coding agent.
Happy (context) engineering!
valid_scopes parameter to OIDC proxy valid scopes by @Educg550 in #4660required order deterministic by @Kludex in #4564Note truncated.
FastMCP 4 beta 5 introduces ClientGroup — one managed client per server, each negotiating its own protocol era independently, with collision-checked t
FastMCP 4 beta 5 introduces ClientGroup — one managed client per server, each negotiating its own protocol era independently, with collision-checked tool namespacing and call routing and no proxy in the middle. It also aligns middleware response limits with output schemas.
Full Changelog: v4.0.0b4...v4.0.0b5
FastMCP 4 beta 4 improves modern multi-server clients and adds Prefect Horizon account commands. It also tightens proxy and CIMD security boundaries a
FastMCP 4 beta 4 improves modern multi-server clients and adds Prefect Horizon account commands. It also tightens proxy and CIMD security boundaries and fixes Unicode search and MCP inspect output.
Full Changelog: v4.0.0b3...v4.0.0b4
Nothing published for this version
Serialize the event store's stream list read-modify-write
Serialize the event store's stream list read-modify-write (#4758)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
Breaking changes. Server-initiated sampling and roots are removed from the server API: both pushed a request down a live connection, which the session…
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.
<!-- Release notes generated using configuration in .github/release.yml at main -->
valid_scopes parameter to OIDC proxy valid scopes by @Educg550 in https://github.com/PrefectHQ/fastmcp/pull/4660required order deterministic by @Kludex in https://github.com/PrefectHQ/fastmcp/pull/4564Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.5...v4.0.0b1
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.
valid_scopes parameter to OIDC proxy valid scopes by @Educg550 in #4660required order deterministic by @Kludex in #4564Note truncated.
Nothing published for this version
Document v3->v4 removals and add upgrade-reality tests
Document v3->v4 removals and add upgrade-reality tests (#4585)
* Document v3->v4 removals and add upgrade-reality tests
* Check canonical imports in a clean subprocess to avoid suite import pollution
* Address review: import_server semantics note, pin traversal error, drop redundant import
* Address review round 2: real screening test, Depends factory, remove_tool/create_proxy notes
* Validate canonical imports in-process; fix lifespan/timeout/error-code/starlette doc notes
* Reconcile with fastmcp.types trim: import protocol types from mcp_types
* Record v4 release codename arc in dev notes
This release contains important security and bug fixes. All users are encouraged to upgrade. Thanks to our 2 contributors.
This release contains important security and bug fixes. All users are encouraged to upgrade. Thanks to our 2 contributors.
Full Changelog: v3.4.7...v3.4.8
FastMCP 3.4.7 restores CIMD private_key_jwt authentication for OAuthProxy deployments at a bare origin. Client assertions are now validated against th
FastMCP 3.4.7 restores CIMD private_key_jwt authentication for OAuthProxy deployments at a bare origin. Client assertions are now validated against the exact token endpoint advertised in authorization server metadata, eliminating the doubled-slash audience mismatch.
<!-- Release notes generated using configuration in .github/release.yml at release/3.x -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.6...v3.4.7
FastMCP 3.4.7 restores CIMD private_key_jwt authentication for OAuthProxy deployments at a bare origin. Client assertions are now validated against the exact token endpoint advertised in authorization server metadata, eliminating the doubled-slash audience mismatch.
Full Changelog: v3.4.6...v3.4.7
FastMCP 3.4.6 backports trusted-proxy support for SSRF-protected OAuth metadata and JWKS fetches. Deployments can now route these requests through a m
FastMCP 3.4.6 backports trusted-proxy support for SSRF-protected OAuth metadata and JWKS fetches. Deployments can now route these requests through a mandated corporate proxy while preserving custom CA certificates; FastMCP refuses the fetch when no proxy is configured instead of risking an unprotected direct request.
<!-- Release notes generated using configuration in .github/release.yml at release/3.x -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.5...v3.4.6
FastMCP 3.4.6 backports trusted-proxy support for SSRF-protected OAuth metadata and JWKS fetches. Deployments can now route these requests through a mandated corporate proxy while preserving custom CA certificates; FastMCP refuses the fetch when no proxy is configured instead of risking an unprotected direct request.
Full Changelog: v3.4.5...v3.4.6
FastMCP 3.4.5 collects five fixes for the 3.x line. The one that prompted it: a single Ed25519 key in a JWKS — which Rauthy, Ory Hydra, and some Keycl
FastMCP 3.4.5 collects five fixes for the 3.x line. The one that prompted it: a single Ed25519 key in a JWKS — which Rauthy, Ory Hydra, and some Keycloak configurations publish by default — made JWTVerifier reject every token, including ones correctly signed by supported keys in the same set.
<!-- Release notes generated using configuration in .github/release.yml at release/3.x -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.4...v3.4.5
FastMCP 3.4.5 collects five fixes for the 3.x line. The one that prompted it: a single Ed25519 key in a JWKS — which Rauthy, Ory Hydra, and some Keycloak configurations publish by default — made JWTVerifier reject every token, including ones correctly signed by supported keys in the same set.
Full Changelog: v3.4.4...v3.4.5
FastMCP 3.4.4 restores HTTP deployment compatibility after the 3.4.3 Host/Origin guard changed default behavior for existing ASGI, serverless, and rev
FastMCP 3.4.4 restores HTTP deployment compatibility after the 3.4.3 Host/Origin guard changed default behavior for existing ASGI, serverless, and reverse-proxy deployments. The guard implementation remains available for deployments that opt in with explicit trusted hosts and origins, while 3.x returns to accepting traffic that worked before the patch. This release also adds Hugging Face OAuth provider support, with docs and examples for public and private apps, PKCE, Dynamic Client Registration, and CIMD.
<!-- Release notes generated using configuration in .github/release.yml at release/3.x -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.3...v3.4.4
FastMCP 3.4.4 restores HTTP deployment compatibility after the 3.4.3 Host/Origin guard changed default behavior for existing ASGI, serverless, and reverse-proxy deployments. The guard implementation remains available for deployments that opt in with explicit trusted hosts and origins, while 3.x returns to accepting traffic that worked before the patch. This release also adds Hugging Face OAuth provider support, with docs and examples for public and private apps, PKCE, Dynamic Client Registration, and CIMD.
Full Changelog: v3.4.3...v3.4.4
FastMCP 3.4.3 closes out a month of SSRF and OAuth hardening: NAT64, 6to4, Teredo, and ISATAP transition addresses can no longer smuggle private IPv4
FastMCP 3.4.3 closes out a month of SSRF and OAuth hardening: NAT64, 6to4, Teredo, and ISATAP transition addresses can no longer smuggle private IPv4 targets past the SSRF allow-list, Streamable HTTP now validates Host and Origin before session handling to block DNS rebinding against localhost-bound servers, and OAuth redirect validation rejects unsafe schemes and unregistered DCR redirect URIs. Alongside the security work, this release also fixes proxy session teardown races, discriminator-tag handling in JSON schema conversion, and several smaller reliability issues.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.2...v3.4.3
FastMCP 3.4.2 restores JWT compatibility for providers that include private, non-critical JWS header parameters. Tokens from providers like Clerk can
FastMCP 3.4.2 restores JWT compatibility for providers that include private, non-critical JWS header parameters. Tokens from providers like Clerk can carry header metadata such as cat without being rejected before signature and claim validation, while unsupported critical headers are still rejected.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.1...v3.4.2
FastMCP 3.4.1 floors Starlette at >=1.0.1 so installs can no longer resolve to a version affected by CVE-2026-48710 — previously the dependency was on…
FastMCP 3.4.1 floors Starlette at >=1.0.1 so installs can no longer resolve to a version affected by CVE-2026-48710 — previously the dependency was only constrained transitively through mcp, which allowed vulnerable versions. It also makes OAuthProxy log refresh-token cache misses instead of failing silently.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.4.0...v3.4.1
FastMCP 3.4 is about reaching servers that live somewhere else. The headline is fastmcp-remote, a standalone bridge that connects stdio-only MCP hosts
FastMCP 3.4 is about reaching servers that live somewhere else. The headline is fastmcp-remote, a standalone bridge that connects stdio-only MCP hosts to servers hosted over HTTP. Around it, this release hardens the proxy layer those remote connections depend on — making bridges fail loudly instead of silently, and keeping authenticated sessions alive across the long idle periods that remote clients are prone to.
Some MCP hosts still insist on launching a local stdio command, even when the server you want is already running over HTTP. FastMCP could already proxy a remote URL through fastmcp run, but that pulls in the full server-runner surface. fastmcp-remote is the small, single-purpose version: one URL in, one local stdio proxy out.
{
"mcpServers": {
"linear": {
"command": "uvx",
"args": ["fastmcp-remote", "https://mcp.linear.app/mcp"]
}
}
}
OAuth is enabled automatically for HTTPS servers, with support for explicit bearer tokens and custom headers when you need them. The implementation stays on FastMCP primitives — Client, OAuth, create_proxy, and stdio — and credits the original npm mcp-remote project for the command shape.
Proxies are lazy bridges: they don't touch the upstream server during construction, but they do forward real MCP requests once a client connects. As of 3.4, initialize is part of that forwarded surface — so a proxy only reports a successful handshake after the upstream server initializes too. A missing backend, a wrong URL (the server root instead of /mcp), denied upstream auth, or a non-MCP upstream now fails the downstream initialize instead of producing a "connected" proxy whose capability fetches quietly come back empty. The proxy also forwards ping upstream now.
This is an intentional behavior change from 3.3, and the reason bridge callers like fastmcp-remote surface real upstream failures instead of degrading into empty tool lists.
Remote sessions sit idle, and short-lived upstream tokens punish that. fastmcp_access_token_expiry_seconds decouples the FastMCP-issued token's lifetime from the upstream expires_in — the FastMCP token is just a reference into proxy storage, re-validated and transparently refreshed on every request, so it can safely outlive a 5-minute upstream token without forcing a full OAuth flow after every idle period. When the upstream issues no refresh token, the lifetime is capped to match.
from fastmcp.server.auth.providers.github import GitHubProvider
auth = GitHubProvider(
client_id="...",
client_secret="...",
base_url="https://your-server.com",
fastmcp_access_token_expiry_seconds=60 * 60 * 24, # 24h client-facing token
)
Alongside it, token_expiry_threshold_seconds treats tokens as expired N seconds early to close refresh races, and WorkOSProvider gains valid_scopes and extra_authorize_params.
A tool could previously only signal an error by raising, which flattens to a text-only result and discards structured content. ToolResult now accepts is_error, mapping to CallToolResult.isError so a tool can hand back a rich error the model can see and act on. The proxy uses this to forward upstream tool errors intact instead of collapsing them.
@mcp.tool
def lookup(id: str) -> ToolResult:
if not found(id):
return ToolResult(
content="not found",
structured_content={"code": 404, "id": id},
is_error=True,
)
...
MontySandboxProvider() now applies a conservative baseline when constructed without limits — 30s duration, 100 MB memory — and CodeMode caps tool calls at 50 per execute block. Both remain explicitly opt-out (limits=None, max_tool_calls=None), so the safe configuration is the default instead of something you had to remember to turn on.
The auth stack migrated its JWT handling to joserfc. The fastmcp dev CLI gains --host and --log-panel/--no-log-panel. Resources created from templates now preserve annotations, meta, title, and icons; resource templates with query params work on proxied servers; OTEL spans cover the sampling step and tool execution; MCP config files are read as UTF-8; and the OAuth server metadata endpoint now answers at the /.well-known/openid-configuration alias.
8 new contributors this release.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.3.1...v3.4.0
FastMCP 3.4 introduces fastmcp-remote, a standalone Python utility for connecting stdio-only MCP hosts to remote MCP servers.
FastMCP 3.4 introduces fastmcp-remote, a standalone Python utility for connecting stdio-only MCP hosts to remote MCP servers.
When a host expects to launch a local command, fastmcp-remote runs locally, connects to a remote server over Streamable HTTP or SSE, and exposes that server back to the host over stdio:
{
"mcpServers": {
"remote-api": {
"command": "uvx",
"args": ["fastmcp-remote", "https://example.com/mcp"]
}
}
}
OAuth is enabled automatically for HTTPS servers, with support for explicit bearer tokens and custom headers when needed.
Please note: the FastMCP 3.4.0 betas are being released for testing the new fastmcp-remote package, host compatibility, and remote authentication behavior, and should not be used for production deployments yet.
FastMCP 3.3.1 is a hotfix for the 3.3 packaging split. Clean installs of 3.3.0 could fail on standalone component imports like from fastmcp.tools impo
FastMCP 3.3.1 is a hotfix for the 3.3 packaging split. Clean installs of 3.3.0 could fail on standalone component imports like from fastmcp.tools import tool because component modules reached auth and task primitives through fastmcp.server, pulling in the server/provider stack and exposing a circular import.
Component-level auth and task primitives now live in lightweight utility modules, with the old server import paths preserved as compatibility re-exports. Component imports stay lightweight, existing server-facing imports continue to work, and the release also includes small docs corrections from the 3.3 rollout.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.3.0...v3.3.1
fix(auth): silence authlib.jose DeprecationWarning at JWT import by @SarthakB11 in https://github.com/PrefectHQ/fastmcp/pull/4100
FastMCP 3.3 ships fastmcp-slim, a new lightweight distribution that separates the client from the server stack. It also closes out a meaningful backlog of security hardening, observability improvements, and auth additions that accumulated through the 3.2 cycle.
The full FastMCP package pulls in Starlette, Uvicorn, and the rest of the server machinery — necessary for running a server, but wasteful if you're writing a client, a script, or an agent that just needs to talk to MCP. fastmcp-slim is a dependency-light distribution that ships the client and transport layer without any of that.
The import namespace is unchanged:
from fastmcp import Client
async with Client("https://example.com/mcp") as client:
result = await client.call_tool("my_tool", {"arg": "value"})
Install fastmcp-slim[client] anywhere you want FastMCP's client without the server footprint — CI environments, lightweight agents, library dependencies that shouldn't force Uvicorn on downstream users.
The OAuth proxy received three hardening upgrades. Silent consent is now guarded against AS-in-the-middle attacks — a malicious authorization server can no longer silently approve a consent it wasn't meant to handle. Redirect URI allowlist matching now rejects dot-segment paths (/../, /./) that could otherwise bypass prefix checks. And ResponseCachingMiddleware partitions its cache by access token, closing a gap where different users could see each other's cached responses.
AzureB2CProvider adds first-class support for Azure AD B2C user flows. The OCI provider is fixed for 3.x installs. And OAuthProxy gains a public update_scopes() API for updating the proxy's required scopes after initialization — useful for servers that determine scope requirements at runtime.
OTEL instrumentation is now fully compliant with MCP semantic conventions. List operations (list_tools, list_resources, list_prompts, list_resource_templates) are instrumented, and delegate spans on proxy servers are enriched with backend attributes.
Sync tools run in a thread pool by default. If your tool holds thread-local state or is bound to a specific thread (UI frameworks, some database drivers), you can now opt out:
@mcp.tool(run_in_thread=False)
def my_tool() -> str:
...
Docket is now reentrant, and mounted servers enter their own lifespan — so a server with startup/shutdown logic works correctly when composed into a larger server. The FastMCP constructor accepts experimental_capabilities for passing raw capability flags. Tool errors accept a log_level parameter to control how they're logged. FormInput supports a default prefill value.
Fixes: ping loop now exits cleanly when a stream closes; sampling from background tasks works correctly; Windows startup no longer crashes on non-UTF-8 console output; blank query string values are preserved in OpenAPI routing; $defs introduced by ArgTransform are hoisted to the schema root; HTTP transports are terminated before lifespan shutdown.
13 new contributors this release.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.2.4...v3.3.0
FastMCP 3.3 introduces fastmcp-slim, a dependency-light distribution for users who want the FastMCP client without installing the full server framewor
FastMCP 3.3 introduces fastmcp-slim, a dependency-light distribution for users who want the FastMCP client without installing the full server framework.
The import namespace stays the same: client-only consumers can install fastmcp-slim[client] and continue writing ordinary FastMCP client code:
from fastmcp import Client
client = Client("https://example.com/mcp")
Please note: the FastMCP 3.3.0 betas are being released for testing the new packages, and should not be used for any other purpose.
FastMCP 3.3 introduces fastmcp-slim, a dependency-light distribution for users who want the FastMCP client without installing the full server framewor
FastMCP 3.3 introduces fastmcp-slim, a dependency-light distribution for users who want the FastMCP client without installing the full server framework.
The import namespace stays the same: client-only consumers can install fastmcp-slim[client] and continue writing ordinary FastMCP client code:
from fastmcp import Client
client = Client("https://example.com/mcp")
Please note: the FastMCP 3.3.0 betas are being released for testing the new packages, and should not be used for any other purpose.
…and stays tied to who started it. This is a breaking change for anyone relying on the old session-scoped semantics.
A grab bag of fixes, hardening, and polish.
The headline behavior change: background tasks are now scoped to the authorization context rather than the MCP session, so a task kicked off by an authenticated user survives session churn and stays tied to who started it. This is a breaking change for anyone relying on the old session-scoped semantics.
Security got three meaningful upgrades. FileUpload now validates actual decoded base64 size instead of trusting the client-reported number, so an attacker can't claim "10 bytes" and deliver 10MB. The proxy client stops forwarding inbound HTTP headers to unrelated remote servers — previously a header meant for server A could leak to server B. And AuthKit now auto-binds token audience to the resource URL per RFC 8707, closing a token-reuse gap across MCP resources.
Schema handling had a rough-edges pass. json_schema_to_type no longer crashes on Python keywords, boolean schemas, empty enums, or name collisions, and we added a 232K-schema crash test from APIs.guru to keep it honest. Gemini 2.5 Flash compatibility is fixed by stripping title fields the model rejects. Parameter descriptions are now extracted from docstrings automatically, so your tool signatures document themselves.
Plus a Keycloak OAuth provider for enterprise auth, improvements to ctx.elicit() (new response_title/response_description, deprecation warning when called without response_type), and dozens of smaller fixes across transforms, retry middleware, resource templates, and client disconnect handling.
<!-- Release notes generated using configuration in .github/release.yml at main -->
or with is not None checks for config/override merging by @strawgate in https://github.com/PrefectHQ/fastmcp/pull/3833Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.2.3...v3.2.4
fakeredis 2.35.0 shipped an undocumented rename (FakeConnection → FakeAsyncRedisConnection) that broke pydocket's memory:// backend, causing fastmcp[t
fakeredis 2.35.0 shipped an undocumented rename (FakeConnection → FakeAsyncRedisConnection) that broke pydocket's memory:// backend, causing fastmcp[tasks] installs to fail at startup with an ImportError. This pins fakeredis<2.35.0 in the tasks extra as a stopgap until a fixed pydocket ships.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.2.2...v3.2.3
The Azure audience fix in 3.2.1 overcorrected: it switched token validation from client_id to identifier_uri, which fixed custom Application ID URIs b
The Azure audience fix in 3.2.1 overcorrected: it switched token validation from client_id to identifier_uri, which fixed custom Application ID URIs but broke the default case where Azure AD v2 tokens set aud to the bare client ID GUID. Both formats are now accepted.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.2.1...v3.2.2
…and asyncio.iscoroutinefunction no longer emits deprecation warnings on Python 3.14.
Most of the fixes in this patch are about auth providers getting audience validation wrong. Cognito token verification was checking the aud JWT claim, but Cognito access tokens don't include one; they use client_id instead. Azure was hardcoding the raw client ID as the expected audience, ignoring the identifier_uri parameter even though Entra v2.0 tokens use the Application ID URI as aud. Both now validate correctly without changing the provider API. Consent cookies also had an unbounded growth problem in high-DCR-client environments, eventually blowing past reverse proxy header limits; they're now capped as an LRU.
On the OpenAPI side, nullable: true fields from 3.0 specs were leaking into tool input schemas as-is instead of being converted to JSON Schema's type: ["string", "null"]. Server variable templates in base URLs (like https://{region}.api.example.com) were also being passed through raw instead of substituted with their defaults.
Smaller fixes: form submissions from Prefab UI now correctly handle unchecked boolean checkboxes, the client no longer crashes on error responses with empty or non-text content from third-party servers, and asyncio.iscoroutinefunction no longer emits deprecation warnings on Python 3.14.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.2.0...v3.2.1
Bump PyJWT >= 2.12.0 (CVE-2026-32597) by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3515
FastMCP 3.2 is the Apps release. The 3.0 architecture gave you providers and transforms; 3.1 shipped Code Mode for tool discovery. 3.2 puts a face on it: your tools can now return interactive UIs — charts, dashboards, forms, maps — rendered right inside the conversation.
FastMCPApp is a new provider class for building interactive applications inside MCP. It separates the tools the LLM sees (@app.ui()) from the backend tools the UI calls (@app.tool()), manages visibility automatically, and gives tool references stable identifiers that survive namespace transforms and server composition — without requiring host cooperation.
from fastmcp import FastMCP, FastMCPApp
from prefab_ui.actions.mcp import CallTool
from prefab_ui.components import Column, Form, Input, Button, ForEach, Text
app = FastMCPApp("Contacts")
@app.tool()
def save_contact(name: str, email: str) -> list[dict]:
db.append({"name": name, "email": email})
return list(db)
@app.ui()
def contact_manager() -> PrefabApp:
with PrefabApp(state={"contacts": list(db)}) as view:
with Column(gap=4):
ForEach("contacts", lambda c: Text(c.name))
with Form(on_submit=CallTool("save_contact")):
Input(name="name", required=True)
Input(name="email", required=True)
Button("Save")
return view
mcp = FastMCP("Server", providers=[app])
The UI is built with Prefab, a Python component library that compiles to interactive UIs. You write Python; the user sees charts, tables, forms, and dashboards. FastMCP handles the MCP Apps protocol machinery — renderer resources, CSP configuration, structured content serialization — so you don't have to.
For simpler cases where you just want to visualize data without server interaction, set app=True on any tool and return Prefab components directly:
@mcp.tool(app=True)
def revenue_chart(year: int) -> PrefabApp:
with PrefabApp() as app:
BarChart(data=revenue_data, series=[ChartSeries(data_key="revenue")])
return app
Five ready-made providers you add with a single add_provider() call:
fastmcp dev apps launches a browser-based preview for your app tools — pick a tool, provide arguments, and see the rendered UI without connecting to an MCP host. Includes an MCP message inspector for debugging the protocol traffic.
This release includes a significant security hardening pass: SSRF/path traversal prevention, JWT algorithm restrictions, OAuth scope enforcement, CSRF fixes, and more. See the changelog for the full list.
forward_resource flag on all OAuth providers for IdPs that don't support RFC 8707. Clerk auth provider. FileResource encoding parameter. SSL verify parameter. client_log_level setting. MCP conformance tests in CI. And contributions from 13 new contributors.
<!-- Release notes generated using configuration in .github/release.yml at main -->
--config-path flag to claude-desktop install command by @Sumanshu-Nankana in https://github.com/PrefectHQ/fastmcp/pull/3380verify parameter for SSL certificate configuration by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3487McpError in initialization middleware to prevent fallthrough by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3413fastmcp list and fastmcp call by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3409version to components in FileSystemProvider by @martimfasantos in https://github.com/PrefectHQ/fastmcp/pull/3458refresh_expires_in=0 as missing, fall back to 30-day default by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3514encoding parameter to FileResource by @shulkx in https://github.com/PrefectHQ/fastmcp/pull/3580Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.1.0...v3.2.0
Pins pydantic-monty<0.0.8 to fix a breaking change in Monty that affects code mode. Monty 0.0.8 removed the external_functions constructor parameter,…
Pins pydantic-monty<0.0.8 to fix a breaking change in Monty that affects code mode. Monty 0.0.8 removed the external_functions constructor parameter, causing MontySandboxProvider to fail. This patch caps the version so existing installs work correctly.
<!-- Release notes generated using configuration in .github/release.yml at release/3.1.1 -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.1.0...v3.1.1
FastMCP 3.1 is the Code Mode release. The 3.0 architecture introduced providers and transforms as the extensibility layer — 3.1 puts that architecture
FastMCP 3.1 is the Code Mode release. The 3.0 architecture introduced providers and transforms as the extensibility layer — 3.1 puts that architecture to work, shipping the most requested capability since launch: servers that can find and execute code on behalf of agents, without requiring clients to know what tools exist.
Standard MCP has two scaling problems. The entire tool catalog loads into context upfront — with a large server, that's tens of thousands of tokens before the LLM reads a single word of the user's request. And every tool call is a round-trip: the LLM calls a tool, the result flows back through the context window, the LLM reasons about it, calls another tool, and so on. Intermediate results that only exist to feed the next step still burn tokens every time.
CodeMode is an experimental transform that solves both. Instead of seeing your tool catalog directly, the LLM gets meta-tools: it searches for relevant tools on demand (using BM25), inspects their schemas, then writes Python that chains call_tool() calls in a sandbox and returns a final answer. Discovery is staged and targeted; intermediate results never touch the model's context window.
from fastmcp import FastMCP
from fastmcp.experimental.transforms.code_mode import CodeMode
mcp = FastMCP("Server", transforms=[CodeMode()])
Your existing tools don't change — CodeMode wraps them. The default three-stage flow (search → get schemas → execute) is configurable: collapse it to two stages for smaller catalogs, skip discovery entirely for tiny ones. The sandbox supports resource limits on time, memory, and recursion depth.
Read the docs here.
Code Mode's discovery layer is also available as a standalone transform. SearchTools adds BM25 text search to any server — clients can query against tool names and descriptions and receive ranked results, without needing to know tool names upfront. This is useful anywhere the tool catalog is large, dynamic, or not known in advance.
3.1 adds early integration with Prefab, a frontend framework with a Python DSL that compiles to React. The vision: Python developers building MCP servers shouldn't have to leave Python to ship a proper UI. Prefab is still under very active development (their words: "probably shouldn't use it yet"), but the integration is here, the pieces are aligning, and 3.2 is where this gets interesting.
MultiAuth lets you compose multiple token verification sources into a single auth layer — useful when you need to accept tokens from more than one provider (e.g., internal JWTs alongside a third-party OAuth provider). This release also adds out-of-the-box support for PropelAuth and a Google GenAI sampling handler.
Heavy imports are now lazy-loaded, meaningfully reducing startup time for servers that don't use every feature. fastmcp run and dev inspector gain a -m/--module flag for module-style invocation, MCPConfigTransport now correctly persists sessions across tool calls, and search_result_serializer gives you a hook to customize how search results are serialized for markdown output. Eight new contributors, and the usual round of fixes.
<!-- Release notes generated using configuration in .github/release.yml at main -->
fastmcp run and dev inspector by @dgenio in https://github.com/PrefectHQ/fastmcp/pull/3331Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.0.2...v3.1.0
Two community-contributed fixes: auth headers from MCP transport no longer leak through to downstream OpenAPI APIs, and background task workers now co
Two community-contributed fixes: auth headers from MCP transport no longer leak through to downstream OpenAPI APIs, and background task workers now correctly receive the originating request ID. Plus a new docs example for context-aware tool factories.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.0.1...v3.0.2
Use max_completion_tokens instead of deprecated max_tokens in OpenAI handler by @jlowin in https://github.com/PrefectHQ/fastmcp/pull/3254
First patch after 3.0 — mostly smoothing out rough edges discovered in the wild. The big ones: middleware state that wasn't surviving the trip to tool handlers now does, Tool.from_tool() accepts callables again, OpenAPI schemas with circular references no longer crash discovery, and decorator overloads now return the correct types in function mode. Also adds verify_id_token to OIDCProxy for providers (like some Azure AD configs) that issue opaque access tokens but standard JWT id_tokens.
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/PrefectHQ/fastmcp/compare/v3.0.0...v3.0.1
Your coding agent can read these notes before it upgrades. Set up the MCP server →