Skip to content

Conversation

@olaservo
Copy link
Member

@olaservo olaservo commented Jan 9, 2026

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_required flow.

This PR demonstrates both directions of MCP Tasks:

  • Client → Server: Server executes tool calls as background tasks
  • Server → Client: Client executes sampling/elicitation requests as background tasks

Server Details

  • Server: everything
  • Changes to: tools, server capabilities, documentation

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)

  • Task creation via tools/call with task parameter
  • Status polling via tasks/get with statusMessage updates
  • Result retrieval via tasks/result
  • The input_required status flow with elicitation side-channel
  • Task TTL and cleanup

Client-side Tasks (Server calls Client) - Bidirectional

  • Server sends sampling/createMessage with task metadata
  • Client creates task and returns CreateTaskResult
  • Server polls tasks/get for status updates
  • Server retrieves result via tasks/result
  • Same pattern for elicitation/create

How Has This Been Tested?

  • ✓ Tested bidirectional task flow with ad-hoc MCP client library
  • ✓ Server-side tasks (simulate-research-query) tested with MCP Inspector v0.18.0
  • ✓ Client-side tasks (trigger-sampling-request-async, trigger-elicitation-request-async) tested with Inspector task support branch

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Protocol Documentation
  • My changes follows MCP security best practices
  • I have updated the server's README accordingly
  • I have tested this with an LLM client (MCP Inspector)
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have documented all environment variables and configuration options

Additional context

Review Feedback Applied

Per spec review, the following changes were made:

  • Task metadata is placed at params.task (not params._meta.task)
  • pollInterval is only returned in task results, not sent in requests

Known Limitations

HTTP Transport Elicitation: The input_required flow with elicitation currently works on STDIO transport but gracefully degrades on HTTP transports. On HTTP, when elicitation would be needed (e.g., simulate-research-query with ambiguous: true), the tool uses a default interpretation and continues the task rather than blocking.

This is because sendRequest for 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

  1. src/everything/server/index.ts

    • Import InMemoryTaskStore and InMemoryTaskMessageQueue from SDK experimental
    • Create task store and message queue instances
    • Add tasks capability with list, cancel, and requests.tools.call
    • Add cleanup call for task store timers
  2. src/everything/tools/simulate-research-query.ts (new)

    • Demonstrates experimental.tasks.registerToolTask() API
    • Simulates a multi-stage research operation with progress updates
    • Shows input_required flow when ambiguous: true is passed
    • Uses elicitation to gather clarification from user
  3. src/everything/tools/trigger-sampling-request-async.ts (new)

    • Demonstrates bidirectional tasks (server → client)
    • Sends sampling request with task metadata
    • Polls client's tasks/get for status
    • Retrieves LLM result via tasks/result
    • Requires client to support tasks.requests.sampling.createMessage
  4. src/everything/tools/trigger-elicitation-request-async.ts (new)

    • Same pattern as sampling for elicitation requests
    • Useful when user input may take time
    • Requires client to support tasks.requests.elicitation.create
  5. src/everything/tools/index.ts

    • Import and register all new task-related tools
  6. src/everything/docs/features.md

    • Added new tools to Tools section
    • Added "Tasks (SEP-1686)" section documenting both task directions
    • Added bidirectional task flow table and explanation

Bidirectional Task Flow

Direction Request Type Task Executor Demo Tool
Client → Server tools/call Server simulate-research-query
Server → Client sampling/createMessage Client trigger-sampling-request-async
Server → Client elicitation/create Client trigger-elicitation-request-async

Related PRs/Issues

- 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)
@olaservo olaservo requested a review from cliffhall January 9, 2026 13:55
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>
@olaservo olaservo marked this pull request as ready for review January 17, 2026 21:07
@olaservo olaservo added the server-everything Reference implementation for the Everything MCP server - src/everything label Jan 17, 2026
olaservo and others added 5 commits January 17, 2026 17:42
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>
Copy link
Member

@cliffhall cliffhall left a 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>
Copy link
Member

@cliffhall cliffhall left a 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
Copy link
Member

Async elicitation and sampling work with the Inspector PR for tasks

Screenshot 2026-01-21 at 10 06 04 PM Screenshot 2026-01-21 at 10 06 35 PM

@olaservo olaservo requested a review from cliffhall January 22, 2026 14:46
Copy link
Member

@cliffhall cliffhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@cliffhall cliffhall merged commit eedb060 into modelcontextprotocol:main Jan 22, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server-everything Reference implementation for the Everything MCP server - src/everything

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Support for SEP-1686: Tasks to Everything Server

2 participants