2. Start the REPL

August 10, 2026 · View on GitHub

morning-cli banner

PyPI version Python versions CI status License Downloads

morning API v2  |  OAuth 2.0 auth  |  Interactive REPL  |  Onboarding wizard  |  JSON envelopes for AI agents  |  Hebrew error messages

Built by JangoAI using the cli-anything methodology  |  README בעברית


Why this exists

I'm Maor, a solo developer running JangoAI — a small AI automation studio in Israel. I use morning's API daily for my own business and my clients', and I got tired of writing the same httpx + JWT boilerplate in every project. So I built a proper CLI around it.

This started as a personal tool, but there's no reason to keep it private — if you work with morning's API, you'll save time with this. I'm sharing it with the Israeli dev community because I think we deserve better tooling for our local platforms. If it helps you, I'd love to hear about it.

v0.2.0 — API v2 ready. morning rewrote their developer docs at developers.morning.co (OpenAPI 2.0.0): OAuth 2.0 token endpoint on dedicated IDP hosts, a new presigned-S3 expense upload flow, Basic-auth partners endpoints, and reference data staying on the shared cache host. This release tracks all of it, with automatic fallback to the legacy token endpoint where the new IDP isn't deployed. See the CHANGELOG.


Install

pip install morning-cli

Get started in 30 seconds

# 1. Run the interactive wizard — connects your morning account
morning-cli auth init

# 2. Start the REPL
morning-cli

# 3. Or use one-shot commands
morning-cli --json auth whoami
morning-cli --json document types --lang he
morning-cli --json client search
What does auth init look like?
  ╭──────────────────────────────────────────────────╮
  │       morning-cli                                │
  │       setup wizard                               │
  │                                                  │
  │       Connect your morning account.              │
  │       You'll be up and running in under a minute.│
  ╰──────────────────────────────────────────────────╯

  >>  Step 1/4  Choose environment
  ╭──────────────────────────────────────────────────╮
  │ Where do you want to connect?                    │
  │   [1]  sandbox      Safe testing, no real money  │
  │   [2]  production   Live business data           │
  ╰──────────────────────────────────────────────────╯
  Enter 1 or 2 [1]:

  OK  Step 1/4  Choose environment
  >>  Step 2/4  Get your API keys
  ╭─ Open in browser ────────────────────────────────╮
  │ https://app.greeninvoice.co.il/settings/developers/api
  │ Settings > Advanced > Developers > Create API Key│
  ╰──────────────────────────────────────────────────╯

  >>  Step 3/4  Enter credentials
    API Key ID:     xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    API Key Secret: (hidden as you type)

  >>  Step 4/4  Verify connection
  Connecting to morning API...

  ╭─ All set ────────────────────────────────────────╮
  │  Connected successfully!                         │
  │  Business   Your Business Name                   │
  │  Env        SANDBOX                              │
  │  Saved to   ~/.greeninvoice/credentials.json     │
  ╰──────────────────────────────────────────────────╯

Commands

Group Endpoints Highlights
authlocalinit (wizard), login, logout, whoami, refresh
sessionlocalshow, reset, history
business10 (legacy)list, current, get, update, numbering, footer, types, file-upload — removed from the v2 docs, still served
client8add, get, update, delete, search, assoc, merge, balance
supplier6add, get, update, delete, search, merge
item5add, get, update, delete, search
document13create, preview, get, search, close, open, download, types, statuses
expense13CRUD + open/close + upload (presigned-S3 flow) + drafts-search/draft-delete
payment3form, tokens-search, charge
partner3users, connect, disconnect (HTTP Basic)
tools4occupations, countries, cities, currencies — shared cache host, no auth

Usage examples

Create a proforma invoice (חשבון עסקה)

cat > /tmp/proforma.json <<'JSON'
{
  "description": "ריטיינר חודשי",
  "type": 300,
  "lang": "he",
  "currency": "ILS",
  "vatType": 0,
  "client": {"name": "Acme Ltd", "emails": ["ap@acme.com"], "country": "IL"},
  "income": [
    {"description": "שירותי ייעוץ", "quantity": 10, "price": 300, "currency": "ILS", "vatType": 0}
  ]
}
JSON
morning-cli --json document create --file /tmp/proforma.json

Search recent clients

morning-cli --json client search --data '{"page":1,"pageSize":10}'
morning-cli --json document download <document_id>

Upload an expense receipt (API v2 presigned-S3 flow)

morning-cli --json expense upload receipt.pdf          # new expense draft
morning-cli --json expense upload receipt.pdf --id <expense_id>   # attach to expense
morning-cli --json expense drafts-search               # parsed draft appears here

JSON output for AI agents

Every --json command returns a consistent envelope:

{"ok": true, "op": "document.create", "data": {"id": "...", "number": 12345}}

Errors include the morning errorCode and Hebrew errorMessage:

{"ok": false, "op": "document.create", "error": {"code": 1110, "message": "מחיר לא תקין.", "http_status": 400}}
Exit codeMeaning
0Success
1Unexpected internal error / aborted confirmation
2Usage error, local config error (e.g. missing credentials), or API error (4xx)
3Server error (5xx) / network failure

Success envelopes go to stdout; error envelopes go to stderr (agents: capture both streams).

Common morning API error codes
CodeMeaning
401Token expired (CLI auto-refreshes)
1003No active business in the account
1006Subscription expired
1007Missing permission
1012Feature requires a higher plan
1110Invalid price in a line item
2002Wrong email or password
2102Can't add more businesses on this plan
2403Document type not supported for this business type

Environment variables

VariablePurposeDefault
MORNING_API_KEY_IDAPI key ID
MORNING_API_KEY_SECRETAPI key secret
MORNING_ENVsandbox or productionsandbox
MORNING_BASE_URLOverride the core REST base URLauto
MORNING_GATEWAY_URLOverride the OAuth IDP + file-upload hosts (proxies/custom deploys)auto
MORNING_AUTH_MODEauto (OAuth with legacy fallback), oauth (no fallback), legacy (skip IDP)auto

How auth works (v0.2.0+): the CLI obtains a 1-hour access token via OAuth 2.0 client_credentials from the morning IDP (POST /idp/v1/oauth/token on api.morning.co / api.sandbox.morning.dev), and falls back to the legacy POST /account/token automatically if the IDP isn't available for your environment. Refresh on 401 is automatic either way. Reference data (tools group) is served from the shared cache.greeninvoice.co.il host, no auth needed.


Tests — 85 tests, including 23 live E2E (sandbox or production via MORNING_E2E_ENV)
pip install -e ".[test]"

# Unit tests — no network
pytest cli_anything/greeninvoice/tests/test_core.py -v

# Full suite with live sandbox
export MORNING_SANDBOX_ID=<your-id>
export MORNING_SANDBOX_SECRET=<your-secret>
CLI_ANYTHING_FORCE_INSTALLED=1 pytest cli_anything/greeninvoice/tests/ -v

Coverage:

  • 52 unit tests — credentials + per-service host resolution, OAuth token acquisition (camelCase/snake_case shapes, legacy fallback, unreachable-host fallback, TLS errors surfaced, no-fallback on bad keys, MORNING_AUTH_MODE overrides, RFC 6749 error strings), wizard verification (gateway override, core-API rejection propagates), Basic-auth partners, presigned-S3 upload flow (field ordering, no-auth on S3), session locking, payload parsing
  • 10 offline E2E — help, version, error envelopes, --json auth init stream purity, REPL smoke, env-var CI path
  • 23 live sandbox E2E — read-only smoke per resource group, paginated searches, item/supplier mutation round-trips, invoice lifecycle, proforma preview with Hebrew content, expense file upload
  • 3 real bugs caught during development (late-binding, type 305 gate, Tools host/locale)
For AI agents — SKILL.md auto-discovery

morning-cli ships a SKILL.md file auto-discovered by the REPL banner and Claude Code / Cursor. It contains:

  • Full command reference with examples
  • Error code table
  • Agent-specific guidance (always use --json, sandbox defaults, token refresh)
  • Non-interactive auth init for CI

If you're an agent reading this, start with the SKILL.md.

Methodology — cli-anything 7-phase SOP

Built following the cli-anything 7-phase pipeline:

  1. Codebase analysis — parsed the Apiary spec into a 66-endpoint map
  2. Architecture — REPL-first, --json envelopes, session locking, sandbox-first
  3. Implementation — PEP 420 namespace package cli_anything.greeninvoice
  4. Test planning — TEST.md written before tests
  5. Test implementation — unit + live E2E
  6. Test documentation — results appended to TEST.md
  7. PyPI publishingpip install morning-cli

Full SOP: GREENINVOICE.md


Contributing

PRs welcome! Run the tests before submitting:

pip install -e ".[test]"
pytest cli_anything/greeninvoice/tests/test_core.py -v

See open issues for good first contributions.


JangoAI — AI automation for Israeli businesses

Website · GitHub · morning API docs

MIT License · morning-cli is a community project and is not officially affiliated with morning Ltd.