* 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
When multiple servers with task-enabled tools are mounted into a parent,
their functions were all registered with Docket using `fn.__name__`. This
meant two mounted servers each having a function named `add` would both
register under `"add"`, with the second overwriting the first.
Now mounted functions use prefixed names matching their client-facing tool
names (e.g., `c1_add`, `c2_add`). Root server functions still use their
original names with no prefix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplifies the task support story for proxies and mounts:
- Mounts get full SEP-1686 task support (unchanged)
- Proxies explicitly forbid task execution
The cross-session task forwarding for proxies turned out to be complex
since each client connection creates a new server lifespan with a new
Docket context, and task keys include session_id. Rather than introduce
that complexity, proxies now explicitly refuse task-augmented execution.
Key changes:
- All proxy components (ProxyTool, ProxyPrompt, ProxyResource,
ProxyTemplate) now have task_config.mode="forbidden"
- Proxy tests verify forbidden behavior (sync execution works,
task=True returns error/raises McpError)
- Fixed prompt task handler to check hasattr(prompt, "task_config")
instead of isinstance(prompt, FunctionPrompt) so it applies to
ProxyPrompt too
- Added test suites for both proxy and mount task behavior
Also includes minor fixes:
- Fixed result.meta_ -> result.meta in ProxyTool.run()
- Fixed client handling of returned_immediately without taskId
- Bumped pydocket>=0.15.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>