-
Notifications
You must be signed in to change notification settings - Fork 9.3k
feat(everything): add SEP-1686 Tasks support #3193
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
feat(everything): add SEP-1686 Tasks support #3193
Conversation
- Add tasks capability with list, cancel, and requests.tools.call - Add InMemoryTaskStore and InMemoryTaskMessageQueue from SDK experimental - Add simulate-research-query tool demonstrating task lifecycle - Task demonstrates working -> input_required -> completed status flow - Uses elicitation for ambiguous queries when client supports it Closes modelcontextprotocol#3037 🦉 Generated with [Claude Code](https://claude.ai/code)
Add tools that demonstrate bidirectional MCP tasks where the server sends requests to the client for async execution: - trigger-sampling-request-async: Send sampling request with task params, client creates task and executes LLM call in background, server polls for completion and retrieves result - trigger-elicitation-request-async: Same pattern for user input, useful when user may take time to fill out forms Both tools: - Check client capabilities (tasks.requests.sampling/elicitation) - Accept both CreateTaskResult and direct result responses - Poll tasks/get for status updates - Fetch final result via tasks/result Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of waiting for the client to call tasks/result to trigger elicitation, the server now sends elicitation/create directly from the background process using sendRequest. This simplifies the flow: - Server sends elicitation proactively when clarification is needed - Client receives and handles it via existing elicitation handler - Task resumes and completes after receiving the response - Client's polling sees completed status This approach avoids requiring the client to detect input_required status and call tasks/result as a side-channel. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update documentation to reflect that simulate-research-query now sends elicitation requests directly from the background task instead of using the tasks/result side-channel approach. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement graceful degradation for elicitation on HTTP transport: - STDIO: Full elicitation works via sendRequest - HTTP: Catches elicitation failure, uses default interpretation - Task completes successfully on both transports simulate-research-query now uses try-catch around sendRequest and includes explanatory message when elicitation is skipped on HTTP. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cliffhall
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The location of the task property in the elicitation and sampling request is misplaced. left suggestions.
Co-authored-by: Cliff Hall <cliff@futurescale.com>
cliffhall
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I didn't catch this before.
…m requests - Use params.task instead of params._meta.task for task metadata - Remove pollInterval from task requests (only available on result) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cliffhall
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 👍


Description
Add support for SEP-1686 Tasks to the Everything Server. This enables the server to demonstrate MCP's task-based execution pattern for long-running operations, including task lifecycle management, status polling, and the
input_requiredflow.This PR demonstrates both directions of MCP Tasks:
Server Details
Motivation and Context
This addresses issue #3037 - adding Tasks support to the Everything Server as part of the SEP-1686 implementation.
The Everything Server serves as a reference implementation demonstrating MCP capabilities. With Tasks now part of the MCP specification (2025-11-25 schema), the Everything Server should demonstrate this feature to help client developers understand and test their Tasks implementations.
Server-side Tasks (Client calls Server)
tools/callwith task parametertasks/getwithstatusMessageupdatestasks/resultinput_requiredstatus flow with elicitation side-channelClient-side Tasks (Server calls Client) - Bidirectional
sampling/createMessagewith task metadataCreateTaskResulttasks/getfor status updatestasks/resultelicitation/createHow Has This Been Tested?
simulate-research-query) tested with MCP Inspector v0.18.0trigger-sampling-request-async,trigger-elicitation-request-async) tested with Inspector task support branchBreaking Changes
None.
Types of changes
Checklist
Additional context
Review Feedback Applied
Per spec review, the following changes were made:
params.task(notparams._meta.task)pollIntervalis only returned in task results, not sent in requestsKnown Limitations
HTTP Transport Elicitation: The
input_requiredflow with elicitation currently works on STDIO transport but gracefully degrades on HTTP transports. On HTTP, when elicitation would be needed (e.g.,simulate-research-querywithambiguous: true), the tool uses a default interpretation and continues the task rather than blocking.This is because
sendRequestfor elicitation over HTTP requires SDK streaming support that isn't yet available in the released SDK. The tool detects this and falls back gracefully.Follow-up: #3228 tracks enabling full HTTP elicitation support once the SDK adds the necessary streaming API.
Files Changed
src/everything/server/index.tsInMemoryTaskStoreandInMemoryTaskMessageQueuefrom SDK experimentaltaskscapability withlist,cancel, andrequests.tools.callsrc/everything/tools/simulate-research-query.ts(new)experimental.tasks.registerToolTask()APIinput_requiredflow whenambiguous: trueis passedsrc/everything/tools/trigger-sampling-request-async.ts(new)tasks/getfor statustasks/resulttasks.requests.sampling.createMessagesrc/everything/tools/trigger-elicitation-request-async.ts(new)tasks.requests.elicitation.createsrc/everything/tools/index.tssrc/everything/docs/features.mdBidirectional Task Flow
tools/callsimulate-research-querysampling/createMessagetrigger-sampling-request-asyncelicitation/createtrigger-elicitation-request-asyncRelated PRs/Issues