@economico/cli
v0.32.0
Published
Agent-facing CLI for Economico — general ledger over a REST API. Pair with the hosted SKILL.md at https://economi.co/skill.md.
Downloads
1,633
Maintainers
Readme
@economico/cli
Agent-facing command line interface for Economico — the agent-native general ledger. Every command emits JSON on stdout (or a compact summary with --human), errors go to stderr with a non-zero exit, and request shapes mirror the OpenAPI spec at https://economi.co/openapi.json.
Pair this CLI with the canonical agent guide at https://economi.co/skill.md for the complete reference, the money model, idempotency rules, and the OAuth 2.1 flow for MCP agents.
Install
Persistent install (recommended for long-lived agents):
npm install -g @economico/cli
economico --versionEphemeral via npx (good for sandboxed agents and CI):
npx -y @economico/cli@latest <command>Requires Node 20+. Works on Linux, macOS, and Windows.
Sign in
Authentication is a single economico login. It runs the OAuth 2.1 authorization-code + PKCE flow: the CLI self-registers as a public client (RFC 7591 dynamic client registration) on first run, binds an ephemeral 127.0.0.1 loopback redirect, and opens your browser to /oauth/authorize.
economico login
# Opening browser for authorization (loopback http://127.0.0.1:<port>/cb)…
# → {"ok":true,"api_url":"https://economi.co","client_id":"…","expires_in":3600}New users sign up through the same browser flow — pick Create account on the login page; existing emails just log in. Email verification happens in the browser, so there is no OTP to copy into the terminal.
Access + refresh tokens are written to ~/.config/economico/config.json (mode 0600) and used — and silently refreshed — for every subsequent call.
Per-project credentials. Working on more than one company? economico login --local writes the tokens to ./.economico/config.json in the current directory (mode 0600) and adds .economico/ to your .gitignore instead of touching the global file. Any command run from that directory — or a subdirectory — auto-discovers the local config (walking up the tree like git), so each project stays signed in to its own business with no --config juggling.
Flags: --local (store credentials in ./.economico/config.json for this project), --server <url> (target a non-default deployment), --no-browser (print the authorization URL instead of opening it, for headless/SSH use), --port <n> (pin the loopback port), --human.
Configure
| Variable | Default | What it does |
| ---------------------- | ---------------------- | ------------------------------------------- |
| ECONOMICO_API_URL | https://economi.co | Point at a different deployment (overrides the saved apiUrl). |
| XDG_CONFIG_HOME | ~/.config | Base path for the config file. |
The config file holds the API URL, the dynamically-registered OAuth clientId, and the OAuth tokens (access + refresh). There is no long-lived API key. Its location is resolved in this order:
ECONOMICO_CONFIG_FILE(or the global--config <path>flag) — an explicit file, always wins.- A project-local
.economico/config.jsondiscovered by walking up from the current directory (created byeconomico login --local). - The global
$XDG_CONFIG_HOME/economico/config.json(mode 0600).
Commands
| Command | What it does |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| economico login | Sign in (or sign up) via the OAuth 2.1 browser flow; persists access + refresh tokens. |
| economico business update | Update the business profile: --name, --legal-entity-type, --jurisdiction, --description, --url (company website). Only the fields you pass change. |
| economico business verify-yc <link> | Verify your YC founder status with your YC verification link (https://www.ycombinator.com/verify/..., created at https://bookface.ycombinator.com/verify). Optional pricing benefit; accounts have full access from signup. Turns on YC founder pricing. |
| economico support file / list | File a support request (--kind support) or feature suggestion (--kind feature_suggestion) to the Economico team with --body (and optional --context JSON); returns a reference id. list shows what you've filed. |
| economico stripe connect / status / sync / disconnect | Connect the read-only Stripe App, inspect status, run deterministic backfill + reconciliation (global --scenario previews), or revoke access and erase stored tokens. |
| economico parties create / list / get / update / archive | Manage customers and vendors (CRM). |
| economico financial-accounts create / list / get / update / archive | Named cash accounts (bank accounts / wallets) mapped to a GL cash account; each holds its own balance (list shows balances). Pass --financial-account <id> to invoices pay / bills pay to route the cash leg. |
| economico payment-endpoints add / get / update / remove / add-method / remove-method | Payment identifiers (payto:// URIs or blockchain addresses) with priced in/out methods — on your own financial accounts, or stored as a counterparty's payment instructions. add-method attaches account-level collection methods (card / flow fee schedules). Pass --payment-endpoint <id> to invoices pay / bills pay (with optional --fee-amount / --fee-account-code) to say how the money moved and book the route fee. |
| economico payment-routes quote | Rank every eligible way to move an amount in or out by effective cost or speed. Pure computation — never moves money. |
| economico contracts create / list / get / set-status / amend / replace | Common Paper contract lifecycle (draft → offer → active → terminated/expired/rejected). amend records a new dated obligation version on the same contract; replace supersedes it with a fresh one. Prior versions retained. |
| economico obligations create / list / get | Billable obligations on a contract (one_off / recurring / usage / revenue_share — a basis-point rate on a ledger aggregate via --rate-bps / --basis / --free-tier-floor), each tied to a GL account. list --as-of <YYYY-MM-DD> returns the obligation set live on a date. |
| economico invoices create / list / get / send / void / pay | Full invoice lifecycle: draft, send, void with reversing journal, record payment. |
| economico bills receive / list / get / approve / pay / void | Vendor bills (accounts payable): draft on receive, post the AP/expense journal on approve, then pay or void. |
| economico revenue summary --from <date> --to <date> | Per-currency invoiced / paid / outstanding / recognized for the period. |
| economico revenue recognition [--party-id\|--contract-id\|--invoice-id] | Deferred-revenue schedule: per annual-subscription invoice — deferred total, recognized to date, remaining, month-by-month plan. |
| economico revenue recognize | Post the due monthly recognition journals (Dr Unearned Revenue / Cr revenue). Idempotent; also runs on a platform schedule. |
| economico captable class create / class list / issue / safe / show | Cap table (share ledger): share classes, share issuance (Dr cash / Cr owners equity), SAFEs (Dr cash / Cr SAFE financing), and the cap-table view. |
| economico accounts list --currency USD | List the chart fields to pass to journals create (code, currency, and any sub-key). |
| economico journals create / get / void | Post, fetch, and reverse raw double-entry journals (bypasses the invoice/bill abstraction). |
| economico balances | Current balances for all postable accounts. |
| economico reports balance-sheet / income-statement | Period-end financial reports. |
| economico reports saas-metrics | SaaS metrics for a month: point-in-time (ARR/MRR/ACV, gross margin, burn, runway, CAC) plus month-over-month history (net-new-ARR waterfall, NRR/GRR, logo churn, burn multiple, Rule of 40, LTV); --trend adds 12-month series. |
| economico reports default-alive | Paul Graham's default-alive test: at current cash, revenue, growth, and burn, do you reach profitability before running out of money? Shows the verdict and, when default dead, the growth or cost cut that flips it; --cash/--revenue/--expenses/--growth override any figure for a what-if, --exclude-credits computes burn gross of startup credits. |
| economico oauth clients create / list / revoke | Register OAuth 2.1 clients for MCP agents that prefer RFC 7523 private_key_jwt. |
| economico skill | Print the canonical agent guide (skill.md) served by the connected deployment. |
| economico agent-context | Emit a versioned JSON map of every command, flag, type, and enum — for agents that introspect before calling. |
Every command accepts --human for a compact summary instead of raw JSON.
For machine introspection, economico agent-context returns the full command surface as versioned JSON (a schema_version field flags breaking shape changes), and economico <command> --help works at every level.
Output
Default JSON, pretty-printed:
economico parties list
# [
# {
# "id": "…",
# "iri": "did:web:acme.com",
# "name": "Acme",
# "url": "https://acme.com",
# ...
# }
# ]Human mode (flatter, no JSON parens):
economico balances --human
# USD:Cash: 12500
# USD:AR: 3200
# ...Errors go to stderr as a structured envelope and exit non-zero:
{
"error": "party not found",
"status": 404,
"body": { "detail": "party not found" }
}Exit codes
| Code | Meaning |
| ---- | ------- |
| 0 | Success. |
| 1 | Local error — bad flags, unknown command, invalid --enum value, or a client-side failure (e.g. malformed --lines JSON, no saved token). Diagnostic on stderr. |
| 2 | API error — the server returned a non-2xx response. The stderr envelope carries the HTTP status and body. |
Invalid values for enum flags (--role, --status, --type, --channel, --interval) are rejected before any request, and the error names the allowed set.
Money model
- Amount: always an integer in minor units (cents for USD). Never floats.
- Currency: the books are USD-only —
USD, a USD-pegged stablecoin shorthand (USDC,USDT,PYUSD), or the full CAIP-19 of a USD-pegged token (eip155:8453/erc20:0x833…). Convert a foreign-currency document to USD at the transaction-date rate and keep the original in--original-currency/--original-amount(invoices, bills, receipts) or the journal line'sasset/asset_amount. - Idempotency: payment recording is safe to retry. On-chain payments dedupe on
(chain_id, tx_hash, log_index, currency, settlement_address, amount); off-chain on(invoice_id, idempotency_key).
Examples
Draft a $2000 invoice for 10 hours of consulting and send it by email:
PARTY_ID=$(economico parties create --name "Acme" --url https://acme.com | jq -r .id)
economico invoices create \
--party-id "$PARTY_ID" \
--amount 200000 \
--currency USD \
--due 2026-06-01 \
--memo "March consulting" \
--external-id "INV-2026-0042" \
--document-url "https://files.example/invoices/INV-2026-0042.pdf" \
--lines '[{"description":"Consulting","quantity_micros":10000000,"unit_price_minor":20000}]'
economico invoices send <invoice_id> --channel emailRecord an on-chain stablecoin payment:
economico invoices pay <invoice_id> \
--amount 200000 \
--currency USDC \
--tx-hash 0xdeadbeef… \
--chain-id eip155:8453 \
--log-index 0Put a customer under contract, then define a recurring subscription obligation against a revenue account:
CONTRACT_ID=$(economico contracts create \
--party-id "$PARTY_ID" \
--role customer \
--currency USD \
--msa-url https://commonpaper.com/standards/cloud-service-agreement/2.0 \
--order-form-url https://acme.example/orders/123 | jq -r .id)
economico obligations create \
--contract-id "$CONTRACT_ID" \
--type recurring \
--interval monthly \
--name "Pro plan" \
--amount 50000 \
--account-code 4110 # Subscription RevenueReceive a vendor bill, approve it (which posts the expense/AP journal), then pay it:
VENDOR_ID=$(economico parties create --name "Hosting Co" --url https://hosting.example | jq -r .id)
BILL_ID=$(economico bills receive \
--party-id "$VENDOR_ID" \
--amount 12000 \
--currency USD \
--due 2026-07-01 \
--external-id "HOSTING-9981" \
--document-url "https://hosting.example/receipts/9981.pdf" \
--lines '[{"description":"Compute","quantity_micros":1000000,"unit_price_minor":12000}]' | jq -r .id)
# Later, locate that bill again by the vendor's own number:
economico bills list --external-id "HOSTING-9981"
economico bills approve "$BILL_ID"
economico bills pay "$BILL_ID" --amount 12000 --currency USD --idempotency-key bill-12000-julRead more
- Agent guide (canonical): https://economi.co/skill.md
- OpenAPI 3.1 spec: https://economi.co/openapi.json
- MCP endpoint (alternative to the CLI for native MCP clients): https://economi.co/mcp
License
MIT
