Commit graph

1,198 commits

Author SHA1 Message Date
Jeremiah Lowin
3bc2805b67
fix: normalize Google scope shorthands and surface valid_scopes
Google accepts shorthand scopes like "email" in authorization requests but
returns full URIs like "https://www.googleapis.com/auth/userinfo.email" in
token responses. The verifier now normalizes shorthands at initialization so
the subset check works regardless of which form was used. GoogleProvider also
now exposes valid_scopes for controlling which scopes clients can request
beyond the required minimum.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 18:29:52 -04:00
d 🔹
33c3acfc87
fix: use intent-based flag for OIDC scope patch in load_access_token (#3465)
When OIDCProxy has verify_id_token=True and the IdP issues the same JWT
for both access_token and id_token, the value-equality check
`verification_token != upstream_token_set.access_token` evaluated to
False, skipping the scope patch entirely. This left AccessToken.scopes
empty, causing RequireAuthMiddleware to return 403 insufficient_scope.

Replace the value-equality check with an intent-based virtual method
`_uses_alternate_verification()` that OIDCProxy overrides to return
`self._verify_id_token`. The base OAuthProxy returns False (preserving
existing behavior for non-OIDC providers).

Fixes #3461

Co-authored-by: voidborne-d <voidborne-d@users.noreply.github.com>
2026-03-13 17:59:03 -04:00
Martim Santos
f08205789e
fix: add version to components (#3458) 2026-03-13 17:33:50 -04:00
Jeremiah Lowin
30308332bb
Add FastMCPApp — a Provider for composable MCP applications (#3385)
* Add FastMCPApp — a Provider for composable MCP applications

* Wire Prefab callable resolver via to_json(tool_resolver=) parameter

* Remove inspect.signature compat check, use try/except until prefab 0.10.0

* Address review: fix add_tool registry gaps, normalize auth errors, bump prefab to 0.10.0

* Register global key after _add_component succeeds

* Simplify: extract decorator dispatch, use get_fastmcp_meta, expose get_global_tool

* Remove prek from Marvin workflows

These workflows run Claude to respond to /marvin mentions — linting
the repo is unnecessary and fails without renderer deps installed.

* Return ResolvedTool from callable resolver, add contacts example

The callable resolver now returns ResolvedTool (from prefab_ui) instead of a
plain string, carrying metadata like unwrap_result that the renderer needs to
correctly handle structuredContent envelopes. The unwrap_result flag is derived
from the tool's x-fastmcp-wrap-result output schema marker.

* Bump prefab-ui requirement to >=0.11.0

* Remove stale ty ignore comments now that prefab-ui 0.11 is published
2026-03-09 13:46:14 -04:00
Jeremiah Lowin
08f590fa9e
Sanitize untrusted output in fastmcp list and fastmcp call (#3409)
* Sanitize untrusted CLI client output

🤖 Generated with GPT-5.2-Codex

* Fix ruff format violations
2026-03-07 12:31:46 -05:00
Jeremiah Lowin
5ed14650ab
Block insecure HS* JWT verification with JWKS/public keys (#3430)
* Block HS* JWT verification with public keys/JWKS

🤖 Generated with GPT-5.2-Codex

* Fix ruff format violations

🤖 Generated with Claude Code

* Handle bytes public_key in HS* algorithm PEM check
2026-03-07 12:20:48 -05:00
Jeremiah Lowin
ad517d09fa
Fix async partial callables rejected by iscoroutinefunction (#3438)
* Fix async partial callables rejected by iscoroutinefunction (#3423)

Add `is_coroutine_function()` utility that unwraps `functools.partial`
before checking, and guard `isroutine` checks so partials aren't
misrouted through `__call__`.

* Also check asyncio.iscoroutinefunction in is_coroutine_function
2026-03-07 12:10:09 -05:00
Jeremiah Lowin
bafd5419fa
Redact sensitive headers in OpenAPI provider debug logging (#3436)
* Redact sensitive headers in OpenAPI provider debug logging (#3427)

* Use safe-header allowlist instead of sensitive-header denylist for redaction
2026-03-07 12:10:05 -05:00
Jeremiah Lowin
58e25ccf47
Preserve kw-only defaults when rebuilding functions for resolved annotations (#3429)
* Preserve kw-only defaults in cloned adapters (🤖 GPT-5.2-Codex)

* Fix ruff format violation in test_types.py
2026-03-07 12:10:01 -05:00
Jeremiah Lowin
ceb8ff18c6
Fix $ref output schema object detection regression (#3420)
* Fix  output schema object detection

🤖 Generated with GPT-5.2-Codex

* Fix ty invalid-type-alias-type error

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
🤖 Generated with Claude Code

* Fix $ref resolution to handle JSON Pointer escaping and nested paths

---------

Co-authored-by: Marvin Context Protocol <41898282+Marvin Context Protocol@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
2026-03-07 12:09:56 -05:00
Jeremiah Lowin
6637bcebe1
Fix server lifespan overlap teardown (#3415)
* Fix server lifespan overlap teardown

🤖 Generated with GPT-5.2-Codex

* Clear lifespan state when non-owner session is last to exit
2026-03-07 12:09:50 -05:00
Jeremiah Lowin
9f8347dbaf
Fix get_* returning None when latest version is disabled (#3439)
* Fix get_* returning None when latest version is disabled (#3421)

When a visibility transform disabled the highest version of a component,
get_tool/get_resource/get_resource_template/get_prompt returned None
instead of falling back to the next-highest enabled version. The list_*
path already worked correctly because deduplication runs after visibility
filtering. The get_* path now falls back to listing all versions and
picking the highest enabled one when the top version is disabled.

* Apply auth checks in version fallback paths

The fallback code in get_tool, get_resource, get_resource_template, and
get_prompt bypassed auth filtering when falling back to older versions
after the highest version was disabled. This could expose auth-protected
older versions to unauthorized users.
2026-03-07 11:55:10 -05:00
Jeremiah Lowin
297880bbfa
Block recursive self-invocation in BulkToolCaller (#3433)
* Block BulkToolCaller self-invocation

🤖 Generated with GPT-5.2-Codex

* Fix ruff format violation in test_bulk_tool_caller.py

🤖 Generated with Claude Code
2026-03-07 11:41:15 -05:00
Jeremiah Lowin
44b8238e40
Guard default progress handler against zero totals (#3432)
🤖 Generated with GPT-5.2-Codex
2026-03-07 11:41:11 -05:00
Jeremiah Lowin
d316f193a8
Fix transform arg collisions with passthrough params (#3431)
🤖 Generated with GPT-5.2-Codex
2026-03-07 11:41:07 -05:00
Jeremiah Lowin
901d8cdd60
Block HS* algorithms when JWTVerifier is configured with JWKS (#3419)
* Block HS* algorithms with JWKS in JWT verifier

🤖 Generated with GPT-5.2-Codex

* Fix ruff format: remove extra blank line in test_supabase.py

🤖 Generated with Claude Code

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>

---------

Co-authored-by: Marvin Context Protocol <41898282+Marvin Context Protocol@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
2026-03-07 11:41:04 -05:00
Jeremiah Lowin
544f072659
Guard OAuth callback result from post-completion overwrites (#3417)
* Guard OAuth callback result overwrite 🤖 Generated with GPT-5.2-Codex

* Fix ruff formatting in test_oauth_callback_race.py

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Marvin Context Protocol <41898282+Marvin Context Protocol@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:41:00 -05:00
Jeremiah Lowin
dcaeef0f3d
Handle missing npx.cmd fallback on Windows 🤖 Generated with GPT-5.2-Codex (#3416) 2026-03-07 11:40:57 -05:00
Jeremiah Lowin
0b97aca02a
Re-hash response cache keys 🤖 Generated with GPT-5.2-Codex (#3414) 2026-03-07 11:40:53 -05:00
Jeremiah Lowin
706b56d555
Harden fastmcp metadata parsing in proxy paths (#3412)
🤖 Generated with GPT-5.2-Codex
2026-03-07 11:40:49 -05:00
Jeremiah Lowin
ea19a2a5f5
Block out-of-skill symlink hashing in skills scan (#3410)
🤖 Generated with GPT-5.2-Codex
2026-03-07 11:40:46 -05:00
Jeremiah Lowin
163c16876f
Avoid stale context leakage when proxying with an already‑connected ProxyClient (#3408)
* Avoid reusing connected ProxyClient sessions

🤖 Generated with Codex

* Fix static analysis: ruff format + ty type narrowing
2026-03-07 11:40:43 -05:00
Jeremiah Lowin
1708e53d9e
Bind AWS Cognito token verification to configured app client (#3406)
* Bind Cognito verifier audience to client ID

🤖 Generated with GPT-5.2-Codex

* Fix ty error: narrow return type of AWSCognitoProvider.get_token_verifier

🤖 Generated with Claude Code
2026-03-07 11:40:39 -05:00
Jeremiah Lowin
9ec4e7ae1b
Validate version metadata to reject non-scalar types (#3437)
* Validate version metadata to reject non-scalar types (#3422)

🤖 Generated with Claude Code

* Reject bool values in version coercion
2026-03-07 11:40:36 -05:00
Jeremiah Lowin
fadb630142
Validate workspace path is a directory in cursor install (#3426) (#3435) 2026-03-07 11:40:33 -05:00
Jeremiah Lowin
9ccaef2b6a
Raise ValueError for invalid boolean query params in resource templates (#3424) (#3434) 2026-03-07 11:40:29 -05:00
Jeremiah Lowin
85c71fa834
Bound client auto-pagination loops to prevent unbounded list fetches (#3411)
* Cap client auto-pagination pages

🤖 Generated with GPT-5.2-Codex

* Raise on pagination limit instead of returning partial data

Add max_pages kwarg (default 250) to list_tools/list_resources/
list_resource_templates/list_prompts so users can control the bound.
2026-03-06 17:43:47 -05:00
Jeremiah Lowin
799c4f1673
Escape client_id in OAuth consent details (#3418)
🤖 Generated with GPT-5.2-Codex
2026-03-06 17:33:12 -05:00
Jeremiah Lowin
e3b6b0c470
Deprecate PromptToolMiddleware and ResourceToolMiddleware (#3389)
* Deprecate PromptToolMiddleware and ResourceToolMiddleware

* Remove deprecated middleware from docs entirely

* Remove entire Tool Injection section from middleware docs
2026-03-06 17:17:01 -05:00
Eric Robinson
9319a2c645 Support ImageContent and AudioContent in Message class
Message.content now accepts ImageContent and AudioContent in addition to
TextContent and EmbeddedResource, matching MCP's ContentBlock type. This
fixes ProxyPrompt.render() silently JSON-serializing image/audio content
instead of preserving it.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:12:29 -05:00
Jeremiah Lowin
216f43d0ba
Bind Discord token verifier to client ID (#3405)
🤖 Generated with GPT-5.2-Codex
2026-03-06 17:01:44 -05:00
Jeremiah Lowin
b8c37bfa89
Fix WorkOS token scope verification bypass 🤖 Generated with Codex (#3407) 2026-03-06 17:01:35 -05:00
Sumanshu Nankana
34d848b16a
feat: add --config-path flag to claude-desktop install command (#3380)
* feat: add --config-path flag to claude-desktop install command

* feat: add --config-path flag to claude-desktop install command

* docs: add --config-path option to install-mcp documentation

* fix: show specific error message when provided --config-path does not exist
2026-03-04 15:30:59 -05:00
Jeremiah Lowin
b061126955 Fix ty 0.0.20 compatibility and improve upgrade check notifications 2026-03-03 17:08:46 -05:00
Jeremiah Lowin
0142fefe1b Add test: VersionFilter applied before CatalogTransform is respected 2026-03-03 17:03:11 -05:00
Jeremiah Lowin
03673d9fad Deduplicate versioned tools in CatalogTransform.get_tool_catalog() 2026-03-03 17:03:11 -05:00
Jeremiah Lowin
f923b671ce Remove stale catalog cache from CodeMode execute 2026-03-03 16:49:50 -05:00
Jeremiah Lowin
cea6e935e9 Increase uv transport test timeout to 60s for cold-start CI 2026-03-03 16:49:40 -05:00
Jeremiah Lowin
fec8e8d5ab Fix flaky test_multi_client_lifespan and test_multi_client_force_close 2026-03-03 16:43:27 -05:00
Jeremiah Lowin
cb34191128 Fix resource templates with query params on mounted servers
Closes #3366
2026-03-03 16:43:27 -05:00
Jeremiah Lowin
6aff9c94be Remove form-action from default consent CSP, forward consent_csp_policy in all providers
Drop form-action from the default Content Security Policy on the OAuth
consent page. Chrome enforces form-action across the entire redirect
chain, which breaks flows where an HTTPS callback internally redirects
to a custom scheme (e.g. claude://, cursor://). Since the form posts
to itself and all redirects are server-controlled, form-action adds
no security value here.

Also forward the consent_csp_policy parameter through all concrete
OAuth providers (Auth0, Azure, Google, GitHub, Discord, WorkOS, AWS
Cognito, OCI) so users can override the CSP without accessing private
attributes.
2026-03-03 14:55:00 -05:00
yangbaechu
8a356ad870
Add include_unversioned option to VersionFilter (#3349)
* Add include_unversioned option to VersionFilter

* test: add include_unversioned=False coverage for prompts/templates; align naming/imports
2026-03-02 21:06:50 -05:00
Joris Vandermeersch
fccbd43c1e
Add FASTMCP_TRANSPORT setting for default transport selection (#1796)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
Co-authored-by: Joris Vandermeersch <joris.vandermeersch@vrt.be>
2026-03-02 18:08:59 -05:00
Jeremiah Lowin
404b820144
Add ListTools, search limit, and catalog size annotation to CodeMode (#3359)
* Add tests for two-stage pattern, empty full-detail results, empty inputs

* Add ListTools, search limit, catalog size annotation; split tests

Co-authored-by: Claude <noreply@anthropic.com>

* Remove BM25 internal cap so Search.limit is the sole truncation point

* Pass default_limit to BM25 instead of arbitrary high cap

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-02 18:00:21 -05:00
Bill Easton
49534ce91d
Add Google GenAI Sampling Handler (#2977)
* Add Google GenAI sampling handler

Co-authored-by: Bill Easton <strawgate@users.noreply.github.com>

* chore: Update SDK documentation

* Filter non-Gemini model hints in _get_model

Match the Anthropic/OpenAI handler pattern of only selecting
provider-compatible models from hints.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Bill Easton <strawgate@users.noreply.github.com>
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-03-02 18:00:03 -05:00
Ankesh Kumar Thakur
af557388c7
feat(contrib): auto-sync MCPMixin decorators with from_function signatures (#3323)
* feat: auto-sync MCPMixin decorators with from_function signatures

Replace hard-coded parameter lists in mcp_tool/mcp_resource/mcp_prompt
with **kwargs validated at decoration time against inspect.signature of
the underlying from_function. Registration methods now splat **kwargs
through directly, so any new from_function parameter is supported
automatically without touching the contrib module.

Also fixes enabled=False being silently ignored during registration.

🤖 Generated with Claude Code

* fix: make enabled keyword-only in mcp_tool and mcp_prompt

Prevents silent positional arg remapping — callers who previously
passed description/title as the second positional arg would have
silently bound to enabled instead.

🤖 Generated with Claude Code
2026-03-02 17:30:30 -05:00
Jeremy Simon
f2dd2e5124
Fix session persistence across tool calls in multi-server MCPConfigTransport (#3330)
* connect ProxyClient via AsyncExitStack

* test session persistence for multiple tool calls

* switch to StatefulProxyClient

* changed to StatefulProxyClient

* stash weakref instead of context

* clear transport list before building new session
2026-03-02 17:19:43 -05:00
Jeremiah Lowin
59da3e4ed4
Decompose CodeMode into composable discovery tools (#3354)
* Decompose CodeMode into composable discovery tools

CodeMode now owns only the execute sandbox. Discovery tools (search,
get_schema, etc.) are composable via the discovery_tools parameter.
Each is a Callable[[GetToolCatalog], Tool] factory.

Ships SearchTool (lightweight name+description results) and SchemaTool
(brief markdown or full JSON schemas by tool name) as built-in defaults.

* Rename to Search/GetSchemas/Tags, add tag filtering, fix bugs

- Rename SearchTool→Search, SchemaTool→GetSchemas, Categories→Tags
- Add tags parameter to Search for LLM-side tag filtering
- Add Tags discovery tool for browsing tools by tag
- Fix shared singleton default factories (now per-instance)
- Fix get_schema full mode returning invalid JSON on partial matches
- Fix "untagged" filter inconsistency between Tags and Search
- Split serialization tests to comply with loq line limit
- Rewrite docs for conceptual clarity

* Add three-tier detail levels, remove default_arguments, rename Tags→GetTags, rewrite docs

* Clean up __all__ exports, return valid JSON for empty full-detail results
2026-03-02 16:35:55 -05:00
Chris Guidry
547daf7a36
Replace vendored DI with uncalled-for (#3301)
* Replace vendored DI with uncalled-for

FastMCP vendored a minimal DI engine extracted from Docket (~164 lines)
with try/except fallback patterns everywhere. The `uncalled-for` package
is a clean, typed extraction of this same system, and since Docket will
also depend on it (chrisguidry/docket#353), `uncalled_for.Dependency`
becomes the single canonical base class.

This deletes the `_vendor/docket_di/` directory, replaces all the
try/except import patterns with direct `uncalled_for` imports, and
updates the `Dependency.execution` → `current_execution` ContextVar
references to match the Docket branch. The `Progress` class now
delegates to an internal impl and returns `self` from `__aenter__`
(matching Docket's pattern) so that ty's generic resolution works
without `type: ignore` suppressions.

Temporarily points pydocket at the `use-uncalled-for` branch so both
sides can be validated together in CI.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Re-export Dependency from fastmcp.dependencies

Internal code like azure.py should import from the fastmcp namespace
rather than reaching into uncalled_for directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Import Dependency from fastmcp namespace in tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add generic type parameters to Dependency subclasses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Mention uncalled-for in DI docs

The DI engine now comes from uncalled-for, so the docs should credit
it alongside Docket. Also updates the Docket docs link to docket.lol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Point docket dependency at main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Bump uncalled-for pin to >=0.2.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix uncalled-for imports for 0.2.0 API changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Support Shared() dependencies without docket

Enters a SharedContext at server lifetime so that Shared() dependencies
from uncalled-for resolve once and are cached across tool/resource/prompt
calls. When running with docket, the Worker already handles this; this
covers the non-docket path and direct call_tool() usage.

Also re-exports Shared from fastmcp.dependencies.

Closes #3251

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Bump docket lockfile to latest main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove duplicate test classes from rebase conflict resolution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Point docket dependency at pydocket>=0.18.0 release

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Pair SharedContext __aenter__ with __aexit__ in Context lifecycle

The old `_ensure_shared_context` on the server called `__aenter__()` on a
lazy `SharedContext` but never `__aexit__()`, leaking the exit stack and
its resources. Moved the SharedContext management into Context's own
enter/exit so it's properly paired: when docket is available the lifespan
handles it, otherwise Context creates and cleans up a per-request one.

Updated Shared() tests to use Client (which runs the lifespan) rather
than calling server methods directly, since cross-request sharing
requires a lifespan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Hoist SharedContext import to module level

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 16:35:15 -05:00
Andrew Israel
5fb72c7200 Adds PropelAuth as an AuthProvider
Adds the PropelAuthProvider which delegates to the IntrospectionTokenVerifier
and optionally does an additional resource check.
Adds an example server and client which makes an authenticated request
and gets information from the token.
Updates the documentation (but only for v3 as this isn't in v2).
2026-03-02 16:18:22 -05:00