
Xero Command Line
CLIXero 官方命令行(alpha 版):财务人员可让 AI 查询和录入联系人、发票、报价、付款、银行流水与手工凭证,导出发票 PDF,生成损益表、资产负债表和试算平衡表,可切换多个组织。需要 Xero 账号并在开发者平台建 OAuth 应用;账务改动与报表结论需会计复核。
xero-command-line
A command-line tool for the Xero API using PKCE OAuth. Authenticates via browser-based login — no client secret required. Supports multiple Xero organisations via named profiles.
Alpha (v0.0.7) — APIs may change.
Install
npm install -g @xeroapi/xero-command-line
Or try it without installing:
npx @xeroapi/xero-command-line <command>
From source
git clone https://github.com/XeroAPI/xero-command-line.git
cd xero-command-line
npm install
npm run build
npm link
Prerequisites
- Node.js >= 18
- A Xero OAuth 2.0 app at developer.xero.com (no client secret needed — PKCE handles authentication)
- Set the redirect URI on your OAuth 2.0 PKCE app to
http://localhost:8742/callback
Setup
- Create a profile with your Xero app's Client ID:
xero profile add my-company
# Prompts for Client ID
Or pass it inline:
xero profile add my-company --client-id YOUR_CLIENT_ID
- Log in via the browser:
xero login
This opens your browser for Xero's OAuth consent flow. After you authorize, the CLI receives tokens via a local callback server. If your app is connected to multiple organisations, you'll be prompted to select one.
Tokens are encrypted (AES-256-GCM) and cached at ~/.config/xero-command-line/tokens.json. Tokens refresh automatically when expired.
Token storage
The CLI encrypts OAuth tokens at rest in ~/.config/xero-command-line/tokens.json. Where the encryption key is stored, from most to least secure:
- OS keychain (default in
automode) — macOS Keychain, Windows Credential Manager, or Linux Secret Service (GNOME Keyring / KWallet via D-Bus). Recommended on desktop systems. No encryption key file is written unless you opt in below. XERO_TOKEN_PASSPHRASE— Derives the key with scrypt from your passphrase and a local salt file. The raw key is not stored on disk. Set the same value beforexero loginand every later command. Stronger than a file-stored key if you accept managing a secret env var.XERO_KEYRING_FILE_BACKUP=1(opt-in) — When the keychain accepts a new key, also writes a copy to~/.config/xero-command-line/.encryption-key(mode0600). If a later command cannot read the keychain (common on WSL, SSH, or headless Linux), the CLI reads this file instead. Off by default so macOS/Windows/Linux desktops keep the key keychain-only. Enable only when the keychain is installed but reads are unreliable.XERO_KEY_STORAGE=file— Store the key only in.encryption-key(skip the keychain). Use when no secret service is available; weaker than keychain-only because any process running as your user can read the key file.
| Variable | Values | Default |
|---|---|---|
XERO_KEY_STORAGE | auto, keyring, file | auto |
XERO_KEYRING_FILE_BACKUP | 1, true, yes | off |
XERO_TOKEN_PASSPHRASE | your passphrase | off |
In auto mode without file backup, if the keychain is completely unavailable at login, the CLI still writes .encryption-key once so login can succeed — same as a file-only fallback for that session.
On Linux, WSL, or SSH, if login works once and later commands fail with an encryption-key error, the secret service was likely unavailable in that shell. The CLI does not delete tokens.json on decrypt errors.
Cache integrity. Writes to tokens.json are atomic (written to a temp file, then renamed into place) and serialised across processes with a short-lived tokens.json.lock directory, so parallel commands, scripts, and background token refreshes cannot overwrite each other's profiles. Before every write the previous version is copied to tokens.json.bak (mode 0600). If the CLI reports that the token cache is corrupted, that is not token expiry: the file exists but could not be parsed. Restore tokens.json.bak over tokens.json, or move tokens.json aside and run xero login for each profile. The CLI never replaces a corrupt cache on its own.
WSL / headless Linux (recommended: fix the keychain):
sudo apt install -y gnome-keyring libsecret-1-0 libsecret-tools dbus-x11
# Add to ~/.bashrc or ~/.zshrc:
if [ -z "$GNOME_KEYRING_CONTROL" ]; then
eval "$(/usr/bin/gnome-keyring-daemon --start --components=secrets 2>/dev/null)"
fi
Verify: secret-tool lookup service xero-command-line username encryption-key (after xero login).
WSL with a flaky keychain (login works, later commands fail):
export XERO_KEYRING_FILE_BACKUP=1 # add to ~/.bashrc on that machine
xero login
Without any keychain — use one of:
export XERO_KEY_STORAGE=file
# or
export XERO_TOKEN_PASSPHRASE='your-secret'
xero login
OAuth scopes
By default, xero login requests a broad set of scopes suitable for full read/write CLI usage. To request a narrower scope set — for example a read-only integration — pass --scope with a space-separated list of API scopes:
xero login --scope "accounting.contacts.read accounting.settings.read accounting.invoices.read accounting.payments.read accounting.banktransactions.read accounting.manualjournals.read accounting.reports.balancesheet.read accounting.reports.profitandloss.read accounting.reports.trialbalance.read accounting.reports.aged.read accounting.budgets.read accounting.attachments.read"
Or set the XERO_SCOPES environment variable (same space-separated format):
XERO_SCOPES="accounting.invoices.read accounting.contacts.read" xero login
API credentials created before Xero's March 2026 scope changes where deprecated broader scopes like accounting.transactions and accounting.reports are available until September 2027 may request those scopes via the --scope override as well. xero login will request the granular scopes that replaced these deprecated broader scopes by default.
Required OAuth scopes (openid, profile, email, offline_access) are always prepended automatically — you only need to list the Xero API scopes your app supports. If you omit --scope, behaviour is unchanged from previous releases.
Re-run xero login (with or without --scope) whenever you change scopes; existing tokens retain the scopes granted at login time.
Global Flags
Every command that calls the Xero API supports:
| Flag | Description |
|---|---|
-p, --profile <name> | Use a specific profile (defaults to the default profile) |
--client-id <id> | Override profile with an inline client ID |
--json | Output raw JSON (for piping/scripting) |
--csv | Output as CSV |
--toon | Output as TOON (compact, LLM-friendly) |
Environment variables XERO_PROFILE and XERO_CLIENT_ID are also supported. Token storage can be tuned with XERO_KEY_STORAGE, XERO_KEYRING_FILE_BACKUP, and XERO_TOKEN_PASSPHRASE (see Token storage). The xero login command additionally accepts XERO_SCOPES (see OAuth scopes above).
Finding IDs
Most commands that reference contacts, invoices, or accounts require a Xero GUID (e.g., edc74793-8d7e-4bf2-9e63-146dc4c675a2). Use the list commands to find IDs:
xero contacts list --search "Acme" # find a contact ID
xero accounts list # find account codes
xero invoices list # find invoice IDs
Commands
Profile Management
# Add a profile (first profile becomes the default)
xero profile add acme-corp
# List all profiles
xero profile list
# Set the default profile
xero profile set-default acme-corp
# Remove a profile
xero profile remove acme-corp
Organisation
xero org details
xero org details --json
Contacts
# List contacts
xero contacts list
xero contacts list --search "Acme"
xero contacts list --page 2 --json
# Create a contact
xero contacts create --name "Acme Corp" --email acme@example.com --phone "+1234567890"
xero contacts create --file contact.json
# Update a contact
xero contacts update --contact-id 00000000-0000-0000-0000-000000000001 --name "Acme Corporation" --email new@acme.com
xero contacts update --file contact-update.json
Contact Groups
xero contact-groups list
xero contact-groups list --group-id 00000000-0000-0000-0000-000000000001
Accounts
xero accounts list
xero accounts list --json
Invoices
# List invoices
xero invoices list
xero invoices list --contact-id 00000000-0000-0000-0000-000000000001
xero invoices list --invoice-number INV-0001
xero invoices list --page 2 --csv
# Download an invoice PDF to a file
xero invoices pdf --invoice-id 00000000-0000-0000-0000-000000000001 --output invoice.pdf
xero invoices pdf --invoice-id 00000000-0000-0000-0000-000000000001 --output invoice.pdf --json
# Stream an invoice PDF to stdout
xero invoices pdf --invoice-id 00000000-0000-0000-0000-000000000001 --output - > invoice.pdf
# Retrieve the customer-facing online invoice URL
xero invoices online-url --invoice-id 00000000-0000-0000-0000-000000000001
xero invoices online-url --invoice-id 00000000-0000-0000-0000-000000000001 --json
# Create an invoice (inline flags for a single line item)
xero invoices create --contact-id 00000000-0000-0000-0000-000000000001 --type ACCREC \
--description "Consulting" --quantity 10 --unit-amount 150 \
--account-code 200 --tax-type OUTPUT2
# Create an invoice (JSON file for multiple line items)
xero invoices create --file invoice.json
# Update a draft invoice
xero invoices update --invoice-id 00000000-0000-0000-0000-000000000001 --reference "Updated ref"
xero invoices update --file invoice-update.json
invoices pdf requires both --invoice-id and -o, --output. Parent directories are created automatically. Use --output - only when redirecting or piping stdout; binary PDF output cannot be combined with --json, --csv, or --toon and is refused when stdout is an interactive terminal. File output supports all structured output flags and reports the saved path, content type, and byte count.
invoices online-url calls Xero's dedicated GET /Invoices/{InvoiceID}/OnlineInvoice endpoint. Xero provides online invoice URLs only for non-draft ACCREC sales invoices. The command does not reuse the invoice url field returned by invoices list, which is a source-document link rather than the customer-facing online invoice URL. If Xero has not made an online URL available, the command exits successfully with a clear message; structured output returns available: false.
Example invoice.json
{
"contactId": "00000000-0000-0000-0000-000000000001",
"type": "ACCREC",
"date": "2025-06-15",
"reference": "REF-001",
"lineItems": [
{
"description": "Consulting",
"quantity": 10,
"unitAmount": 150,
"accountCode": "200",
"taxType": "OUTPUT2"
},
{
"description": "Travel",
"quantity": 1,
"unitAmount": 500,
"accountCode": "200",
"taxType": "OUTPUT2"
}
]
}
Quotes
# List quotes
xero quotes list
xero quotes list --contact-id 00000000-0000-0000-0000-000000000001
xero quotes list --quote-number QU-0001
# Create a quote
xero quotes create --file quote.json
xero quotes create --contact-id 00000000-0000-0000-0000-000000000001 --title "Project Quote" \
--date 2025-12-30 --description "Web design" --quantity 1 --unit-amount 5000 \
--account-code 200 --tax-type OUTPUT2
# Update a draft quote
xero quotes update --file quote-update.json
Credit Notes
# List credit notes
xero credit-notes list
xero credit-notes list --contact-id 00000000-0000-0000-0000-000000000001 --page 2
# Create a credit note
xero credit-notes create --file credit-note.json
xero credit-notes create --contact-id 00000000-0000-0000-0000-000000000001 \
--description "Refund" --quantity 1 --unit-amount 100 \
--account-code 200 --tax-type OUTPUT2
# Update a draft credit note
xero credit-notes update --file credit-note-update.json
Manual Journals
# List manual journals
xero manual-journals list
xero manual-journals list --manual-journal-id 00000000-0000-0000-0000-000000000001
xero manual-journals list --modified-after 2025-01-01
# Create a manual journal (requires JSON file — minimum 2 lines)
xero manual-journals create --file journal.json
# Update a draft manual journal
xero manual-journals update --file journal-update.json
Example journal.json
{
"narration": "Reclassify office supplies",
"manualJournalLines": [
{ "accountCode": "200", "lineAmount": 100, "description": "Debit" },
{ "accountCode": "400", "lineAmount": -100, "description": "Credit" }
]
}
Bank Transactions
# List bank transactions
xero bank-transactions list
xero bank-transactions list --bank-account-id 00000000-0000-0000-0000-000000000001
# Create a bank transaction
xero bank-transactions create --file bank-transaction.json
xero bank-transactions create --type SPEND --bank-account-id 00000000-0000-0000-0000-000000000001 \
--contact-id 00000000-0000-0000-0000-000000000002 --description "Office supplies" \
--quantity 1 --unit-amount 50 --account-code 429 --tax-type INPUT2
# Update a bank transaction
xero bank-transactions update --file bank-transaction-update.json
Payments
# List payments
xero payments list
xero payments list --invoice-id 00000000-0000-0000-0000-000000000001
xero payments list --invoice-number INV-0001
xero payments list --reference "Payment ref"
# Create a payment
xero payments create --invoice-id 00000000-0000-0000-0000-000000000001 --account-id 00000000-0000-0000-0000-000000000002 --amount 500
xero payments create --file payment.json
Items
# List items
xero items list
xero items list --page 2
# Create an item
xero items create --code WIDGET --name "Widget" --sale-price 29.99
xero items create --file item.json
# Update an item
xero items update --item-id 00000000-0000-0000-0000-000000000001 --code WIDGET --name "Updated Widget"
xero items update --file item-update.json
Currencies
xero currencies list
xero currencies list --json
Tax Rates
xero tax-rates list
xero tax-rates list --json
Tracking Categories & Options
# List tracking categories
xero tracking categories list
xero tracking categories list --include-archived
# Create a tracking category
xero tracking categories create --name "Department"
# Update a tracking category
xero tracking categories update --category-id 00000000-0000-0000-0000-000000000001 --name "Region"
xero tracking categories update --category-id 00000000-0000-0000-0000-000000000001 --status ARCHIVED
# Create tracking options
xero tracking options create --category-id 00000000-0000-0000-0000-000000000001 --names "Sales,Marketing,Engineering"
# Update tracking options
xero tracking options update --category-id 00000000-0000-0000-0000-000000000001 --file tracking-options.json
Reports
# Trial balance
xero reports trial-balance
xero reports trial-balance --date 2025-12-31 --json
# Profit and loss
xero reports profit-and-loss
xero reports profit-and-loss --from 2025-01-01 --to 2025-12-31
xero reports profit-and-loss --timeframe QUARTER --periods 4
# Balance sheet
xero reports balance-sheet
xero reports balance-sheet --date 2025-12-31
xero reports balance-sheet --timeframe MONTH --periods 12
# Aged receivables (requires contact ID)
xero reports aged-receivables --contact-id 00000000-0000-0000-0000-000000000001
xero reports aged-receivables --contact-id 00000000-0000-0000-0000-000000000001 --report-date 2025-12-31
# Aged payables (requires contact ID)
xero reports aged-payables --contact-id 00000000-0000-0000-0000-000000000001
xero reports aged-payables --contact-id 00000000-0000-0000-0000-000000000001 --from-date 2025-01-01 --to-date 2025-12-31
JSON File Input
Commands that create or update resources accept a --file flag with a JSON payload. All inputs are validated before being sent to the API. Validation errors are displayed with specific field-level messages.
xero invoices create --file invoice.json
Output Formats
# Formatted table (default)
xero contacts list
# JSON (for piping to jq, scripts, etc.)
xero contacts list --json
# CSV (for spreadsheets)
xero contacts list --csv
# TOON (compact format, ~40% fewer tokens — ideal for LLM pipelines)
xero contacts list --toon
Multiple Organisations
Use profiles to manage multiple Xero orgs:
xero profile add client-a --client-id ID_A
xero profile add client-b --client-id ID_B
xero login -p client-a
xero login -p client-b
xero contacts list --profile client-a
xero invoices list --profile client-b
Development
# Run in dev mode (no build step)
npm run dev -- contacts list
# Build
npm run build
# Run tests
npm test
npm run test:watch
相关资源

tax-season-organizer
SkillAnthropic 官方 small-business 插件里的报税准备技能,面向美国小企业主:从 QuickBooks、Xero 等账套或上传的利润表测算季度预缴税;年末汇总全年付款超 600 美元的承包商,生成 1099-NEC 清单并标出缺 W-9 的记录,交给会计师。要求当期账已结清,仅适用美国联邦税,不构成税务建议,结果需会计师复核。
anthropics/knowledge-work-plugins35.3k
Month End Prep
Skill帮小企业做月结对账:把 QuickBooks、Xero 等账套与 PayPal、Stripe、Shopify 等的结算逐笔核对,标出疑似重复、缺票的交易,写出通俗的损益说明并导出结账包(Excel 和 PDF)。没有连接器可用 CSV,结果需会计复核。Anthropic 官方出品。
anthropics/knowledge-work-plugins35.3k
Xero MCP Server
MCP让 agent 读写 Xero 会计数据:联系人、科目表、发票、付款、日记账,以及损益表等财务报表;薪资类查询仅限新西兰与英国账套。Xero 官方维护,需在开发者后台创建 Custom Connection。
XeroAPI/xero-mcp-server391
Apideck MCP Server
MCPApideck 官方 MCP:用一套接口读写 QuickBooks、Xero、NetSuite 等会计系统的发票、账目与报表,以及 HR、CRM、招聘系统的数据,适合同时管理多套系统的财务或代账团队。需要 Apideck 付费账号(可免费试用 30 天)、API Key 与 App ID,并先在 Apideck 里连好自己的系统;报表结论需会计复核。
apideck-libraries/mcp21
Actual CLI
CLI本地优先预算软件 Actual Budget 的官方命令行(命令是 actual):连接 Actual 同步服务器后,可查询和修改账户、交易、分类、收款方、规则与月度预算,默认输出 JSON,也能导出 CSV,适合让 agent 批量归类账目、整理报表。需 Node.js 22+,并准备已部署的 Actual 服务器地址、密码和预算 Sync ID。
actualbudget/actual30.1k
Beancount
CLI用文本文件记录复式记账交易的记账语言与工具集:bean-check 校验账本、bean-format 统一格式,配合 Fava、beanquery 出报表与查询;账本是纯文本,便于 agent 生成和版本管理。
beancount/beancount6.2k