Engine modules (keys, context snapshot, docket lifespan, worker CLI,
client handles) move intact; SEP-1686 wire modules park in _legacy_wire
for adaptation to SEP-2663. Core keeps task=True declaration on tools
only and raises at serve time until the tasks extension is registered.
Co-Authored-By: Claude <noreply@anthropic.com>
Removes pins added while making the auto-default suite pass that weren't
actually testing older-protocol-only behavior, and keeps (with a stated
reason) the ones that are. Along the way, fixes two real defects the audit
surfaced in the modern protocol path: PingMiddleware could leak a
_active_sessions entry when a connection's exit_stack closed before its
keepalive task got its first scheduler turn, and FastMCP(experimental_
capabilities=...) was silently dropped from server/discover responses
(it only ever reached the legacy initialize handshake).
Client negotiates the newest mutual protocol era by default (probe
server/discover, fall back to the initialize handshake). ProxyClient and the
inspect utility explicitly pin the handshake era so proxy forwarding and
server_info reads are unchanged. SSE and multi-server config transports are
legacy-only. extensions= and result_claims= (SEP-2133) are thin passthroughs
to the SDK session.
* Make the SDK seam the root of FastMCP middleware dispatch (D3)
Notifications, cancellations, and malformed/unroutable messages now reach
on_message/on_request/on_notification at the SDK seam. Component methods keep
their interior dispatch (typed hooks, tool-exception visibility) unchanged; the
seam covers only messages the interior never dispatches, so each hook fires once.
* Document the middleware seam coverage and suspend semantics (D3)
* Align seam docs and ask-visibility test with the result-cycle MRTR model
An InputRequiredResult is the full result of a complete request->response
cycle, not a suspension: component hooks observe an asking round's
InputRequiredToolResult as an ordinary return value.
* Replace 'seam' language with plain dispatch terminology
* Keep the raw middleware __call__ signature; forward middleware message edits
* Cover fires-once across an MRTR continuation round
* Align cherry-picked coverage test with renamed recorder
* Rewrite only the message, never the dispatch destination
* Fix typos
* Document Cachable* -> Cacheable* rename as v4 breaking change
Adds the response-cache model rename to the change register, per
maintainer decision to skip compatibility aliases in favor of clear
documentation.
* Skip invalid Before import in doc test; use inline codespell ignore
The Cachable* -> Cacheable* breaking-change entry showed the old,
now-invalid import for contrast, which the doc-example test picked up
as a real import and flagged as a regression. Comment out the
deliberately-broken "Before" line (matching the McpError entry just
above it) so only the working "After" import is exercised.
Also swap the blanket codespell ignore-words-list entry for a
narrower inline `codespell:ignore` directive on the one line that
needs it, so codespell keeps flagging "cachable" everywhere else.
---------
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
Replaces FastMCP.as_proxy() helper calls with create_proxy(), rewrites the
mount() as_proxy=/prefix= kwarg tests to plain mount() (the params are gone),
and deletes deprecation-only tests for as_proxy() and remove_tool().
* pin pydantic-monty to 0.0.8
* rename tool/prompt/resource base modules to avoid decorator name shadow
* add sys.modules shims for old submodule import paths
* preserve original module paths in deprecation warnings
* clarify when sys.modules shims can be removed
* 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>
* Fix ty 0.0.19 type errors
🤖 Generated with Claude Code
* Fix ruff formatting in sampling/run.py
🤖 Generated with Claude Code
https://claude.ai/code/session_01GWzbyF1vHvVeS4yJ5bhScf
---------
Co-authored-by: Claude <noreply@anthropic.com>
* 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 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>
* 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>