I asked Claude to pull my unpaid Xero invoices. It worked. Here's the 10-minute setup nobody wrote down clearly.
Claude Code supports MCP servers — small plugins that give Claude access to external tools and data sources. Xero has an official one: @xeroapi/xero-mcp-server. Once it's connected, you stop context-switching. You ask Claude "what's overdue this month?" and get a real answer. You ask "summarize last quarter's expenses by category" and it queries your books directly.
This guide covers the exact steps. There's one catch if you're outside the US, AU, NZ, or UK — covered separately here.
What You'll Need
- A Xero account (any plan)
- Claude Code installed (
brew install --cask claude-code) - Node.js v18 or later (
node --versionto check)
Step 1 — Create a Xero Web App
Go to developer.xero.com/app/manage and click New app.
Choose Web app as the integration type. (If you're in AU, NZ, UK, or US, you can also use Custom Connection for a simpler setup — but Web App works everywhere.)
Fill in:
- App name: anything (e.g. "Claude MCP")
- Company or application URL:
http://localhost - Redirect URI:
http://localhost:3000/callback
Save. Copy the Client ID and Client Secret from the app detail page. These are the only credentials you need.
Step 2 — Add to Your MCP Config
Open (or create) ~/.mcp.json and add:
{
"mcpServers": {
"xero": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@xeroapi/xero-mcp-server"],
"env": {
"XERO_CLIENT_ID": "your-client-id-here",
"XERO_CLIENT_SECRET": "your-client-secret-here"
}
}
}
}
If you already have other MCP servers configured, add the "xero" block inside the existing "mcpServers" object.
For security, store the credentials as environment variables rather than hardcoding them:
export XERO_CLIENT_ID="your-client-id" export XERO_CLIENT_SECRET="your-client-secret"
Then reference them in the config as "${XERO_CLIENT_ID}" and "${XERO_CLIENT_SECRET}".
Step 3 — One-Time OAuth Login
Restart Claude Code. On first use, the MCP server will need to authorize access to your Xero organization. It will open a browser window for the standard Xero OAuth flow.
Log in to Xero, select your organization, and click Allow access. The server captures the authorization code, exchanges it for a refresh token, and stores it. You won't need to do this again — the server handles token refresh automatically.
Step 4 — Ask Claude About Your Books
Once connected, Claude has access to your Xero data through natural language. Try:
- "Show me all unpaid invoices from the last 30 days"
- "What were my top 5 expense categories last quarter?"
- "List contacts with overdue balances"
- "Summarize this month's profit and loss"
- "Which invoices are due this week?"
Claude translates these into Xero API calls, formats the results, and responds in plain language. No dashboard switching, no CSV exports, no manual lookups.
What the MCP Server Can Access
The @xeroapi/xero-mcp-server exposes most of the Xero accounting API:
- Invoices — create, read, update, filter by status/date/contact
- Contacts — customers, suppliers, contact groups
- Accounts — chart of accounts, account codes
- Reports — P&L, balance sheet, aged receivables/payables
- Payments — payment records, allocations
- Bank transactions — statements, reconciliation status
Payroll requires NZ or UK region settings. Everything else works for any Xero organization.
Scopes
The default scopes cover read access to all the above. If you want Claude to create or update records (not just read), add XERO_SCOPES to your config:
"env": {
"XERO_CLIENT_ID": "...",
"XERO_CLIENT_SECRET": "...",
"XERO_SCOPES": "accounting.transactions accounting.contacts accounting.settings accounting.reports.read"
}
Start with read-only. Add write scopes only if you specifically need Claude to create invoices or update contacts.
Troubleshooting
Server doesn't appear in Claude Code: Check that Node.js v18+ is installed. Run node --version. If you use nvm, specify the full path to npx in the config instead of just "npx".
OAuth window doesn't open: Make sure http://localhost:3000/callback is listed as a redirect URI in your Xero app settings. The URL must match exactly.
Getting "Custom Connection not available": You're outside AU/NZ/UK/US. Use the Web App approach described here. Full details in the workaround post.
Token expired after restart: On the first run after a long gap, you may need to re-authorize. This is normal for Web App OAuth with short token lifetimes.
The Result
Your AI assistant has live access to your books. You can ask accounting questions in plain language, get answers without leaving your terminal, and string together financial queries that would normally take 10 minutes of dashboard navigation.
For anyone who runs their own business and lives in the terminal, this is the integration that makes Claude genuinely useful for day-to-day finance work.