Commit graph

1,251 commits

Author SHA1 Message Date
Jeremiah Lowin
ecee38d3d6
fix: resolve CurrentFastMCP/ctx.fastmcp to child server in mounted background tasks
Closes #3571
2026-03-27 10:10:48 -04:00
Bill Easton
b1505ba5d7
Run MCP conformance tests in CI (#3628)
🤖 Generated with Claude Code

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:19:13 -04:00
Bill Easton
f5804f4761
fix: recover StdioTransport after subprocess exits (#3630)
* fix: recover StdioTransport after subprocess exits

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: improve Windows reliability for stdio crash recovery

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:16:54 -04:00
Bill Easton
65ea57963a
fix: filesystem provider import machinery (#3626)
* fix: filesystem provider import machinery

- Temporary sys.path entries (both package and non-package mode) now removed
  immediately after exec_module via try/finally, eliminating permanent process-wide pollution
- Non-package files use bare stem as sys.modules key only if unclaimed; falls back
  to private hash-based key to prevent stdlib shadowing (e.g. json.py clobbering json)
- Reload of private-key modules uses spec.loader.exec_module directly instead of
  importlib.reload, which cannot find files by their private synthetic name
- _find_package_root gains stop_at parameter; discover_and_import passes provider_root
  to prevent package root discovery from escaping above the provider boundary

Closes #3625 (issues 2, 3, 6)

🤖 Generated with Claude Code

* fix: use contextlib.suppress for SIM105 linting

🤖 Generated with Claude Code

* test: add import machinery regression tests

🤖 Generated with Claude Code

* fix: resolve provider_root before path comparison; improve tests

- Resolve provider_root in import_module_from_file so the stop_at boundary
  in _find_package_root works correctly when provider_root is a relative path
  (e.g. FileSystemProvider(Path("./mcp"))) — previously the resolved file_path
  and unresolved stop_at.parent would never compare equal
- Fix test_stdlib_not_shadowed: use unconditional finally to restore sys.modules["json"]
- Strengthen test_same_stem_files: assert mod_a is not mod_b and that sys.modules["helpers"]
  was not clobbered by the second import
- Replace direct _find_package_root unit test with an integration test through
  import_module_from_file(provider_root=...) that also verifies the module name
  and that tmp_path is not added to sys.path

🤖 Generated with Claude Code
2026-03-26 17:53:12 -04:00
Jeremy Simon
492db9972f
fix: resolve EntraOBOToken dependency injection through MultiAuth (#3609)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-03-25 10:58:19 -04:00
AIKAWA Shigechika
c3f0223bbb
fix(google): replace deprecated /oauth2/v1/tokeninfo with /oauth2/v3/userinfo (#3603)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-03-25 10:39:34 -04:00
Jeremiah Lowin
1eabe7f74a
Move app modules to fastmcp.apps package (#3616) 2026-03-24 21:51:20 -04:00
Jeremiah Lowin
c397e68d39
Update ty ignore comments for 0.0.25 compatibility (#3614) 2026-03-24 20:26:26 -04:00
Jeremiah Lowin
ca76b82878
Respect OpenAPI content type in request body serialization (#3611) 2026-03-24 18:39:37 -04:00
Jeremiah Lowin
c04ce8972f
Apps Phase 1: docs, examples, app-only tool filtering (#3593)
* Apps Phase 1: docs, examples, app-only tool filtering, Rx() migration

* Clarify architecture page is Prefab-specific

* Fix component reference inaccuracies and DataTable search prop

- Charts import: clarify they must come from prefab_ui.components.charts
- DataTable: searchable→search (the actual prop name), remove nonexistent
  table-level sortable prop
- Select: remove nonexistent options prop, show SelectOption children
- Tabs: default_value→value
- Fix search=True in inventory, patterns, datatable examples

* Consistent Rx usage across all examples, fix imports

* Address review: fix chart imports, Select import, docstring --stdio claims
2026-03-24 13:35:29 -04:00
Jeremiah Lowin
6f30e89dd1
Fix query parameter serialization to respect OpenAPI explode/style settings (#3595)
* Fix query parameter serialization to respect OpenAPI explode setting

* Support pipeDelimited and spaceDelimited query param styles

* Lowercase booleans in comma/pipe/space-joined query values

* Omit empty arrays from query string when explode=false

* Handle object query params with explode=false
2026-03-23 15:19:55 -04:00
Jeremiah Lowin
e5dce51286
Fix app tool routing: visibility check and middleware propagation (#3591) 2026-03-22 19:59:23 -04:00
Rushabh Doshi
204e566227
Fix loopback redirect URI port matching per RFC 8252 §7.3 (#3589)
🤖 Generated with Claude Code

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 19:35:02 -04:00
Jeremiah Lowin
96497acd16
Route app tool calls through provider chain, remove process-level registry (#3587)
Adds Provider.get_app_tool(app_name, tool_name) — a dedicated method for
finding app-visible tools by their original name, bypassing transforms.
AggregateProvider queries children, WrappedProvider delegates to inner,
FastMCPProvider delegates to nested server. The default implementation
checks _get_tool and matches meta.fastmcp.app.

This replaces the process-level _APP_TOOLS registry. Tool routing now
works through the provider tree, which exists in every process — no
shared state needed for horizontal scaling.
2026-03-22 19:29:33 -04:00
Jeremiah Lowin
52feff6878
Transparently refresh upstream token in OAuthProxy.load_access_token() (#3584)
* Transparently refresh upstream token in OAuthProxy.load_access_token()

When upstream token validation fails during load_access_token, attempt
to refresh using the stored refresh token before returning None. This
prevents premature 401s that force clients into expensive full re-auth
flows when the upstream token expires.

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

* Gate transparent refresh on token expiry, add advisory lock

Only attempt upstream refresh when the token is actually expired, not
on any validation failure (scope mismatch, revocation, etc.). Add
per-token advisory lock to prevent concurrent async tasks from racing
to refresh the same upstream token.

* Re-check expiry inside lock, reload from storage after refresh failure

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-22 10:43:44 -04:00
Jeremiah Lowin
d27c26e0ff
Replace UUID global keys with (app_name, tool_name) registry (#3585)
* Replace UUID global keys with (app_name, tool_name) registry

Collapses three module-level registries (_APP_TOOL_REGISTRY,
_FN_TO_GLOBAL_KEY, _NAME_TO_GLOBAL_KEY) into one: _APP_TOOLS keyed by
(app_name, tool_name). Removes UUID generation, global key stamping in
metadata, and the complex resolver that mapped callables and strings
through multiple fallback paths.

The server now reads _meta.fastmcp.app from the MCP request (set by the
Prefab renderer) and routes directly to the named app's tool. Two apps
with the same tool name are disambiguated by app name, not by UUID.

The resolver is simplified to pass-through: CallTool("save") serializes
as "save", and the server resolves it at call time using the app context.

* Read app name from _meta.prefab.app to match Prefab renderer

* Inject _meta.fastmcp.app into @app.ui() structured content

The @app.ui() decorator stores the FastMCPApp name in the tool's metadata.
When the tool result is serialized, _prefab_to_json injects it as
_meta.fastmcp.app in the structured content. The Prefab renderer reads
this on init and echoes it back as _meta.fastmcp.app on every
callServerTool call, completing the routing loop.
2026-03-22 10:41:50 -04:00
Marcus Shu
2d7bc4e73d
Add encoding parameter to FileResource (#3580)
* feat: Add encoding parameter to FileResource

- Add optional encoding field (str | None, default None) to FileResource.
- Pass encoding through to read_text() for cross-platform text file reading.
- Preserve backward compatibility by defaulting to system encoding.

* test: Add tests for FileResource encoding parameter

- Test UTF-8 reading with explicit encoding for non-ASCII content.
- Test backward compatibility when no encoding is specified.
- Test that encoding is ignored for binary file reads.
- Test Latin-1 reading with matching encoding.

* docs: Document FileResource encoding parameter

- Add encoding="utf-8" to FileResource example in resource classes guide.
- Update FileResource description to mention encoding support.

* feat: Change FileResource encoding default from None to utf-8

- Default to utf-8 instead of system encoding to prevent cross-platform footgun.
- Update field description to reflect new default.
- Update test to verify default encoding is utf-8 with non-ASCII content.
- Remove redundant encoding="utf-8" from docs example since it is now the default.
2026-03-22 09:55:16 -04:00
Jeremiah Lowin
718ed8b140
fix: preserve tool properties named 'title' during schema compression (#3582) 2026-03-22 09:48:20 -04:00
Jeremiah Lowin
1be9b4d39c
Comprehensive MCP Apps docs, string CallTool resolution (#3575)
* Comprehensive MCP Apps docs, string CallTool resolution, bump prefab-ui >=0.13.0

Rewrites the apps documentation as a learning journey: overview → Prefab apps
→ FastMCPApp → patterns → dev tools → custom HTML. Adds a new FastMCPApp page
covering composable apps with @app.tool()/@app.ui(), CallTool, forms, actions,
and composition. Teaches Rx() and set_initial_state() as the primary state API.

Adds string-based CallTool resolution so CallTool("save_contact") resolves to
the tool's global key, matching callable ref behavior. Requires prefab-ui 0.13.0
which passes strings through the tool resolver.

* Detect ambiguous string CallTool resolution across apps

* Simplify string name registry to plain dict (last-write-wins)
2026-03-21 19:44:11 -04:00
Jeremiah Lowin
faef74b374
fix: store absolute token expiry to prevent stale expires_in on reload (#3572) 2026-03-21 12:12:50 -04:00
Bill Easton
196e2b48c5
fix: increase sleep duration in proxy cache tests (#3567) 2026-03-21 11:38:58 -04:00
Jeremiah Lowin
269c9c9f46
Extract TokenCache utility, add caching to GitHubTokenVerifier (#3547)
* feat: add TokenCache utility and caching to GitHubTokenVerifier

Extract the caching machinery from IntrospectionTokenVerifier into a
shared TokenCache class in fastmcp.utilities.token_cache, then wire
it into both IntrospectionTokenVerifier and GitHubTokenVerifier.

* Remove dead constant, validate negative cache params

* Fix overwrite eviction bug, skip cache on scope lookup failure
2026-03-18 15:26:09 -04:00
Jeremiah Lowin
02d55dec32
Graceful degradation for multi-server proxy setup (#3546)
* Graceful degradation for multi-server proxy setup

* Add comment for broad except, parameterize test ordering
2026-03-18 15:25:56 -04:00
Jeremiah Lowin
734b93b999
Support ImageContent and AudioContent in sampling handlers (#3550)
* feat: support ImageContent and AudioContent in sampling handlers

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

* Validate image MIME types, fix silent drop in assistant list messages

* Reject image/audio in assistant messages with tool_calls

* Reject ImageContent in assistant messages for Anthropic

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-18 15:25:16 -04:00
Jeremiah Lowin
9aa31d57f2
fix: suppress output schema for ToolResult subclass annotations (#3548)
* fix: suppress output schema for ToolResult subclass annotations

* use issubclass_safe/is_class_member_of_type for ToolResult subclass checks

* use parsed_fn.return_type for ToolResult check in transform fallback
2026-03-18 15:22:37 -04:00
Jeremiah Lowin
a50dcd8705
fix: filter warnings by message in KEY_PREFIX test (#3549) 2026-03-18 11:33:19 -04:00
Jeremiah Lowin
360c9c31e5
fix: resolve Pyright "Module is not callable" on @tool, @resource, @prompt decorators (#3540)
* 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
2026-03-17 18:11:42 -04:00
Jeremiah Lowin
f9ed06176a
fix: route ResourcesAsTools/PromptsAsTools through server middleware (#3495)
* fix: enforce auth/visibility in ResourcesAsTools and PromptsAsTools for non-FastMCP providers

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

* fix: honor stdio auth bypass and correct transform ordering in provider wrappers

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

* fix: move context/dependencies imports into function to break circular import

* fix: route ResourcesAsTools/PromptsAsTools through ctx.fastmcp

Instead of manually reimplementing auth, visibility, and session
transforms in the transform layer, tool functions now call
ctx.fastmcp.read_resource() / ctx.fastmcp.render_prompt() which
routes through the server's full middleware chain. This matches
the pattern CodeMode uses with ctx.fastmcp.call_tool().

The isinstance(provider, FastMCP) branching is removed entirely.

* feat: add _scope parameter for provider-scoped listing

AggregateProvider can now filter which child providers to query when
listing components. ResourcesAsTools and PromptsAsTools use this to
scope listings to their configured provider while still routing
through ctx.fastmcp for full middleware coverage.

The scope matching walks wrapped providers, so a
WrappedProvider(Namespace, inner=MyProvider) matches if MyProvider
is in the scope list.

* test: add coverage for ResourcesAsTools scoped to a sub-server

* fix: delegate to super() when _scope is None, add AggregateProvider to scope matching

* simplify: remove _scope machinery, route everything through ctx.fastmcp

Reverts the _scope parameter from Provider/AggregateProvider/Server.
ResourcesAsTools and PromptsAsTools now simply route through
ctx.fastmcp for all operations. Apply to a FastMCP server instance
for proper auth/visibility/middleware coverage.

Tests rewritten to use FastMCP server directly instead of raw providers.

* warn when ResourcesAsTools/PromptsAsTools is applied to a non-FastMCP provider

* docs: explain that ResourcesAsTools/PromptsAsTools should wrap a FastMCP server

* raise TypeError instead of warning when applied to non-FastMCP provider

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-15 16:35:54 -04:00
Jeremiah Lowin
bb37c3bb6b
fix: reject refresh tokens used as Bearer access tokens (#3524) 2026-03-15 15:21:30 -04:00
Jeremiah Lowin
b0b3a6dd95
fix: use raw strings for regex in pytest.raises match (#3523) 2026-03-15 15:14:15 -04:00
Jeremiah Lowin
b2d4cc90e5
fix: validate server names in install commands (#3522)
* fix: validate server names in install commands

* Scope validation to shell-backed install paths only
2026-03-15 14:54:24 -04:00
Jeremiah Lowin
8fdb3cc27c
fix: CSRF double-submit cookie check in consent flow (#3519)
* Upgrade examples/testing_demo lockfile, drops diskcache (CVE-2025-69872)

* fix: add CSRF double-submit cookie check to consent flow (GHSA-rww4-4w9c-7733)

* fix: preserve CSRF state across concurrent flows, fix test isolation

* fix: reject non-__Host consent-state cookie on HTTPS
2026-03-15 14:22:01 -04:00
Jeremiah Lowin
32dfe50f39
Treat refresh_expires_in=0 as missing, fall back to 30-day default (#3514)
Keycloak returns refresh_expires_in=0 for offline tokens (offline_access scope),
meaning "no fixed time-based expiry". The truthiness check on this value caused
the proxy to skip issuing a PROXY_RT, forcing browser re-auth every hour.

Closes #3509

🤖 Generated with Claude Code

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-15 11:49:50 -04:00
Jeremiah Lowin
226bfb49fa
fix: remove forced follow_redirects from httpx_client_factory calls (#3496)
* fix: stop passing follow_redirects to httpx_client_factory

Remove the `follow_redirects=True` kwarg that was being forced onto
custom httpx_client_factory calls with a type: ignore suppression.
The McpHttpClientFactory protocol does not include follow_redirects,
so this was a protocol violation. httpx already strips Authorization
headers on cross-origin redirects via its _redirect_headers mechanism.

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

* fix: restore follow_redirects=True for custom httpx client factories

httpx already strips Authorization headers on cross-origin redirects,
so follow_redirects is safe to keep. Removing it broke redirect
handling for users providing custom factories.

* fix: remove vacuous test that never invoked connect_session

The test asserted on received_kwargs but never called connect_session,
so the factory was never invoked and the assertion was a no-op.

* fix: use AsyncClient with transport= instead of monkey-patching _transport
2026-03-15 11:30:41 -04:00
Jeremiah Lowin
b720fc5e38
fix: prevent path traversal in skill download (#3493)
* fix: prevent path traversal in skill download via malicious skill names

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

* fix: resolve skill_dir once and use consistently to prevent overwrite bypass

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-15 11:22:13 -04:00
Jeremiah Lowin
ea529f6a49
feat: make upstream_client_secret optional in OAuthProxy (#3486)
* feat: make upstream_client_secret optional in OAuthProxy

Extract _create_upstream_oauth_client() factory method for subclass
override. Cookie signing falls back to JWT key material when no secret.

* fix: include client_id in revocation requests for public clients

* fix: use factory method for revocation auth
2026-03-15 11:14:56 -04:00
Jeremiah Lowin
40bdfb6b1d
fix: URL-encode path params to prevent SSRF/path traversal (GHSA-vv7q-7jx5-f767) (#3507)
* fix: URL-encode path params in OpenAPI provider to prevent SSRF/path traversal

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

* Exempt too-long from core-category requirement in triage

* fix: also encode dots in path params to prevent bare .. traversal

* fix: only encode .. (not all dots) to preserve valid dotted values

* fix: encode all dots in path params to prevent single-dot normalization

* fix: check decoded path stays within prefix in double-encoding test

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-15 10:45:24 -04:00
Jeremiah Lowin
9be42d9013
perf: reduce PBKDF2 iterations in tests, fix warnings and timeouts (#3504)
- 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
2026-03-14 16:42:06 -04:00
Jeremiah Lowin
7017106c63
fix: restrict $ref resolution to local refs only (SSRF/LFI) (#3502)
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-14 16:35:53 -04:00
Jeremiah Lowin
71ba030380
fix: reject empty/OIDC-only required_scopes in AzureProvider (#3503)
🤖 Generated with Claude Code
2026-03-14 16:35:43 -04:00
Jeremiah Lowin
5ff64ce21b
fix: handle re.error from malformed URI templates in build_regex (#3501) 2026-03-14 16:34:06 -04:00
Jeremiah Lowin
ca8069cb86
Enforce per-tool auth checks in SamplingTool.from_callable_tool wrapper (#3494)
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-14 16:14:50 -04:00
Jeremiah Lowin
32f1118a11
Expose minimum_check_interval, reduce task pickup latency (#3500)
* perf: expose minimum_check_interval, reduce task pickup latency

The Docket Worker polls for new tasks every minimum_check_interval
(previously hardcoded to 250ms in pydocket). Expose this setting so
users can tune it, default to 50ms, and override to 10ms in tests.

This cuts average task pickup latency from ~125ms to ~5ms per task.

* perf: reduce task test overhead and eliminate cross-test contamination

- Expose minimum_check_interval setting (default 50ms, 10ms in tests)
  to reduce Docket Worker task pickup latency
- Isolate fakeredis per test via unique memory:// URLs to prevent
  stale _async_blocking tasks from contaminating subsequent tests
- Make client disconnect timeout configurable (default 5s, 1s in tests)
- Add --durations=50 to CI for passive performance regression detection
- Remove 15s timeout band-aids from task test conftest files
- Add explicit @pytest.mark.timeout(10) to cancellation tests
- Fix deprecated FastMCP.as_proxy() usage in test_task_proxy.py
2026-03-14 16:08:28 -04:00
Jeremiah Lowin
cedf734f15
fix: task test teardown hanging 5s per test (#3499)
Fix context manager ordering in FastMCPTransport so the task group
(server run + subscriptions) is cancelled before the lifespan
(Docket Worker) tears down. Also break subscription loop on terminal
task states.

Closes #3498
2026-03-14 15:33:44 -04:00
Sascha Buehrle
dc7ae0bad1
fix: remove hardcoded version from CLI help text (#3456)
Changed 'FastMCP 2.0' to 'FastMCP' per maintainer feedback.
Dynamic version via fastmcp.__version__ still available via version flag.
2026-03-14 12:07:24 -04:00
Jeremiah Lowin
0b8479ad73
Add verify parameter for SSL certificate configuration (#3487)
* feat: add `verify` parameter for SSL certificate configuration

* Propagate verify to OAuth preflight clients

* Propagate verify to pre-constructed OAuth instances

* Fix verify override not propagating to existing OAuth factory

* Warn when both httpx_client_factory and verify are provided

* Preserve user-provided OAuth factory when transport has verify

* Skip OAuth re-sync when transport has custom httpx_client_factory
2026-03-14 11:48:32 -04:00
Jeremiah Lowin
139d2d8f96
Propagate x-fastmcp-wrap-result in tool result _meta (#3490)
* Propagate x-fastmcp-wrap-result flag in tool result _meta

🤖 Generated with Claude Code

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

* Skip listTools round-trip when _meta has x-fastmcp-wrap-result

🤖 Generated with Claude Code

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

* Use namespaced meta key: {"fastmcp": {"wrap_result": true}}

🤖 Generated with Claude Code

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

* Clean up _parse_call_tool_result: hoist cast import, document local CallToolResult import, extract fastmcp_meta

🤖 Generated with Claude Code

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

* Merge _meta in tasks result handler instead of overwriting

🤖 Generated with Claude Code

* Preserve type validation in meta-based unwrap path

🤖 Generated with Claude Code

* Fix type validation for wrapped task results, guard non-dict meta

🤖 Generated with Claude Code

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-14 11:09:46 -04:00
Jeremiah Lowin
e2bdc9288b
Support logging/setLevel and add client_log_level setting (#3491) 2026-03-14 10:36:01 -04:00
d 🔹
68e76fea2e
fix: forward custom_route endpoints from mounted servers (#3462)
* fix: forward custom_route endpoints from mounted servers

When a child server with custom HTTP routes (registered via
@server.custom_route()) is mounted onto a parent, the routes were
silently dropped because _get_additional_http_routes() only returned
self._additional_http_routes without recursing into mounted providers.

This caused 404s for endpoints like /readyz health checks that worked
in v2 but broke in v3 (regression).

The fix updates _get_additional_http_routes() to traverse providers,
unwrap _WrappedProvider layers (from namespace transforms), find
FastMCPProvider instances, and recursively collect their server's
custom routes.

Fixes #3457

* fix: narrow type annotation from BaseRoute to Route

All items in _additional_http_routes are Route objects (created via
Route(...) in custom_route()). Using list[Route] instead of
list[BaseRoute] fixes the ty type checker failure where .path is
accessed on BaseRoute which doesn't have that attribute.

Removes unused BaseRoute imports from both server.py and transport.py.

* fix: revert route type to list[BaseRoute] to fix ty errors

The previous commit narrowed _additional_http_routes from list[BaseRoute]
to list[Route], which broke:
- component_manager appending Mount objects (Mount is BaseRoute, not Route)
- tests assigning list[BaseRoute] variables (generics are invariant)

Revert to list[BaseRoute] and use isinstance(r, Route) guards in tests
for type-safe .path access.

* fix: remove unused import and fix import grouping

- Remove unused `Route` import from server.py
- Fix import grouping in test_advanced.py (ruff check)

* Address review: move imports to module root, type Provider, add collision note

* fix: sort imports in transport.py

---------

Co-authored-by: voidborne-d <voidborne-d@users.noreply.github.com>
Co-authored-by: d 🔹 <258577966+voidborne-d@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-03-13 20:37:22 -04:00
Jeremiah Lowin
24d7aefe28
fix: shield lifespan teardown from cancellation (#3480)
* 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>
2026-03-13 19:47:42 -04:00