* fix: shield lifespan teardown from cancellation
Co-authored-by: Claude <noreply@anthropic.com>
* fix: stabilize flaky task and timeout tests under parallel execution
Co-authored-by: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: cache component lists in ProxyProvider to avoid redundant backend connections
Every call_tool through a proxy was triggering _list_tools() to resolve
the tool by name, opening a full MCP session just for the lookup, then
opening a second session for the actual execution. This caches component
lists on the ProxyProvider with a configurable TTL (default 300s),
cutting backend handshakes in half for repeated calls.
* docs: document component caching and session reuse for proxy providers
* fix: add sleep in cache TTL test for Windows clock resolution
* docs: clarify cache scope and dynamic backend guidance
* 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>
* remove unused GOOGLE_SCOPE_ALIASES_REVERSE
---------
Co-authored-by: Claude <noreply@anthropic.com>
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>
* 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
* 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
* 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
* 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.
* Block BulkToolCaller self-invocation
🤖 Generated with GPT-5.2-Codex
* Fix ruff format violation in test_bulk_tool_caller.py
🤖 Generated with Claude Code
* 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
* 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.
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>
* 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
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.
* 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>
* 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>
* 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