fix: align task response types with MCP spec (#658)

This commit is contained in:
Dale Seo 2026-02-13 17:56:44 -05:00 • committed by GitHub
commit 08a5b0551b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 349 additions and 134 deletions

View file

@ -407,6 +407,70 @@
"content"
]
},
"CancelTaskResult": {
"description": "Response to a `tasks/cancel` request.\n\nPer spec, `CancelTaskResult = allOf[Result, Task]` — same shape as `GetTaskResult`.",
"type": "object",
"properties": {
"_meta": {
"type": [
"object",
"null"
],
"additionalProperties": true
},
"createdAt": {
"description": "ISO-8601 creation timestamp.",
"type": "string"
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
},
"status": {
"description": "Current lifecycle status (see [`TaskStatus`]).",
"allOf": [
{
"$ref": "#/definitions/TaskStatus"
}
]
},
"statusMessage": {
"description": "Optional human-readable status message for UI surfaces.",
"type": [
"string",
"null"
]
},
"taskId": {
"description": "Unique task identifier generated by the receiver.",
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
}
},
"required": [
"taskId",
"status",
"createdAt",
"lastUpdatedAt"
]
},
"CancelledNotificationMethod": {
"type": "string",
"format": "const",
@ -937,21 +1001,72 @@
"messages"
]
},
"GetTaskInfoResult": {
"GetTaskPayloadResult": {
"description": "Response to a `tasks/result` request.\n\nPer spec, the result structure matches the original request type\n(e.g., `CallToolResult` for `tools/call`). This is represented as\nan open object. The payload is the original request's result\nserialized as a JSON value."
},
"GetTaskResult": {
"description": "Response to a `tasks/get` request.\n\nPer spec, `GetTaskResult = allOf[Result, Task]` — the Task fields are\nflattened at the top level, not nested under a `task` key.",
"type": "object",
"properties": {
"task": {
"anyOf": [
"_meta": {
"type": [
"object",
"null"
],
"additionalProperties": true
},
"createdAt": {
"description": "ISO-8601 creation timestamp.",
"type": "string"
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
},
"status": {
"description": "Current lifecycle status (see [`TaskStatus`]).",
"allOf": [
{
"$ref": "#/definitions/Task"
},
{
"type": "null"
"$ref": "#/definitions/TaskStatus"
}
]
},
"statusMessage": {
"description": "Optional human-readable status message for UI surfaces.",
"type": [
"string",
"null"
]
},
"taskId": {
"description": "Unique task identifier generated by the receiver.",
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
}
},
"additionalProperties": false
"required": [
"taskId",
"status",
"createdAt",
"lastUpdatedAt"
]
},
"Icon": {
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
@ -2701,13 +2816,16 @@
"$ref": "#/definitions/ListTasksResult"
},
{
"$ref": "#/definitions/GetTaskInfoResult"
"$ref": "#/definitions/GetTaskResult"
},
{
"$ref": "#/definitions/TaskResult"
"$ref": "#/definitions/CancelTaskResult"
},
{
"$ref": "#/definitions/CustomResult"
},
{
"$ref": "#/definitions/GetTaskPayloadResult"
}
]
},
@ -2813,7 +2931,7 @@
"const": "string"
},
"Task": {
"description": "Primary Task object that surfaces metadata during the task lifecycle.",
"description": "Primary Task object that surfaces metadata during the task lifecycle.\n\nPer spec, `lastUpdatedAt` and `ttl` are required fields.\n`ttl` is nullable (`null` means unlimited retention).",
"type": "object",
"properties": {
"createdAt": {
@ -2822,10 +2940,7 @@
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": [
"string",
"null"
]
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
@ -2856,7 +2971,7 @@
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.",
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
@ -2868,7 +2983,8 @@
"required": [
"taskId",
"status",
"createdAt"
"createdAt",
"lastUpdatedAt"
]
},
"TaskRequestsCapability": {
@ -2907,30 +3023,6 @@
}
}
},
"TaskResult": {
"description": "Final result for a succeeded task (returned from `tasks/result`).",
"type": "object",
"properties": {
"contentType": {
"description": "MIME type or custom content-type identifier.",
"type": "string"
},
"summary": {
"description": "Optional short summary for UI surfaces.",
"type": [
"string",
"null"
]
},
"value": {
"description": "The actual result payload, matching the underlying request's schema."
}
},
"required": [
"contentType",
"value"
]
},
"TaskStatus": {
"description": "Canonical task lifecycle status as defined by SEP-1686.",
"oneOf": [

View file

@ -407,6 +407,70 @@
"content"
]
},
"CancelTaskResult": {
"description": "Response to a `tasks/cancel` request.\n\nPer spec, `CancelTaskResult = allOf[Result, Task]` — same shape as `GetTaskResult`.",
"type": "object",
"properties": {
"_meta": {
"type": [
"object",
"null"
],
"additionalProperties": true
},
"createdAt": {
"description": "ISO-8601 creation timestamp.",
"type": "string"
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
},
"status": {
"description": "Current lifecycle status (see [`TaskStatus`]).",
"allOf": [
{
"$ref": "#/definitions/TaskStatus"
}
]
},
"statusMessage": {
"description": "Optional human-readable status message for UI surfaces.",
"type": [
"string",
"null"
]
},
"taskId": {
"description": "Unique task identifier generated by the receiver.",
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
}
},
"required": [
"taskId",
"status",
"createdAt",
"lastUpdatedAt"
]
},
"CancelledNotificationMethod": {
"type": "string",
"format": "const",
@ -937,21 +1001,72 @@
"messages"
]
},
"GetTaskInfoResult": {
"GetTaskPayloadResult": {
"description": "Response to a `tasks/result` request.\n\nPer spec, the result structure matches the original request type\n(e.g., `CallToolResult` for `tools/call`). This is represented as\nan open object. The payload is the original request's result\nserialized as a JSON value."
},
"GetTaskResult": {
"description": "Response to a `tasks/get` request.\n\nPer spec, `GetTaskResult = allOf[Result, Task]` — the Task fields are\nflattened at the top level, not nested under a `task` key.",
"type": "object",
"properties": {
"task": {
"anyOf": [
"_meta": {
"type": [
"object",
"null"
],
"additionalProperties": true
},
"createdAt": {
"description": "ISO-8601 creation timestamp.",
"type": "string"
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
},
"status": {
"description": "Current lifecycle status (see [`TaskStatus`]).",
"allOf": [
{
"$ref": "#/definitions/Task"
},
{
"type": "null"
"$ref": "#/definitions/TaskStatus"
}
]
},
"statusMessage": {
"description": "Optional human-readable status message for UI surfaces.",
"type": [
"string",
"null"
]
},
"taskId": {
"description": "Unique task identifier generated by the receiver.",
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 0
}
},
"additionalProperties": false
"required": [
"taskId",
"status",
"createdAt",
"lastUpdatedAt"
]
},
"Icon": {
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
@ -2701,13 +2816,16 @@
"$ref": "#/definitions/ListTasksResult"
},
{
"$ref": "#/definitions/GetTaskInfoResult"
"$ref": "#/definitions/GetTaskResult"
},
{
"$ref": "#/definitions/TaskResult"
"$ref": "#/definitions/CancelTaskResult"
},
{
"$ref": "#/definitions/CustomResult"
},
{
"$ref": "#/definitions/GetTaskPayloadResult"
}
]
},
@ -2813,7 +2931,7 @@
"const": "string"
},
"Task": {
"description": "Primary Task object that surfaces metadata during the task lifecycle.",
"description": "Primary Task object that surfaces metadata during the task lifecycle.\n\nPer spec, `lastUpdatedAt` and `ttl` are required fields.\n`ttl` is nullable (`null` means unlimited retention).",
"type": "object",
"properties": {
"createdAt": {
@ -2822,10 +2940,7 @@
},
"lastUpdatedAt": {
"description": "ISO-8601 timestamp for the most recent status change.",
"type": [
"string",
"null"
]
"type": "string"
},
"pollInterval": {
"description": "Suggested polling interval (milliseconds).",
@ -2856,7 +2971,7 @@
"type": "string"
},
"ttl": {
"description": "Retention window in milliseconds that the receiver agreed to honor.",
"description": "Retention window in milliseconds that the receiver agreed to honor.\n`None` (serialized as `null`) means unlimited retention.",
"type": [
"integer",
"null"
@ -2868,7 +2983,8 @@
"required": [
"taskId",
"status",
"createdAt"
"createdAt",
"lastUpdatedAt"
]
},
"TaskRequestsCapability": {
@ -2907,30 +3023,6 @@
}
}
},
"TaskResult": {
"description": "Final result for a succeeded task (returned from `tasks/result`).",
"type": "object",
"properties": {
"contentType": {
"description": "MIME type or custom content-type identifier.",
"type": "string"
},
"summary": {
"description": "Optional short summary for UI surfaces.",
"type": [
"string",
"null"
]
},
"value": {
"description": "The actual result payload, matching the underlying request's schema."
}
},
"required": [
"contentType",
"value"
]
},
"TaskStatus": {
"description": "Canonical task lifecycle status as defined by SEP-1686.",
"oneOf": [