File tree Expand file tree Collapse file tree 15 files changed +65
-15
lines changed
simple-task-interactive/mcp_simple_task_interactive
simple-task/mcp_simple_task
shared/experimental/tasks Expand file tree Collapse file tree 15 files changed +65
-15
lines changed Original file line number Diff line number Diff line change @@ -187,6 +187,7 @@ async def handle_get_task(request: types.GetTaskRequest) -> types.GetTaskResult:
187187 status = task .status ,
188188 statusMessage = task .statusMessage ,
189189 createdAt = task .createdAt ,
190+ lastUpdatedAt = task .lastUpdatedAt ,
190191 ttl = task .ttl ,
191192 pollInterval = task .pollInterval ,
192193 )
Original file line number Diff line number Diff line change @@ -90,6 +90,7 @@ async def handle_get_task(request: types.GetTaskRequest) -> types.GetTaskResult:
9090 status = task .status ,
9191 statusMessage = task .statusMessage ,
9292 createdAt = task .createdAt ,
93+ lastUpdatedAt = task .lastUpdatedAt ,
9394 ttl = task .ttl ,
9495 pollInterval = task .pollInterval ,
9596 )
Original file line number Diff line number Diff line change @@ -132,6 +132,7 @@ async def _send_notification(self) -> None:
132132 status = self ._task .status ,
133133 statusMessage = self ._task .statusMessage ,
134134 createdAt = self ._task .createdAt ,
135+ lastUpdatedAt = self ._task .lastUpdatedAt ,
135136 ttl = self ._task .ttl ,
136137 pollInterval = self ._task .pollInterval ,
137138 )
Original file line number Diff line number Diff line change @@ -54,10 +54,12 @@ def create_task_state(
5454 Returns:
5555 A new Task in "working" status
5656 """
57+ now = datetime .now (timezone .utc )
5758 return Task (
5859 taskId = task_id or generate_task_id (),
5960 status = "working" ,
60- createdAt = datetime .now (timezone .utc ),
61+ createdAt = now ,
62+ lastUpdatedAt = now ,
6163 ttl = metadata .ttl ,
6264 pollInterval = 500 , # Default 500ms poll interval
6365 )
Original file line number Diff line number Diff line change @@ -122,6 +122,9 @@ async def update_task(
122122 if status_message is not None :
123123 stored .task .statusMessage = status_message
124124
125+ # Update lastUpdatedAt on any change
126+ stored .task .lastUpdatedAt = datetime .now (timezone .utc )
127+
125128 # If task is now terminal and has TTL, reset expiry timer
126129 if status is not None and is_terminal (status ) and stored .task .ttl is not None :
127130 stored .expires_at = self ._calculate_expiry (stored .task .ttl )
Original file line number Diff line number Diff line change @@ -128,10 +128,17 @@ async def handle(
128128 result = await self ._store .get_result (task_id )
129129 # GetTaskPayloadResult is a Result with extra="allow"
130130 # The stored result contains the actual payload data
131+ # Per spec: tasks/result MUST include _meta.io.modelcontextprotocol/related-task
132+ # with taskId, as the result structure itself does not contain the task ID
133+ related_task_meta : dict [str , Any ] = {"io.modelcontextprotocol/related-task" : {"taskId" : task_id }}
131134 if result is not None :
132- # Copy result fields into GetTaskPayloadResult
133- return GetTaskPayloadResult .model_validate (result .model_dump (by_alias = True ))
134- return GetTaskPayloadResult ()
135+ # Copy result fields and add required metadata
136+ result_data = result .model_dump (by_alias = True )
137+ # Merge with existing _meta if present
138+ existing_meta : dict [str , Any ] = result_data .get ("_meta" ) or {}
139+ result_data ["_meta" ] = {** existing_meta , ** related_task_meta }
140+ return GetTaskPayloadResult .model_validate (result_data )
141+ return GetTaskPayloadResult .model_validate ({"_meta" : related_task_meta })
135142
136143 # Wait for task update (status change or new messages)
137144 await self ._wait_for_task_update (task_id )
Original file line number Diff line number Diff line change @@ -492,6 +492,9 @@ class Task(BaseModel):
492492 createdAt : datetime # Pydantic will enforce ISO 8601 and re-serialize as a string later
493493 """ISO 8601 timestamp when the task was created."""
494494
495+ lastUpdatedAt : datetime
496+ """ISO 8601 timestamp when the task was last updated."""
497+
495498 ttl : Annotated [int , Field (strict = True )] | None
496499 """Actual retention duration from creation in milliseconds, null for unlimited."""
497500
Original file line number Diff line number Diff line change @@ -76,6 +76,7 @@ async def get_task_handler(
7676 status = task .status ,
7777 statusMessage = task .statusMessage ,
7878 createdAt = task .createdAt ,
79+ lastUpdatedAt = task .lastUpdatedAt ,
7980 ttl = task .ttl ,
8081 pollInterval = task .pollInterval ,
8182 )
@@ -327,6 +328,7 @@ async def cancel_task_handler(
327328 taskId = updated .taskId ,
328329 status = updated .status ,
329330 createdAt = updated .createdAt ,
331+ lastUpdatedAt = updated .lastUpdatedAt ,
330332 ttl = updated .ttl ,
331333 )
332334
@@ -450,6 +452,7 @@ async def get_task_handler(
450452 status = task .status ,
451453 statusMessage = task .statusMessage ,
452454 createdAt = task .createdAt ,
455+ lastUpdatedAt = task .lastUpdatedAt ,
453456 ttl = task .ttl ,
454457 pollInterval = task .pollInterval ,
455458 )
Original file line number Diff line number Diff line change @@ -96,6 +96,7 @@ async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
9696 status = task .status ,
9797 statusMessage = task .statusMessage ,
9898 createdAt = task .createdAt ,
99+ lastUpdatedAt = task .lastUpdatedAt ,
99100 ttl = task .ttl ,
100101 pollInterval = task .pollInterval ,
101102 )
@@ -419,6 +420,7 @@ async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
419420 status = task .status ,
420421 statusMessage = task .statusMessage ,
421422 createdAt = task .createdAt ,
423+ lastUpdatedAt = task .lastUpdatedAt ,
422424 ttl = task .ttl ,
423425 pollInterval = task .pollInterval ,
424426 )
@@ -437,6 +439,7 @@ async def handle_cancel_task(request: CancelTaskRequest) -> CancelTaskResult:
437439 taskId = updated_task .taskId ,
438440 status = updated_task .status ,
439441 createdAt = updated_task .createdAt ,
442+ lastUpdatedAt = updated_task .lastUpdatedAt ,
440443 ttl = updated_task .ttl ,
441444 )
442445
Original file line number Diff line number Diff line change @@ -169,6 +169,7 @@ async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
169169 status = task .status ,
170170 statusMessage = task .statusMessage ,
171171 createdAt = task .createdAt ,
172+ lastUpdatedAt = task .lastUpdatedAt ,
172173 ttl = task .ttl ,
173174 pollInterval = task .pollInterval ,
174175 )
You can’t perform that action at this time.
0 commit comments