◉CLAUDE LABJP
●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.307 — Fixes MCP failing to reconnect after sleep or a keychain lock (10/21). 2.1.306 also fixed the false claude -p login message●SONNET 4.5 — Retires on the Claude API on 11/30, 38 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.307 — Fixes MCP failing to reconnect after sleep or a keychain lock (10/21). 2.1.306 also fixed the false claude -p login message●SONNET 4.5 — Retires on the Claude API on 11/30, 38 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Claude Code
⟐ Claude Code/2026-10-23Intermediate

When a Nightly claude -p Says MCP "Needs Authentication": Check Mac Sleep and the Keychain First

If an unattended claude -p run leaves "needs authentication" or MCP timeouts in the morning log, check whether the Mac slept or the login keychain was locked. What v2.1.307 changed, and what it still leaves to you.

Claude Code272MCP58Troubleshooting23claude -p3macOSv2.1.307

Some mornings I open last night's run log on my iMac and find the task finished without touching a single MCP server. One line sits in the log: "needs authentication". I had signed in the day before, and when I open claude by hand the same servers connect fine.

My first instinct was an expired OAuth token, so I re-authenticated server after server. It didn't help. The same line came back the next night. The cause wasn't authentication at all: the Mac had gone to sleep during the run, and the login keychain was locked.

So here is the point up front: when an unattended MCP run fails, look at the state of the Mac before you touch servers or credentials. The rest of this post is the order I now check things in.

What v2.1.307 changed

The v2.1.307 release notes (October 21, 2026) include three fixes that bear on this symptom:

  • On macOS, MCP servers in claude -p showed "needs authentication" while the login keychain was locked. They now say why, and the next run after an unlock connects without a new sign-in.
  • MCP servers were reported as timed out, and stayed failed in headless runs, when a macOS or Linux machine went to sleep while they were connecting. This is fixed.
  • HTTP MCP tool calls could be sent twice when the connection closed mid-call. Only read-only or idempotent tools are retried now.

Before this, "authentication expired" and "the Mac was asleep" could look identical in the log. A better message doesn't remove the underlying cause, though, so it helps to have a way to tell the two apart.

The order I check things in

1. Check the version

claude --version
# 2.1.307 or later reports a locked keychain with a reason

If you're on 2.1.306 or earlier, update first (claude update).

2. Did the Mac sleep during the run?

# Pull last night's power events with timestamps
pmset -g log | grep -E "Sleep|Wake|DarkWake" | tail -n 20

A Sleep entry close to the run's start time is the likely culprit. A midnight job may start on a DarkWake (a brief wake with the display off), and the machine can drop back to sleep mid-connection.

3. Was the login keychain locked?

security show-keychain-info ~/Library/Keychains/login.keychain-db

This prints the keychain's settings (whether it locks on sleep, and the timeout). It can't tell you for certain whether the keychain is closed right now, but knowing it locks on sleep is useful before a nightly run. After a screen lock or sleep the keychain can close, and stored credentials become unreadable. An unattended run has nobody to type the password.

4. Know what the fix does not cover

The 2.1.307 fix stops at "show the reason" and "no new sign-in after unlock". If the keychain stays closed overnight, that run still proceeds without MCP. The message got more honest, but the nights where it can't work didn't disappear. That part is yours to guard.

The preflight wrapper I put in front of nightly runs

#!/bin/bash
# nightly-claude.sh — check the Mac before an unattended run
set -u
 
MIN="2.1.307"
CUR="$(claude --version | awk '{print $1}')"
 
# Skip if the version is older than MIN (sort -V compares version strings)
if [ "$(printf '%s\n%s\n' "$MIN" "$CUR" | sort -V | head -n 1)" != "$MIN" ]; then
  echo "SKIP: claude $CUR is older than $MIN" >&2
  exit 2
fi
 
# If the keychain can't be queried, log it and stop (a rough check, not proof of a lock)
if ! security show-keychain-info ~/Library/Keychains/login.keychain-db >/dev/null 2>&1; then
  echo "SKIP: login keychain check failed" >&2
  exit 3
fi
 
# caffeinate -i blocks idle sleep while the command runs
caffeinate -i claude -p "$(cat "$1")" --permission-mode default

caffeinate -i only prevents idle sleep. It doesn't stop a closed laptop lid from sleeping the machine. That's enough on a desktop iMac, but on a laptop you'll want to verify power and lid state separately.

The distinct exit codes exist so I can tell "version", "keychain", and "something else" apart from one line of the morning log, before I re-authenticate anything.

Two things that tripped me up

First, I assumed security show-keychain-info was a clean lock check. It returns settings, not the current locked state, so the wrapper treats it only as a rough "can I reach the keychain" check, with output redirected to >/dev/null 2>&1. If you need the keychain open for certain, add a separate security unlock-keychain step before the run.

Second, the duplicate-call fix means only read-only or idempotent HTTP tools are retried. A tool that writes will not be retried if the connection drops mid-call. For overnight runs, I check the results of write-capable tools by hand the next morning.

After updating

Run the unattended job once during the day, by hand. Mid-run, claude mcp list shows which servers connected. If the count matches what you see when you open claude interactively, you're in decent shape.

Related symptoms are covered elsewhere on this site: a general diagnosis for MCP servers that suddenly stop working, the lifecycle of remote MCP OAuth tokens, and the 60-second per-server timeout cap when the cause isn't sleep.

Ask whether the Mac was awake before you ask whether the login expired. I keep to that even on tired mornings.

Next time you see that line, start with the last 20 lines of pmset -g log. That's where I started, too.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Claude Code2026-09-04
The ~/.claude.json Rollback Is Fixed in v2.1.259. Putting Back What It Erased Is Still Your Job
Concurrent sessions used to silently roll back each other's ~/.claude.json changes. v2.1.259 fixed that, but nothing restores the trust settings and MCP servers you already lost. Here is how I find and rebuild them, with a small key-path diff script.
⟐ Claude Code2026-10-22
When Only claude -p Refuses to Log In: Check the Credential Order Before You Re-Login
Interactive Claude Code works but claude -p or a script is refused? Here is where to look before running /login again, following the credential order in the official docs.
⟐ Claude Code2026-10-19
If You Wrote MCP Allow Rules as Just `mcp__servername` — Three Lines to Recheck After v2.1.299
Claude Code v2.1.299 changed MCP allow rules to match only the server they name. Here is how to audit older entries in settings.json, with a short Python script that does it.