Skip to main content

Aegro CLI

Command-line interface for the Aegro agricultural management API.

Python 3.11+ PyPI License: MIT


Install

# pipx (recommended)
pipx install aegro

# uv
uv tool install aegro

# Homebrew (macOS)
brew tap aegro/tap
brew install aegro
# Windows — pipx (recommended)
pipx install aegro

# Windows — uv
uv tool install aegro

# Windows — pip
pip install aegro

Credentials are stored in %USERPROFILE%\.aegro\ (outside AppData on purpose: packaged apps like Claude Desktop and Store Python run under MSIX filesystem virtualization, which would silently redirect AppData writes to a per-app shadow folder). Files from the previous location (%LOCALAPPDATA%\aegro\) are migrated automatically on first run.

WSL: Inside WSL, follow the Linux instructions. WSL and Windows credentials are stored separately — do not mix installations.

OneDrive/Dropbox: Avoid pointing AEGRO_CONFIG_DIR to cloud-synced folders, as file locking may cause intermittent errors.

For development:

git clone https://github.com/aegro/tool-aegro-cli.git
cd tool-aegro-cli
uv sync
uv run aegro --help

Quick Start

# 1. Authenticate — opens the browser for Aegro login (email/password, OTP or Google)
aegro auth login

# Alternative: static API key (CI, agents, fallback)
aegro auth login --farm-name "Fazenda Sul" --api-key "aegro_abc123..."

# 2. Select a farm
aegro farms list
aegro farms select "Fazenda Sul"       # persists to state.json (global per machine)

# Per-command farm — preferred with parallel sessions (one per farm), because
# one session's `farms select` retargets the others
aegro crops list --farm "Fazenda Sul"
aegro crops list --farm farm::abc123   # key: opaque, stable, no quoting needed

# 3. Start working
aegro crops list --start-date 2025-01-01 --end-date 2025-12-31
aegro financial installments --status NOT_PAID
aegro stock items --output table

Commands

Group Commands Domain
auth login, status, logout Authentication
farms list, select, info Farm management
crops get, list, prorate, harvest-discounts, prorates, glebes Harvest management
activities get, list, plan, realizations, get-plan, get-realization, create-plan Activity planning
financial bill, installment, installments, create-bill, update-bill, closes, realize, settle, category-usage, migrate-category (plan/apply/verify) Accounts payable/receivable, incluindo troca de categoria em massa
stock item, location, items, locations, logs, log, transfer, entry, removal Inventory
elements get, list, create-defensive/fertilizer/item/seed/service, set-categories Inputs/supplies
assets get, list, create-machine/vehicle/garner/immobilized/pivot/weather-station Equipment
fuel-supplies get, list, create, update Fuel management
maintenances get, list, create, update Maintenance records
harvest-logs get, create Harvest records
bank-accounts get, list, create Bank accounts
bank-reconciliation import-ofx, entries, candidates, confirm, ignore, undo, history, accounts, clear-pending Bank reconciliation (OFX × financeiro; requires OAuth)
companies get, list, create Suppliers/vendors
fin-categories get, list, create, subcategories Chart of accounts
catalogs list, element-keys, elements Catalog lookups
tags get, list, create Tags/labels
weather get, create Weather data
purchase-orders get, list, create Purchase orders
glebes get, list Farm fields
crop-glebes get, list Crop fields

Output Formats

All commands support three output formats:

aegro crops list --output json    # JSON (default, for LLMs/scripts)
aegro crops list --output table   # Rich table for humans
aegro crops list --output csv     # CSV export

Safe Mode for Mutations

Agents and automation should enable safe mode before running workflows that may create, update, delete, realize, transfer, enter, or remove data:

export AEGRO_SAFE_MODE=1
aegro purchase-orders create ... --dry-run   # Preview request; no API mutation
# Execute after validating the payload. The farm must be explicit in safe mode
# (see below) — `--execute` on its own is refused.
aegro purchase-orders create ... --execute --farm "Fazenda Sul"

--dry-run prints the target farm (plus farmSource, where that farm came from), method, endpoint, payload, and local warnings without calling the Aegro API. With AEGRO_SAFE_MODE=1, mutating commands are blocked unless --execute is passed. List/filter/get commands continue to work.

Safe mode also requires writes to name their farm explicitly. If the active farm came from state.json (written by farms select, global per machine and shared by every session), --execute fails with IMPLICIT_FARM_BLOCKED (exit 4):

export AEGRO_SAFE_MODE=1
aegro tags create --name Plantio --relation-type CROP --execute
# → IMPLICIT_FARM_BLOCKED: repeat with --farm "Fazenda Sul"
aegro tags create --name Plantio --relation-type CROP --execute --farm "Fazenda Sul"

This exists because parallel sessions — one per farm — used to overwrite each other's farms select, silently retargeting writes at the wrong farm. --farm is per-invocation, so it cannot race.


Usage Examples

Human workflow

# Morning overview
aegro farms select "Fazenda Norte"
aegro crops list --output table
# Date windows come in pairs (--due-date-start needs --due-date-end)
aegro financial installments --status NOT_PAID --due-date-start 2025-03-01 --due-date-end 2025-03-31 --output table
aegro stock items --output table

# Register a fuel supply
aegro fuel-supplies create --asset-key K --date 2025-03-13 --quantity 150 --unit L --cost 900

# Check harvest
aegro harvest-logs get <key>

LLM/Agent workflow

# Agents use JSON output (default) for structured data
aegro crops list --start-date 2025-01-01 --end-date 2025-12-31
aegro activities list --crop-key <key>
aegro stock items
aegro financial installments --status NOT_PAID

AI Skills

The source of truth for public Aegro skills is the Aegro-owned Claude plugin repository aegro/skills. Internal harness skills live separately in the private aegro/skills-internal repository.

This CLI embeds a generated snapshot of aegro/skills in aegro/_skills/ for PyPI installs. Do not edit embedded skills directly; update aegro/skills and then run:

python scripts/sync-skills.py <version>
/plugin marketplace add aegro/skills
/plugin install aegro-skills@aegro-skills

Users who install the CLI from PyPI get the skills with:

pip install --upgrade aegro
aegro skills install

install reads aegro/skills and falls back to the snapshot embedded in the wheel only if the repository is unreachable. Pass --offline to require the snapshot and skip the network entirely.

The snapshot is a safety net — corporate networks that intercept HTTPS, GitHub being down, machines without access — not the source of truth. It is generated at build time and deliberately not tracked in git; a checkout produces it with python scripts/sync-skills.py <version>.

Staying up to date

aegro skills sync is the explicit form: it always reads the repository, and adds --ref, --prune and --dry-run. Unlike install, a network failure is an error rather than a silent fallback.

aegro skills sync              # install/update from the default branch
aegro skills sync --dry-run    # show what would change
aegro skills sync --ref v0.7.0 # pin to a tag or commit
aegro skills sync --prune      # also drop skills deleted upstream

Sync overwrites local edits to aegro-* skills and repairs partially broken ones — it makes the target directory match the repository. It records the commit it installed in .aegro-skills-sync.json, which aegro skills status reports as the provenance.

To keep an assistant current without anyone remembering to run it, wire it to a SessionStart hook in ~/.claude/settings.json (see docs/ev-cowork/settings.example.json). Use --quiet --offline-ok there so a session never fails or gets noisy because GitHub was unreachable:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [{ "type": "command", "command": "aegro skills sync --quiet --offline-ok" }]
      }
    ]
  }
}

Overrides: AEGRO_SKILLS_REPO, AEGRO_SKILLS_REF, AEGRO_SKILLS_PATH.

Behind a TLS-intercepting proxy

Corporate networks that inspect HTTPS re-sign traffic with their own root CA. The OS trusts it, but Python verifies against the bundled certifi CAs, so sync fails with self-signed certificate in certificate chain. sync retries with the OS trust store automatically, which is usually enough. If it still fails, point it at your network's root certificate:

export AEGRO_CA_BUNDLE=/path/to/corporate-root-ca.pem   # or SSL_CERT_FILE

aegro skills install needs no network at all and remains the offline fallback. Never disable certificate verification to work around this.

Claude Code's own plugin marketplace (autoUpdate) does the same job natively and is the better default when the assistant is Claude Code; sync covers other tools and environments where that is not available.

Domain skills (personas)

Skill Purpose
aegro-agronomo Agronomic domain — crops, fields, activities, harvests, weather, inputs
aegro-estoquista Stock domain — items, locations, movements, catalogs, elements
aegro-financeiro Financial domain — bills, installments, categories, bank accounts, companies
aegro-operacional Operational domain — farms, auth, tags, cross-domain orchestration
aegro-patrimonial Asset domain — machines, vehicles, fuel supplies, maintenances

Workflow skills

Skill Purpose
aegro-visao-geral Farm overview dashboard
aegro-fechamento-safra Crop season closing checklist
aegro-lancamento-financeiro Financial entry guide
aegro-conciliacao-bancaria Bank reconciliation (OFX × financeiro)
aegro-reconciliacao-estoque Stock reconciliation
aegro-monitoramento-pragas Pest monitoring
aegro-analise-rentabilidade Profitability analysis
aegro-cadastro-patrimonio Asset registration

Configuration

Authentication

Two authentication modes:

  • OAuth login (default)aegro auth login opens the browser for the regular Aegro login (email/password, e-mail code or Google). The CLI stores the user session (access + refresh token) and discovers the user's farms automatically. The session renews itself; no key handling needed.
  • API keyaegro auth login --api-key ... stores a static per-farm key. Best for CI/CD, scripts and agents.

API key resolution priority (when both modes have credentials for a farm, the API key wins):

  1. AEGRO_FARMS env var (JSON) — for CI/CD and scripts
  2. AEGRO_FARMS_FILE env var (path) — for Docker/K8s secrets
  3. Config directory (~/.config/aegro/ on Linux, ~/Library/Application Support/aegro/ on macOS, %USERPROFILE%\.aegro\ on Windows) — interactive setup via aegro auth login
# Option 1: Browser login (recommended for humans)
aegro auth login

# Option 2: Environment variable
export AEGRO_FARMS='{"Fazenda Norte": "aegro_key1", "Fazenda Sul": "aegro_key2"}'

# Option 3: Static API key (saves to OS-native config directory)
aegro auth login --farm-name "Fazenda Norte" --api-key "aegro_key1"

# Inspect the session (method, user, expiry, farms)
aegro auth status

# Remove local credentials (revokes the OAuth session server-side)
aegro auth logout             # everything
aegro auth logout --env staging   # one environment only

Active Farm Resolution

With credentials configured, the active farm is resolved from two sources, in this order:

  1. --farm flag — scoped to a single invocation, accepted by every API command
  2. state.json written by aegro farms select — global per machine

Use --farm when several sessions run in parallel, one per farm. Only the flag survives that: state.json is shared, so one session's farms select retargets every other session.

--farm accepts either the farm name (case- and accent-insensitive, so "fazenda sul" finds "Fazenda Sul") or the farm key (farm::...), which is opaque and stable — handy for avoiding shell quoting of names with spaces. An ambiguous name is rejected rather than guessed.

# Scope a single command to one farm, regardless of what any session selected
aegro assets list --farm "Fazenda Norte"
aegro assets list --farm farm::abc123

# Confirm which farm is active, where it came from, and each farm's key
aegro farms list    # 'source': "flag" | "state" | null, plus 'key'

AEGRO_ACTIVE_FARM was removed

Three ways to name the same thing was itself the source of the confusion it was meant to solve, so the env var is gone — --farm covers every case it did.

The removal is loud, not silent: while the variable is still set in the environment, API commands fail with ACTIVE_FARM_ENV_REMOVED (exit 4) instead of running. Ignoring it quietly would resolve the farm from state.json — a different farm from the one the variable names — which is exactly the accident --farm exists to prevent. Remove the variable and pass --farm instead.

Environment Variables

Variable Default Purpose
AEGRO_API_BASE_URL https://app.aegro.com.br Aegro API base URL
AEGRO_FARMS JSON map of farm name → API key
AEGRO_FARMS_FILE Path to JSON credentials file
AEGRO_CONFIG_DIR Override config directory path
AEGRO_SAFE_MODE Blocks mutating commands unless --execute; also requires the farm to come from --farm. Use --dry-run to preview
AEGRO_OAUTH_CLIENT_ID aegro-cli OAuth client id (AEGRO_OAUTH_CLIENT_ID_<ENV> for other envs)
AEGRO_NO_VERSION_CHECK 1 disables the outdated-version notice (no PyPI lookup)

Outdated-version notice

aegro --version and aegro auth status compare the installed version against PyPI and print one line to stderr when a newer release exists. Commands that fail with API_ERROR, UNEXPECTED or NOT_PERSISTED carry the same hint as an upgrade field next to error in the JSON on stderr — a contract error is very often a CLI that predates the fix.

The lookup runs at most once a day (cached under the config dir; once an hour after a failure), times out in 1.5s and fails silently: no network, no notice, no change in behaviour. A successful command never triggers it. Set AEGRO_NO_VERSION_CHECK=1 to switch it off entirely.

Updates are verified after they are written

fuel-supplies update, maintenances update and harvest-logs update re-read the record after a successful PATCH and compare it against what was sent; purchase-orders create-shipment re-reads the order and looks for the shipment the POST returned. If the change did not persist, the command fails with NOT_PERSISTED and exit code 1 instead of reporting success — an API that answers 200 and discards the payload is worse than one that errors, because the operator marks the task done. What could not be compared with confidence (a unit the server converted, a nested structure) is reported as unverified on stderr rather than treated as a failure.

Pass --skip-verify to skip the re-read. On success the command prints the re-read record; with --skip-verify, or if the re-read itself fails, it prints the PATCH response instead.


Development

# Install dependencies
uv sync

# Run tests
uv run pytest -v

# Lint
uv run ruff check aegro/ tests/

# Format
uv run ruff format aegro/ tests/

Links


License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aegro-0.20.0.tar.gz (603.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aegro-0.20.0-py3-none-any.whl (474.7 kB view details)

Uploaded Python 3

File details

Details for the file aegro-0.20.0.tar.gz.

File metadata

  • Download URL: aegro-0.20.0.tar.gz
  • Upload date:
  • Size: 603.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for aegro-0.20.0.tar.gz
Algorithm Hash digest
SHA256 b19f86387117c0d65b148a29b68181d2831e8170bb0dec26e5e1c33398a96062
MD5 4409c545d23d4eb442717abcd11a7dd4
BLAKE2b-256 7c84725fe642c7e3a775f88a4ac79a7f2d3b2d7143d5c38e1476c76e73d64927

See more details on using hashes here.

Provenance

The following attestation bundles were made for aegro-0.20.0.tar.gz:

Publisher: publish.yml on aegro/tool-aegro-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aegro-0.20.0-py3-none-any.whl.

File metadata

  • Download URL: aegro-0.20.0-py3-none-any.whl
  • Upload date:
  • Size: 474.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for aegro-0.20.0-py3-none-any.whl
Algorithm Hash digest
SHA256 49c856bf08e4724951664f16e4d4484788f54a391524ea2960c15af541618bb9
MD5 4f17a155b8e66d55fc5c11fa6003b3cc
BLAKE2b-256 1141826efecc87f2f0cf546cc6839af60f3108c62b61b21b19b820a4274711d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for aegro-0.20.0-py3-none-any.whl:

Publisher: publish.yml on aegro/tool-aegro-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.23.0

2 files

0.22.0

2 files

0.21.0

2 files

This release

0.20.0 This release

2 files

0.19.0

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.15.0

2 files

0.14.1

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.1

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page