SOPs
Reset macOS Screen Sharing Remotely
The Symptom
Section titled “The Symptom”Screen Sharing.app shows:
Connection Failed Screen Sharing is not permitted on “192.168.1.220”. Disable and re-enable Screen Sharing or Remote Management in System Settings before trying again.
But on the target Mac, the System Settings toggle is already on, the user is in the access list, and netstat shows *.5900 listening. Often there is even an ESTABLISHED socket from the failing client, which means the TCP handshake completed and the rejection happened at the macOS permission layer above it.
This usually follows a sleep/wake cycle, an OS update, or any event that changes user session state. screensharingd keeps running, but its in-memory permission cache has rotted.
The Fix
Section titled “The Fix”Bootout and bootstrap the daemon. This is the command-line equivalent of toggling the System Settings switch off and back on.
sudo launchctl bootout system /System/Library/LaunchDaemons/com.apple.screensharing.plistsleep 2sudo launchctl bootstrap system /System/Library/LaunchDaemons/com.apple.screensharing.plistbootout may exit non-zero if the service is already in a partial state. That is fine — bootstrap reloads it from a known place either way.
Verify port 5900 is back to a clean listening state with no stale ESTABLISHED sockets:
lsof -iTCP:5900 -sTCP:LISTEN -nThen reconnect with Screen Sharing.app. The “not permitted” dialog goes away.
Doing This Remotely
Section titled “Doing This Remotely”The reason this SOP exists at all is that the obvious fix — walk over to the machine and flip the System Settings toggle — is the thing you cannot do when Screen Sharing is broken. You also cannot SSH in and sudo directly from a non-interactive shell because sudo needs a TTY for the password prompt (see Running sudo Over SSH).
The pattern that works: open a Terminal on the client (the Mac you are sitting at), have it ssh -t into the target (the Mac that needs the reset), and let sudo prompt for the password locally so you can type it.
If Claude is running on the broken machine itself and cannot pop a Terminal where you are, use run-terminal-over-ssh.sh — it scp’s a script to the client, runs it via Terminal do script, polls until the tab finishes, and closes the window so dead terminals do not pile up.
The script body looks like this:
#!/bin/bashset -u
ssh -t studio 'sudo bash -c " launchctl bootout system /System/Library/LaunchDaemons/com.apple.screensharing.plist 2>&1 || echo \"(bootout returned non-zero, often fine)\" sleep 2 launchctl bootstrap system /System/Library/LaunchDaemons/com.apple.screensharing.plist 2>&1 sleep 1 lsof -iTCP:5900 -sTCP:LISTEN -n | head -5"'
echo ""echo "Press return to close this window."readSave to /tmp/fix-screensharing.sh, then on the server side:
bash ~/apps/cc/bin/run-terminal-over-ssh.sh mbp /tmp/fix-screensharing.shA Terminal window pops up on the client, prompts for the target’s sudo password, runs the bootout/bootstrap pair, prints the verification output, and closes itself when you press return.
Why Not Just AppleScript The System Settings Toggle
Section titled “Why Not Just AppleScript The System Settings Toggle”tell application "System Events" to click ... requires Accessibility permission on the target, which a remote osascript session almost never has. It fails with (1002). The launchctl pair is what the toggle does under the hood anyway, so skip the UI dance.
Why Not Just Kill The Daemon
Section titled “Why Not Just Kill The Daemon”sudo killall screensharingd does restart the process via launchd, but it does not flush the same caches that bootout does. In practice the “not permitted” state survives a plain kill and only clears with the bootout/bootstrap cycle.
Related
Section titled “Related”- Running sudo Over SSH
- Working Over SSH — the full audit of what breaks when Claude is on the other machine, including
run-terminal-over-ssh.sh