You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Almost every session, open_colab_browser_connection opens a fresh empty.ipynb, but the notebook-editing tools never unlock — the call just times out. The only thing that reliably fixes it is to both restart the MCP server and wipe colab.research.google.com cookies. Restarting alone doesn't work; wiping cookies alone doesn't work. It has to be both, every time.
Root cause (I dug into my own process list + the MCP logs)
There seem to be two independent pieces of stale state, which is why only resetting both helps:
1. Orphaned server processes never exit. A colab-mcp process started 5 days ago was still alive and LISTENing on its port (127.0.0.1:50419), with a second, newer instance also running. Each new client session spawns a fresh server via uvx, but the previous ones don't terminate when their stdio client disconnects — they linger for days, each holding a port and its own fixed token (token = secrets.token_urlsafe(16) is minted once per process in ColabWebSocketServer.__init__).
2. The browser reconnects to the old server using a cached token/port. When the new session opened a tab pointing at the new port via the #mcpProxyToken=…&mcpProxyPort=… fragment (session.py, check_session_proxy_tool_fn → webbrowser.open_new), the old server's log recorded the connection open — i.e. the Colab frontend dialed the stale port from cached state instead of honoring the fresh fragment. The new server never received a connection, so await_proxy_connection() hit its 60 s timeout and returned false.
So: wiping cookies clears the cached token so the fresh fragment is used; restarting removes/replaces the zombie server. You need both because they're two separate stale states — and a lingering zombie can still grab the single connection slot even after a cookie wipe.
3. No teardown signal / heartbeat. The old server's log showed 3 connection open events and 0 closes, ever. _connection_handler holds connection_lock for the connection's lifetime with no ping/keepalive or idle timeout (websocket_server.py), so a dead-but-not-closed socket never releases the slot, and connection_live is only cleared on a clean ConnectionClosed.
Suggested fixes
Exit when the stdio client disconnects. The server process should terminate on stdin EOF / client disconnect instead of lingering for days. This is the core of the problem — orphaned servers are what make the stale cached token point at something still alive.
Make the frontend honor the fresh URL-fragment token/port over any cached value, or key the cached connection by token so a stale token can't hijack a new session. (Frontend isn't in this repo, but the behavior is observable in the logs.)
Add a heartbeat / idle timeout to the WS connection so a half-open socket releases connection_lock and clears connection_live.
Optional, separate annoyance:webbrowser.open_new always force-opens a new empty.ipynb. A way to attach to an already-open notebook (or just print the connect URL/token to paste) would avoid piling up scratch tabs — and each extra open tab is another candidate to occupy the single connection slot.
Happy to share full (token-redacted) logs or test a patch.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Client: Claude Code (local, stdio) · OS: macOS · Install:
uvx git+https://github.com/googlecolab/colab-mcp,timeout: 30000Symptom
Almost every session,
open_colab_browser_connectionopens a freshempty.ipynb, but the notebook-editing tools never unlock — the call just times out. The only thing that reliably fixes it is to both restart the MCP server and wipecolab.research.google.comcookies. Restarting alone doesn't work; wiping cookies alone doesn't work. It has to be both, every time.Root cause (I dug into my own process list + the MCP logs)
There seem to be two independent pieces of stale state, which is why only resetting both helps:
1. Orphaned server processes never exit. A colab-mcp process started 5 days ago was still alive and
LISTENing on its port (127.0.0.1:50419), with a second, newer instance also running. Each new client session spawns a fresh server viauvx, but the previous ones don't terminate when their stdio client disconnects — they linger for days, each holding a port and its own fixed token (token = secrets.token_urlsafe(16)is minted once per process inColabWebSocketServer.__init__).2. The browser reconnects to the old server using a cached token/port. When the new session opened a tab pointing at the new port via the
#mcpProxyToken=…&mcpProxyPort=…fragment (session.py,check_session_proxy_tool_fn→webbrowser.open_new), the old server's log recorded theconnection open— i.e. the Colab frontend dialed the stale port from cached state instead of honoring the fresh fragment. The new server never received a connection, soawait_proxy_connection()hit its 60 s timeout and returnedfalse.So: wiping cookies clears the cached token so the fresh fragment is used; restarting removes/replaces the zombie server. You need both because they're two separate stale states — and a lingering zombie can still grab the single connection slot even after a cookie wipe.
3. No teardown signal / heartbeat. The old server's log showed 3
connection openevents and 0 closes, ever._connection_handlerholdsconnection_lockfor the connection's lifetime with no ping/keepalive or idle timeout (websocket_server.py), so a dead-but-not-closed socket never releases the slot, andconnection_liveis only cleared on a cleanConnectionClosed.Suggested fixes
connection_lockand clearsconnection_live.webbrowser.open_newalways force-opens a newempty.ipynb. A way to attach to an already-open notebook (or just print the connect URL/token to paste) would avoid piling up scratch tabs — and each extra open tab is another candidate to occupy the single connection slot.Happy to share full (token-redacted) logs or test a patch.
All reactions