claude-mac-hotkeys
Press one key → new terminal tab. Press another → Claude Code already running in your dev folder.
No Karabiner. No BetterTouchTool. No third-party anything — just macOS built-ins plus Ghostty 1.3+, wired together with two Shortcuts and a little AppleScript.
Built and battle-tested on macOS 26.5 with Ghostty 1.3.1 and Claude Code 2.x. Everything here was set up live in a Claude Code session — including hitting every dead end below, for real, in order. This guide exists so you can skip them.
What you get
| Key | Action |
|---|---|
| F13 | New tab in your most recent Ghostty window — from anywhere on macOS |
| F14 | New Ghostty tab in ~/Developer with claude already launching — and a normal shell prompt waiting when you quit |
Both work system-wide, whatever app you're in. When no Ghostty window exists, they open one instead.
Make Claude do it for you
The entire setup below — minus four unavoidable GUI clicks that macOS reserves for humans (permission prompts and key recording) — can be driven by Claude Code. Paste this:
Set up two global hotkeys on my Mac using only built-in tools plus Ghostty 1.3+'s
AppleScript support — no Karabiner/BTT:
F13 → new tab in my frontmost Ghostty window (new window if none exist)
F14 → new Ghostty tab in <MY FOLDER> that types "<MY COMMAND>" into the shell
Use Ghostty's AppleScript dictionary: `new tab in front window with configuration
{initial working directory, initial input}` — initial input, NOT command, so my
real shell and PATH load. Generate the two Shortcuts programmatically (unsigned
WFWorkflow plist → `shortcuts sign` — note the input file must have a .shortcut
extension), open them for one-click import, then walk me through: Allow Running
Scripts, freeing F14 from Display brightness, ticking Use as Quick Action, and
binding the keys under System Settings → Keyboard Shortcuts → Services → the
"Shortcuts" group (NOT General, and NOT the Shortcuts app's own flaky recorder).
Test with AppleScript before handing steps to me.
Rather know what you're running first? Keep reading — the dead ends below are why the prompt looks the way it does.
The dead ends (read this first, save an hour)
Every "obvious" approach fails in a non-obvious way:
- Ghostty's global keybinds —
keybind = global:f13=new_windowworks great. But change it tonew_taband pressing the key from another app opens a window anyway: with Ghostty unfocused there's no focused surface for the tab to attach to. Global keybinds also require Accessibility permission and die entirely if Ghostty isn't running. - The
opencommand —open -na Ghostty.app --args -e claudelaunches a whole second Ghostty instance: second dock icon, never a tab in your existing window. Fine for windows (add--quit-after-last-window-closed=trueso it cleans up), structurally incapable of tabs. - The Shortcuts app's own hotkey recorder — the ⓘ → "Add Keyboard Shortcut" field is flaky with bare function keys. It either runs the shortcut instead of recording, or shows a recorded key that silently never fires system-wide.
- The wrong Services group — when you bind keys in System Settings instead, Shortcuts-based quick actions are not under Services → "General" where you'd look. They get their own "Shortcuts" group at the very bottom of the list.
- Pre-claimed F-keys — F14 and F15 look free but are silently owned by Decrease/Increase display brightness. Bindings on them never fire until you untick those.
How it actually works
F-key ──► macOS Services hotkey ──► Shortcuts quick action ──► osascript ──► Ghostty AppleScript
└─► new tab in front window
(working dir + initial input)
The linchpin is Ghostty 1.3's AppleScript dictionary. Its new tab command accepts a surface configuration:
new tab in front window with configuration ¬
{initial working directory:"/Users/you/Developer", initial input:"claude" & return}
Two properties do all the work:
initial working directory— the tab opens already in your folder.initial input— text typed into your real shell after it starts. Your.zshrc/PATH load normally, soclauderesolves with no hardcoded paths — and when claude exits you're at a live prompt in that directory instead of the tab closing.
Prerequisites
- macOS 13 or later (built on macOS 26)
- Ghostty 1.3+ (AppleScript support shipped in 1.3)
- Claude Code CLI — or any command you want F14 to launch
Setup (~10 minutes)
Create the two Shortcuts
In the Shortcuts app: ⌘N → name it New Ghostty Tab → search the right-hand panel for Run Shell Script and double-click it → replace the script body with:
osascript -e 'tell application "Ghostty"
if (count of windows) > 0 then
new tab in front window
else
new window
end if
activate
end tell'
Repeat (⌘N → Claude in Developer → Run Shell Script) with:
osascript -e 'tell application "Ghostty"
set devCfg to {initial working directory:"'"$HOME"'/Developer", initial input:"claude" & return}
if (count of windows) > 0 then
new tab in front window with configuration devCfg
else
new window with configuration devCfg
end if
activate
end tell'
Don't see "Run Shell Script" in the action search? That's the next step.
Let Shortcuts run scripts
Shortcuts → Settings… (⌘,) → Advanced → ✅ Allow Running Scripts (tick Allow Sharing Large Amounts of Data too). Without this, your shortcuts fail at run time with no useful error — and the scripting actions don't even appear in search.
Free your F-keys
System Settings → Keyboard → Keyboard Shortcuts… → Display → untick Decrease display brightness (F14) and Increase display brightness (F15) if present. Skip this and your F14 binding will record fine and then silently never fire.
Bind the keys — in System Settings, not in Shortcuts
First, expose each shortcut to the system: open it in Shortcuts, click ⓘ → Details, tick Use as Quick Action and Services Menu. (Resist the "Add Keyboard Shortcut" button right next to it — that's dead end #3.)
Then the binding that actually works:
- System Settings → Keyboard → Keyboard Shortcuts… → Services
- Scroll past General to the Shortcuts group at the very bottom and expand it
- Tick New Ghostty Tab → double-click the "none" on its right → press F13
- Tick Claude in Developer → double-click its "none" → press F14
- Done
First run
Click into Finder and press F13, then F14. The first press of each asks permission ("…wants to control Ghostty" / run-script confirmation) — Allow, once per shortcut. First triggers can lag a second or two; after that they're instant.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Key press does nothing | Binding was made with Shortcuts' own ⓘ recorder | Remove it there; rebind via System Settings → Services → Shortcuts group |
| Key press does nothing (still) | F14/F15 owned by Display brightness | Step 3, then rebind |
| Shortcut missing from the Services list | "Use as Quick Action" unticked, or stale panel | Tick it (+ Services Menu); fully quit System Settings and reopen |
| Recorder runs the shortcut instead of recording | You're in the Shortcuts app's recorder | That's dead end #3 — use the Services panel recorder |
| New window instead of a tab | Using global:…=new_tab or open -na |
Use the AppleScript path from this guide |
command not found in the new tab |
Used the command property instead of initial input |
initial input types into your real shell, so PATH loads |
shortcuts sign says "isn't in the correct format" |
Input file lacks a .shortcut extension |
Rename input to whatever.shortcut, re-sign |
| Shortcut errors instantly when triggered | Allow Running Scripts is off | Step 2 |
Make it yours
The pattern is hotkey → Shortcuts quick action → AppleScript, and every piece swaps out:
- Different folder / command: edit
initial working directoryandinitial input—"npm run dev" & return,"ssh prod" & return, anything you'd type. - More keys: F15 is free after step 3. F16–F19 exist on full-size keyboards and are usually unclaimed.
- Different terminal: Terminal.app (
do script "claude" in front window) and iTerm2 have their own AppleScript dialects — same Shortcuts + Services wiring. - Not a terminal at all: the quick action can run any shell one-liner — toggle dark mode, start a screen recording, open a project workspace.
How this guide was made
One Claude Code session: the goal was "F13 opens a terminal, F14 opens Claude." Claude probed Ghostty's actual .sdef scripting dictionary on disk, tested the AppleScript live before recommending it, generated and signed the Shortcuts programmatically, and — together with a human pressing the keys macOS won't let software press — walked into every dead end documented above. This page — guide, diagrams, and all — was then produced by Claude with a small fleet of subagents.
License
MIT. Go bind some keys.