Adding Claude Code Status to Your Mac Status Bar
How to set up a Mac menu bar indicator that shows when Claude Code is idle, working, or needs your attention using SwiftBar and hooks.
On this page
If you’re anything like me, you fire off a task in Claude Code and then flip over to something else — a browser tab, Slack, another terminal. The problem is knowing when Claude is done or needs your attention without constantly checking back.
I put together a simple setup that adds a status indicator right in the Mac menu bar. Three states, zero guesswork:
- 🤖 Idle/Done — Claude is finished or waiting
- 🔨 Working — Claude is actively using tools
- 🔔 Needs Attention — Claude has a question or notification for you
Here’s how to set it up.
Step 1: Install SwiftBar
SwiftBar is a lightweight, open-source menu bar customization tool. All it does is run shell scripts on an interval and display their output in your menu bar — no network calls, no telemetry. You can review the full source on GitHub if you want to see exactly what it’s doing under the hood. Install it with Homebrew:
brew install swiftbar
Step 2: Create a Plugins Directory
SwiftBar needs a directory to look for plugin scripts. Create one:
mkdir -p ~/.swiftbar
Step 3: Create the Status Script
Create a file at ~/.swiftbar/claude-status.3s.sh with the following contents:
#!/bin/bash
FLAG=/tmp/claude-status-flag
if [ -f "$FLAG" ]; then
case $(cat "$FLAG") in
notify) echo "🔔 Claude" ;;
working) echo "🔨Claude" ;;
done) echo "🤖 Claude" ;;
esac
else
echo "🤖" # idle state - minimal
fi
The .3s. in the filename tells SwiftBar to refresh the script every 3 seconds. Make it executable:
chmod +x ~/.swiftbar/claude-status.3s.sh
Step 4: Add Hooks to Claude Code
Claude Code supports hooks — shell commands that fire in response to lifecycle events. Open your Claude settings file at ~/.claude/settings.json and add the following hooks section (if you already have content in this file, add this before the closing }):
"hooks": {
"Notification": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "echo 'notify' > /tmp/claude-status-flag && open -g 'swiftbar://refreshPlugin?name=claude-status'",
"timeout": 2
}]
}],
"PreToolUse": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "echo 'working' > /tmp/claude-status-flag && open -g 'swiftbar://refreshPlugin?name=claude-status'",
"timeout": 2
}]
}],
"Stop": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "echo 'done' > /tmp/claude-status-flag && open -g 'swiftbar://refreshPlugin?name=claude-status'",
"timeout": 2
}]
}]
}
Each hook writes a state to a temp file and tells SwiftBar to refresh immediately (rather than waiting for the next 3-second poll). The open -g flag opens the URL in the background so it doesn’t steal focus.
Step 5: Launch SwiftBar and Set the Plugin Directory
Open SwiftBar and point it to the plugin directory you created.
Tip: If you used ~/.swiftbar, the directory will be hidden in Finder. When the “Choose plugin folder” dialog appears, press ⇧⌘G (Shift + Command + G) to open the “Go to folder” input, then type ~/.swiftbar to navigate there directly.
Testing It Out
You can verify everything works without running Claude Code by executing one of the hook commands directly in your terminal:
echo 'notify' > /tmp/claude-status-flag && open -g 'swiftbar://refreshPlugin?name=claude-status'
You should see the 🔔 icon appear in your menu bar. Swap notify for working or done to test the other states.
Once it’s wired up, you’ll always know at a glance whether Claude is heads-down, finished, or waiting on you — no terminal switching required.