moha is a native terminal client for Claude AI — a single ~9 MB binary, C++26, no runtime dependencies. It gives Claude sandboxed access to your files, shell, and git so you can do real development work without context-switching to a browser.
🚀 Quick Start
If you haven’t installed moha yet, head over to the Installation guide.
# Start in your project directory
cd your-project
moha
Auth happens in-app on first launch. You can paste an API key or sign in with your Claude Pro/Max subscription via OAuth.
Your First Session
1. Explore the codebase
❯ You: what does this project do? walk me through the main entry points
✦ Sonnet: [reads files, maps the architecture]
2. Fix something
❯ You: the tests in tests/auth_test.cpp are failing, figure out why and fix it
✦ Sonnet: [reads → greps → edits → runs tests]
✓ done · 4 actions · 3.2s
3. Ask about a bug
❯ You: why is the user's session sometimes null after login?
✦ Sonnet: [reads auth code, traces the call chain]
Found it — race condition between session write and redirect.
🔑 Authentication
moha supports two authentication methods. Both work in-app — no external setup required.
OAuth (Claude Pro / Max)
Sign in with your existing Claude Pro or Max subscription:
moha # choose OAuth when prompted
moha opens a browser for authentication and stores the refresh token locally. Same OAuth flow as Claude Code — you can switch between the two without re-authing. The environment variable CLAUDE_CODE_OAUTH_TOKEN also works.
API key
Paste an Anthropic API key (sk-ant-…):
moha # paste when prompted
moha -k sk-ant-api03-... # pass directly
Or set it as an environment variable:
export ANTHROPIC_API_KEY=sk-ant-api03-...
moha
Credentials are stored at ~/.config/moha/ with 0600 permissions (POSIX) / restrictive ACLs (Windows).
⌨️ Essential Shortcuts
The shortcut row at the bottom of the terminal shows the most-used keybindings:
^K palette ^J threads ^T todo S-Tab profile ^/ models ^N new ^C quit
Composer
| Key | Action |
|---|---|
Enter | Send message |
Alt+Enter or ↑↓ | Insert newline |
Ctrl+E | Expand composer (multi-line editing) |
Esc | Cancel current generation / reject permission |
You can type while Claude is streaming — your message queues and sends automatically when the stream finishes.
Navigation
| Key | Action |
|---|---|
Ctrl+K | Command palette |
Ctrl+J | Thread list (browse, fork, delete) |
Ctrl+T | Todo / plan checklist |
Ctrl+/ | Model picker |
Ctrl+N | New thread |
Ctrl+C | Quit |
Permission prompts
When Claude proposes a tool call that requires approval:
| Key | Action |
|---|---|
Tab | Approve the tool call |
Esc | Reject the tool call |
🧠 Switching Models
Use Ctrl+/ during a session, or start with a specific model:
moha --model claude-haiku-4-5 # faster, cheaper
moha --model claude-sonnet-4-6 # balanced (default)
moha --model claude-opus-4-7 # most capable
🛡️ Air-Gapped Mode
Run moha on a host that can’t reach the internet directly — your laptop relays the bytes, TLS stays end-to-end with the real upstreams.
From the laptop that does have internet:
moha airgap --setup user@airgapped-host # first time: copies credentials too
moha airgap user@airgapped-host # every time after
That’s it. The remote moha connects to Claude through the SSH tunnel.
How it works
ssh -R 1080 makes OpenSSH expose a SOCKS5 proxy on the remote at localhost:1080. Connections to it are tunnelled back over SSH and dialed by your laptop.
The remote moha gets MOHA_SOCKS_PROXY=localhost:1080 and routes every TCP destination through that single proxy (chat, OAuth refresh, web search).
TLS happens end-to-end with the real upstream over the tunnelled socket, so the proxy can’t MITM you. SNI, cert verification, and the HTTP Host header stay pinned on the real upstreams.
The --setup flag
The --setup flag does three remote operations:
mkdir -p ~/.config/moha && chmod 700scpyour laptop’s~/.config/moha/credentials.jsonto the remotechmod 600the remote copy
Re-run after a fresh moha login on your laptop when the refresh token eventually rotates.
Bare-metal version
The moha airgap subcommand is sugar. The equivalent, from the laptop:
ssh -t -R 1080 user@airgapped-host \
'MOHA_SOCKS_PROXY=localhost:1080 moha'