Commit graph

1,264 commits

Author SHA1 Message Date
Jeremiah Lowin
8e57fe43a0 Update tests for client_secret=None behavior 2025-12-03 15:48:47 -05:00
Chris Guidry
654442bfd3 Update FastMCP for MCP SDK 1.23.1 auth changes
- 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>
2025-12-03 11:50:08 -05:00
Jeremiah Lowin
54692c361e
Expose InitializeResult to middleware (#2516)
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.
2025-12-01 20:55:29 -05:00
Jeremiah Lowin
b501f05794
Switch to new OpenAPI parser as default (#2513)
* Switch to new OpenAPI parser as default

Remove the legacy OpenAPI parser and make the experimental parser the
default. The experimental parser (introduced in 2.11) offers better
performance, improved compatibility, and a more maintainable architecture.

- Delete legacy parser (server/openapi.py, utilities/openapi.py)
- Move experimental parser to main locations
- Remove enable_new_openapi_parser feature flag
- Update documentation to remove experimental references

* Add deprecation stubs for experimental OpenAPI imports

* Add deprecated enable_new_openapi_parser setting and deprecation tests

* SDK docs

* REview comments

* Fix docstrings

* Update docstring

* Review comments

* Fix broken links
2025-12-01 20:29:18 -05:00
Jeremiah Lowin
ee5f465a82
2.14 deprecation removals (#2329)
* 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
2025-12-01 14:11:00 -05:00
Jeremiah Lowin
9c21754a45
Fix Azure provider OIDC scope handling (#2506)
* 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
2025-12-01 13:42:36 -05:00
Ayesha Shafique
e1d41f5e3b
Add Discord OAuth provider and corresponding tests (#2428)
* 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>
2025-12-01 12:58:29 -05:00
Jeremiah Lowin
246a0adefd
Fix get_access_token() returning stale token after OAuth refresh (#2505)
* Fix get_access_token() returning stale token after OAuth refresh

Fixes #1863

* Update dependencies.py
2025-12-01 10:51:02 -05:00
Jeremiah Lowin
3341c0c893
Add icons support to proxy classes (#2502) 2025-12-01 08:55:51 -05:00
Muspi Merol
adbb7d6e53
Add title attribute to ProxyTool, ProxyResource, … (#2497)
* fix: add title attribute to ProxyTool, ProxyResource, ProxyTemplate, and ProxyPrompt

* test: add title assertions for proxy tools, resources, and prompts
2025-12-01 08:48:42 -05:00
Jeremiah Lowin
ba69fba305
Add consent_csp_policy parameter for CSP customization (#2484)
* 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.
2025-11-26 16:53:40 -05:00
Akshay Parihar
a57a155c2e
Scalekit provider updates (#2413)
* 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
2025-11-22 12:22:13 -05:00
Kevin J Gao
05db547d86
feat: Made Changes to DescopeProvider to Support New Well Known URLs (#2392)
* added new DescopeProvider for Agentic Identity Hub

* fixed formatting with ruff

* made coderabbit change

* changed wording in descope.mdx

* added backwards compatibility

* ran ruff

* added scopes_supported to protected metadata resource

* empty commit to re-run tests
2025-11-22 12:20:50 -05:00
William Easton
16562c918e
Merge branch 'main' into latest-py-key-value 2025-11-22 11:07:28 -06:00
Jeremiah Lowin
3592af524a
Merge pull request #2462 from Neet-Nestor/main
Fix Azure OAuth token refresh with unprefixed scopes
2025-11-22 12:04:04 -05:00
Jeremiah Lowin
f06193850a
Merge pull request #2440 from jlowin/fix-exclude-args-serialization
Fix exclude_args with non-serializable types
2025-11-22 12:02:29 -05:00
Nestor Qin
119bf445ea Resolve comments 2025-11-20 15:16:50 -08:00
Nestor Qin
463652a878 Add unit tests 2025-11-20 15:08:50 -08:00
William Easton
6a462827a4
Merge branch 'main' into latest-py-key-value 2025-11-17 12:12:58 -06:00
William Easton
1b5e3cb272
Actually update lockfile, ignore caching diskstore cleanup 2025-11-17 12:03:24 -06:00
Jeremiah Lowin
52100b08ff Fix exclude_args with non-serializable types
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.
2025-11-17 12:25:43 -05:00
Jeremiah Lowin
dd876b5833
Merge pull request #2439 from jlowin/oidc-proxy-extra-params
Add extra_authorize_params and extra_token_params to OIDCProxy
2025-11-17 12:23:11 -05:00
Jeremiah Lowin
e0f0f816b7 Add extra_authorize_params and extra_token_params to OIDCProxy 2025-11-17 11:57:58 -05:00
Jeremiah Lowin
ea31747572 Add refresh token support defaults to GoogleProvider
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.
2025-11-17 11:54:00 -05:00
Jeremiah Lowin
e9667b6624 Fix test regex pattern for updated error message 2025-11-15 12:32:37 -05:00
Jeremiah Lowin
f6635aa15b Fix type errors in oauth_proxy and test_auth_integration
- 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
2025-11-15 12:21:15 -05:00
Jeremiah Lowin
3826f1a240 Fix typos and formatting 2025-11-15 12:21:15 -05:00
Jeremiah Lowin
ec38507f9b Exclude MCP SDK 1.21.1 and update OAuth client tests
- Exclude MCP SDK 1.21.1 due to bug adding metadata URL to scopes
- Update OAuth client tests to use valid scopes
2025-11-15 12:21:15 -05:00
Patrick Stöckle
18d4a6ab63
chore(typos): fix additional typos (#2396) 2025-11-08 10:47:56 -05:00
William Easton
05ac9457b8
Fix duplicate keyword argument error in configure_logging (#2381)
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>
2025-11-06 10:11:16 -05:00
Jeremiah Lowin
f8b896490e
Fix Windows test timeout and restore parallel testing (#2383)
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.
2025-11-05 20:25:10 -05:00
Cemal Kılıç
f540385b58
feat: add algorithm configuration to Supabase auth provider (#2376) 2025-11-05 20:21:10 -05:00
Jeremiah Lowin
48fc8cbc9a
Fix consent form action for subpath mounting (#2382)
* 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
2025-11-05 20:20:38 -05:00
Giovanna Zanardini
a6ddde27df
Allow OAuth instance to use the same httpx factory as the Transport (#2324)
* 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>
2025-11-04 12:14:28 -05:00
Jeremiah Lowin
80d10d23f4
Fix: URL-encode server name in Cursor deeplinks (#2369)
Server names with special characters (&, ?, #, etc.) were creating
malformed deeplink URLs. Now properly percent-encoded.
2025-11-04 11:26:57 -05:00
Jeremiah Lowin
c6a9b3df22
Fix Windows test timeouts from SQLite locking (#2368) 2025-11-04 10:58:49 -05:00
Jeremiah Lowin
5747cb6237
Fix OAuth metadata endpoint URLs when base_url differs from issuer_url (#2353)
* Fix OAuth metadata endpoint URLs when base_url differs from issuer_url

OAuth operational endpoints (/authorize, /token) are mounted at base_url,
but metadata was incorrectly declaring them at issuer_url. This caused
clients following the documented mounting pattern to receive incorrect
endpoint URLs in /.well-known/oauth-authorization-server.

Fixes #2287

* Update auth.py

* Remove unnecessary assertion from OAuthProvider init

* Add info log when issuer_url differs from base_url
2025-11-04 10:38:41 -05:00
Antonio Iorga
7e6610b7b6
Add meta to call tool (#2206)
* feat: Add optional meta parameter to Client tool call methods

* fix: Add support for mcp<1.19

* chore: cleaner solution

* Refactor call_tool to directly accept meta parameter and add tests for meta functionality

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-11-04 10:25:52 -05:00
Jeremiah Lowin
9c861b232b
Add manual initialization control to Client (#2355)
* Add manual initialization control to Client

- Add auto_initialize parameter (default True) to control automatic initialization
- Make initialize() method public with idempotent caching
- Add comprehensive test suite for initialization behavior

* Document client initialization control and server instructions

- Expand documentation to cover auto_initialize parameter
- Show manual initialization for advanced use cases
- Document accessing server instructions via initialize_result

* Update client.mdx
2025-11-03 16:01:30 -05:00
Jeremiah Lowin
6cc9559f84
Bump ty to ==0.0.1a25 (#2350)
* Bump ty to >=0.0.1a25 with type fixes

Follow-up to #2295. Updates ty and fixes compatibility issues with alpha 25, including:

- Updated ignore comment syntax (possibly-unbound-attribute → possibly-missing-attribute)
- Fixed async generator type handling with anext()
- Fixed type narrowing for timeout parameters
- Converted base_url assignments to AnyHttpUrl after string manipulation
- Added CallToolResult to return type annotations
- Removed redundant type casts
- Fixed test form data to use strings instead of bytes

ty alpha 25 has limitations with isinstance() narrowing on unions (see pyproject.toml for details), requiring some targeted type ignores.

* Pin ty to ==0.0.1a25

Alpha releases can have breaking changes, so pin to the tested version.
2025-11-02 20:02:45 -05:00
Cole Murray
0e97a261cf
Security: Validate Cursor deeplink URLs and use safer Windows API (#2348)
* 🤖 Security: Validate Cursor deeplink URLs and replace cmd.exe on Windows

- Add URL scheme validation to reject non-cursor:// URLs
- Replace subprocess cmd.exe call with os.startfile() on Windows
- Add tests for scheme validation and error handling

* 🤖 Fix tests for cross-platform deeplink validation
2025-11-02 19:49:07 -05:00
Brandon Shar
c18782f02b
Add meta support to ToolResult (#2283)
* Add meta to ToolResult

* add this at the client level and test the full integration

* add example

* slipped through linting somehow

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-11-02 16:46:52 -05:00
Jeremiah Lowin
c9ec1459e1
Mark flaky Windows test for retry (#2344)
* Mark flaky Windows test for retry

test_multi_client_transform_with_filtering occasionally times out on Windows CI during exception formatting in linecache.checkcache(). Add @pytest.mark.flaky with 3 retries.

* Remove unnecessary delay from flaky marker
2025-11-01 16:52:08 -04:00
Jeremiah Lowin
dab125e069
Remove test warnings (#2331) 2025-11-01 14:53:51 -04:00
Harshith Thota
321f404046
Added to_data_uri method for Image class. (#2227)
* Added to_data_uri method and path_to_data_uri classmethod for Image class.

* Removed path_to_data_uri classmethod and modified _get_mime_type to use mimetypes.guess_type function instead of hardcoded dictionary.

* Register image/webp with mimetypes before guess_type to support WEBP mimetype detection on Python 3.10.

* Improved branch coverage for Image.to_data_uri.

* Added Image._to_data_uri example in the docs.
2025-11-01 11:40:08 -04:00
Josh Thomas
08c49e62e8
Fix query-only resource templates not matching URIs without query strings (#2323)
* Fix query-only resource templates not matching URIs without query strings

* apply the same fix to `has_resource`
2025-11-01 11:27:37 -04:00
Jeremiah Lowin
de58bb0e6c
Add DebugTokenVerifier with custom sync/async validation (#2296)
* Add DebugTokenVerifier with custom sync/async validation

* move import
2025-10-31 10:38:01 -04:00
Jeremiah Lowin
1ca53b4134
Add base_authority parameter to AzureProvider for Azure Government support (#2306) 2025-10-29 14:06:21 -04:00
mhassaninmsft
b24d771457
Supporting Multiple Issuers For JWTVerifier Oauth Workflow (#2233)
* multiple issuers

* Update tests/server/auth/test_jwt_provider.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix static checks

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-27 18:13:40 -04:00
Jeremiah Lowin
15dbe7ecf0
Add custom token verifier support to OIDCProxy (#2279)
* Add custom token verifier support to OIDCProxy

OIDCProxy now accepts an optional token_verifier parameter to support
non-JWT token formats like opaque tokens from providers such as Clerk.

When provided, the custom verifier is used instead of creating a default
JWTVerifier. Parameters that only apply to JWTVerifier creation (algorithm,
required_scopes) raise clear errors when specified alongside a custom
verifier. Parameters with other purposes (audience for OAuth flow,
timeout_seconds for config fetch) remain allowed.

The custom verifier's required_scopes are automatically loaded and
advertised through OAuth discovery endpoints.

* Document custom token verifier support in OIDC proxy
2025-10-27 13:38:20 -04:00