Monitoring and response

Diagnose a stalled MCP session before you resume the agent run

You will find out whether a stalled MCP session comes from an SDK version mismatch, a session routing problem, or a stale auth header before you restart the agent. Ruling these out first keeps you from resuming a run against a broken connection.

  1. Server startsCheck for AttributeError on startup
  2. Session ID acceptedConfirm one instance or sticky routing
  3. Auth header cleanRemove stale custom Authorization header
  4. Read-only call succeedsVerify before resuming the run

Why it matters

A stalled MCP session usually has a concrete cause. A fresh install can pull in an SDK major version the server was not written for, which makes startup fail outright (mcp-server-git fails to start (opens external site)). Streamable HTTP sessions in the Python SDK are held in memory per process, so a request routed to another instance returns a 400 (open limitation (opens external site)). Resuming the agent before you know which case you are in just replays the failure.

Steps

  1. Start the server by itself and read the first error. An AttributeError such as 'Server' object has no attribute 'list_tools' points to an SDK version mismatch, not a session problem. Pin the MCP SDK to v1 in the client config for that server by using the args "--with", "mcp<2", "mcp-server-git", then restart the client.

  2. If the client gets a 400 with "No valid session ID provided", confirm that every request reaches the same instance. Use sticky routing or run a single instance, since the session lives in the process that created it.

  3. If you connect through an OAuth-enabled client and see repeated 401 responses after login, open the Authentication section and delete the custom Authorization header placeholder. A stale custom header overrides the bearer token from the login flow, and the client keeps refreshing and retrying (Inspector OAuth loop (opens external site)).

  4. If an "Invalid Authorization Header" error persists, disable the custom-header toggle and clear the Inspector's browser local storage, since a header saved from an earlier version can stay enabled. To rule out the newer build, run npx @modelcontextprotocol/inspector@0.16.7. Version 0.16.7 behaved correctly in this case (Inspector OAuth loop (opens external site)).

  5. Once the server starts and the session ID is accepted, make one read-only call and confirm the response. Only then let the agent continue with actions that change state.

  6. Record the MCP SDK, Inspector, and Python versions you used so the next stall is easier to compare against a known working setup.

Common mistakes

  • Restarting the agent without reading the server's startup output, which hides a version mismatch.
  • Treating a 400 or 401 as a network fault when it is a session or header problem.
  • Keeping a hand-typed Authorization header alongside an OAuth login.
  • Resuming a run that performs writes before a read-only call has succeeded.

Checklist

0 of 8 done

Sources

  1. mcp-server-git fails to start: 'Server' object has no attribute 'list_tools'
  2. Can streamable HTTP MCP sessions persist across multiple server instances behind a load balancer?
  3. MCP Inspector OAuth login loops with 401 after Keycloak redirect (0.16.8/0.17.0)
Was this guide useful?