Commit graph

2,666 commits

Author SHA1 Message Date
Jeremiah Lowin
70fac26f9f
Fix prompt return type documentation (#2741) 2025-12-25 22:34:11 -05:00
Jeremiah Lowin
1ed1032ca5
Fix Proxy provider to return all resource contents (#2742) 2025-12-25 22:33:45 -05:00
Jeremiah Lowin
61ebc64730
Introduce Message and PromptResult as canonical prompt types (#2738) 2025-12-25 22:16:26 -05:00
Jeremiah Lowin
7da06025e2
Bump ty to 0.0.7+ (#2737) 2025-12-25 21:22:24 -05:00
Jeremiah Lowin
648684d2bb
Introduce ResourceResult as canonical resource return type (#2734) 2025-12-25 21:21:55 -05:00
Jeremiah Lowin
04cf7bc458
Make ToolResult a BaseModel for serialization support (#2736) 2025-12-25 21:06:37 -05:00
Jeremiah Lowin
4de06d7f73
Fix documentation to use 'meta' instead of '_meta' for MCP spec field (#2735) 2025-12-25 21:05:11 -05:00
Jeremiah Lowin
9f5a177126
Consistent decorator-based MCP handler registration (#2732) 2025-12-25 17:48:54 -05:00
Jeremiah Lowin
9f72096c67
Parallelize list_* calls in Provider.get_tasks() (#2731) 2025-12-25 12:16:44 -05:00
Jeremiah Lowin
9d8a608c37
Add documentation check to required PR workflow (#2730) 2025-12-25 10:52:37 -05:00
Jeremiah Lowin
e7128b0295
Fix Provider.get_tasks() to include custom component subclasses (#2729) 2025-12-25 10:49:48 -05:00
Jeremiah Lowin
b05801d66f
Consolidate execution method chains into single public API (#2728) 2025-12-25 10:38:12 -05:00
Jeremiah Lowin
1d17334803
Reorganize docs around provider architecture (#2723) 2025-12-25 09:00:20 -05:00
Jeremiah Lowin
1abd986c80
Revert "Enable parallel tests on Windows (#2715)" (#2726) 2025-12-25 08:54:05 -05:00
lif
8d80299f82
Fix: resolve root-level $ref in outputSchema for MCP spec compliance (#2720) 2025-12-25 08:42:29 -05:00
Jeremiah Lowin
46aeb6b197
Add changelog entries for v2.13.1 through v2.14.1 (#2725) 2025-12-25 08:23:49 -05:00
Jeremiah Lowin
125f79ff39
Consolidate get_* and _list_* methods into single API (#2719) 2025-12-24 22:26:52 -05:00
Jeremiah Lowin
3e67f9fd23
Parallelize provider operations (#2716) 2025-12-24 20:54:08 -05:00
Jeremiah Lowin
dab72007a9
Enable parallel tests on Windows (#2715) 2025-12-24 16:45:21 -05:00
Jeremiah Lowin
e821446044
Skip test_multi_client on Windows (#2714) 2025-12-24 16:37:35 -05:00
marvin-context-protocol[bot]
9d5ffa86b3
chore: Update SDK documentation (#2604)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
2025-12-24 16:21:31 -05:00
Jeremiah Lowin
ae3c2abbf6
Consolidate notification system with unified API (#2710) 2025-12-24 16:05:08 -05:00
Jeremiah Lowin
66be7c203b
Add v3 breaking changes notice to README (#2712) 2025-12-24 15:57:16 -05:00
Jeremiah Lowin
dccd25af4f
Skip parallel MCP config test on Windows (#2711) 2025-12-24 15:55:50 -05:00
Jeremiah Lowin
7a1796fbdf
Add VisibilityFilter for hierarchical enable/disable (#2708) 2025-12-24 14:43:41 -05:00
A Ashif
f2233baa87
docs(server): add http to transport options in run method docstring (#2707) 2025-12-24 13:51:26 -05:00
Jeremiah Lowin
aef1ccc026
Add type-prefixed keys for globally unique component identification (#2704) 2025-12-24 08:39:43 -05:00
Mathew Goldsborough
5c49f7a919
Fix Prefect website URL in docs footer (#2701)
Co-authored-by: Mathew Goldsborough <1759329+mgoldsborough@users.noreply.github.com>
2025-12-24 08:26:11 -05:00
Jeremiah Lowin
f36b147f60
Unify component storage in LocalProvider (#2680) 2025-12-23 19:24:09 -05:00
Jeremiah Lowin
9147518c01
Fix uvicorn 0.39+ test timeouts and FastMCPError propagation (#2699) 2025-12-23 19:02:47 -05:00
Chris Guidry
fec24a9eea
Merge pull request #2683 from jlowin/2679-task-cancel-fix
Bump pydocket to 0.16.3 for task cancellation support
2025-12-23 18:45:36 -05:00
Chris Guidry
18538e872b Bump pydocket to 0.16.3 to fix worker cleanup race condition
pydocket 0.16.3 fixes a race condition in `_worker_loop` where cancellation
arriving between `_worker_done.clear()` and the try block would cause
`_worker_done.set()` to never run, blocking `Worker.__aexit__` forever.

Also fixes:
- Simplified `_docket_lifespan` cleanup (timeout wrapper no longer needed)
- Fixed `nested_server` test fixture to use graceful uvicorn shutdown
- Fixed uv transport tests to use local fastmcp in dev mode

Closes #2679

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 18:40:07 -05:00
Chris Guidry
7aae52d18d Bump pydocket to 0.16.2 for task cancellation support
Adds a test that verifies task cancellation actually interrupts running
coroutines (they receive CancelledError) rather than just marking the task
as cancelled in Redis while the coroutine continues to completion.

This requires pydocket >= 0.16.2 which added best-effort cancellation via
Redis pub/sub signaling to workers.

Closes #2679

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 14:43:09 -05:00
Jeremiah Lowin
7dcccef82b
Remove execution methods from Provider base class (#2681) 2025-12-23 09:55:14 -05:00
Jeremiah Lowin
4177d8358d
Fix ty 0.0.5 type errors (#2676) 2025-12-22 19:47:20 -05:00
Jeremiah Lowin
bca310cdde
Use ergonomic provider initialization pattern (#2675)
Updates examples and convenience methods to pass providers directly to FastMCP's __init__ instead of calling add_provider() after instantiation.
2025-12-22 14:49:39 -05:00
Rafi Olaverria
820b69aa2e
fix: check the cause of the tool error (#2674) 2025-12-22 11:45:17 -05:00
Jeremiah Lowin
96c7a74b27
Move OpenAPI to providers/openapi submodule (#2672)
* Move OpenAPI to providers/openapi/ submodule

Migrates the OpenAPI implementation to the provider pattern:
- Creates src/fastmcp/server/providers/openapi/ submodule with provider.py,
  components.py, and routing.py
- Converts server/openapi/ to deprecated re-export stubs
- FastMCPOpenAPI remains as deprecated wrapper that uses OpenAPIProvider
- Updates experimental/server/openapi to import from new canonical location

* Update tests and FastMCP methods to use OpenAPIProvider

- Update FastMCP.from_openapi() and from_fastapi() to use OpenAPIProvider
  directly, returning FastMCP instead of deprecated FastMCPOpenAPI
- Move tests from tests/server/openapi/ to tests/server/providers/openapi/
- Update all test imports to use new canonical location
- Add tests/deprecated/openapi/ for backward compatibility testing
- Update tests/client/test_openapi.py to use new imports

* Fix deprecation warning tests and address CodeRabbit feedback

- Use importlib.reload() to ensure deprecation warnings fire in tests
- Change logger.error to logger.exception for better stack traces
2025-12-22 11:13:33 -05:00
Jeremiah Lowin
748d25eede
Refactor FastMCPProxy into ProxyProvider (#2669)
* Refactor FastMCPProxy into ProxyProvider

Move proxy functionality from custom manager classes to the Provider pattern:

- Create ProxyProvider that implements the Provider interface
- Move all proxy code to src/fastmcp/server/providers/proxy.py
- Keep FastMCPProxy as a convenience wrapper using ProxyProvider
- Add deprecation warning when importing from old location
- Convert handler classmethods to module-level functions
- Remove redundant get_* methods (base class defaults work)

* Remove unused Components class, simplify TaskComponents()
2025-12-21 21:30:03 -05:00
Jeremiah Lowin
3afdb3f7b3
Refactor task module: rename protocol.py to requests.py and reduce redundancy (#2667)
Renamed protocol.py to requests.py for clarity - it handles MCP task
request endpoints (tasks/get, tasks/result, tasks/cancel, tasks/list).

Consolidated constants to config.py as single source of truth:
- DEFAULT_POLL_INTERVAL_MS now derived from DEFAULT_POLL_INTERVAL
- TaskConfig uses constant instead of hardcoded timedelta(seconds=5)

Extracted _lookup_task_execution() helper to eliminate ~50 lines of
duplicated Redis lookup code. Uses redis.mget() for single round-trip
instead of 3 separate calls (performance improvement).
2025-12-21 17:21:22 -05:00
Jeremiah Lowin
7ff23a06f4
Add poll_interval to TaskConfig (#2666)
* Add poll_interval to TaskConfig

Allow users to configure polling interval per component via
TaskConfig(poll_interval=timedelta(...)). Default is 5 seconds.

* Update snapshots for poll_interval field

* Add version badge to poll_interval docs

* Add defensive handling for Redis data and align default poll intervals
2025-12-21 16:59:43 -05:00
Jeremiah Lowin
049bd22827
Replace type: ignore[attr-defined] with isinstance assertions in tests (#2665)
* Replace type: ignore[attr-defined] with isinstance assertions in tests

* Fix isinstance assertions in failing tests

- Fix enum test to check for ResponseEnum instead of str
- Fix binary resource test to check for BlobResourceContents instead of TextResourceContents
- Fix Root type tests to check attributes directly instead of isinstance checks

* Fix type errors without using type: ignore

- Remove execution methods from TransformingProvider (only handles transformations)
- Add execution methods to base Provider class with default implementations
- Fix type narrowing in tests using cast() instead of type: ignore
- Fix PromptResult type handling in prompt render tests
- Fix type narrowing in middleware test for arguments and structured_content
2025-12-21 16:37:20 -05:00
Jeremiah Lowin
d6654a2379
Add supports_tasks() method to replace string mode checks (#2664)
* Add supports_tasks() method to replace string mode checks

Consolidates task config mode checks into a readable method on TaskConfig.
Instead of `task_config.mode == "forbidden"` or `task_config.mode != "forbidden"`,
code now uses `task_config.supports_tasks()` for clearer intent.

Updated 20 instances across the codebase and added type assertions in tests
to resolve type checker warnings.

* Update test to match new error message
2025-12-21 15:41:46 -05:00
Jeremiah Lowin
19fdac7b02
Refactor provider execution: components own their execution (#2663)
* Add test_custom_subclass_tasks.py

* Refactor provider execution: delegate to middleware via wrapper components

- Remove execution methods (call_tool, read_resource, etc.) from Provider base
- Add FastMCPProvider* wrapper classes that delegate to child server middleware
- Move task routing to Tool._run() using contextvars (_task_metadata, _tool_call_key)
- Add convert_to_tool_result(result, output_schema) utility for Docket results
- Add convert_to_prompt_result() utility for prompt task results
- Pass namespaced key via add_to_docket(name=) for mounted tool lookup

* Standardize add_to_docket() with fn_key/task_key parameters

All components now use explicit fn_key (function lookup) and task_key
(result storage) parameters instead of relying on implicit key handling.
This fixes mounted component task execution where the MCP-visible key
differs from the Docket-registered function name.

* Add middleware chain tests for three-level mount hierarchy

Tests verify middleware runs at parent, child, and grandchild levels
for tools, resources, prompts, and resource templates.

* WIP: Provider refactor - unified submit_to_docket, template _read() in progress

Work in progress on refactoring execution to use component _read()/_run()/_render() methods.
Template background tasks not yet working - needs fix for Docket key lookup.

* Fix conversion functions to take full component for attribute access

Pass Tool/Prompt/Resource/Template to conversion functions instead of
individual attributes, ensuring access to serializer, output_schema,
mime_type, etc. Also fixes mixed-content output schema validation.

* Refactor: unified convert_result() methods and check_background_task helper

- Add convert_result() instance methods to all component types (Tool, Prompt, Resource, ResourceTemplate)
- Extract duplicated task routing logic into check_background_task() helper
- Fix type annotations on FastMCPProviderResource.read() and FastMCPProviderPrompt.render()
- Update protocol.py to use component.convert_result() uniformly

* Update tests to use namespace= instead of deprecated prefix= parameter
2025-12-21 15:03:24 -05:00
Jeremiah Lowin
fc8ba728a8
Use CreateTaskResult for background task creation (#2660)
* Use CreateTaskResult for background task creation

Move result conversion logic to components (convert_result methods) and
return proper CreateTaskResult SDK type from task handlers. Consolidates
MCP protocol handler overrides into server.py with documentation.

* Address CodeRabbit nitpicks

- Add type annotation for resource parameter in handle_resource_as_task
- Move RootModel import to module level in client.py

* Document intentionally unused task_meta parameters

Prefix with underscore to suppress lint warnings. Client TTL will be
configurable via TaskConfig in the future; keeping parameter for API stability.
2025-12-20 20:19:11 -05:00
Jeremiah Lowin
9f486e5e0c
Add register_with_docket() and add_to_docket() to all components (#2657)
Refactors docket/background task support to be encapsulated within each
component rather than requiring external coordination:

- Move task_config to FastMCPComponent base class (default: forbidden)
- Add register_with_docket(docket) method that components use to register
  themselves, checking task_config internally
- Add add_to_docket() method that handles component-specific calling
  conventions (splatted kwargs vs positional dict)
- Simplify server registration to just call component.register_with_docket()
- Update task handlers to use component.add_to_docket()

This enables custom Tool/Resource/Prompt subclasses to support background
tasks by setting task_config and optionally overriding the docket methods.
2025-12-20 07:47:25 -05:00
ivan
790ea92eb5
Undocumented McpError exceptions (#2656)
Minor documentation fix addressing missing MCPError raise event. Given there are no documentation guidelines I proceeded to modify docstrings of methods that both
- MAY raise `McpError`
- have a docstring that contains a `Raises` section
2025-12-19 21:41:16 -05:00
Jeremiah Lowin
3a6b1ba894
Refactor MountedProvider into FastMCPProvider + TransformingProvider (#2653)
* Refactor MountedProvider into FastMCPProvider + TransformingProvider

Split the monolithic MountedProvider into two focused components:
- FastMCPProvider: wraps a FastMCP server as a provider
- TransformingProvider: applies namespace/rename transformations to any provider

Add with_transforms() method to Provider base class for fluent API.
Rename mount() prefix parameter to namespace (deprecate prefix).

* Reuse compiled URI_PATTERN in deprecated import_server
2025-12-19 11:42:59 -05:00
Jeremiah Lowin
caeaa86394
Simplify .key as computed property (#2648)
* Simplify .key as computed property

Keep .key as the standard lookup interface for all components but
implement it as a computed property instead of a stored field.

- Remove _key private attribute and custom model_copy(key=...)
- .key returns .name for tools/prompts, str(.uri) for resources,
  .uri_template for templates
- Use .key universally for component lookups in managers
- MountedProvider: prefix URIs only for resources/templates, not names
- Docket registration: tools/prompts use .key, resources use .name
  (matches fn.__name__ for function lookup)

* Simplify .key as computed property

Keep .key as the standard lookup interface for all components but
implement it as a computed property instead of a stored field.

- Remove _key private attribute and custom model_copy(key=...)
- .key returns .name for tools/prompts, str(.uri) for resources,
  .uri_template for templates
- Use .key universally for component lookups and Docket registration
- MountedProvider: prefix URIs only for resources/templates, not names
- Add _backend_* fields to proxy classes to preserve original identifiers
  for backend calls when prefixed via import_server

* Standardize .key as computed property

- .key is now a read-only computed property:
  - Tools/Prompts: returns .name
  - Resources: returns str(.uri)
  - Templates: returns .uri_template
- Prefixing uses model_copy(update={...}) to change underlying field
- Resource/template names are NOT prefixed, only URIs
- Move import_server tests to tests/deprecated/
2025-12-18 14:48:47 -05:00
Chris Guidry
8d758baeda
Merge pull request #2645 from jlowin/2642-task-custom-name
Fix task execution for tools with custom names
2025-12-18 11:45:07 -05:00