CLI
npx leaseclock show leases lists leases, and npx leaseclock do Lease.renew 4b --endsOn 2027-11-30 renews one. Your team and your customers' scripts use the same commands, with the same permissions as the app.
In short
$npx leaseclock show leases --status activeUNIT RENTER ENDS ON 4B dana.whitfield@example.com 2026-11-30 2A marcus.bell@example.com 2026-12-15 7C lena.okafor@example.com 2027-01-31 3D tomas.rivera@example.com 2027-03-31 1F owen.price@example.com 2027-06-30 $npx leaseclock do Lease.renew 4b --endsOn 2027-11-30Preview Lease 4B endsOn 2026-11-30 → 2027-11-30 Renew it? y ✓ Renewed lease 4B. It now ends 2027-11-30. Undo: npx leaseclock undo Lease.renew 4b $
- The CLI ships in the
leaseclockpackage on npm, under your product's name.npx leaseclockruns it with nothing to install. showreads records. The words after it are the API path, soshow leases 4breturns whatGET leaseclock.com/api/leases/4breturns.doruns a Verb. Every Verb in your definition is a command, and every Noun also hascreateandupdate.- Each
dopreviews the change and asks before it runs, andundoreverses it. - A token carries its owner's role and workspace, so the CLI can do exactly what that person can do in the app.
Leaseclock in a terminal
Priya Shah, the leasing coordinator at Northgate Rentals, runs Leaseclock from her terminal. She checks which leases are active and renews Dana Whitfield's lease on Unit 4B for another year.
$ npx leaseclock show leases --status active
UNIT RENTER ENDS ON
4B dana.whitfield@example.com 2026-11-30
2A marcus.bell@example.com 2026-12-15
7C lena.okafor@example.com 2027-01-31
3D tomas.rivera@example.com 2027-03-31
1F owen.price@example.com 2027-06-30
$ npx leaseclock do Lease.renew 4b --endsOn 2027-11-30
Preview Lease 4B endsOn 2026-11-30 → 2027-11-30
Renew it? y
✓ Renewed lease 4B. It now ends 2027-11-30.
Undo: npx leaseclock undo Lease.renew 4bThe leases come back sorted by end date, because endsOn is indexed in Lease.mdx. The same renewal is a button in the app, a POST in the API and a do call in MCP, and it lands in the lease's history the same way from each.
What each definition line makes
Each command, flag and help line comes from a line of Leaseclock's definition.
In Lease.mdx | In the CLI |
|---|---|
name: Lease | show leases, show leases 4b and do Lease.… |
endsOn: { type: date, required: true, indexed: true } | Lists sorted by end date, and the --endsOn.before and --endsOn.after filters |
status: { type: choice, options: [{ key: active }, { key: ended }] } | --status active, with any other value rejected before the request is sent |
input: { endsOn: { says: the new end date, type: date, required: true } } | do Lease.renew <lease> --endsOn <date>, which stops when --endsOn is missing |
from: [active] | renew runs only on an active lease |
does: Move the end date forward | The first line of help Lease.renew, and says gives the flag its description |
$ npx leaseclock help Lease.renew
Lease.renew: Move the end date forward
npx leaseclock do Lease.renew <lease> --endsOn <date>
--endsOn <date> the new end date (required)
Runs on: activeSign in
npx leaseclock loginlogin opens Leaseclock's sign-in in the browser and stores the token on the machine. Every later command uses it.
Scripts and CI read the token from LEASECLOCK_TOKEN instead. Create one in the Leaseclock app under Settings → API keys. It carries the role of the person who created it, and it can be revoked there at any time.
Read records
show takes a Noun's plural name, and optionally one record's id.
$ npx leaseclock show leases 4b
Lease 4B
unit 4B · Alder Court
renter dana.whitfield@example.com
endsOn 2027-11-30
status active
Verbs renew, endAny field filters by its value: --status active, --unit 4b. An indexed field also takes .before and .after:
npx leaseclock show leases --status active --endsOn.before 2027-01-01A list returns up to 200 records. Pass --limit for fewer, or --all to page through every match.
Run a Verb
do takes Noun.verb, the record's id and the Verb's input as flags.
npx leaseclock do Lease.renew 4b --endsOn 2027-11-30
npx leaseclock do Lease.end 7c
npx leaseclock do Unit.create --label 6E --building "Birch House"
npx leaseclock do Lease.update 2a --renter m.bell@example.comBefore anything changes, do prints the preview and asks to confirm. --preview prints it and stops. When a Verb cannot run, the CLI says why, links the fix and exits non-zero:
$ npx leaseclock do Lease.renew 5a --endsOn 2027-09-30
✗ Lease 5A is ended, and renew runs only on an active lease.
See https://leaseclock.com/docs/lease#renewUndo and history
Every do is recorded as a version of the record. undo reverses the last run of a Verb, and history lists every change with who made it and from where.
$ npx leaseclock history leases 4b
2026-10-25 14:02 renew endsOn 2026-11-30 → 2027-11-30 priya@northgaterentals.com CLI
2025-11-12 09:40 create priya@northgaterentals.com App
$ npx leaseclock undo Lease.renew 4b
Preview Lease 4B endsOn 2027-11-30 → 2026-11-30
Undo the renewal? y
✓ Lease 4B ends 2026-11-30 again.Use it in scripts
--json prints each record on its own line, as the same JSON the API returns. --yes confirms without a prompt. Without a terminal to confirm in, do prints the preview and stops, so a script changes nothing unless it passes --yes.
# Who to call this week: every active lease ending before the new year.
npx leaseclock show leases --status active --endsOn.before 2027-01-01 --json \
| jq -r '.renter'dana.whitfield@example.com
marcus.bell@example.comIn CI, pass the token as a secret:
- run: npx leaseclock show leases --status active --endsOn.before 2027-01-01 --json
env:
LEASECLOCK_TOKEN: ${{ secrets.LEASECLOCK_TOKEN }}Who can run what
The CLI checks the same roles as the app, on every command.
- Your customers see only their own workspace. A token from Northgate Rentals lists Northgate's leases and nobody else's.
- A viewer can
showandhistory. A member, admin or owner can alsodoandundo. - Your team signs in as Leaseclock's own admins and picks a customer with
--workspace, as innpx leaseclock show leases --workspace northgate-rentals. - Offer limits hold in the CLI too. On Leaseclock Pro,
do Unit.createstops at 200 Units with a link to upgrade.
Commands
| Command | What it does |
|---|---|
login | Signs in through the browser and stores the token |
show <nouns> [id] | Lists records, or shows one |
do <Noun.verb> [id] [--input value] | Runs a Verb, after a preview |
undo <Noun.verb> <id> | Reverses the last run of that Verb on that record |
history <nouns> <id> | Lists every change to a record |
help [Noun.verb] | Lists every command, or explains one Verb |
| Flag | What it does |
|---|---|
--json | Prints records as the API's JSON, one per line |
--yes | Confirms without a prompt |
--preview | Prints the preview and runs nothing |
--workspace <slug> | Picks a customer's workspace, for your team |
--limit <n>, --all | Sets how many records a list returns |
A Test key reaches the Test copy, with its own records and Stripe's test mode, and a Live key reaches Live, so the same command works in both.
Questions
Does anyone need to install it?
No. npx leaseclock downloads and runs it. Anyone who uses it daily can run npm i -g leaseclock and type leaseclock instead. The package also holds the SDK.
How is it different from npx saas.dev?
npx saas.dev is for you: it creates your product and pushes its definition. npx leaseclock is your product's own CLI, for your team and your customers to work with records. Nothing in it names SaaS.Dev.
What happens when I add a Verb?
Push the file and the Verb is a command. Add pause to Lease, and npx leaseclock do Lease.pause 4b runs on the next call, with its own help line, preview and undo.
Should my customers' agents use the CLI or MCP?
MCP. An agent connected to leaseclock.com/mcp gets search, fetch and do as tools, with no shell to run. The CLI is for people at a terminal and for scripts. See MCP.