Month-end has a rhythm to it: total the hours, reconcile the money, chase the invoices, file the numbers. If you already live in a terminal, clicking through screens to do that is the slow way. The command-line client (@ceum/cli) drives the same operations as the app — so the whole routine becomes a handful of commands you can read back next month, or hand to cron.
This walkthrough follows one concrete job — closing out a month — from a blank shell to a report you can file. The setup in step 1 is a one-time cost; steps 2 and 3 are the routine you'll actually repeat.
The goal
Turn "it's the end of the month" into a short, repeatable sequence: pull the month's tracked time and transactions in a format a machine can read, shape it into the summary you need, and write any corrections back — scriptably, so next month is one command.
1. Install and authenticate — once
The CLI is a small binary you install from npm:
$ npm install -g @ceum/cli # installs the `ceum` command (Node.js 22+)
It authenticates with an MCP token, the same token that powers the MCP integration. Mint one in the app under Settings → Integrations, then sign in:
$ ceum auth login # paste the token (starts with ceum_)
Signed in. 42 tools available under this token.
The token is stored with 0600 permissions in your config directory. For a scheduled job that shouldn't touch disk, pass it through the environment instead — ideal for cron or CI:
$ CEUM_TOKEN=ceum_… ceum invoices list
Keep separate workspaces apart with named profiles (ceum auth add work, then ceum --profile work …). The command surface is derived live from what your token can do, so ceum --help always shows exactly the resources and actions available to you.
2. Fetch a month of data — in a format you can use
Every list command is resource-first (ceum <resource> <action>) and takes -o to choose an output. The default text tabulates nicely for reading; the machine formats — json, csv, ndjson — are byte-clean for piping.
Start with the headline number. time-entries aggregate totals tracked time over a filter set and can group it:
$ ceum time-entries aggregate \
--start-date 2026-07-01 --end-date 2026-07-31 \
--group-by project -o json
That returns the month's total seconds and a per-project breakdown. To pull the underlying rows for a spreadsheet, list them straight to CSV — and use --all to walk past the per-request page cap and merge every page:
$ ceum time-entries list --start-date 2026-07-01 --end-date 2026-07-31 \
--all -o csv > july-time.csv
$ ceum transactions list --all -o csv > july-transactions.csv
Two touches make the output tighter: --columns picks exactly the fields you want, and a saved preset captures a filter set so you don't retype it:
$ ceum transactions list --columns date,desc,amount,type,client
$ ceum presets save transactions month --type expense # save once
$ ceum transactions list --preset month -o json # reuse (explicit flags win)
3. Shape it, then push corrections back
Because only command output goes to stdout — prompts, progress, and errors all go to stderr — pipelines stay clean. That means jq and friends work exactly as you'd expect:
$ ceum invoices list -o json | jq '.[] | select(.status=="overdue") | .invoiceNumber'
$ ceum time-entries aggregate --group-by tag -o json \
| jq -r '.groups[] | [.key, .totalSeconds/3600] | @tsv'
The pipe runs both ways. When the month-end includes writing data back — recording a batch of expenses, say — feed rows from a file or stdin to a bulk-create command; the input is auto-detected (JSON array, single object, NDJSON, or CSV) and chunked to the server's 50-per-request cap:
$ ceum transactions bulk-create --file july-expenses.ndjson
$ jq -c '.[]' corrections.json | ceum transactions bulk-create --stdin
Now the whole thing is a script. Exit codes encode the failure class (0 ok, 2 usage, 3 auth, 4 forbidden, 5 tool error, 6 network, 7 config), so a cron job can tell a network blip from a bad token and act on it rather than failing silently.
What you end up with
A month-end that's a file you run, not a screen you click through: authenticate once, pull the month in JSON or CSV, reshape it with tools you already know, and write the result back — the same operations the app performs, wired into your shell and your scheduler.
Prefer to stay in the app but keep the keyboard-driven speed? The in-app command palette runs the same command grammar from a panel inside Ceum. And once the numbers are out, See where your time actually goes and From tracked work to a paid invoice pick up where the export leaves off.