modelcontextprotocol / modelcontextprotocol/csharp-sdk
Add a stable server-side MCP Task execution extension point
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 4.5k
- Forks
- 814
- Avg merge
- 9d 19h
- Merged PRs (30d)
- 4
Description
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:
- An MCP task is created.
- A custom executor submits it to an external durable runtime.
- The original MCP server process exits.
- Another server instance continues serving
tasks/get,tasks/update, andtasks/cancel. - The task reaches a terminal state without depending on the original process.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
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.
Assessment
- Tech stack
- csharp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100