Contents (14)

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
Info

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

KeyAction
EnterSend message
Alt+Enter or ↑↓Insert newline
Ctrl+EExpand composer (multi-line editing)
EscCancel current generation / reject permission
Tip

You can type while Claude is streaming — your message queues and sends automatically when the stream finishes.

KeyAction
Ctrl+KCommand palette
Ctrl+JThread list (browse, fork, delete)
Ctrl+TTodo / plan checklist
Ctrl+/Model picker
Ctrl+NNew thread
Ctrl+CQuit

Permission prompts

When Claude proposes a tool call that requires approval:

KeyAction
TabApprove the tool call
EscReject 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:

  1. mkdir -p ~/.config/moha && chmod 700
  2. scp your laptop’s ~/.config/moha/credentials.json to the remote
  3. chmod 600 the 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'