Add a stable server-side MCP Task execution extension point

Open
#1,820 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
csharp

Research direction

Start by tracing WithTasks, IMcpTaskStore, and the existing tasks/get, tasks/update, and tasks/cancel handlers to understand task creation and local execution. Define the executor context and lifecycle around the stated requirements, including authorization, filters, request-scoped disposal, cancellation, and access to normal tool invocation. Done means the default remains process-local and a custom executor can hand work to a durable runtime that survives the original server process.

Written by the indexing model from the issue text.

Description

enhancement P2 ready for work

Is your feature request related to a problem? Please describe.

WithTasks creates a durable task record through IMcpTaskStore, but executes the tool in a process-local Task.Run.

This prevents servers from delegating task execution to durable systems such as Temporal, Orleans, Hangfire, or an external queue. A durable IMcpTaskStore preserves task state, but it cannot control how execution is started.

Replacing the call-tool handler is not a suitable alternative because it relies on experimental alternate-result APIs and replaces parts of the standard MCP tool pipeline.

Describe the solution you'd like

Add a stable extension point that allows WithTasks to delegate execution after the task record has been created.

The extension point should provide:

  • The created task information, including task ID.
  • The matched tool request and request context.
  • Access to the normal tool invocation pipeline when local execution is desired.
  • Clear ownership of request-scoped services and disposal.
  • Defined ordering for authorization and request filters.
  • Cancellation information.

The existing process-local behavior should remain the default.

A custom executor should be able to submit the task to an external durable runtime without invoking the tool body in the MCP server process. Existing tasks/get, tasks/update, and tasks/cancel handling should continue to use IMcpTaskStore.

The exact interface is open for discussion. Conceptually:

public interface IMcpTaskExecutor
{
    ValueTask StartAsync(
        McpTaskExecutionContext context,
        CancellationToken cancellationToken);
}

Describe alternatives you've considered

  • Custom IMcpTaskStore: persists state but cannot replace the process-local execution mechanism.
  • Custom CallToolWithAlternateHandler: uses experimental APIs and replaces the normal tool pipeline.
  • Forking or reimplementing WithTasks: duplicates task negotiation, filtering, DI-scope, cancellation, and result-handling behavior.
  • Keeping execution process-local: unsuitable for tasks that must survive server process replacement.

Additional context

The extension point should preserve existing behavior for applications that do not configure a custom executor.

A useful acceptance scenario would be:

  1. An MCP task is created.
  2. A custom executor submits it to an external durable runtime.
  3. The original MCP server process exits.
  4. Another server instance continues serving tasks/get, tasks/update, and tasks/cancel.
  5. The task reaches a terminal state without depending on the original process.
Dominant language
C#
Stars
4.5k
Forks
814
Avg merge
9d 19h
Merged PRs (30d)
4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from modelcontextprotocol/csharp-sdk

All issues in modelcontextprotocol/csharp-sdk

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.