[FEATURE] computer-use: release the machine lock at end of turn (or after an idle timeout) instead of only on session exit

Status Open
Reported on v2.1.284
Maintainer reply None cached
Activity 0 comments · opened Sep 29, 2026

Summary

The built-in computer-use MCP server takes a machine-wide lock (~/.claude/computer-use.lock) at the first computer-use action of a session and releases it only when that session's process exits. Ending the turn, finishing the task, or pressing Esc does not release it. On a machine that runs several Claude Code sessions at once, one idle session that used computer-use once keeps every other session locked out until someone finds it and exits it.

Version

  • Claude Code 2.1.284 (native build), macOS (Apple Silicon)
  • computer-use built-in MCP, in-process

Documented behavior

From https://code.claude.com/docs/en/computer-use, "One session at a time":

Only one session at a time can use your computer. A session takes a lock at its first computer use action and releases it when the session exits, not when the task finishes. A second session's computer use fails with an error naming the session that holds the lock. Exit that session first.

So this is working as documented. The request is to change the release point.

Observed behavior

  • The lock file is JSON with sessionId, pid and acquiredAt. It is written with wx at the first action.
  • The "I hold the lock" state lives in memory (the registered exit-cleanup callback). Releasing happens only through that exit-cleanup callback.
  • The session already tracks computer use per turn (an activeThisTurn flag drives the "Claude is using your computer" notification), but the lock is not tied to it.
  • Another session is blocked only when sessionId differs and kill(pid, 0) succeeds. A crashed session is recovered automatically, but an idle one that is still running is not: its pid stays alive.

In practice we had one idle session hold the lock for ~21 hours. It no longer showed up in the list of agents, so the other sessions had no way to ask it to exit. A human had to find the pid and close the terminal.

Impact with several sessions

We run several Claude Code sessions in parallel on the same Mac (different tasks in different terminals). Computer use is needed for short, occasional steps (read a native app's state, one click in a desktop app). Because the lock outlives the step by hours, the first session that touches computer use blocks all others for the rest of its life. The workaround, "exit that session", means throwing away a working session's context just to free the screen.

Why deleting the lock file from outside is not a safe workaround

We tried a Stop hook that deletes the lock file at end of turn. It works for the common case, but it opens a double-control window:

  1. Session A takes the lock. Its in-memory "held" state stays set.
  2. The lock file is deleted from outside (hook, or a user following the troubleshooting advice).
  3. Session B acquires the lock. The file now names B.
  4. On A's next action, the check sees the in-memory "held" state first and treats A as the owner, even though the file names B. Both sessions can now drive the desktop at the same time.
  5. When A exits, its release path deletes the file without checking the sessionId (because the in-memory state is set), so B's lock file disappears too.

We had to add a PreToolUse hook that denies computer-use actions when the lock file names another live session, to close step 4. That is a lot of machinery to rebuild a behavior that belongs in the tool.

Request

Any of these would solve it (in order of preference):

  1. Release at end of turn. The lock is already scoped to a turn for the notification; release it at the same point, and re-acquire on the next action. If another session took it in between, fail with the existing "in use by another Claude session" error.
  2. Idle timeout. Release after N minutes without a computer-use action (configurable, e.g. computerUse.lockIdleTimeoutMinutes).
  3. At minimum, make the in-memory state follow the file. Before each action, re-read the lock and treat a file that names another session as "blocked", not "held by self". And make the exit release check the sessionId before deleting. This would make external release (hook or manual) safe.

Related

  • #69447 (closed): concurrent sessions contending for the screen-capture stream. Different root cause, same multi-session setup.

View original on GitHub ↗