Wear the right hat for every client.
Client-centric virtual workspaces for macOS, with a drag-and-drop overview and first-class Claude integration.
If you work for several clients at once, each with its own Chrome profile, Teams tenant, Jira, Slack and a pile of native windows, your desktop quickly turns into a coat room after a party. Hatrack gives every client a hook:
- 🎩 One workspace per client. A workspace groups that client's windows and knows who the client is: aliases, Chrome profiles, domains and handy links.
- ⚡ Instant switching. It follows the AeroSpace approach: all windows live on a single macOS Space, and inactive workspaces are parked off-screen. No Mission Control, no minimize animations, and no need to disable SIP.
- 🗂️ Visual overview. An Exposé-like panel with one lane per client. Drag windows between lanes, search, and drive it entirely from the keyboard.
- 🧭 Chrome profile aware. It knows which Chrome profile and installed web app belongs to which client, and opens links in the right one.
- 📏 Rules. Auto-assign new windows by app, bundle ID, title regex or Chrome profile.
- 🚀 Launch sets. One command opens a client's apps, profile and links.
- 🤖 Built for Claude. A built-in, auto-discoverable MCP server lets Claude ask "which client does this URL belong to?", open it in the right profile, or switch your context for you.
- 🛟 Safe by design. "Show all windows" is always one click away, and windows are restored on quit and even after a crash.
Status: early development. The design is done (see
docs/design.md) and the code is being written in phases. Star or watch the repo to follow along.
# ~/.config/hatrack/config.toml
[[workspace]]
id = "client-a"
name = "Client A"
emoji = "⚡"
color = "#2E7DFF"
hotkey = "alt-1"
aliases = ["CA", "Client A BV"]
chrome-profile = "Profile 3"
domains = ["client-a.com", "clienta.atlassian.net"]
launch = [{ chrome-profile = "Profile 3" }, { link = "jira" }, { app = "Visual Studio Code" }]
[workspace.links]
jira = "https://clienta.atlassian.net/jira/your-work"
[[rule]]
match = { chrome-profile = "Profile 3" }
workspace = "client-a"hatrack workspace client-a # switch
hatrack open https://clienta.atlassian.net/browse/X-1 # right profile, right workspace
hatrack resolve "CA" # → client-a (confidence 0.98)
hatrack show-all # emergency: bring every window backAsk Claude things like:
"Open the Jira board for Client A." "Which client does portal.azure.com/#@clienta.onmicrosoft.com belong to?" "Switch me to whatever client I was working on before this one."
Hatrack ships an MCP server (hatrack mcp) that bridges to the running app. Once connected, it describes itself: server instructions, documented tools, client resources and prompts. "Connect to Claude…" in the menu bar sets up Claude Desktop and Claude Code for you. For manual setup:
claude mcp add hatrack -- /Applications/Hatrack.app/Contents/MacOS/hatrack mcpPrivacy is built in. Window titles can be hidden or redacted for MCP, individual clients can be excluded entirely, and every action Claude takes is logged. Hatrack never lets an AI close windows, quit apps or edit your config.
AI agents: start at llms.txt.
- macOS 14 Sonoma or later, Apple Silicon
- Accessibility permission (required) and Screen Recording (optional, for titles and thumbnails)
- Works on managed Macs: no SIP changes and no code injection
Coming with the first milestone. The project is a plain SwiftPM package. Xcode is optional.
- Spike: window control, Chrome profile detection, Claude in Chrome
- MVP: engine, menu bar, config, hotkeys, CLI, MCP server
- Overview panel with drag and drop
- Chrome profile awareness, launch sets, persistence
- Settings UI, onboarding,
.mcpbbundle, signed releases
Hatrack's virtual-workspace technique is inspired by AeroSpace by Nikita Bobko.
MIT: free to use, modify and share.