Capture snapshots, not screenshots
Save the creation result and each later tasks/get result as JSONL. Preserve timestamps, status, polling interval and result discriminator. Redact the payload, not the lifecycle fields.
{"resultType":"task","taskId":"exp_42","status":"working",
"createdAt":"2026-07-29T09:00:00Z",
"lastUpdatedAt":"2026-07-29T09:00:00Z","ttlMs":3600000,
"pollIntervalMs":3000}Separate worker completion from task completion
The background job writing a file does not automatically update the durable MCP task record. Find the transaction that stores the terminal status and result. If it runs after an exception-prone notification, move the state update earlier or make both operations retry-safe.
Check the clock and terminal payload
lastUpdatedAt must not move backward between replicas. A completed task needs its result; a failed task needs a JSON-RPC error. Once terminal, it cannot return to working because a delayed worker wrote an old snapshot.
Respect input_required
If work is waiting for approval, the task is not merely working. Return input_required with the outstanding input request keys and accept the reply through the current task update flow.
Poll at the interval the server returns. A tight client loop can turn a state bug into a load incident.
Validate the sequence
Paste the ordered JSONL into MCP Task Trace. Fix the first impossible transition, then rerun the real worker with process restarts and duplicate delivery.
Expected result
The task survives reconnects, timestamps only advance, polling slows when requested, and the first terminal snapshot remains terminal with the correct result or error.
Check the task lifecycle →