Command Line
The lumber command reads your logs in the terminal: the newest ones, a search, or a live tail. Like the Lumber app, it decrypts them on your own machine, so Lumber's servers still hold only ciphertext. It can also hand your logs to an AI agent: see AI Agents.
It only reads. Apps, API keys and notes are made in the Lumber app.
Requirements
- macOS. Your account key is kept in the Keychain; Linux and Windows are planned.
- Node.js 20 or later
- A Lumber account, and a phone or Mac where Lumber already has your account key, to show the code that links your Mac
Install
npm install -g @infinitetoken/lumber-cli
The package is scoped: the unscoped lumber and lumber-cli packages on npm aren't Lumber's.
Sign in and link your Mac
lumber login
- Enter your Lumber email and password.
- Open Lumber on a phone or Mac that has your account key. Your phone gets a notification, and the Mac app asks when you switch to it (or open Account > Link another device). Tap Show Code.
- Type the 7-digit code it shows, like
482 9138, atlumber's Code prompt. A typo is caught before it's sent. - Your other device checks the code and sends your account key.
lumbercan then read every app you can.
The request lasts 10 minutes. A wrong code ends it, so run lumber login again for a new one.
Linking works the way a new phone links (see Linking a device): your Mac makes a one-time key pair, and your other device encrypts your account key to its public half only once the code proves which device is asking. The code never goes through Lumber's servers, so they can't choose where your account key goes. Never give the code to anyone, even someone who says they're from Lumber.
Your session and account key are kept in your login Keychain, in an item named "Lumber CLI". The session renews itself each day you use lumber, so it only ends after 30 days unused, and signing in again then, as the same person, needs no new link. lumber logout removes both.
Commands
| Command | What it does |
|---|---|
lumber status | Who's signed in, and which apps your Mac can read |
lumber apps | Your apps, and how many days of logs each one's plan keeps |
lumber logs [app...] | The newest logs, oldest at the bottom |
lumber tail [app...] | Follow new logs as they arrive |
lumber mcp | Serve your logs to an AI agent (see AI Agents) |
lumber login, lumber logout | Sign in and link your Mac, or sign out and remove its account key |
lumber help | Every command, or lumber logs help for one |
Apps are names, in any case, or ids. Naming none means every app.
Finding logs
lumber logs # the newest 100 logs from every app
lumber logs Billing -l error -s 2h # one app's errors and fatals from the last two hours
lumber logs -g "card declined" -n 20 # the newest 20 logs mentioning "card declined"
lumber logs Billing -s yesterday -v # since yesterday, with each log's fields under it
| Option | Meaning |
|---|---|
-l, --level | One level for that level and above (warn is warn, error and fatal), or a list for exactly those (info,warn). The levels are debug, info, warn, error and fatal. |
-s, --since, -u, --until | An age (15m, 2h, 3d), a day (2026-10-29, today, yesterday), or an ISO time |
-g, --grep | Text to look for, ignoring case, in the message, request and trace IDs, context and metadata |
-n, --lines | How many logs, 100 unless you say |
-v, --verbose | Each log's id, request and trace IDs, context and metadata under it |
--json | One JSON object per log (see Scripts) |
Each log is one line, in your local time:
2026-10-29 14:02:11 WARN Payment retry scheduled
2026-10-29 14:02:13 ERROR Payment failed: card declined
Lumber's servers can filter by level and time, since those stay readable to them (see What the server sees). Text is another matter: the server only has ciphertext, so lumber searches on your Mac, decrypting as it reads back through your logs, up to 20,000 of them. Narrow with --since to search further back.
Following logs
lumber tail Billing -l warn
tail shows the last 10 logs (-n changes that), then each new one as it arrives. Apps on Dev and Pro plans stream over Lumber's live connection; for apps on Hobby, tail checks every 5 seconds. If the connection drops, or your Mac sleeps, it catches up on what it missed when it's back.
In a terminal, the connection's state stays on a line under the logs, such as Following Billing · live. -q hides it.
Scripts
--json prints one JSON object per line, with id, app, appId, level, time, message, and requestId, traceId, context and metadata when a log has them. A log your Mac has no key for has a null message and locked: true.
# Billing's most common errors today
lumber logs Billing -l error -s today -n 1000 --json | jq -r .message | sort | uniq -c | sort -rn
Piped, or with --json, the output is plain text, with no colors or spinners.
Colors
lumber takes the Lumber app's colors: spinners, help and prompts in the accent you picked on the app's Account screen, levels in their colors, and a square in each app's color before its name.
Limits
- macOS only, for now.
- It only reads: apps, API keys, notes and flags are made in the Lumber app.
- An app you've just been given access to shows as locked until someone who has its key shares it with you, as in the app (see Sharing with your team).
helpanywhere on the command line shows help, solumber logs -g helpprints help rather than searching. Search for-g Helpinstead: the match ignores case.