* Fix background Context request correlation
* Make OptionalCurrentContext type-safe
Refactor OptionalCurrentContext to wrap CurrentContext instead of overriding __aenter__ with a wider return type. Adds a background-task origin_request_id round-trip test and applies ruff formatting.
* Fix ty ignore syntax in OpenAPI provider
* Fix flaky rate limiting and ping timing tests
* Assert rate limit error message in flaky test fix
* Catch only ToolError in rate limiting test
* Fix NameError with future annotations and Context/Depends parameters
Closes#3238, closes#905
* chore: Update SDK documentation
* Drop unnecessary pre-resolution of annotations
Pydantic (even 2.11.7) uses __module__ not __globals__ to resolve
annotations, so setting __module__ alone is sufficient.
* chore: Update SDK documentation
* Restore annotation pre-resolution for Pydantic compat
The wrapper's __globals__ is read-only and points to dependencies.py,
so some Pydantic versions use it instead of __module__ when resolving
string annotations. Pre-resolving via get_type_hints on the original
function ensures annotations are type objects before Pydantic sees them.
* chore: Update SDK documentation
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* Fix non-serializable state lost between middleware and tools
Inherit _request_state dict from parent Context in __aenter__ so
middleware and tool contexts share the same in-memory state.
Closes#3228
* chore: Update SDK documentation
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* Use standard traceparent/tracestate keys per OTel MCP semconv
The OTel semantic conventions for MCP (https://opentelemetry.io/docs/specs/semconv/gen-ai/mcp/)
put `traceparent` and `tracestate` directly in `params._meta` without a prefix.
FastMCP was using `fastmcp.traceparent` / `fastmcp.tracestate`, which meant
non-FastMCP clients sending the standard keys couldn't propagate traces.
Switches injection to the bare keys and adds fallback extraction for the old
prefixed keys so older FastMCP clients still work.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: Update SDK documentation
* Drop legacy fastmcp.-prefixed trace key fallback
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: Update SDK documentation
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* Update repository references from jlowin/fastmcp to prefecthq/fastmcp
* Retrigger CI after repo transfer
* chore: Update SDK documentation
* Only run deep triage on bug issues for jlowin
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* Add consent binding cookie to prevent confused deputy attacks (GHSA-rww4-4w9c-7733)
The OAuthProxy's consent page verified user intent but didn't bind the
consenting browser to the IdP callback. An attacker could intercept the
upstream authorization URL after consent and send it to a victim, whose
browser would complete the flow without having the consent cookie.
This adds a signed consent binding cookie set during consent approval
(both manual and auto-approve paths) and verified in the IdP callback
handler. A different browser won't have this cookie and gets a 403.
* Use startswith for URL assertion in consent binding test
* Store consent bindings as per-transaction map to support parallel flows
* Only accept __Host- consent binding cookie on HTTPS
* chore: Update SDK documentation
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* fix: restore request context in StatefulProxyClient handlers
StatefulProxyClient reuses sessions across requests, so its receive-loop
task inherits a stale request_ctx ContextVar from the first request.
Server-initiated messages (elicitation, sampling, etc.) that depend on
related_request_id routing get sent to a closed stream and hang forever.
Closes#3169
* chore: Update SDK documentation
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
* fix: guard client pagination loops against misbehaving servers
Treat empty/falsy nextCursor as end-of-pagination and detect cursor
cycles across all client list methods and the server context proxy
helper.
* chore: Update SDK documentation
---------
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Moves relay_elicitation() into elicitation.py so it can reuse
handle_task_input() for the Redis push instead of duplicating that logic.
notifications.py just detects the trigger and calls it.
Also fixes the related-task metadata key from modelcontextprotocol.io/ to
io.modelcontextprotocol/ to match the current spec:
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a background task calls ctx.elicit(), the notification subscriber now
detects the input_required notification and sends a standard elicitation/create
request to the client via session.elicit(). The client's elicitation_handler
fires, and the relay pushes the response to Redis for the blocked worker.
This means clients can respond to background task elicitation using the same
elicitation_handler they'd use for any other elicitation — no need to interact
with Redis or call handle_task_input() directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rename ui= to app= and consolidate ToolUI/ResourceUI into AppConfig
* Remove backward-compat aliases for ToolUI/ResourceUI/ui_to_meta_dict
* Add extra=allow to AppConfig model_config for forward compatibility
* generate-cli: auto-generate SKILL.md alongside CLI script
generate-cli now produces a SKILL.md agent skill file next to the CLI
script, documenting every tool's exact invocation syntax, parameter
flags, and types. Agents can use the CLI immediately without discovery.
* Use uv run --with fastmcp in generated SKILL.md invocations
* Fix skill generation issues from review
- Escape pipe chars in union type labels so markdown tables render
- Boolean params omit <value> placeholder in example invocations
- Quote YAML frontmatter values to handle special chars in names
- Match cyclopts camelCase→snake_case in flag derivation
- Use four-backtick fence for nested code block in docs
* Replace --skill/--no-skill with just --no-skill
* Escape quotes in YAML frontmatter description
* Strip newlines from param descriptions in skill table rows
* Detect boolean union types for flag placeholder
Replace 1300+ lines of mock-heavy unit tests with 391 lines of integration
tests using real Client(mcp) connections and memory:// Docket backend.
- test_context_background_task.py: 17 tests covering report_progress delta
tracking, elicitation flow, edge cases, and fail-fast on push failure
- test_notifications.py: 2 E2E tests for notification queue lifecycle
Fixes#3097
When using FastMCP.from_openapi() with APIs that require specific
Content-Type headers (e.g., application/vnd.api+json), the transport
connection's content-type: application/json was being injected into
downstream API requests, causing HTTP 415 (Unsupported Media Type) errors.
This change adds content-type to the exclude_headers set in get_http_headers(),
similar to how accept is already excluded. The MCP transport's content type
has no relevance to downstream API calls and should not be forwarded.
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>