Provider REST API

Finance

Connect Claude to Xero

Read Xero invoices, contacts, accounts, bank transactions, payments, and the two headline reports. Toolspoke puts 10 of its actions behind one MCP endpoint that Claude, Cursor, and Codex all speak.

Connection
Provider REST API
Authentication
Sign in with Xero
Actions exposed
10
Cost per call (typical)
1 credit
Adapter
Maintained by Toolspoke

Connected in three steps

  1. 1

    Install Xero

    Open the marketplace in your workspace, add Xero to the project your agents work in, and it appears on the gateway immediately.

  2. 2

    Connect the credential

    Authenticate with sign in with xero. Where to get one, and what it has to be able to reach, is the next section.

  3. 3

    Point your agent at the gateway

    Give your client one address, https://toolspoke.com/mcp. Claude Code takes it as a command, Claude and Claude Desktop add it as a custom connector, and Cursor, Codex and VS Code each read it from a config file of their own.

.mcp.json
{
  "mcpServers": {
    "toolspoke": {
      "type": "http",
      "url": "https://toolspoke.com/mcp"
    }
  }
}

One block covers every tool you have installed. Xero shows up in the client as soon as your policy allows it, and so does everything else you install later.

Where the address goes, per client

Claude Code

Run it in your project, then /mcp to sign in

claude mcp add --transport http toolspoke https://toolspoke.com/mcp
Claude and Claude Desktop

Settings, then Connectors, then Add custom connector

https://toolspoke.com/mcp
Cursor

~/.cursor/mcp.json, or .cursor/mcp.json for one project

{ "mcpServers": { "toolspoke": { "url": "https://toolspoke.com/mcp" } } }
Codex

~/.codex/config.toml

[mcp_servers.toolspoke]
url = "https://toolspoke.com/mcp"
VS Code

.vscode/mcp.json, or the MCP: Add Server command

{ "servers": { "toolspoke": { "type": "http", "url": "https://toolspoke.com/mcp" } } }

What Xero asks for

Sign in with Xero. You provide it once, when you install the connector. Toolspoke encrypts it at rest and decrypts it only for the length of a single call, and the gateway attaches it to the outbound request itself, so it is never part of the arguments an agent sends.

Xero organisation (tenant) IDRequired
Xero sends this header on every call to say which organisation to read. One sign-in can reach several, and Xero will not choose for you - a missing or wrong value fails in a way that reads like a permissions problem. Get it from https://api.xero.com/connections with your access token, where each entry's tenantId is one organisation you have connected.
00000000-0000-0000-0000-000000000000

What Claude can do in Xero

10 actions, each one declared and named by the connector rather than discovered at runtime. A workspace policy grants a person all of them, a hand-picked selection, everything on the read side, everything on the write side, or none.

Reads
10Reads
Writes
0Writes
Destructive
0Destructive

Reads

10

Fetches data and changes nothing.

  • list_organisations

    Return the organisation this connection is pointed at: its name, legal name, country, base currency, financial year end, tax settings and edition. Xero's route is singular, /Organisation, and the payload comes back under a plural Organisations key - that is Xero's shape, not a mistake here. This is the connection test: it needs nothing, costs nothing, names no person, and it is the one call that proves the tenant id in the credential actually resolves to a set of books this sign-in can read.

  • list_accounts

    Return the chart of accounts: every account with its code, name, type, tax type, class and status. This is the organisation's accounting structure rather than anybody's data, so it is the map to read before interpreting an invoice line or a report row. Its response is kept in the audit log for that reason - an agent that has to reason about where a figure came from needs the account list in front of it. Narrow with `where`, e.g. Type=="BANK", or Status=="ACTIVE".

  • list_invoices

    List invoices and bills - Xero keeps both in this one resource and separates them by Type, ACCREC for what you have billed a customer and ACCPAY for what a supplier has billed you. Narrow before you fetch: `statuses` takes a comma-separated list such as AUTHORISED,PAID, `where` filters on any field, and `search_term` matches the invoice number and reference. Set summary_only for a much lighter response without line items, which is what you want when counting or listing. Xero pages this 100 at a time by default; ask for a page with `page`. Its response is kept out of the audit log because an invoice names a real customer or supplier and what they were charged.

  • get_invoice

    Fetch one invoice by its InvoiceID, with its full line items, the contact it belongs to, its payments, credit notes and prepayments, and its running amounts due and paid. Ids come from list_invoices. Its response is kept out of the audit log - it names a counterparty and the amounts between you.

  • list_contacts

    List the customers and suppliers on the organisation, with their names, contact people, email addresses, addresses, tax numbers and outstanding balances. `search_term` matches name, first name, last name, contact number and email address, which is the fastest way from a person's name to a ContactID. Set summary_only for a lighter response. Its output is kept out of the audit log and `where` and `search_term` are masked before the call is logged, because both the answer and the question name real people.

  • get_contact

    Fetch one customer or supplier by ContactID, with their full record: addresses, phone numbers, email, tax number, default account codes, payment terms and outstanding balances. Ids come from list_contacts. Xero accepts no query parameters at all on this route. Its response is kept out of the audit log - it is one named person or company and their details.

  • list_bank_transactions

    List money in and out of the organisation's bank accounts - spend and receive transactions - with the contact, the bank account, the line items and the reconciliation state. This is the cash view, as opposed to the invoice view: an invoice is what was billed, a bank transaction is what actually moved. Narrow with `where`, e.g. Status=="AUTHORISED", or by bank account. Kept out of the audit log because each row names a counterparty and an amount.

  • list_payments

    List payments applied against invoices and credit notes, with the invoice each one settles, the account it went through, the amount and the date. Use it to answer "has this been paid, and when" without pulling whole invoices. Narrow with `where`, e.g. Status=="AUTHORISED", or Date>=DateTime(2026,08,01). Kept out of the audit log because a payment names the counterparty it settles with.

  • get_profit_and_loss

    Run the Profit and Loss report and return it as Xero's row-and-cell report structure. Every parameter is optional: with none, Xero reports the current month. Pass from_date and to_date for an explicit range, both as YYYY-MM-DD, or use periods together with timeframe to compare several periods side by side - periods 1 to 11, timeframe MONTH, QUARTER or YEAR. The response is aggregate figures with no customer or supplier named in it, which is why, unlike the invoice and contact reads here, it is kept in the audit log: a number an agent reported should be checkable afterwards.

  • get_balance_sheet

    Run the Balance Sheet report and return it as Xero's row-and-cell report structure. Note the difference from the Profit and Loss: a balance sheet is a position at a single moment, so it takes `date` rather than a range, and Xero defaults to the end of the current month. Add periods and timeframe to show prior positions beside it. Note too that Xero's tracking parameters are named differently on this report - trackingOptionID1 and trackingOptionID2, with no category parameter - which is Xero's own asymmetry and not a typo here. Aggregate figures, no counterparties, so the response is kept in the audit log.

What it will not do

Enforced by the gateway rather than left to convention, which is why each of these can be stated flatly.

It cannot call anything else
The 10 actions above are the whole of it. A call to any other name is refused before it reaches Xero rather than forwarded on, and connecting your account does not add to the list: it is fixed by the connector, not discovered at run time.
It only reads
Every action here reads. Nothing this connector can do changes anything in Xero.
It reaches no further than your credential
Toolspoke holds no access to Xero of its own. Every call carries the credential you stored and nothing besides, so whatever that credential cannot reach, this connector cannot reach either.
It never hears from Xero
Nothing is pushed to it. There is no webhook, no subscription and no polling, so this connector cannot notice by itself that something changed in Xero. An agent has to ask.
It does not smooth over provider limits
Toolspoke does not retry, queue or back off around Xero's own rate limits. A call that Xero refuses comes back to the agent as a failed call.

Before you connect it

What can Claude do in Xero?

10 named actions: 10 that only read. They include list_organisations, list_accounts and list_invoices. Nothing outside that list is reachable: the connector declares each operation by name rather than proxying whatever an agent asks for.

What credentials does the Xero connector need?

Sign in with Xero. The connector asks for xero organisation (tenant) id. Values are encrypted at rest and attached to the outbound request by the gateway, so they are never part of the arguments an agent sends and never reach the audit log.

Does the Xero connector work with Cursor and Codex, or only Claude?

Any client that speaks MCP, and every one of them gets the same 10 actions. There is a single address, https://toolspoke.com/mcp. Claude Code adds it with claude mcp add --transport http, Claude and Claude Desktop take it as a custom connector in settings, Cursor reads it from .cursor/mcp.json, Codex from ~/.codex/config.toml, and VS Code from .vscode/mcp.json. Each of them signs in to the gateway itself, so there is no key to paste.

What does the Xero connector not do?

The 10 actions above are the whole of it. A call to any other name is refused before it reaches Xero rather than forwarded on, and connecting your account does not add to the list: it is fixed by the connector, not discovered at run time. Every action here reads. Nothing this connector can do changes anything in Xero. Toolspoke holds no access to Xero of its own. Every call carries the credential you stored and nothing besides, so whatever that credential cannot reach, this connector cannot reach either. Nothing is pushed to it. There is no webhook, no subscription and no polling, so this connector cannot notice by itself that something changed in Xero. An agent has to ask. Toolspoke does not retry, queue or back off around Xero's own rate limits. A call that Xero refuses comes back to the agent as a failed call.

Can I limit which actions an agent can call?

Yes, in two places. The project switches Xero's actions on and off one at a time, for everyone in the project at once, and the screen groups them by read, write and destructive so turning off everything that deletes is one click. An individual agent key can then be narrowed further, to particular toolkits in a project and to particular actions in a toolkit. Whatever it was granted, a key never reaches a project its owner cannot.

What gets recorded when an agent calls Xero?

Every attempt, with the agent that made it and the person that agent belongs to, the full request payload, the response payload, the status, the duration, and the credits spent. Values whose key names a secret are masked out before the record is shown to anyone. An operation the connector marks as not retained never has its response body written at all, so the gateway keeps no second copy of what was read.