Class InMemoryMcpTaskStore
- Namespace
- ModelContextProtocol.Server
- Assembly
- ModelContextProtocol.Core.dll
Provides an in-memory implementation of IMcpTaskStore for development and testing scenarios.
public class InMemoryMcpTaskStore : IMcpTaskStore
- Inheritance
-
InMemoryMcpTaskStore
- Implements
- Inherited Members
Remarks
This implementation stores all task state in memory using immutable snapshots and compare-and-swap updates for thread safety without locks. Tasks are not persisted across process restarts.
For production scenarios requiring durability, session isolation, or TTL-based cleanup, implement a custom IMcpTaskStore.
Properties
DefaultPollIntervalMs
Gets or sets the default poll interval in milliseconds for new tasks.
public long DefaultPollIntervalMs { get; set; }
Property Value
- long
The default is 1000 milliseconds.
DefaultTimeToLive
Gets or sets the default time-to-live for new tasks, or null for unlimited.
public TimeSpan? DefaultTimeToLive { get; set; }
Property Value
Methods
CreateTaskAsync(CancellationToken)
Creates a new task for tracking an asynchronous execution.
public Task<McpTaskInfo> CreateTaskAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task<McpTaskInfo>
A McpTaskInfo with a unique task ID, initial status of Working, and timing metadata (TTL, poll interval).
Remarks
Implementations must generate a unique task ID and set appropriate timestamps. The server infrastructure maps the returned McpTaskInfo to the appropriate protocol response type when communicating with clients.
Per the MCP specification (SEP-2663 ยง306), the returned task MUST be durably created before this method completes: a subsequent GetTaskAsync(string, CancellationToken) with the returned TaskId MUST resolve, even if it runs on a different process or node. Implementations backed by eventually-consistent storage must therefore wait for the write to be visible (e.g., quorum acknowledgement, write-through, or an equivalent barrier) before returning.
GetTaskAsync(string, CancellationToken)
Retrieves the current state of a task.
public Task<McpTaskInfo?> GetTaskAsync(string taskId, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task to retrieve.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task<McpTaskInfo>
A McpTaskInfo representing the current task state, or null if the task does not exist.
ResolveInputRequestsAsync(string, IDictionary<string, InputResponse>, CancellationToken)
Removes input requests that have been satisfied by the provided responses and raises InputResponseReceived for each resolved entry.
public Task ResolveInputRequestsAsync(string taskId, IDictionary<string, InputResponse> inputResponses, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task.
inputResponsesIDictionary<string, InputResponse>The input responses keyed by the original request identifier. Matched input requests are removed from the task's pending set.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
Remarks
After removing the satisfied requests, if no pending input requests remain the task transitions back to Working. Otherwise it remains in InputRequired.
Implementations must raise InputResponseReceived for each entry in
inputResponses after updating the store state. In distributed
deployments, this event enables the originating server to be notified even if a
different server instance processes the tasks/update request.
SetCancelledAsync(string, CancellationToken)
Transitions the task to Cancelled.
public Task<bool> SetCancelledAsync(string taskId, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task to cancel.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task<bool>
true if the task was successfully cancelled; false if the task does not exist or was already in a terminal state.
SetCompletedAsync(string, JsonElement, CancellationToken)
Stores the result of a completed execution, transitioning the task to Completed.
public Task SetCompletedAsync(string taskId, JsonElement result, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task.
resultJsonElementThe serialized result payload.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task
A task representing the asynchronous operation.
SetFailedAsync(string, JsonElement, CancellationToken)
Marks a task as failed, transitioning it to Failed.
public Task SetFailedAsync(string taskId, JsonElement error, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task.
errorJsonElementThe serialized error information.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task
A task representing the asynchronous operation.
SetInputRequestsAsync(string, IDictionary<string, InputRequest>, CancellationToken)
Adds input requests to a task, transitioning it to InputRequired.
public Task SetInputRequestsAsync(string taskId, IDictionary<string, InputRequest> inputRequests, CancellationToken cancellationToken = default)
Parameters
taskIdstringThe unique identifier of the task.
inputRequestsIDictionary<string, InputRequest>The input requests to add. Keys are arbitrary identifiers for matching requests to responses. Each value is an InputRequest wrapping the server-to-client request payload. New requests are merged with any existing pending requests.
cancellationTokenCancellationTokenCancellation token for the operation.
Returns
- Task
A task representing the asynchronous operation.
Events
InputResponseReceived
Occurs when an input response is resolved for a task.
public event Action<InputResponseReceivedEventArgs>? InputResponseReceived
Event Type
Remarks
Implementations must raise this event for each input response resolved in ResolveInputRequestsAsync(string, IDictionary<string, InputResponse>, CancellationToken). Subscribers use this to complete pending input request waiters (e.g., elicitation or sampling calls that are awaiting a client response).