Implement SEP-2663 Tasks Extension (#1579)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Pranav Senthilnathan 2026-06-11 13:10:45 -07:00 • committed by GitHub
commit dbb7a20176
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 8190 additions and 11405 deletions

View file

@ -26,24 +26,4 @@ public sealed class CallToolRequestParams : RequestParams
/// </remarks>
[JsonPropertyName("arguments")]
public IDictionary<string, JsonElement>? Arguments { get; set; }
/// <summary>
/// Gets or sets optional task metadata to augment this request with task execution.
/// </summary>
/// <remarks>
/// When present, indicates that the requestor wants this operation executed as a task.
/// The receiver must support task augmentation for this specific request type.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
[JsonIgnore]
public McpTaskMetadata? Task
{
get => TaskCore;
set => TaskCore = value;
}
// See ExperimentalInternalPropertyTests.cs before modifying this property.
[JsonInclude]
[JsonPropertyName("task")]
internal McpTaskMetadata? TaskCore { get; set; }
}

View file

@ -64,25 +64,4 @@ public sealed class CallToolResult : Result
/// </remarks>
[JsonPropertyName("isError")]
public bool? IsError { get; set; }
/// <summary>
/// Gets or sets the task data for the newly created task.
/// </summary>
/// <remarks>
/// This property is populated only for task-augmented tool calls. When present, the other properties
/// (<see cref="Content"/>, <see cref="StructuredContent"/>, <see cref="IsError"/>) may not be populated.
/// The actual tool result can be retrieved later via <c>tasks/result</c>.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
[JsonIgnore]
public McpTask? Task
{
get => TaskCore;
set => TaskCore = value;
}
// See ExperimentalInternalPropertyTests.cs before modifying this property.
[JsonInclude]
[JsonPropertyName("task")]
internal McpTask? TaskCore { get; set; }
}

View file

@ -1,84 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a tasks/cancel request to explicitly cancel a task.
/// </summary>
/// <remarks>
/// <para>
/// Receivers must reject cancellation requests for tasks already in a terminal status
/// (<see cref="McpTaskStatus.Completed"/>, <see cref="McpTaskStatus.Failed"/>, or
/// <see cref="McpTaskStatus.Cancelled"/>) with error code -32602 (Invalid params).
/// </para>
/// <para>
/// Upon receiving a valid cancellation request, receivers should attempt to stop the task
/// execution and must transition the task to <see cref="McpTaskStatus.Cancelled"/> status
/// before sending the response.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CancelMcpTaskRequestParams : RequestParams
{
/// <summary>
/// Gets or sets the unique identifier of the task to cancel.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
}
/// <summary>
/// Represents the result of a tasks/cancel request.
/// </summary>
/// <remarks>
/// The result contains the updated task state after cancellation. The task will be in
/// <see cref="McpTaskStatus.Cancelled"/> status if the cancellation was successful.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CancelMcpTaskResult : Result
{
/// <summary>
/// Gets or sets the task ID.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current status of the task (should be <see cref="McpTaskStatus.Cancelled"/>).
/// </summary>
[JsonPropertyName("status")]
public required McpTaskStatus Status { get; set; }
/// <summary>
/// Gets or sets an optional message describing the cancellation.
/// </summary>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task status was last updated.
/// </summary>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time to live (retention duration) from creation before the task may be deleted.
/// </summary>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? TimeToLive { get; set; }
/// <summary>
/// Gets or sets the suggested time between status checks.
/// </summary>
[JsonPropertyName("pollInterval")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? PollInterval { get; set; }
}

View file

@ -0,0 +1,29 @@
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a <c>tasks/cancel</c> request to signal intent to cancel an in-progress task.
/// </summary>
/// <remarks>
/// <para>
/// Cancellation is cooperative: the request signals intent, and the server decides whether and when to honor it.
/// A server is not obligated to actually stop the work; it is only obligated to acknowledge the request.
/// Eventual transition to <see cref="McpTaskStatus.Cancelled"/> is not guaranteed.
/// </para>
/// <para>
/// The <c>notifications/cancelled</c> notification must not be used for task cancellation.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
public sealed class CancelTaskRequestParams : RequestParams
{
/// <summary>
/// Gets or sets the identifier of the task to cancel.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
}

View file

@ -0,0 +1,22 @@
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the result of a <c>tasks/cancel</c> request. This is an empty acknowledgement.
/// </summary>
/// <remarks>
/// <para>
/// The server acknowledges the request with an empty result. Cancellation processing is
/// eventually consistent — the task's observable status may remain <see cref="McpTaskStatus.Working"/>
/// after the ack, and may ultimately reach a terminal status other than <see cref="McpTaskStatus.Cancelled"/>
/// if the work finished before cancellation could take effect.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
public sealed class CancelTaskResult : Result
{
}

View file

@ -68,32 +68,6 @@ public sealed class ClientCapabilities
[JsonPropertyName("elicitation")]
public ElicitationCapability? Elicitation { get; set; }
/// <summary>
/// Gets or sets the client's tasks capability for supporting task-augmented requests.
/// </summary>
/// <remarks>
/// <para>
/// The tasks capability enables servers to augment their requests with tasks for long-running
/// operations. When present, servers can request that certain operations (like sampling or
/// elicitation) execute asynchronously, with the ability to poll for status and retrieve results later.
/// </para>
/// <para>
/// See <see cref="McpTasksCapability"/> for details on configuring which operations support tasks.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
[JsonIgnore]
public McpTasksCapability? Tasks
{
get => TasksCore;
set => TasksCore = value;
}
// See ExperimentalInternalPropertyTests.cs before modifying this property.
[JsonInclude]
[JsonPropertyName("tasks")]
internal McpTasksCapability? TasksCore { get; set; }
/// <summary>
/// Gets or sets optional MCP extensions that the client supports.
/// </summary>

View file

@ -153,24 +153,4 @@ public sealed class CreateMessageRequestParams : RequestParams
/// </remarks>
[JsonPropertyName("toolChoice")]
public ToolChoice? ToolChoice { get; set; }
/// <summary>
/// Gets or sets optional task metadata to augment this request with task execution.
/// </summary>
/// <remarks>
/// When present, indicates that the requestor wants this operation executed as a task.
/// The receiver must support task augmentation for this specific request type.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
[JsonIgnore]
public McpTaskMetadata? Task
{
get => TaskCore;
set => TaskCore = value;
}
// See ExperimentalInternalPropertyTests.cs before modifying this property.
[JsonInclude]
[JsonPropertyName("task")]
internal McpTaskMetadata? TaskCore { get; set; }
}

View file

@ -1,28 +1,68 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the response to a task-augmented request.
/// Represents the result returned by a server when it creates a task in lieu of a standard result.
/// </summary>
/// <remarks>
/// <para>
/// When a client sends a request with a <c>task</c> parameter, the server immediately returns
/// a <see cref="CreateTaskResult"/> containing the created task information instead of the
/// normal result type. The actual result can be retrieved later via <c>tasks/result</c>.
/// A server returns <see cref="CreateTaskResult"/> instead of the standard result shape (e.g., <see cref="CallToolResult"/>)
/// to indicate that the request will be processed asynchronously. The client then uses
/// <see cref="TaskId"/> for subsequent <c>tasks/get</c>, <c>tasks/update</c>, and <c>tasks/cancel</c> calls.
/// </para>
/// <para>
/// This type is returned for any task-augmented request including <c>tools/call</c>,
/// <c>sampling/createMessage</c>, and <c>elicitation/create</c>.
/// A server must not return <see cref="CreateTaskResult"/> to a client that did not include the
/// <c>io.modelcontextprotocol/tasks</c> extension capability on its request.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CreateTaskResult : Result
{
/// <summary>
/// Gets or sets the task data for the newly created task.
/// Gets or sets the stable identifier for this task.
/// </summary>
[JsonPropertyName("task")]
public McpTask Task { get; set; } = null!;
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current task status.
/// </summary>
[JsonPropertyName("status")]
public required McpTaskStatus Status { get; set; }
/// <summary>
/// Gets or sets an optional message describing the current task state.
/// </summary>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was last updated.
/// </summary>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time-to-live duration from creation in milliseconds, or <see langword="null"/> for unlimited.
/// </summary>
[JsonPropertyName("ttlMs")]
public long? TtlMs { get; set; }
/// <summary>
/// Gets or sets the suggested polling interval in milliseconds.
/// </summary>
[JsonPropertyName("pollIntervalMs")]
public long? PollIntervalMs { get; set; }
}

View file

@ -92,26 +92,6 @@ public sealed class ElicitRequestParams : RequestParams
[JsonPropertyName("requestedSchema")]
public RequestSchema? RequestedSchema { get; set; }
/// <summary>
/// Gets or sets optional task metadata to augment this request with task execution.
/// </summary>
/// <remarks>
/// When present, indicates that the requestor wants this operation executed as a task.
/// The receiver must support task augmentation for this specific request type.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
[JsonIgnore]
public McpTaskMetadata? Task
{
get => TaskCore;
set => TaskCore = value;
}
// See ExperimentalInternalPropertyTests.cs before modifying this property.
[JsonInclude]
[JsonPropertyName("task")]
internal McpTaskMetadata? TaskCore { get; set; }
/// <summary>Represents a request schema used in a form mode elicitation request.</summary>
public sealed class RequestSchema
{

View file

@ -1,27 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a tasks/result request to retrieve the result of a completed task.
/// </summary>
/// <remarks>
/// <para>
/// This request blocks until the task reaches a terminal status (<see cref="McpTaskStatus.Completed"/>,
/// <see cref="McpTaskStatus.Failed"/>, or <see cref="McpTaskStatus.Cancelled"/>).
/// </para>
/// <para>
/// The result structure matches the original request type (e.g., <see cref="CallToolResult"/> for tools/call).
/// This is distinct from the initial <see cref="Result"/> response, which contains only task data.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class GetTaskPayloadRequestParams : RequestParams
{
/// <summary>
/// Gets or sets the unique identifier of the task whose result to retrieve.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
}

View file

@ -1,77 +1,26 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a tasks/get request to retrieve task status.
/// Represents the parameters for a <c>tasks/get</c> request to poll for task completion.
/// </summary>
/// <remarks>
/// Requestors poll for task completion by sending tasks/get requests. They should
/// respect the <see cref="McpTask.PollInterval"/> provided in responses when determining
/// polling frequency.
/// <para>
/// Clients poll for task completion by sending <c>tasks/get</c> requests.
/// Clients should respect the <see cref="GetTaskResult.PollIntervalMs"/> provided in responses
/// when determining polling frequency.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class GetTaskRequestParams : RequestParams
{
/// <summary>
/// Gets or sets the unique identifier of the task to retrieve.
/// Gets or sets the identifier of the task to query.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
}
/// <summary>
/// Represents the result of a tasks/get request.
/// </summary>
/// <remarks>
/// The result contains the current state of the task, including its status, timestamps,
/// and any status message.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class GetTaskResult : Result
{
/// <summary>
/// Gets or sets the task ID.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current status of the task.
/// </summary>
[JsonPropertyName("status")]
public required McpTaskStatus Status { get; set; }
/// <summary>
/// Gets or sets an optional human-readable message describing the current state.
/// </summary>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task status was last updated.
/// </summary>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time to live (retention duration) from creation before the task may be deleted.
/// </summary>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? TimeToLive { get; set; }
/// <summary>
/// Gets or sets the suggested time between status checks.
/// </summary>
[JsonPropertyName("pollInterval")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? PollInterval { get; set; }
}

View file

@ -0,0 +1,450 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the result of a <c>tasks/get</c> request, containing the full task state.
/// </summary>
/// <remarks>
/// <para>
/// This is the abstract base for status-specific task results. The concrete type returned depends on the
/// task's current <see cref="Status"/>:
/// <list type="bullet">
/// <item><see cref="WorkingTaskResult"/> — <see cref="McpTaskStatus.Working"/></item>
/// <item><see cref="CompletedTaskResult"/> — <see cref="McpTaskStatus.Completed"/></item>
/// <item><see cref="FailedTaskResult"/> — <see cref="McpTaskStatus.Failed"/></item>
/// <item><see cref="CancelledTaskResult"/> — <see cref="McpTaskStatus.Cancelled"/></item>
/// <item><see cref="InputRequiredTaskResult"/> — <see cref="McpTaskStatus.InputRequired"/></item>
/// </list>
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
[JsonConverter(typeof(Converter))]
public abstract class GetTaskResult : Result
{
/// <summary>Prevent external derivations.</summary>
private protected GetTaskResult()
{
}
/// <summary>
/// Gets or sets the stable identifier for this task.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current task status.
/// </summary>
[JsonPropertyName("status")]
public abstract McpTaskStatus Status { get; }
/// <summary>
/// Gets or sets an optional message describing the current task state.
/// </summary>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was last updated.
/// </summary>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time-to-live duration from creation in milliseconds, or <see langword="null"/> for unlimited.
/// </summary>
[JsonPropertyName("ttlMs")]
public long? TtlMs { get; set; }
/// <summary>
/// Gets or sets the suggested polling interval in milliseconds.
/// </summary>
[JsonPropertyName("pollIntervalMs")]
public long? PollIntervalMs { get; set; }
/// <summary>
/// JSON converter that deserializes <see cref="GetTaskResult"/> to the appropriate concrete subtype
/// based on the <c>status</c> discriminator field.
/// </summary>
internal sealed class Converter : JsonConverter<GetTaskResult>
{
public override GetTaskResult? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Expected StartObject token for GetTaskResult.");
}
string? taskId = null;
string? statusString = null;
string? statusMessage = null;
DateTimeOffset? createdAt = null;
DateTimeOffset? lastUpdatedAt = null;
long? ttlMs = null;
long? pollIntervalMs = null;
string? resultType = null;
JsonObject? meta = null;
JsonElement? result = null;
JsonElement? error = null;
Dictionary<string, InputRequest>? inputRequests = null;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected property name.");
}
string propertyName = reader.GetString()!;
reader.Read();
switch (propertyName)
{
case "taskId":
taskId = reader.GetString();
break;
case "status":
statusString = reader.GetString();
break;
case "statusMessage":
statusMessage = reader.GetString();
break;
case "createdAt":
createdAt = reader.GetDateTimeOffset();
break;
case "lastUpdatedAt":
lastUpdatedAt = reader.GetDateTimeOffset();
break;
case "ttlMs":
ttlMs = reader.GetInt64();
break;
case "pollIntervalMs":
pollIntervalMs = reader.GetInt64();
break;
case "resultType":
resultType = reader.GetString();
break;
case "_meta":
meta = JsonSerializer.Deserialize(ref reader, options.GetTypeInfo<JsonObject>());
break;
case "result":
result = JsonElement.ParseValue(ref reader);
break;
case "error":
error = JsonElement.ParseValue(ref reader);
break;
case "inputRequests":
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("'inputRequests' must be a JSON object.");
}
inputRequests = new Dictionary<string, InputRequest>(StringComparer.Ordinal);
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected property name in 'inputRequests'.");
}
string requestKey = reader.GetString()!;
reader.Read();
var inputRequest = JsonSerializer.Deserialize(ref reader, McpJsonUtilities.JsonContext.Default.InputRequest)
?? throw new JsonException($"Failed to deserialize InputRequest for key '{requestKey}'.");
inputRequests[requestKey] = inputRequest;
}
break;
default:
reader.Skip();
break;
}
}
if (taskId is null)
{
throw new JsonException("Missing required 'taskId' property on GetTaskResult.");
}
if (statusString is null)
{
throw new JsonException("Missing required 'status' property on GetTaskResult.");
}
if (createdAt is null)
{
throw new JsonException("Missing required 'createdAt' property on GetTaskResult.");
}
if (lastUpdatedAt is null)
{
throw new JsonException("Missing required 'lastUpdatedAt' property on GetTaskResult.");
}
GetTaskResult taskResult = statusString switch
{
"working" => new WorkingTaskResult
{
TaskId = taskId,
CreatedAt = createdAt.Value,
LastUpdatedAt = lastUpdatedAt.Value,
},
"completed" => result is not null
? new CompletedTaskResult
{
TaskId = taskId,
CreatedAt = createdAt.Value,
LastUpdatedAt = lastUpdatedAt.Value,
Result = result.Value,
}
: throw new JsonException("Completed task is missing required 'result' property."),
"failed" => error is not null
? new FailedTaskResult
{
TaskId = taskId,
CreatedAt = createdAt.Value,
LastUpdatedAt = lastUpdatedAt.Value,
Error = error.Value,
}
: throw new JsonException("Failed task is missing required 'error' property."),
"cancelled" => new CancelledTaskResult
{
TaskId = taskId,
CreatedAt = createdAt.Value,
LastUpdatedAt = lastUpdatedAt.Value,
},
"input_required" => inputRequests is not null
? new InputRequiredTaskResult
{
TaskId = taskId,
CreatedAt = createdAt.Value,
LastUpdatedAt = lastUpdatedAt.Value,
InputRequests = inputRequests,
}
: throw new JsonException("Input-required task is missing required 'inputRequests' property."),
_ => throw new JsonException($"Unknown task status: '{statusString}'.")
};
taskResult.StatusMessage = statusMessage;
taskResult.TtlMs = ttlMs;
taskResult.PollIntervalMs = pollIntervalMs;
taskResult.ResultType = resultType;
taskResult.Meta = meta;
return taskResult;
}
public override void Write(Utf8JsonWriter writer, GetTaskResult value, JsonSerializerOptions options)
{
writer.WriteStartObject();
if (value.ResultType is not null)
{
writer.WriteString("resultType", value.ResultType);
}
if (value.Meta is not null)
{
writer.WritePropertyName("_meta");
JsonSerializer.Serialize(writer, value.Meta, options.GetTypeInfo<JsonObject>());
}
writer.WriteString("taskId", value.TaskId);
writer.WriteString("status", value.Status switch
{
McpTaskStatus.Working => "working",
McpTaskStatus.Completed => "completed",
McpTaskStatus.Failed => "failed",
McpTaskStatus.Cancelled => "cancelled",
McpTaskStatus.InputRequired => "input_required",
_ => throw new JsonException($"Unknown McpTaskStatus: {value.Status}")
});
if (value.StatusMessage is not null)
{
writer.WriteString("statusMessage", value.StatusMessage);
}
writer.WriteString("createdAt", value.CreatedAt);
writer.WriteString("lastUpdatedAt", value.LastUpdatedAt);
if (value.TtlMs is not null)
{
writer.WriteNumber("ttlMs", value.TtlMs.Value);
}
if (value.PollIntervalMs is not null)
{
writer.WriteNumber("pollIntervalMs", value.PollIntervalMs.Value);
}
switch (value)
{
case CompletedTaskResult completed:
writer.WritePropertyName("result");
completed.Result.WriteTo(writer);
break;
case FailedTaskResult failed:
writer.WritePropertyName("error");
failed.Error.WriteTo(writer);
break;
case InputRequiredTaskResult inputRequired:
writer.WritePropertyName("inputRequests");
writer.WriteStartObject();
if (inputRequired.InputRequests is { } reqs)
{
foreach (var kvp in reqs)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value, McpJsonUtilities.JsonContext.Default.InputRequest);
}
}
writer.WriteEndObject();
break;
}
writer.WriteEndObject();
}
}
}
/// <summary>
/// Represents a task that is currently being processed by the server.
/// </summary>
/// <remarks>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </remarks>
public sealed class WorkingTaskResult : GetTaskResult
{
/// <inheritdoc/>
[JsonPropertyName("status")]
public override McpTaskStatus Status => McpTaskStatus.Working;
}
/// <summary>
/// Represents a task that has completed successfully, carrying the final result.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="Result"/> field contains the result structure matching the original request type.
/// For example, a <c>tools/call</c> task would contain the <see cref="CallToolResult"/> structure.
/// This includes tool calls that returned results with <c>isError: true</c>.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
public sealed class CompletedTaskResult : GetTaskResult
{
/// <inheritdoc/>
[JsonPropertyName("status")]
public override McpTaskStatus Status => McpTaskStatus.Completed;
/// <summary>
/// Gets or sets the final result of the task as raw JSON.
/// </summary>
/// <remarks>
/// The structure matches the result type of the original request.
/// </remarks>
[JsonPropertyName("result")]
public required JsonElement Result { get; set; }
}
/// <summary>
/// Represents a task that failed due to a JSON-RPC error during execution.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="Error"/> field contains the JSON-RPC error object that caused the failure.
/// This status must not be used for non-JSON-RPC errors.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
public sealed class FailedTaskResult : GetTaskResult
{
/// <inheritdoc/>
[JsonPropertyName("status")]
public override McpTaskStatus Status => McpTaskStatus.Failed;
/// <summary>
/// Gets or sets the JSON-RPC error that caused the task to fail.
/// </summary>
[JsonPropertyName("error")]
public required JsonElement Error { get; set; }
}
/// <summary>
/// Represents a task that was cancelled before completion.
/// </summary>
/// <remarks>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </remarks>
public sealed class CancelledTaskResult : GetTaskResult
{
/// <inheritdoc/>
[JsonPropertyName("status")]
public override McpTaskStatus Status => McpTaskStatus.Cancelled;
}
/// <summary>
/// Represents a task that requires input from the client before it can proceed.
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="InputRequests"/> field contains outstanding server-to-client requests
/// that the client must fulfil. Each entry is keyed by an arbitrary identifier for matching
/// requests to responses, and each value is an <see cref="InputRequest"/> wrapping the
/// server-to-client request payload.
/// </para>
/// <para>
/// Clients must treat each entry as they would the equivalent standalone server-to-client request.
/// Clients should deduplicate keys across consecutive polls to avoid presenting the same request
/// to the user or model more than once.
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </para>
/// </remarks>
public sealed class InputRequiredTaskResult : GetTaskResult
{
/// <inheritdoc/>
[JsonPropertyName("status")]
public override McpTaskStatus Status => McpTaskStatus.InputRequired;
/// <summary>
/// Gets or sets the server-to-client requests that need to be fulfilled.
/// </summary>
/// <remarks>
/// Keys are arbitrary identifiers for matching requests to responses.
/// Each value is an <see cref="InputRequest"/> wrapping the server-to-client request
/// (e.g., a sampling, elicitation, or roots-list request).
/// </remarks>
[JsonPropertyName("inputRequests")]
public IDictionary<string, InputRequest>? InputRequests { get; set; }
}

View file

@ -1,34 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a tasks/list request to retrieve a list of tasks.
/// </summary>
/// <remarks>
/// This operation supports cursor-based pagination. Receivers should use cursor-based
/// pagination to limit the number of tasks returned in a single response.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class ListTasksRequestParams : PaginatedRequestParams
{
// Inherits Cursor property from PaginatedRequestParams
}
/// <summary>
/// Represents the result of a tasks/list request.
/// </summary>
/// <remarks>
/// The result contains an array of task objects and an optional cursor for pagination.
/// If <see cref="PaginatedResult.NextCursor"/> is present, more tasks are available.
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class ListTasksResult : PaginatedResult
{
/// <summary>
/// Gets or sets the list of tasks.
/// </summary>
[JsonPropertyName("tasks")]
public required IList<McpTask> Tasks { get; set; }
}

View file

@ -0,0 +1,18 @@
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Provides constants for well-known MCP extension identifiers.
/// </summary>
public static class McpExtensions
{
/// <summary>
/// The extension identifier for the MCP Tasks extension.
/// </summary>
/// <remarks>
/// When included in client per-request capabilities, indicates the client can handle
/// <see cref="CreateTaskResult"/> in lieu of a standard result.
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </remarks>
public const string Tasks = "io.modelcontextprotocol/tasks";
}

View file

@ -1,104 +0,0 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents an MCP task, which is a durable state machine carrying information
/// about the underlying execution state of a request.
/// </summary>
/// <remarks>
/// <para>
/// Tasks are useful for representing expensive computations and batch processing requests.
/// Each task is uniquely identifiable by a receiver-generated task ID.
/// </para>
/// <para>
/// Tasks follow a defined lifecycle through the <see cref="Status"/> property. They begin
/// in the <see cref="McpTaskStatus.Working"/> status and may transition through various states
/// before reaching a terminal status (<see cref="McpTaskStatus.Completed"/>, <see cref="McpTaskStatus.Failed"/>,
/// or <see cref="McpTaskStatus.Cancelled"/>).
/// </para>
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/draft/basic/utilities/tasks.mdx">tasks specification</see> for details.
/// </para>
/// </remarks>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class McpTask
{
/// <summary>
/// Gets or sets the unique identifier for the task.
/// </summary>
/// <remarks>
/// Task IDs are generated by the receiver when creating a task and must be unique
/// among all tasks controlled by that receiver.
/// </remarks>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current state of the task execution.
/// </summary>
[JsonPropertyName("status")]
public required McpTaskStatus Status { get; set; }
/// <summary>
/// Gets or sets an optional human-readable message describing the current state.
/// </summary>
/// <remarks>
/// This message can be present for any status, including error details for failed tasks.
/// </remarks>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
/// <remarks>
/// Receivers must include this timestamp in all task responses to indicate when
/// the task was created.
/// </remarks>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task status was last updated.
/// </summary>
/// <remarks>
/// Receivers must include this timestamp in all task responses to indicate when
/// the task was last updated.
/// </remarks>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time to live (retention duration) from creation before the task may be deleted.
/// </summary>
/// <remarks>
/// <para>
/// A null value indicates unlimited lifetime. After a task's TTL lifetime has elapsed,
/// receivers may delete the task and its results, regardless of the task status.
/// </para>
/// <para>
/// Receivers may override the requested TTL duration and must include the actual TTL
/// duration (or null for unlimited) in task responses.
/// </para>
/// </remarks>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? TimeToLive { get; set; }
/// <summary>
/// Gets or sets the suggested time between status checks.
/// </summary>
/// <remarks>
/// Requestors should respect this value when provided to avoid excessive polling.
/// This value is optional and may not be present in all task responses.
/// </remarks>
[JsonPropertyName("pollInterval")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? PollInterval { get; set; }
private string DebuggerDisplay => $"Task {TaskId}: {Status}" + (StatusMessage != null ? $" - {StatusMessage}" : "");
}

View file

@ -1,41 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents metadata for augmenting a request with task execution.
/// </summary>
/// <remarks>
/// <para>
/// When included in a request's params, this metadata signals that the requestor
/// wants the receiver to execute the request as a task rather than synchronously.
/// The receiver will return a <see cref="Result"/> containing task data
/// instead of the actual operation result.
/// </para>
/// <para>
/// Requestors can specify a desired TTL (time-to-live) duration for the task,
/// though receivers may override this value based on their resource management policies.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class McpTaskMetadata
{
/// <summary>
/// Gets or sets the requested time to live (retention duration) to retain the task from creation.
/// </summary>
/// <remarks>
/// <para>
/// This is a hint to the receiver about how long the requestor expects to need access
/// to the task data. Receivers may override this value based on their resource constraints
/// and policies.
/// </para>
/// <para>
/// A null value indicates no specific retention requirement. The actual TTL used by the
/// receiver will be returned in the <see cref="McpTask.TimeToLive"/> property.
/// </para>
/// </remarks>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? TimeToLive { get; set; }
}

View file

@ -1,4 +1,3 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
@ -7,73 +6,44 @@ namespace ModelContextProtocol.Protocol;
/// Represents the status of an MCP task.
/// </summary>
/// <remarks>
/// <para>
/// Tasks progress through a defined lifecycle:
/// <list type="bullet">
/// <item><description><see cref="Working"/>: The request is currently being processed.</description></item>
/// <item><description><see cref="InputRequired"/>: The receiver needs input from the requestor.
/// The requestor should call tasks/result to receive input requests.</description></item>
/// <item><description><see cref="Completed"/>: The request completed successfully and results are available.</description></item>
/// <item><description><see cref="Failed"/>: The request did not complete successfully.</description></item>
/// <item><description><see cref="Cancelled"/>: The request was cancelled before completion.</description></item>
/// </list>
/// </para>
/// <para>
/// Terminal states are <see cref="Completed"/>, <see cref="Failed"/>, and <see cref="Cancelled"/>.
/// Once a task reaches a terminal state, it cannot transition to any other status.
/// </para>
/// Tasks are durable state machines that carry information about the underlying execution state
/// of the request they augment. See the
/// <see href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md">SEP-2663</see>
/// specification for details.
/// </remarks>
[JsonConverter(typeof(JsonStringEnumConverter<McpTaskStatus>))]
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public enum McpTaskStatus
{
/// <summary>
/// The request is currently being processed.
/// </summary>
/// <remarks>
/// Tasks begin in this status when created. From <see cref="Working"/>, tasks may transition
/// to <see cref="InputRequired"/>, <see cref="Completed"/>, <see cref="Failed"/>, or <see cref="Cancelled"/>.
/// </remarks>
[JsonStringEnumMemberName("working")]
Working,
/// <summary>
/// The receiver needs input from the requestor.
/// The server needs input from the client before the task can proceed.
/// The <c>tasks/get</c> response will include outstanding requests in the <c>inputRequests</c> field.
/// </summary>
/// <remarks>
/// The requestor should call tasks/result to receive input requests, even though the task
/// has not reached a terminal state. From <see cref="InputRequired"/>, tasks may transition
/// to <see cref="Working"/>, <see cref="Completed"/>, <see cref="Failed"/>, or <see cref="Cancelled"/>.
/// </remarks>
[JsonStringEnumMemberName("input_required")]
InputRequired,
/// <summary>
/// The request completed successfully and results are available.
/// This includes tool calls that returned results with <c>isError: true</c>.
/// </summary>
/// <remarks>
/// This is a terminal status. Tasks in this status cannot transition to any other status.
/// </remarks>
[JsonStringEnumMemberName("completed")]
Completed,
/// <summary>
/// The associated request did not complete successfully.
/// </summary>
/// <remarks>
/// This is a terminal status. For tool calls specifically, this includes cases where
/// the tool call result has isError set to true. Tasks in this status cannot transition
/// to any other status.
/// </remarks>
[JsonStringEnumMemberName("failed")]
Failed,
/// <summary>
/// The request was cancelled before completion.
/// </summary>
/// <remarks>
/// This is a terminal status. Tasks in this status cannot transition to any other status.
/// </remarks>
[JsonStringEnumMemberName("cancelled")]
Cancelled
Cancelled,
/// <summary>
/// The request failed due to a JSON-RPC error during execution.
/// This status must not be used for non-JSON-RPC errors.
/// </summary>
[JsonStringEnumMemberName("failed")]
Failed,
}

View file

@ -1,67 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the parameters for a notifications/tasks/status notification.
/// </summary>
/// <remarks>
/// <para>
/// When a task status changes, receivers may send this notification to inform the
/// requestor of the change. This notification includes the full task state.
/// </para>
/// <para>
/// Requestors must not rely on receiving this notification, as it is optional. Receivers
/// are not required to send status notifications and may choose to only send them for
/// certain status transitions. Requestors should continue to poll via tasks/get to ensure
/// they receive status updates.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class McpTaskStatusNotificationParams : NotificationParams
{
/// <summary>
/// Gets or sets the task ID.
/// </summary>
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }
/// <summary>
/// Gets or sets the current status of the task.
/// </summary>
[JsonPropertyName("status")]
public required McpTaskStatus Status { get; set; }
/// <summary>
/// Gets or sets an optional human-readable message describing the current state.
/// </summary>
[JsonPropertyName("statusMessage")]
public string? StatusMessage { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task was created.
/// </summary>
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets or sets the ISO 8601 timestamp when the task status was last updated.
/// </summary>
[JsonPropertyName("lastUpdatedAt")]
public required DateTimeOffset LastUpdatedAt { get; set; }
/// <summary>
/// Gets or sets the time to live (retention duration) from creation before the task may be deleted.
/// </summary>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? TimeToLive { get; set; }
/// <summary>
/// Gets or sets the suggested time between status checks.
/// </summary>
[JsonPropertyName("pollInterval")]
[JsonConverter(typeof(TimeSpanMillisecondsConverter))]
public TimeSpan? PollInterval { get; set; }
}

View file

@ -1,160 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
/// <summary>
/// Represents the tasks capability configuration for servers and clients.
/// </summary>
/// <remarks>
/// <para>
/// The tasks capability enables requestors (clients or servers) to augment their requests with
/// tasks for long-running operations. Tasks are durable state machines that carry information
/// about the underlying execution state of requests.
/// </para>
/// <para>
/// During initialization, both parties exchange their tasks capabilities to establish which
/// operations support task-based execution. Requestors should only augment requests with a
/// task if the corresponding capability has been declared by the receiver.
/// </para>
/// </remarks>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class McpTasksCapability
{
/// <summary>
/// Gets or sets whether this party supports the tasks/list operation.
/// </summary>
/// <remarks>
/// When present, indicates support for listing all tasks.
/// </remarks>
[JsonPropertyName("list")]
public ListMcpTasksCapability? List { get; set; }
/// <summary>
/// Gets or sets whether this party supports the tasks/cancel operation.
/// </summary>
/// <remarks>
/// When present, indicates support for cancelling tasks.
/// </remarks>
[JsonPropertyName("cancel")]
public CancelMcpTasksCapability? Cancel { get; set; }
/// <summary>
/// Gets or sets which request types support task augmentation.
/// </summary>
/// <remarks>
/// <para>
/// The set of capabilities in this property is exhaustive. If a request type is not present,
/// it does not support task augmentation.
/// </para>
/// <para>
/// For servers, this typically includes tools/call. For clients, this typically includes
/// sampling/createMessage and elicitation/create.
/// </para>
/// </remarks>
[JsonPropertyName("requests")]
public RequestMcpTasksCapability? Requests { get; set; }
}
/// <summary>
/// Represents task support for tool-specific requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class RequestMcpTasksCapability
{
/// <summary>
/// Gets or sets task support for tool-related requests.
/// </summary>
[JsonPropertyName("tools")]
public ToolsMcpTasksCapability? Tools { get; set; }
/// <summary>
/// Gets or sets task support for sampling-related requests.
/// </summary>
[JsonPropertyName("sampling")]
public SamplingMcpTasksCapability? Sampling { get; set; }
/// <summary>
/// Gets or sets task support for elicitation-related requests.
/// </summary>
[JsonPropertyName("elicitation")]
public ElicitationMcpTasksCapability? Elicitation { get; set; }
}
/// <summary>
/// Represents task support for tool-related requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class ToolsMcpTasksCapability
{
/// <summary>
/// Gets or sets whether tools/call requests support task augmentation.
/// </summary>
/// <remarks>
/// When present, indicates that the server supports task-augmented tools/call requests.
/// </remarks>
[JsonPropertyName("call")]
public CallToolMcpTasksCapability? Call { get; set; }
}
/// <summary>
/// Represents task support for sampling-related requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class SamplingMcpTasksCapability
{
/// <summary>
/// Gets or sets whether sampling/createMessage requests support task augmentation.
/// </summary>
/// <remarks>
/// When present, indicates that the client supports task-augmented sampling/createMessage requests.
/// </remarks>
[JsonPropertyName("createMessage")]
public CreateMessageMcpTasksCapability? CreateMessage { get; set; }
}
/// <summary>
/// Represents task support for elicitation-related requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class ElicitationMcpTasksCapability
{
/// <summary>
/// Gets or sets whether elicitation/create requests support task augmentation.
/// </summary>
/// <remarks>
/// When present, indicates that the client supports task-augmented elicitation/create requests.
/// </remarks>
[JsonPropertyName("create")]
public CreateElicitationMcpTasksCapability? Create { get; set; }
}
/// <summary>
/// Represents the capability for listing tasks.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class ListMcpTasksCapability;
/// <summary>
/// Represents the capability for cancelling tasks.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CancelMcpTasksCapability;
/// <summary>
/// Represents the capability for task-augmented tools/call requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CallToolMcpTasksCapability;
/// <summary>
/// Represents the capability for task-augmented sampling/createMessage requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CreateMessageMcpTasksCapability;
/// <summary>
/// Represents the capability for task-augmented elicitation/create requests.
/// </summary>
[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)]
public sealed class CreateElicitationMcpTasksCapability;

View file

@ -143,39 +143,12 @@ public static class NotificationMethods
public const string CancelledNotification = "notifications/cancelled";
/// <summary>
/// The name of the notification sent when a task status changes.
/// The name of the notification sent by the server to push task status updates to subscribed clients.
/// </summary>
/// <remarks>
/// <para>
/// When a task status changes, receivers may send this notification to inform the requestor
/// of the change. This notification includes the full task state.
/// </para>
/// <para>
/// Requestors must not rely on receiving this notification, as it is optional. Receivers
/// are not required to send status notifications and may choose to only send them for
/// certain status transitions. Requestors should continue to poll via tasks/get to ensure
/// they receive status updates.
/// </para>
/// Part of the <c>io.modelcontextprotocol/tasks</c> extension.
/// Each notification carries a complete task state for the current status, identical to what
/// <c>tasks/get</c> would have returned at that moment.
/// </remarks>
public const string TaskStatusNotification = "notifications/tasks/status";
/// <summary>
/// The metadata key used to associate requests, responses, and notifications with a task.
/// </summary>
/// <remarks>
/// <para>
/// This constant defines the key <c>"io.modelcontextprotocol/related-task"</c> used in the
/// <c>_meta</c> field to associate messages with their originating task across the entire
/// request lifecycle.
/// </para>
/// <para>
/// For example, an elicitation that a task-augmented tool call depends on must share the
/// same related task ID with that tool call's task.
/// </para>
/// <para>
/// For <c>tasks/get</c>, <c>tasks/list</c>, and <c>tasks/cancel</c> operations, this
/// metadata should not be included as the taskId is already present in the message structure.
/// </para>
/// </remarks>
public const string RelatedTaskMetaKey = "io.modelcontextprotocol/related-task";
public const string TaskStatusNotification = "notifications/tasks";
}

Some files were not shown because too many files have changed in this diff Show more