Earn Claude credits from your terminal.
FreeAI adds a reversible claude shell alias that shows one subtle
sponsored line in Claude Code’s status bar only while Claude Code is
thinking — and returns 50% of the revenue to you as
credits you redeem for Claude Pro or Max.
What it looks like: the ad· line is a clickable link, and it disappears the moment Claude Code stops working.
Before you start
- Claude Code installed — the real
claudecommand must already be on yourPATH. (Tryclaude --version.) - Node.js 20.12 or newer — check with
node --version. - A supported shell — zsh, bash, or fish.
No account or sign-in is needed to start earning — a device credential is created locally on first run, the same way the browser extension works.
1 Install the freeai command
Until the package lands on npm, install it from the repo. This puts a global freeai command on your PATH (the shell alias depends on it):
# clone and link the terminal client
git clone https://github.com/conorplunkett/freeai.fyi.git
cd freeai.fyi/terminal
npm link # exposes the global `freeai` command
Keep the cloned folder in place — npm link points the global command at it. To remove it later, run npm rm -g @freeai/terminal.
2 Run setup
This finds your real claude, records it, and adds a small, clearly-marked, reversible block to your shell config that aliases claude to the FreeAI wrapper:
freeai claude setup
Then restart your shell, or source your config — setup prints the exact path:
source ~/.zshrc # or ~/.bashrc, or ~/.config/fish/config.fish
That’s it. Use claude exactly as you always have — every flag, argument, and exit code is forwarded untouched.
3 Verify it works
Check the wiring — doctor prints the resolved paths as JSON; ok: true means the real claude was found:
freeai claude doctor
{
"ok": true,
"realClaudePath": "/usr/local/bin/claude",
"configPath": "~/.freeai/claude/config.json",
"shell": "zsh",
"rcPath": "~/.zshrc"
}
Watch it live — open a project and ask Claude Code to do something that takes a few seconds:
claude
- While Claude Code is thinking or running tools, a subtle
ad·line appears in the status bar. - It’s a clickable link — opening it counts as a click (worth 50× an impression).
- The moment Claude Code finishes and waits for you, the line disappears.
- After 5 continuous seconds of activity, one impression is recorded — and 50% of its value becomes your credit balance.
Confirm it credited your device — the first run creates a device credential at ~/.freeai/device.json. After a session with a few seconds of activity, read it and check your earnings straight from the API:
# needs `jq`; the device file holds your deviceId + deviceKey
BASE="https://wpjfhezklpczxzocgxsb.supabase.co/functions/v1/api"
DID=$(jq -r .deviceId ~/.freeai/device.json)
DK=$(jq -r .deviceKey ~/.freeai/device.json)
curl -s "$BASE/v1/me/earnings?deviceId=$DID&deviceKey=$DK"
{
"revenueShare": 0.5,
"earnedUsd": 0.0025,
"paidOutUsd": 0,
"redeemedUsd": 0,
"balanceUsd": 0.0025
}
A nonzero earnedUsd (and matching balanceUsd) means the impression landed server-side and your 50% share is in the ledger.
Redeem what you’ve earned anytime on the user login page — the terminal client shares the same device-credit balance as the browser extension.
How it stays out of your way
- It never edits the real Claude. No changes to the
claudebinary, the npm shim, or your persistent~/.claude/settings.json. The ad is delivered through a per-session, temporary--settingsfile using Claude Code’s documentedstatusLinesurface. - It chains, never clobbers. If you already use a custom status line, yours still runs — the ad line is added above it.
- It fails open. If anything — network, config, ad fetch — doesn’t work, the wrapper just runs plain
claude. You’re never blocked. - It reads none of your prompts. Activity is detected only from the structure of Claude Code’s transcript (is it mid-response?), never its contents.
Not seeing an ad?
The ad path stays silent by design, so use these two checks to see what’s happening:
1. Probe the backend — doctor runs the full ad pipeline and ends with an adsWillServe verdict:
freeai claude doctor
{
"backend": "https://…supabase.co/functions/v1/api",
"steps": {
"config": { "ok": true, "serving": true },
"ads": { "ok": true, "count": 1, "first": "Plan your next sprint faster" },
"device": { "ok": true },
"clickIntent": { "ok": true }
},
"adsWillServe": true
}
"error": "fetch failed"onconfig/ads→ your network can’t reach the API (firewall, proxy, or offline)."count": 0→ no ad is in rotation right now; nothing to show.adsWillServe: false→ the failing step above is why no ad serves.
2. Trace a real run — set FREEAI_DEBUG=1 and watch why the wrapper did (or didn’t) inject an ad:
FREEAI_DEBUG=1 claude
If you see no freeai[debug] lines at all, the alias isn’t active — confirm with type claude (it should say aliased to freeai claude run), then re-open your shell.
Remember the ad only shows while Claude Code is actively working — it is hidden the moment it finishes and waits for you.
Opt out & uninstall
Skip ads for a single run without uninstalling:
FREEAI_DISABLE=1 claude
Remove the shell alias entirely (safe to run repeatedly):
freeai claude restore
Pointing at a local backend? By default the client talks to the production FreeAI API. Override it with FREEAI_BASE=http://127.0.0.1:8787, or a backendBaseUrl entry in ~/.freeai/config.json.
FreeAI is not affiliated with, endorsed by, or sponsored by Anthropic. “Claude” and “Claude Code” are trademarks of Anthropic. By installing you agree to the Terms; see how earnings are computed in the open-source backend.
← Back to FreeAI