SEP-1686: Tasks (#1645)
This commit is contained in:
parent
5983a650cc
commit
c92bb2f7ff
1 changed files with 14230 additions and 120 deletions
451
src/mcp/types.py
451
src/mcp/types.py
|
|
@ -1,5 +1,6 @@
|
|||
from collections.abc import Callable
|
||||
from typing import Annotated, Any, Generic, Literal, TypeAlias, TypeVar
|
||||
from datetime import datetime
|
||||
from typing import Annotated, Any, Final, Generic, Literal, TypeAlias, TypeVar
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, FileUrl, RootModel
|
||||
from pydantic.networks import AnyUrl, UrlConstraints
|
||||
|
|
@ -39,6 +40,23 @@ Role = Literal["user", "assistant"]
|
|||
RequestId = Annotated[int, Field(strict=True)] | str
|
||||
AnyFunction: TypeAlias = Callable[..., Any]
|
||||
|
||||
TaskExecutionMode = Literal["forbidden", "optional", "required"]
|
||||
TASK_FORBIDDEN: Final[Literal["forbidden"]] = "forbidden"
|
||||
TASK_OPTIONAL: Final[Literal["optional"]] = "optional"
|
||||
TASK_REQUIRED: Final[Literal["required"]] = "required"
|
||||
|
||||
|
||||
class TaskMetadata(BaseModel):
|
||||
"""
|
||||
Metadata for augmenting a request with task execution.
|
||||
Include this in the `task` field of the request parameters.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
ttl: Annotated[int, Field(strict=True)] | None = None
|
||||
"""Requested duration in milliseconds to retain task from creation."""
|
||||
|
||||
|
||||
class RequestParams(BaseModel):
|
||||
class Meta(BaseModel):
|
||||
|
|
@ -52,6 +70,16 @@ class RequestParams(BaseModel):
|
|||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
task: TaskMetadata | None = None
|
||||
"""
|
||||
If specified, the caller is requesting task-augmented execution for this request.
|
||||
The request will return a CreateTaskResult immediately, and the actual result can be
|
||||
retrieved later via tasks/result.
|
||||
|
||||
Task augmentation is subject to capability negotiation - receivers MUST declare support
|
||||
for task augmentation of specific request types in their capabilities.
|
||||
"""
|
||||
|
||||
meta: Meta | None = Field(alias="_meta", default=None)
|
||||
|
||||
|
||||
|
|
@ -321,6 +349,71 @@ class SamplingCapability(BaseModel):
|
|||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksListCapability(BaseModel):
|
||||
"""Capability for tasks listing operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksCancelCapability(BaseModel):
|
||||
"""Capability for tasks cancel operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksCreateMessageCapability(BaseModel):
|
||||
"""Capability for tasks create messages."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksSamplingCapability(BaseModel):
|
||||
"""Capability for tasks sampling operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
createMessage: TasksCreateMessageCapability | None = None
|
||||
|
||||
|
||||
class TasksCreateElicitationCapability(BaseModel):
|
||||
"""Capability for tasks create elicitation operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksElicitationCapability(BaseModel):
|
||||
"""Capability for tasks elicitation operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
create: TasksCreateElicitationCapability | None = None
|
||||
|
||||
|
||||
class ClientTasksRequestsCapability(BaseModel):
|
||||
"""Capability for tasks requests operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
sampling: TasksSamplingCapability | None = None
|
||||
|
||||
elicitation: TasksElicitationCapability | None = None
|
||||
|
||||
|
||||
class ClientTasksCapability(BaseModel):
|
||||
"""Capability for client tasks operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
list: TasksListCapability | None = None
|
||||
"""Whether this client supports tasks/list."""
|
||||
|
||||
cancel: TasksCancelCapability | None = None
|
||||
"""Whether this client supports tasks/cancel."""
|
||||
|
||||
requests: ClientTasksRequestsCapability | None = None
|
||||
"""Specifies which request types can be augmented with tasks."""
|
||||
|
||||
|
||||
class ClientCapabilities(BaseModel):
|
||||
"""Capabilities a client may support."""
|
||||
|
||||
|
|
@ -335,6 +428,9 @@ class ClientCapabilities(BaseModel):
|
|||
"""Present if the client supports elicitation from the user."""
|
||||
roots: RootsCapability | None = None
|
||||
"""Present if the client supports listing roots."""
|
||||
tasks: ClientTasksCapability | None = None
|
||||
"""Present if the client supports task-augmented requests."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
|
|
@ -376,6 +472,37 @@ class CompletionsCapability(BaseModel):
|
|||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksCallCapability(BaseModel):
|
||||
"""Capability for tasks call operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class TasksToolsCapability(BaseModel):
|
||||
"""Capability for tasks tools operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
call: TasksCallCapability | None = None
|
||||
|
||||
|
||||
class ServerTasksRequestsCapability(BaseModel):
|
||||
"""Capability for tasks requests operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
tools: TasksToolsCapability | None = None
|
||||
|
||||
|
||||
class ServerTasksCapability(BaseModel):
|
||||
"""Capability for server tasks operations."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
list: TasksListCapability | None = None
|
||||
cancel: TasksCancelCapability | None = None
|
||||
requests: ServerTasksRequestsCapability | None = None
|
||||
|
||||
|
||||
class ServerCapabilities(BaseModel):
|
||||
"""Capabilities that a server may support."""
|
||||
|
||||
|
|
@ -391,9 +518,156 @@ class ServerCapabilities(BaseModel):
|
|||
"""Present if the server offers any tools to call."""
|
||||
completions: CompletionsCapability | None = None
|
||||
"""Present if the server offers autocompletion suggestions for prompts and resources."""
|
||||
tasks: ServerTasksCapability | None = None
|
||||
"""Present if the server supports task-augmented requests."""
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
TaskStatus = Literal["working", "input_required", "completed", "failed", "cancelled"]
|
||||
|
||||
# Task status constants
|
||||
TASK_STATUS_WORKING: Final[Literal["working"]] = "working"
|
||||
TASK_STATUS_INPUT_REQUIRED: Final[Literal["input_required"]] = "input_required"
|
||||
TASK_STATUS_COMPLETED: Final[Literal["completed"]] = "completed"
|
||||
TASK_STATUS_FAILED: Final[Literal["failed"]] = "failed"
|
||||
TASK_STATUS_CANCELLED: Final[Literal["cancelled"]] = "cancelled"
|
||||
|
||||
|
||||
class RelatedTaskMetadata(BaseModel):
|
||||
"""
|
||||
Metadata for associating messages with a task.
|
||||
|
||||
Include this in the `_meta` field under the key `io.modelcontextprotocol/related-task`.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
taskId: str
|
||||
"""The task identifier this message is associated with."""
|
||||
|
||||
|
||||
class Task(BaseModel):
|
||||
"""Data associated with a task."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
taskId: str
|
||||
"""The task identifier."""
|
||||
|
||||
status: TaskStatus
|
||||
"""Current task state."""
|
||||
|
||||
statusMessage: str | None = None
|
||||
"""
|
||||
Optional human-readable message describing the current task state.
|
||||
This can provide context for any status, including:
|
||||
- Reasons for "cancelled" status
|
||||
- Summaries for "completed" status
|
||||
- Diagnostic information for "failed" status (e.g., error details, what went wrong)
|
||||
"""
|
||||
|
||||
createdAt: datetime # Pydantic will enforce ISO 8601 and re-serialize as a string later
|
||||
"""ISO 8601 timestamp when the task was created."""
|
||||
|
||||
lastUpdatedAt: datetime
|
||||
"""ISO 8601 timestamp when the task was last updated."""
|
||||
|
||||
ttl: Annotated[int, Field(strict=True)] | None
|
||||
"""Actual retention duration from creation in milliseconds, null for unlimited."""
|
||||
|
||||
pollInterval: Annotated[int, Field(strict=True)] | None = None
|
||||
"""Suggested polling interval in milliseconds."""
|
||||
|
||||
|
||||
class CreateTaskResult(Result):
|
||||
"""A response to a task-augmented request."""
|
||||
|
||||
task: Task
|
||||
|
||||
|
||||
class GetTaskRequestParams(RequestParams):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
taskId: str
|
||||
"""The task identifier to query."""
|
||||
|
||||
|
||||
class GetTaskRequest(Request[GetTaskRequestParams, Literal["tasks/get"]]):
|
||||
"""A request to retrieve the state of a task."""
|
||||
|
||||
method: Literal["tasks/get"] = "tasks/get"
|
||||
|
||||
params: GetTaskRequestParams
|
||||
|
||||
|
||||
class GetTaskResult(Result, Task):
|
||||
"""The response to a tasks/get request."""
|
||||
|
||||
|
||||
class GetTaskPayloadRequestParams(RequestParams):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
taskId: str
|
||||
"""The task identifier to retrieve results for."""
|
||||
|
||||
|
||||
class GetTaskPayloadRequest(Request[GetTaskPayloadRequestParams, Literal["tasks/result"]]):
|
||||
"""A request to retrieve the result of a completed task."""
|
||||
|
||||
method: Literal["tasks/result"] = "tasks/result"
|
||||
params: GetTaskPayloadRequestParams
|
||||
|
||||
|
||||
class GetTaskPayloadResult(Result):
|
||||
"""
|
||||
The response to a tasks/result request.
|
||||
The structure matches the result type of the original request.
|
||||
For example, a tools/call task would return the CallToolResult structure.
|
||||
"""
|
||||
|
||||
|
||||
class CancelTaskRequestParams(RequestParams):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
taskId: str
|
||||
"""The task identifier to cancel."""
|
||||
|
||||
|
||||
class CancelTaskRequest(Request[CancelTaskRequestParams, Literal["tasks/cancel"]]):
|
||||
"""A request to cancel a task."""
|
||||
|
||||
method: Literal["tasks/cancel"] = "tasks/cancel"
|
||||
params: CancelTaskRequestParams
|
||||
|
||||
|
||||
class CancelTaskResult(Result, Task):
|
||||
"""The response to a tasks/cancel request."""
|
||||
|
||||
|
||||
class ListTasksRequest(PaginatedRequest[Literal["tasks/list"]]):
|
||||
"""A request to retrieve a list of tasks."""
|
||||
|
||||
method: Literal["tasks/list"] = "tasks/list"
|
||||
|
||||
|
||||
class ListTasksResult(PaginatedResult):
|
||||
"""The response to a tasks/list request."""
|
||||
|
||||
tasks: list[Task]
|
||||
|
||||
|
||||
class TaskStatusNotificationParams(NotificationParams, Task):
|
||||
"""Parameters for a `notifications/tasks/status` notification."""
|
||||
|
||||
|
||||
class TaskStatusNotification(Notification[TaskStatusNotificationParams, Literal["notifications/tasks/status"]]):
|
||||
"""
|
||||
An optional notification from the receiver to the requestor, informing them that a task's status has changed.
|
||||
Receivers are not required to send these notifications
|
||||
"""
|
||||
|
||||
method: Literal["notifications/tasks/status"] = "notifications/tasks/status"
|
||||
params: TaskStatusNotificationParams
|
||||
|
||||
|
||||
class InitializeRequestParams(RequestParams):
|
||||
"""Parameters for the initialize request."""
|
||||
|
||||
|
|
@ -1011,9 +1285,29 @@ class ToolAnnotations(BaseModel):
|
|||
of a memory tool is not.
|
||||
Default: true
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class ToolExecution(BaseModel):
|
||||
"""Execution-related properties for a tool."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
taskSupport: TaskExecutionMode | None = None
|
||||
"""
|
||||
Indicates whether this tool supports task-augmented execution.
|
||||
This allows clients to handle long-running operations through polling
|
||||
the task system.
|
||||
|
||||
- "forbidden": Tool does not support task-augmented execution (default when absent)
|
||||
- "optional": Tool may support task-augmented execution
|
||||
- "required": Tool requires task-augmented execution
|
||||
|
||||
Default: "forbidden"
|
||||
"""
|
||||
|
||||
|
||||
class Tool(BaseMetadata):
|
||||
"""Definition for a tool the client can call."""
|
||||
|
||||
|
|
@ -1035,6 +1329,9 @@ class Tool(BaseMetadata):
|
|||
See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields)
|
||||
for notes on _meta usage.
|
||||
"""
|
||||
|
||||
execution: ToolExecution | None = None
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
|
|
@ -1419,10 +1716,17 @@ class RootsListChangedNotification(
|
|||
class CancelledNotificationParams(NotificationParams):
|
||||
"""Parameters for cancellation notifications."""
|
||||
|
||||
requestId: RequestId
|
||||
"""The ID of the request to cancel."""
|
||||
requestId: RequestId | None = None
|
||||
"""
|
||||
The ID of the request to cancel.
|
||||
|
||||
This MUST correspond to the ID of a request previously issued in the same direction.
|
||||
This MUST be provided for cancelling non-task requests.
|
||||
This MUST NOT be used for cancelling tasks (use the `tasks/cancel` request instead).
|
||||
"""
|
||||
reason: str | None = None
|
||||
"""An optional string describing the reason for the cancellation."""
|
||||
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
|
|
@ -1462,29 +1766,41 @@ class ElicitCompleteNotification(
|
|||
params: ElicitCompleteNotificationParams
|
||||
|
||||
|
||||
class ClientRequest(
|
||||
RootModel[
|
||||
PingRequest
|
||||
| InitializeRequest
|
||||
| CompleteRequest
|
||||
| SetLevelRequest
|
||||
| GetPromptRequest
|
||||
| ListPromptsRequest
|
||||
| ListResourcesRequest
|
||||
| ListResourceTemplatesRequest
|
||||
| ReadResourceRequest
|
||||
| SubscribeRequest
|
||||
| UnsubscribeRequest
|
||||
| CallToolRequest
|
||||
| ListToolsRequest
|
||||
]
|
||||
):
|
||||
ClientRequestType: TypeAlias = (
|
||||
PingRequest
|
||||
| InitializeRequest
|
||||
| CompleteRequest
|
||||
| SetLevelRequest
|
||||
| GetPromptRequest
|
||||
| ListPromptsRequest
|
||||
| ListResourcesRequest
|
||||
| ListResourceTemplatesRequest
|
||||
| ReadResourceRequest
|
||||
| SubscribeRequest
|
||||
| UnsubscribeRequest
|
||||
| CallToolRequest
|
||||
| ListToolsRequest
|
||||
| GetTaskRequest
|
||||
| GetTaskPayloadRequest
|
||||
| ListTasksRequest
|
||||
| CancelTaskRequest
|
||||
)
|
||||
|
||||
|
||||
class ClientRequest(RootModel[ClientRequestType]):
|
||||
pass
|
||||
|
||||
|
||||
class ClientNotification(
|
||||
RootModel[CancelledNotification | ProgressNotification | InitializedNotification | RootsListChangedNotification]
|
||||
):
|
||||
ClientNotificationType: TypeAlias = (
|
||||
CancelledNotification
|
||||
| ProgressNotification
|
||||
| InitializedNotification
|
||||
| RootsListChangedNotification
|
||||
| TaskStatusNotification
|
||||
)
|
||||
|
||||
|
||||
class ClientNotification(RootModel[ClientNotificationType]):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -1585,41 +1901,74 @@ class ElicitationRequiredErrorData(BaseModel):
|
|||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
|
||||
class ClientResult(RootModel[EmptyResult | CreateMessageResult | ListRootsResult | ElicitResult]):
|
||||
ClientResultType: TypeAlias = (
|
||||
EmptyResult
|
||||
| CreateMessageResult
|
||||
| ListRootsResult
|
||||
| ElicitResult
|
||||
| GetTaskResult
|
||||
| GetTaskPayloadResult
|
||||
| ListTasksResult
|
||||
| CancelTaskResult
|
||||
| CreateTaskResult
|
||||
)
|
||||
|
||||
|
||||
class ClientResult(RootModel[ClientResultType]):
|
||||
pass
|
||||
|
||||
|
||||
class ServerRequest(RootModel[PingRequest | CreateMessageRequest | ListRootsRequest | ElicitRequest]):
|
||||
ServerRequestType: TypeAlias = (
|
||||
PingRequest
|
||||
| CreateMessageRequest
|
||||
| ListRootsRequest
|
||||
| ElicitRequest
|
||||
| GetTaskRequest
|
||||
| GetTaskPayloadRequest
|
||||
| ListTasksRequest
|
||||
| CancelTaskRequest
|
||||
)
|
||||
|
||||
|
||||
class ServerRequest(RootModel[ServerRequestType]):
|
||||
pass
|
||||
|
||||
|
||||
class ServerNotification(
|
||||
RootModel[
|
||||
CancelledNotification
|
||||
| ProgressNotification
|
||||
| LoggingMessageNotification
|
||||
| ResourceUpdatedNotification
|
||||
| ResourceListChangedNotification
|
||||
| ToolListChangedNotification
|
||||
| PromptListChangedNotification
|
||||
| ElicitCompleteNotification
|
||||
]
|
||||
):
|
||||
ServerNotificationType: TypeAlias = (
|
||||
CancelledNotification
|
||||
| ProgressNotification
|
||||
| LoggingMessageNotification
|
||||
| ResourceUpdatedNotification
|
||||
| ResourceListChangedNotification
|
||||
| ToolListChangedNotification
|
||||
| PromptListChangedNotification
|
||||
| ElicitCompleteNotification
|
||||
| TaskStatusNotification
|
||||
)
|
||||
|
||||
|
||||
class ServerNotification(RootModel[ServerNotificationType]):
|
||||
pass
|
||||
|
||||
|
||||
class ServerResult(
|
||||
RootModel[
|
||||
EmptyResult
|
||||
| InitializeResult
|
||||
| CompleteResult
|
||||
| GetPromptResult
|
||||
| ListPromptsResult
|
||||
| ListResourcesResult
|
||||
| ListResourceTemplatesResult
|
||||
| ReadResourceResult
|
||||
| CallToolResult
|
||||
| ListToolsResult
|
||||
]
|
||||
):
|
||||
ServerResultType: TypeAlias = (
|
||||
EmptyResult
|
||||
| InitializeResult
|
||||
| CompleteResult
|
||||
| GetPromptResult
|
||||
| ListPromptsResult
|
||||
| ListResourcesResult
|
||||
| ListResourceTemplatesResult
|
||||
| ReadResourceResult
|
||||
| CallToolResult
|
||||
| ListToolsResult
|
||||
| GetTaskResult
|
||||
| GetTaskPayloadResult
|
||||
| ListTasksResult
|
||||
| CancelTaskResult
|
||||
| CreateTaskResult
|
||||
)
|
||||
|
||||
|
||||
class ServerResult(RootModel[ServerResultType]):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Reference in a new issue