Five review fixes. ctx.session_id / get_state / set_state now work in a Docket
worker by falling back to the snapshotted session id. Task management wire calls
(submission, tasks/get/update/cancel) create client spans and propagate trace
context. TasksClientSettings loads .env like DocketSettings, and the docs use
its real env var name. A state-only guard round (request_state, no input
requests) fails with a clear error instead of silently completing wrong.
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>
* Add FASTMCP_SSRF_TRUST_PROXY to allow SSRF fetches through a corporate proxy
🤖 Generated with Claude Code
* Make SSRF fetch client trust_env explicit for proxy routing
🤖 Generated with Claude Code
* Warn when SSRF proxy trust is enabled without a configured proxy
🤖 Generated with Claude Code
* Warn when NO_PROXY would send an SSRF-trust-proxy fetch direct
🤖 Generated with Claude Code
* Refuse SSRF-trust-proxy fetches when no proxy would route the target
🤖 Generated with Claude Code
* Fix TestProxyMode mocks to patch httpx2.AsyncClient
main's httpx -> httpx2 migration (#4503) landed after these tests were
written; ssrf.py's fetch path already uses httpx2.AsyncClient, but
TestProxyMode still patched the old httpx module, so the mock silently
stopped intercepting and requests escaped to the real network.
* Fix port-qualified NO_PROXY bypass in SSRF proxy-trust guard
proxy_bypass(hostname) discarded the port, so a NO_PROXY entry like
127.0.0.1:8443 went undetected while httpx2 honored it and sent the
request direct with the blocklist already disabled. Pass host:port
instead, except for IPv6 literals, where httpx2 ignores port when
matching NO_PROXY and neither bracketed nor unbracketed host:port
reliably matches through proxy_bypass()'s own parser.
* Replace NO_PROXY prediction with explicit proxy control in SSRF trust-proxy mode
Predicting httpx2's proxy routing (via proxy_bypass(), then via httpx2's own
get_environment_proxies()/URLPattern internals) kept diverging from its real
NO_PROXY handling — three rounds, three different divergences, always in the
unsafe direction. Read HTTPS_PROXY/ALL_PROXY directly and pass it to httpx2
explicitly with trust_env=False, so the request provably goes through that
proxy instead of being predicted to. NO_PROXY is no longer evaluated in this
mode: a NO_PROXY'd host is now routed through the proxy rather than refused,
since that's strictly safer than the alternative (direct with the blocklist
already off).
---------
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
* Turn OpenTelemetry instrumentation on by default with explicit off-switch
Add FASTMCP_ENABLE_TELEMETRY setting (default true) and mcp.protocol.version
span attribute for SDK parity.
* Make disabled telemetry a transparent pass-through, not a NoOpTracer
The stock NoOpTracer.start_as_current_span attaches a NonRecordingSpan, hijacking the current OTel context from any enclosing application span. When telemetry is disabled, get_tracer() now returns a non-attaching pass-through tracer so trace.get_current_span() inside handlers still resolves to the caller's span.
- Use 10 PBKDF2 iterations in test_mode (vs 1M in production) for
JWT key derivation — cuts auth test setup from ~2.5s to <0.1s
- Add timeout(15) to subprocess-spawning tests (TestKeepAlive,
test_mcp_config) that exceed 5s under parallel CI load
- Remove pytestmark filterwarnings overrides in tests/deprecated/
that were leaking DeprecationWarning to test output
- Fix deprecated add_tool_transformation() usage in test_authorization
- Document new settings in settings.mdx