agents-wg/meetings/2025-11-11.md
2026-02-24 11:10:41 -08:00

5.7 KiB

2025-11-11 Agents WG

Originally published as https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/1797

Date: November 11, 2025 Attendees: Luca Chang, Che Liu, Shaun Smith, Peter Alexander, Peder Holdgaard Pedersen, Casey Boyle

Discussion

SEP-1686: Tasks - Major Architecture Changes

The Agents Working Group reviewed revisions to SEP-1686 based on Core Maintainer feedback from last week. The proposal has been accepted with changes and will be marked as "experimental" in the upcoming release to signal that further refinements may be introduced in future releases.

Core Changes: Server-Side Task IDs and Request/Response Model

The most fundamental change is moving task ID generation from clients to servers. This shift enables a more robust architecture where task lifetimes are decoupled from individual requests.

In the previous SEP revision, when a client called a tool, it still had to effectively wait for a CallToolResult before proceeding, forcing servers to block the entire request until completion. Now, the server immediately returns a CreateTaskResult with a server-generated task ID, allowing the actual work to continue asynchronously. A TaskCreatedNotification is still sent for convenience, but the result is the canonical source of truth.

Tool implementors no longer need to implement their own polling mechanisms when integrating with external workflow APIs - the server can accept the request, return immediately, and update the task status as work progresses.

However, this means requests are now polymorphic. A task-augmented CallToolRequest returns a CreateTaskResult instead of a CallToolResult. This means SDK maintainers need to expose new methods to handle these different response types, should they wish to expose this to developers. To minimize the new API surface being introduced, task support is initially restricted to just three request types:

  • tools/call
  • elicitation/create
  • sampling/createMessage

Streaming Challenges for sHTTP

The architecture change also creates a challenge for sHTTP: how do you stream messages back to the client when the initial request stream ends immediately? #1699 isn't applicable here, as the point of ambiguity is which stream to send data back on to begin with, as the initial stream would end with the CreateTaskResult being sent. This is an implementation decision for SDK maintainers, but the group discussed two approaches:

Option 1: Each tasks/get call returns pending messages on a short-lived SSE stream. This is more complex to implement but avoids long-running connections.

Option 2: tasks/get returns JSON, while tasks/result opens a long-lived SSE stream for all messages. Simpler architecture but requires maintaining connections for the task duration. To support Option 2, the proposal also modifies the input_required status behavior: when clients encounter this status, they should call tasks/result immediately, allowing a stream to open before work continues.

The group agreed that Option 1 makes sense and aligns with the approach proposed by #1700. Option 2 was not as heavily discussed, as the group had trouble reasoning through its implications.

To reiterate, however: The approach used will be an implementation decision that SDKs may diverge on. As long as the approach used is compliant with existing sHTTP semantics, this will not be a problem, and the Transports WG can come to an evolved specification in the future.

Merging Task Cancellation and Deletion

The latest SEP revision merges cancellation and deletion into a single tasks/cancel method, as their purposes were overlapping. This avoids the need to modify existing cancellation notification semantics.

The group agreed that deletion of the underlying task should be optional and implementation-defined. While tasks/delete was originally proposed to prevent unbounded growth of tasks/list, servers that don't implement TTLs would face this issue regardless (and were allowed to ignore deletion requests anyway).

Keepalives vs. TTLs

On TTL design, the group favored setting TTL at task creation rather than using keepalive on terminal states. This lets clients declare upfront how long they're willing to wait and simplifies server implementation for databases with built-in TTL support.

Implementation Status and SDK Impact

@evalstate shared updates on using the reference implementations with the HF Jobs API MCP server. The current reference implementation changes do not include all of the upcoming changes and are server-side only in the TypeScript SDK, allowing implementors to update their code without protocol breaking changes. The next wave of updates (which will be synchronized across TypeScript and Python SDKs) will complete the migration by moving task ID generation to servers and introducing CreateTaskResult, in addition to improving on the PendingRequest API. The Python SDK still requires client-side task IDs temporarily during this transition.

Feedback on the new server interface was positive overall.

Host Application Integration

The group discussed how host applications inform LLMs when a result has been deferred to a task:

  • MCP servers should have some control over the immediate response, not just hosts
  • Should there be an optional immediate response to the model/user?
    • Not all task-augmented requests are model-visible, like non-tool calls
    • The _meta field could potentially be used for this, but official guidance would be needed
  • Given the proximity to spec freeze, this will require developer guidance and experimentation in the short term

The group acknowledged that host integration pattern guidance is overdue and will be prioritized.

Follow-ups

  • @LucaButBoring: Final revisions to the SEP verbiage