| name | harvest-cli |
| description | Track time and manage Harvest projects via the harvest CLI. Use when the user wants to log time entries, start/stop timers, view weekly dashboards, manage invoices, run reports, or handle expenses. Triggered by mentions of Harvest, time tracking, timesheets, billable hours, or timesheet workflows.
|
| license | MIT |
| homepage | https://github.com/dedene/harvest-cli |
| metadata | {"author":"dedene","version":"1.1.0","openclaw":{"primaryEnv":"HARVESTCLI_ACCOUNT","requires":{"env":["HARVESTCLI_ACCOUNT","HARVESTCLI_ACCOUNT_ID"],"bins":["harvest"]},"install":[{"kind":"brew","tap":"dedene/tap","formula":"harvestcli","bins":["harvest"]},{"kind":"go","package":"github.com/dedene/harvest-cli/cmd/harvest","bins":["harvest"]}]}} |
harvest-cli
CLI for Harvest time tracking and invoicing.
Quick Start
harvest auth status
harvest dashboard
harvest timer start
harvest time list -f today
Authentication
Requires OAuth setup or Personal Access Token from Harvest Developer Settings.
harvest auth status
harvest auth list
If not authenticated, user must run harvest auth login interactively (browser OAuth). Do not attempt auth setup on behalf of the user.
Core Rules
- Always use
--json when parsing output programmatically
- Read before write - check current timer/entries before modifying
- Timer is singleton - only one timer runs at a time; starting new stops old
- Multi-account - use
-a email or -a alias for specific accounts
Output Formats
| Flag | Format | Use case |
|---|
| (default) | Table | User-facing display |
--json | JSON | Agent parsing, scripting |
--plain | TSV | Pipe to awk/cut |
Workflows
Timer Control
harvest timer
harvest timer start
harvest timer start -p "My Project" --task "Development"
harvest timer stop
harvest timer toggle
harvest timer restart
Time Entries
harvest time list -f today
harvest time list -f monday -t today
harvest time list -p "Client Project"
harvest time add -p "Project" --task "Development" -h 2 -n "Worked on feature"
harvest time add -p "Project" --task "Dev" -h 1.5 \
--external-ref-id "JIRA-123" --external-ref-service jira
harvest time edit <entry_id> -h 3 -n "Updated notes"
harvest time remove <entry_id>
harvest time log
Dashboard
harvest dashboard
harvest dashboard --json
Reports
harvest reports time -f "2024-01-01" -t "2024-01-31" --by projects
harvest reports time -f "2024-01-01" -t "2024-01-31" --by tasks
harvest reports expenses -f "2024-01-01" -t "2024-01-31" --by categories
harvest reports uninvoiced -f "2024-01-01" -t "2024-01-31"
harvest reports budget --active
Projects & Clients
harvest projects list
harvest projects list --active
harvest projects show <id>
harvest clients list
harvest clients show <id>
Invoices
harvest invoices list
harvest invoices list --status draft
harvest invoices show <id>
harvest invoices add -c "Client Name" --subject "January 2024"
harvest invoices send <id> -r "billing@client.com"
harvest invoices payments add <id> --amount 1500.00
harvest invoices mark-sent <id>
harvest invoices mark-closed <id>
Expenses
harvest expenses list
harvest expenses add -p "Project" --category "Travel" \
--amount 50.00 --receipt /path/to/receipt.pdf
harvest expenses show <id>
Bulk Operations
harvest bulk export -f "2024-01-01" -t "2024-01-31" -o timesheet.csv
harvest bulk import timesheet.csv
harvest bulk import timesheet.csv --dry-run
Multi-Account
harvest auth list
harvest auth switch user@example.com
harvest -a work@company.com time list
harvest config set alias.work work@company.com
harvest -a work dashboard
Scripting Examples
harvest timer --json | jq -r '.project.name'
harvest time list -f today --json | jq '[.[].hours] | add'
harvest projects list --json | jq -r '.[] | select(.name == "My Project") | .id'
if harvest timer --json | jq -e '.is_running' > /dev/null; then
harvest timer stop
fi
Environment Variables
| Variable | Description |
|---|
HARVESTCLI_ACCOUNT | Default account email or alias |
HARVESTCLI_ACCOUNT_ID | Harvest account ID override |
Global Flags
| Flag | Description |
|---|
-a, --account | Account email or alias |
--account-id | Harvest account ID override |
-j, --json | Output as JSON |
--plain | Output as TSV |
-v, --verbose | Verbose output |
--color | Color: auto, always, never |
Command Reference
| Command | Description |
|---|
auth | login, logout, status, list, switch |
config | show, set, unset, path |
time | list, show, add, edit, remove, log |
timer | status, start, stop, restart, toggle |
dashboard | Weekly summary |
projects | list, show, add, edit, remove |
clients | list, show, add, edit, remove |
tasks | list, show, add, edit, remove |
users | list, show, me, add, edit, remove |
expenses | list, show, add, edit, remove |
invoices | list, show, add, edit, remove, send, payments |
estimates | list, show, add, edit, remove, send |
reports | time, expenses, uninvoiced, budget |
approvals | pending, submit, approve, reject |
bulk | export, import |
company | Show company info |
Guidelines
- Never expose OAuth tokens or credentials
- Confirm destructive operations (remove, bulk import) with user first
- Timer commands affect real billable time - confirm before stopping/modifying
- Rate limits handled automatically with backoff
Installation
brew install dedene/tap/harvestcli