- Move from fastmcp.experimental.sampling.handlers.openai to fastmcp.server.sampling.openai
- Update docs and tests to use new import path
- Remove experimental handlers directory
Functions passed to ctx.sample(tools=[...]) are now auto-converted
via SamplingTool.from_function(). Users can still use that method
directly for custom name/description overrides.
* Implement MCP background tasks (SEP-1686) using Docket
Adds support for background task execution via the MCP task protocol,
powered by Docket for task queue management.
- Tools, resources, and prompts can be marked with `task=True` to run async
- Progress dependency for tracking task progress
- CurrentDocket and CurrentWorker dependencies for advanced use cases
- Client API with `.call_tool(..., task=True)` returns task handles
- Task status notifications via subscriptions
- CLI worker command for distributed task processing
Configuration via environment:
- FASTMCP_ENABLE_DOCKET=true
- FASTMCP_ENABLE_TASKS=true
- FASTMCP_DOCKET_URL=redis://... (or memory:// for single-process)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix tasks example import (TaskStatusResponse → GetTaskResult)
The example was using a non-existent TaskStatusResponse type.
Updated to use mcp.types.GetTaskResult which is what the
on_status_change callback actually receives.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix env var name in Docket error messages
The error messages referenced FASTMCP_EXPERIMENTAL_ENABLE_DOCKET but the
actual setting is FASTMCP_ENABLE_DOCKET.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove deprecated code re-added from pre-#2329 branch
- Remove ExtendedEnvSettingsSource (FASTMCP_SERVER_ prefix support)
- Remove dependencies parameter from FastMCP.__init__
* Replace fakeredis git pin with PyPI release
* Remove redundant fakeredis dev dep (pulled via pydocket)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
- Add tools and result_type parameters to ctx.sample()
- Update OpenAI handler for tool content types
- Client advertises sampling.tools capability by default
- Collect tool results into single message with list content
When GitHub's API rate limits cause asyncio shutdown issues, the test
times out rather than failing with the underlying 429 error. Updated the
detection logic to check for 429 indicators in the captured output when
a timeout occurs.
Also increased the per-test timeout from 15s to 30s to give remote API
calls more breathing room.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
All OAuth providers now return correct invalid_client error codes
instead of unauthorized_client for auth failures. Previously only
OAuthProxy had this fix; now OAuthProvider (and InMemoryOAuthProvider)
also benefit.
The pytest-retry plugin was causing teardown crashes due to a bug with
pytest's tmp_path fixture stash. Removing `@pytest.mark.flaky` and instead
improving the rate limit detection to properly skip tests on 429 errors.
Also fixed a brittle error message regex - GitHub changed their error
format from "tool not found" to "unknown tool".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* Fix RFC 8414 path-aware authorization server metadata discovery
Override get_well_known_routes() in OAuthProvider to rewrite the
authorization server metadata route to be path-aware based on issuer_url,
matching how protected resource metadata already works.
Closes#2527
* Update readme
- Bump mcp SDK to >=1.23.1
- Add `client_secret_basic` authentication support (SDK PR #1334)
- TokenHandler now wraps SDK's handle() to transform `unauthorized_client`
to `invalid_client` on 401 responses per OAuth 2.1 spec
- Update `sample()` return type to use SDK's SamplingMessageContentBlock
- Update test expectations for new SDK fields (`task`, `_meta`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wrap responder.respond() to capture the InitializeResult before it's
sent to the write stream, then return it through the middleware chain.
This allows middleware (e.g., logging) to access the server's initialize
response, not just the client's request.
* Initialize 2.14 deprecation removal branch
* Remove deprecated FASTMCP_SERVER_ environment variable prefix (#2330)
* Remove deprecated Context.get_http_request method (#2332)
* Remove fastmcp.Image top-level import (deprecated 2.8.1) (#2334)
* Remove test warnings (#2331)
* Create new branch and fix issue
* Remove deprecated client parameter from FastMCPProxy (#2333)
* Remove deprecated run_streamable_http_async method (#2338)
* Remove deprecated sse_app method (#2337)
* Remove deprecated run_sse_async method (#2335)
* Remove deprecated run_sse_async method
* Update CLI and tests to use run_http_async(transport="sse")
- Change CLI to call run_http_async with transport="sse" instead of run_sse_async
- Update test to mock run_http_async with create=True for v1 servers
* Revert CLI changes - v1 servers do have run_sse_async
- Keep CLI calling run_sse_async() for v1 compatibility
- Update test to mock run_sse_async (which exists on v1)
* Remove unnecessary type ignore for run_sse_async
Method exists on v1 FastMCP class, no type error
* Remove unused imports after test deletion
* Remove deprecated streamable_http_app method (#2336)
* Remove deprecated dependencies parameter from FastMCP constructor (#2340)
* Remove output_schema=False support (deprecated 2.11.4) (#2339)
* Remove deprecated client parameter from FastMCPProxy (#2333)
* Delete deprecated test_output_schema_false.py
Tests functionality that has been removed
* Remove deprecated BearerAuthProvider module (#2341)
* Remove resource_prefix_format="protocol" support (deprecated 2.4.0) (#2342)
* Remove resource_prefix_format="protocol" support (fixes#2195)
Removes deprecated protocol format (prefix+resource://path) and keeps only
path format (resource://prefix/path). Since only one format remains:
- Removed resource_prefix_format from settings, FastMCP.__init__, and helpers
- Simplified add_resource_prefix, remove_resource_prefix, has_resource_prefix
- Removed MountedServer.resource_prefix_format field
- Deleted tests for protocol format
All resource prefixes now use path format exclusively.
* Clean up resource_prefix_format references
- Remove from test files
- Update documentation to remove protocol format section
- Move custom HTTP routes note to mounting section
- Remove resource_prefix_format from settings docs
* Use inline version note instead of badge for prefix format
* Remove obsolete test functions and update docs
- Delete test functions that no longer assert anything
- Remove proxy.mdx reference to deleted prefix format section
* Format error messages per ruff
* Remove from_client classmethod (deprecated 2.8.0) (#2343)
* Remove deprecated from_client classmethod (fixes#2192)
* Remove unused Client import
* Remove add_resource_fn method (deprecated 2.7.0) (#2345)
* Update SDK
* Add missing imports for exclude_args deprecation warning
* Fix Azure provider to handle OIDC scopes correctly
OIDC scopes (openid, profile, email, offline_access) were being
incorrectly prefixed with identifier_uri, causing Azure to reject
authorization requests. This fix:
- Detects OIDC scopes and sends them unprefixed to Azure
- Filters OIDC scopes from token validation (Azure doesn't include
them in access token scp claims)
- Still advertises OIDC scopes to clients via valid_scopes
- Also handles dot-notation scopes (e.g., User.Read) correctly
Fixes#2451, #2420
* Fix dot-notation scopes to be prefixed (custom scopes can have dots)
* Improve Azure scope handling docs with clear examples
* Add Discord OAuth provider and corresponding tests
* Update DiscordProvider client_secret and required_scopes documentation
* Add Discord to authentication support list in README
* Fix Discord token verifier to match actual API response format
Discord's /api/oauth2/@me endpoint returns:
- "scopes" as a list, not "scope" as a space-separated string
- "expires" as ISO timestamp, not "expires_in" as seconds
- "user" data directly in the response (no need for extra API call)
* Simplify Discord token verifier
---------
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
* fix: add title attribute to ProxyTool, ProxyResource, ProxyTemplate, and ProxyPrompt
* test: add title assertions for proxy tools, resources, and prompts
* Add consent_csp_policy parameter to OAuthProxy
Allows customization or disabling of CSP directives on the consent page.
Fixes#2476.
* Add consent_csp_policy to OIDCProxy and update docs
* Fix HTML injection vulnerability in CSP policy
HTML-escape the CSP policy value before inserting into meta tag to prevent HTML injection when CSP policies contain quotes.
* sk-provider updates - aud not enforce, scopes enforce if present
* updating env_prefix, adding debug logs
* updating docs
* ruff formatting
* not changing prefix for backward compatiblity
* backward compatibility changes
* give more preference to base_url than mcp_url if both passed
* updating docs
* refactor
* updating example server
* updating readme of example
* updating docs
* updating tests to reflect what should ideally go in the parameter
Fixes issue #2431 where exclude_args fails when excluded parameters have
non-serializable types (e.g., ServerSession). The fix excludes parameters
from function annotations before Pydantic tries to serialize them.
Also adds deprecation notice that exclude_args will be deprecated in
FastMCP 2.14 in favor of dependency injection.
Set access_type=offline and prompt=consent by default to ensure
refresh tokens are returned by Google. Also expose extra_authorize_params
so users can customize authorization behavior.
- Add null checks for client_id before using in OAuthTransaction, AuthorizationCode, AccessToken, RefreshToken
- Add null check for redirect_uris before len() call
- Import AuthorizeError from mcp.server.auth.provider
Allow traceback-related kwargs to override defaults by building a dict
with defaults first, then updating with user-provided values.
Fixes#2356
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: William Easton <strawgate@users.noreply.github.com>
OAuth consent tests were timing out on Windows due to SQLite database
locking when OAuthProxy instances used the default DiskStore without
explicit MemoryStore configuration. Added explicit client_storage=MemoryStore()
to three tests in TestConsentPageServerIcon.
Also restored parallel testing on Windows (--numprocesses auto) which
was previously disabled but is now safe with proper test isolation.
* Fix consent form action for subpath mounting
When a FastMCP server is mounted at a subpath (e.g., /api/v1), the consent
form used a hardcoded absolute path (/consent/submit) that didn't include
the mount prefix, causing 404 errors on submission.
Changed the form to use an empty action (action="") which submits to the
current URL, making it work correctly regardless of mount path. Also
consolidated the consent endpoints to handle both GET and POST at /consent.
Fixes#2380
* Update integration test to use /consent instead of /consent/submit
* Allow OAuth instance to use the same httpx factory as the Transport
* Fix test
* Update SSL verification mode assertion in tests
* This is actually not needed
* Creating a Client instance is not needed for this test
* Fix test
* Apply httpx_client_factory fix to SSETransport
Extends the OAuth httpx_client_factory changes to SSETransport.
SSETransport had the same issues as StreamableHttpTransport where it
wasn't passing the custom httpx client factory to OAuth, causing
certificate verification settings to be ignored during OAuth flows.
Changes:
- Set httpx_client_factory before calling _set_auth()
- Pass httpx_client_factory to OAuth constructor
- Add test for SSETransport OAuth client factory propagation
---------
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>