xero-mcp-auth
Enables MCP access to Xero accounting data by handling the PKCE browser sign-in, storing and rotating refresh tokens, and launching the official Xero MCP server with a freshly minted access token.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@xero-mcp-authAuthenticate my Xero account so I can use the official MCP server"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
xero-mcp-auth
Run the official Xero MCP server from Claude Code, Claude Desktop, Cowork, Cursor, or any other MCP client, without paying for a Xero Custom Connection.
The official server supports two ways to authenticate:
Custom Connection. Client ID and secret, tokens handled for you. Xero charges a monthly fee per organisation for this.
Bearer token. Free, but you must supply an already-minted access token in an environment variable, and Xero access tokens expire after 30 minutes. The README says the MCP client should "execute an auth flow such as PKCE". None of them do.
xero-mcp-auth is that missing auth flow. It does the one-time PKCE browser sign-in against a free Xero app, stores the long-lived refresh token locally, and on every server start mints a fresh access token and hands it to the official server. It also persists the rotated refresh token, which Xero changes on every use.
Zero dependencies. Needs Node 18 or later, which you already have if you can run the official server.
Setup
1. Create a free Xero app (two minutes)
Go to developer.xero.com/app/manage and click New app.
Name it whatever you like. Integration type: Mobile or desktop app. This type uses PKCE and has no client secret, which is why it is free.
Company or application URL: anything, for example your GitHub profile.
Redirect URI:
http://localhost:8734/callbackSave, then copy the Client ID.
Every user needs their own app. Uncertified Xero apps are limited to 25 connected organisations, so a shared client ID would stop working for everyone once that cap was hit.
2. Authorise
npx xero-mcp-auth auth <your-client-id>A browser opens. Sign in to Xero and choose the organisation you want the MCP server to see. The refresh token is saved to a private file in your platform's config directory (see xero-mcp-auth status for the path).
3. Point your MCP client at it
Claude Code
claude mcp add xero -- npx -y xero-mcp-auth serveClaude Desktop and Cowork (claude_desktop_config.json, via Settings → Developer → Edit Config)
{
"mcpServers": {
"xero": {
"command": "npx",
"args": ["-y", "xero-mcp-auth", "serve"]
}
}
}Cursor, Windsurf, VS Code, Zed use the same shape: command npx, args ["-y", "xero-mcp-auth", "serve"].
If your client cannot find npx (common when Node is installed through nvm or Homebrew and the client launches with a minimal PATH), install globally and use the absolute path instead:
npm install -g xero-mcp-auth
which xero-mcp-auth # use this path as the command, with args ["serve"]Related MCP server: Xero Expenses MCP
Day to day
Access tokens last 30 minutes from when the server starts. When Xero calls start failing with 401, restart or reconnect the MCP server in your client (in Claude Code:
/mcp). That re-runsserve, which mints a new token.Refresh tokens expire after 60 days unused. Starting the server renews it. If you have been away longer than that, run
authagain.xero-mcp-auth statusshows how long ago it was last used.Several clients on one machine can share the credentials file. A lock around the refresh step stops two of them rotating the token at the same moment.
Several machines should each run
auththemselves. Each authorisation gets its own refresh token, and they count against the same single organisation connection, not the 25-org cap.
Commands
xero-mcp-auth auth <client_id> [--port N] [--scopes "a b c"] [--profile NAME]
One-time browser sign-in. Stores a refresh token locally.
xero-mcp-auth serve [--profile NAME]
Mint an access token and run @xeroapi/xero-mcp-server. Point your MCP client here.
xero-mcp-auth token [--profile NAME]
Print a fresh access token to stdout, for scripts or curl.
xero-mcp-auth status [--profile NAME]
Show where credentials are and when they were last used.More than one Xero organisation
The official server has no organisation selector. After it gets a token it lists the organisations connected to the app and always uses the first one. So if you connect two organisations to the same Xero app, the server will silently pick one of them, and it may not be the one you meant.
Until that changes upstream, the reliable way to work with several organisations is one Xero app and one profile per organisation, exposed to your MCP client as separately named servers:
# a second free app, authorised while signed in to the second organisation
npx xero-mcp-auth auth <second-client-id> --profile shop
claude mcp add xero-club -- npx -y xero-mcp-auth serve --profile club
claude mcp add xero-shop -- npx -y xero-mcp-auth serve --profile shopEach server carries its organisation in its name, so every tool call the model makes says which books it is touching. Profiles are just separate credentials files in the config directory; XERO_MCP_AUTH_PROFILE does the same job as --profile for clients that prefer environment variables.
Scopes
By default auth requests the same scope list the official server uses, plus offline_access for the refresh token. These are Xero's V2 granular scopes (accounting.invoices, accounting.contacts, and so on). Apps created after March 2026 reject the older coarse scopes such as accounting.transactions, so do not substitute those.
To request less, pass --scopes to auth:
npx xero-mcp-auth auth <client-id> --scopes "offline_access accounting.invoices accounting.contacts"Environment variables
Variable | Purpose |
| Same as |
| Explicit path to a credentials file. Overrides the profile. |
| Config directory. Defaults to |
Troubleshooting
invalid_grant on start. The stored refresh token is dead. Either it went 60 days unused, or a rotated token failed to save (a full disk, a read-only config directory). Run auth again.
invalid_scope during auth. Your Xero app was created after March 2026 and one of the requested scopes is a legacy one. Use the default list or the V2 names.
Redirect URI mismatch. The URI registered on the Xero app must be exactly http://localhost:8734/callback. If port 8734 is taken on your machine, pass --port to auth and register the matching URI.
Nothing on stdout, client says the server died. Run npx xero-mcp-auth serve in a terminal. The wrapper logs to stderr, so the real error will be visible there.
Why not a pull request to the official server?
It would be the better home, and one may follow. But a mode that runs a browser flow and writes credentials to disk is a bigger ask of a vendor-maintained repo than a ten-line env-var addition, and in the meantime people are paying for a Custom Connection they do not need.
Licence
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
OAuth MCP for Google, Meta, X, LinkedIn, Reddit, TikTok, GSC, GA4, WordPress and GHL.
Hosted OAuth MCP at https://www.taskade.com/mcp, or local @taskade/mcp-server.
Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA complete OAuth 2.1 server implementation for FastMCP with PKCE support, enabling secure authentication and authorization flows. Provides authorization code exchange, token management, and refresh capabilities for building authenticated MCP applications.-
- AlicenseAqualityDmaintenanceEnables interaction with Xero accounting software to create and manage invoices, bills, expenses, and expense claims with file attachments through PKCE authentication.211MIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude.ai to connect to a Hermes MCP server via OAuth 2.1 authorization code flow with PKCE, acting as a reverse proxy and single-user authorization gateway.-
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients like Cursor to securely access freee API via OAuth 2.1 authentication on Cloudflare Workers.Apache 2.0