Expired MCP session after 30 idle minutes: resume by job id

MCP Python SDK v2.2.0 closes idle Streamable HTTP sessions after 30 minutes by default. Keep the Sume job_id and resume the render with jobs_wait.

4 min readSume
All posts

If your MCP server runs on the Python SDK v2.2.0 or later, an idle Streamable HTTP session expires after 30 minutes by default, and a long render can outlive it. Store the Sume job_id outside the session; a new session can then wait on the same job with jobs_wait instead of submitting again.

What the release notes say

The Python SDK releases page lists v2.2.0 with two server defaults: a stateful session with nothing in flight for 30 minutes is closed (the client's next request gets a 404 and must initialize again), and the server holds at most 10,000 sessions at once (beyond that, new sessions get a 503). These apply to legacy Streamable HTTP connections and can be changed in server configuration; check yours.

MCP Python SDK v2.2.0 defaults (read 2026-10-03)
SettingDefault
Idle session expiry (nothing in flight)30 minutes
Maximum concurrent sessions10,000

Why a render can outlive the session

A video or avatar render is asynchronous. Sume's remote MCP jobs_wait holds at most 55 seconds per call and returns wait_slice_expired when the slice ends, so a long job is waited on repeatedly. If the client goes quiet, for instance while a user steps away, the session on the other side can expire between calls.

The job does not stop when the session does. Sume docs state that a client-side timeout does not cancel the job: it keeps running and still bills. The only loss is your handle on it.

Carry the job_id as an argument

Treat the job_id as the durable handle. Persist it with your own record the moment the create call returns, and pass it as an explicit tool argument in whatever workflow resumes the work. After reconnecting, call jobs_wait with that id, then jobs_result once the job completes.

Never resubmit the paid create because the session died. If you must retry the submit itself, reuse the same idempotency key so the retry returns the original job.

  • Persist job_id before you do anything else.
  • Resume with jobs_wait, never with a second create.
  • Batch waits take 1-20 ids via job_ids.
  • Unknown or foreign-workspace ids fail the whole call.
{ "job_id": "job_01HXYZ" }
// call jobs_wait with this input in the new session
// on wait_slice_expired, call jobs_wait again with the same id
// when the job is completed, call jobs_result with the same id

Sources

Related posts

More in Developers

All Developers posts

Written by Sume