-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Migrate to SDK task protocol types #2469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Switched to local SDK path to test against maxisbey/SEP-1686_Tasks branch. Updated taskHint from bool to Literal['never', 'optional', 'always'] to match SDK's new type definition. This fixes 19 task tests. Remaining issue: 94 task tests still fail with "Method not found" - the SDK's task protocol methods (tasks/get, tasks/result, etc.) need to be registered with the session. That's next. Test results: 76/170 task tests passing (44.7%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Successfully migrated from FastMCP's custom task protocol registration to use the SDK's built-in types and request handling. All 165 task tests now passing. Changes: - Use SDK types directly: GetTaskResult, CancelTaskResult, ListTasksResult from mcp.types - Register task handlers with SDK's request_handlers (tasks/get, tasks/result, tasks/list, tasks/cancel) - Remove setup_task_protocol_handlers() - no longer needed - Remove tasks/delete entirely (not in SEP-1686 spec, only tasks/cancel exists) - Remove DeleteTaskRequest, Task.delete(), Client.delete_task() - Remove 4 delete-related tests Test results: 165/165 task tests passing (100%), up from 76/170 (44.7%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
The SDK's monkeypatched CallToolRequestParams now includes the spec-compliant 'task' field, which appears in serialized payloads. Updated inline snapshots to reflect this change: - payload JSON now includes "task":null - payload_length: 98 → 110 bytes (+12 characters) - payload_tokens: 24 → 27 (+3 tokens) All logging middleware tests now pass.
The SDK expects `TaskMetadata` instances but FastMCP was passing raw dicts like `{"ttl": 60000}`, causing 179 Pydantic serialization warnings across the test suite.
Fixed by:
- Importing TaskMetadata from mcp.types in shims
- Updating extended param classes to use `TaskMetadata | None` instead of `dict[str, Any] | None`
- Converting task metadata dicts to TaskMetadata instances in client code before passing to request params
All 3269 tests passing, zero warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Removed defensive _meta duplication from client requests. Task metadata now sent only via spec-compliant params.task field. Server now accesses task metadata through SDK's request_context.experimental.task_metadata instead of trying to extract from req.params directly. This is the canonical SDK pattern per the simple-task example. Changes: - Client: removed _meta=meta from call_tool, get_prompt, read_resource requests - Server: updated _call_tool_mcp to use request_context.experimental.is_task - Server: custom handlers for read_resource and get_prompt to support CreateTaskResult returns - Task routing moved to custom handlers since SDK decorators for read_resource/get_prompt don't support CreateTaskResult yet All 3269 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
The SDK now includes all task protocol types we were shimming, so we can replace our temporary definitions with SDK imports. This reduces code duplication and ensures we stay aligned with SDK changes. Changes: - Import task protocol types from mcp.types: GetTaskRequest, GetTaskPayloadRequest, ListTasksRequest, CancelTaskRequest, TaskStatusNotification - Hoist task imports to top of client.py (removed inline imports) - Remove redundant monkeypatch code that extended RequestParams classes - SDK's RequestParams base class already includes the task field - Remove 60 lines of now-redundant type definitions What stays: - TasksResponse wrapper (FastMCP-specific result parser) - Union patching to register task methods with SDK - task_capable_initialize and ClientMessageHandler (client capability helpers) All 3269 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
The SDK now provides all task protocol types, so we can remove our temporary definitions. Consolidated remaining SDK workarounds into the client shim. Deleted: - Server shim file entirely (was nearly empty after removing protocol types) - Protocol type definitions (GetTaskRequest, ListTasksRequest, etc.) - SDK has these - Union monkeypatching (SDK unions already include task types) - TaskCapableClientSession class (unused) - Legacy type names (TasksGetRequest, TasksResultRequest, etc.) Moved: - TasksResponse from server shim to client shim (FastMCP result parser) - Renamed ClientMessageHandler to TaskNotificationHandler (clearer naming) Fixed: - TaskStatusResponse.created_at now accepts datetime (SDK passes datetime objects in-process) What remains in client shim: - task_capable_initialize() - SDK doesn't support capability injection yet - TasksResponse - FastMCP's result parser for polymorphic task results - CallToolResult - FastMCP's enhanced wrapper with .data field - TaskStatusResponse - FastMCP's snake_case ergonomic wrapper - TaskNotificationHandler - Notification routing to Task objects All 3269 tests passing. Examples/tasks client validated (both background and immediate modes work). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
CallToolResult is not SEP-1686 specific - it's existing FastMCP functionality for typed tool results that was on main. It got moved to the shims file during cleanup but belongs in its permanent home. Moved: - CallToolResult from _temporary_sep_1686_shims.py to client.py (after ClientSessionState, matching main branch structure) - Updated tasks.py to import via TYPE_CHECKING to avoid circular imports - Added __future__ annotations to tasks.py for forward reference support All 3269 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Changed from local file:// reference to GitHub git reference pointing at the SEP-1686 task implementation branch. This allows CI and other developers to build without needing a local SDK checkout. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
client
Related to the FastMCP client SDK or client-side functionality.
enhancement
Improvement to existing functionality. For issues and smaller PR improvements.
server
Related to FastMCP server implementation or server-side functionality.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We've migrated FastMCP off temporary shim types and onto the MCP SDK's native task protocol implementation. The SDK's SEP-1686 branch now provides all the types we were defining ourselves, so we can use them directly.
Key changes:
GetTaskRequest,ListTasksRequest,CancelTaskRequest,TaskStatusNotification) directly frommcp.typesinstead of our temporary definitionsRequestParamsbase class already includes thetaskfield, so our extensions were unnecessary (~60 lines removed)TasksResponseresult parser to client shim, deleted entire server shim file, kept only FastMCP-specific helpersdatetimeobjects in task responses, remove_metaduplication in favor of spec-compliantparams.taskfieldWhat's gone:
What remains (~150 lines):
task_capable_initialize()- SDK doesn't support capability injection yetTasksResponse- FastMCP's result parser for polymorphic responsesCallToolResult- FastMCP's existing typed result wrapper (moved back from shims)TaskStatusResponse- Snake_case ergonomic wrapperTaskNotificationHandler- Notification routing to Task objectsAll 3269 tests passing. Examples validated.
Related: modelcontextprotocol/python-sdk#1645
🤖 Generated with Claude Code