Invio Xero MCP
Server Details
Every Xero organisation you run, in one AI session. Writes wait for a person to approve them.
- Status
- Healthy
- Uptime
- 96.0% over 44 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 38 tools
Most tools map to a single resource+action, and potentially overlapping pairs are actively disambiguated (list_xero_contacts vs get_xero_outstanding_receivables, list_xero_pay_runs vs get_xero_pay_run_summary, single-org reports vs get_xero_group_report). The remaining risk is volume: an agent scanning 38 tools must still distinguish list/get/create/update/post variants of the same resource, and the pending-change tools (list, approve, reject) sit apart from the main verb pattern.
The dominant pattern is a clean verb_xero_noun scheme (list_xero_invoices, get_xero_invoice, create_xero_invoice, update_xero_invoice, post_xero_pay_run), applied consistently across domains. The pending-change lifecycle breaks it: list_pending_changes, approve_xero_pending_change and reject_xero_pending_change use a different prefix/suffix arrangement and approval-specific semantics, a minor but visible deviation.
38 tools is heavy, well above the typical 3-15 band, though the surface genuinely spans invoices, contacts, credit notes, quotes, payments, journals, payroll, projects, reports and an approval workflow. Each tool has a defensible place, but the overall set is large enough that discovery and selection cost is real and some read tools could plausibly be consolidated.
Drafting coverage is strong and the approval lifecycle is well-formed (propose, list, approve, reject), but there are no void/delete operations anywhere despite descriptions repeatedly telling the agent to 'void it and create a new one' or that a payment 'can only be reversed by deleting inside Xero'. Quotes and credit notes have no update path, and there is no way to reverse a recorded payment, leaving several dead ends.
Available Tools
38 toolsapprove_xero_pending_changeapprove_xero_pending_changeADestructiveIdempotentInspect
Approves a change YOU (or another assistant on this account) have already proposed to Xero - create_xero_invoice, update_xero_invoice, create_xero_contact, update_xero_contact, create_xero_manual_journal or create_xero_credit_note - and immediately executes it. This is the ONE tool in this connector that actually writes to a live Xero ledger; treat it with the same weight as send_invoice or archive_business, not as a formality. Call this ONLY after the person using this account has clearly said, in their own words, to go ahead with THIS specific change - never infer approval from context, never call this speculatively "to see what happens", and never approve a change without first showing them what it actually says (call list_pending_changes if you do not already have its summary in this conversation). If they seem unsure, or ask what a value means, answer the question and wait - hesitation is not consent. Only once they have clearly agreed, call this with confirm: true. Afterwards, relay the real outcome verbatim: whether the write to Xero actually succeeded (and, if so, the id/number Xero assigned), or exactly why it failed if it did not - you cannot retry a failed write yourself, only draft a new change. Approving in Invio's own Settings > MCP > Xero screen remains available at all times and works exactly the same either way.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. Set this ONLY after the person using this account has explicitly said, in their own words, to approve (or reject) this specific change - never infer consent from context, and never pass true speculatively "to see what happens". | |
| pendingChangeId | Yes | The pendingChangeId of the row to act on - from list_pending_changes' own result, or the pendingChangeId a draft-creating tool (create_xero_invoice etc.) just returned. Never invent one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as destructive, non-read-only, open-world, and idempotent. The description adds crucial context beyond them: the write is real and live, the agent cannot retry a failed write itself, it must relay the actual Xero outcome or failure verbatim, and approval through Invio Settings remains equivalent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose and immediately follows with the critical approval and execution warnings before the outcome instructions. It is somewhat verbose and repeats consent cautions already present in the schema, but the length is defensible for a destructive live-ledger write.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-stakes destructive mutation with no output schema, the description covers approval preconditions, the need to inspect the pending change first, execution behavior, failure handling, outcome reporting, and the equivalent Settings path. An agent has enough information to call it correctly and report results safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and both parameters are already fully documented in the schema, including confirm's const true requirement and pendingChangeId provenance. The description reinforces consent semantics and says to call with confirm: true, but it largely repeats what the schema already provides rather than adding new parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it approves an already-proposed pending change and immediately executes it. It enumerates the draft-creating tools it applies to and explicitly distinguishes itself as the one tool in the connector that writes to a live Xero ledger.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use and when-not-to-use guidance: only after the user has clearly approved THIS specific change in their own words, never speculatively, and never without first showing them the change summary via list_pending_changes. It also covers hesitation and questions by telling the agent to wait.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_contactcreate_xero_contactAInspect
Proposes adding a new contact (customer or supplier) to this Xero organisation - it does NOT create anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. name is the only required field. Once approved and executed, the resulting contactId can be used with create_xero_invoice or update_xero_invoice - but only after this change has actually been approved, never before.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| phone | No | ||
| emailAddress | No | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false): explains it never creates in Xero on its own, requires human approval, and that the agent cannot self-approve. This is critical behavioral context for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the key caveat that this only queues a pending change. Slightly repetitive ('it does NOT create anything' / 'never will on its own' / 'you have no way to approve it yourself') but every sentence carries meaningful constraint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but the description explains the approvalUrl response field and contactId result, plus downstream dependency ordering. Complete enough for a mutation tool; lacks detail on rejection behavior or what happens to queued changes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 25%; description compensates by stating name is the only required field, but phone and emailAddress remain undocumented in both schema and description. Partial compensation for the coverage gap; no format or syntax added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and object - 'Proposes adding a new contact (customer or supplier)' - and immediately clarifies it does not create in Xero directly. Distinguishable from create_xero_invoice (which consumes the resulting contactId).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the approval workflow clearly: queues a pending change requiring human approval via approvalUrl, and states contactId can feed create_xero_invoice or update_xero_invoice only after approval. No explicit guidance versus update_xero_contact, but the 'new contact' scope makes it inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_credit_notecreate_xero_credit_noteAInspect
Proposes creating a new credit note in this Xero organisation - it does NOT create anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Tell the user what you are proposing (contact, ACCRECCREDIT or ACCPAYCREDIT, line items, total) and that it needs their approval in Invio before it goes anywhere - do not describe it as done, issued, or created. contactId must come from list_xero_contacts (never invented); if the contact doesn't exist yet, propose it with create_xero_contact first and wait for that to be approved and executed. Even once approved, this only ever creates a DRAFT credit note inside Xero - a human still authorises and applies or refunds it from within Xero itself, this connector never does that. You CAN state a currency (currency, e.g. "NZD") when the user names one - it is checked against the organisation's own configured currencies, and refused with the real list if it is not one of them, so a currency is never silently swapped for the base currency. You CAN also say whether the amounts include tax (lineAmountTypes): use "Inclusive" for "$1,500 including GST", "Exclusive" (the default) for "$1,500 plus GST", "NoTax" for no tax at all. Never adjust the numbers yourself to fake either one. DATES: date is strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts a credit note a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Credit note date, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| type | Yes | ACCRECCREDIT = a credit note against a sales invoice (reduces what this contact owes this business - e.g. a refund or correction on money owed TO the business). ACCPAYCREDIT = a credit note against a bill (reduces what this business owes this contact). | |
| currency | No | The currency this credit note is raised in, e.g. "NZD". Set this whenever the user names a currency or a currency symbol ("NZ$1,500", "credit them in USD") - it is checked against the currencies this organisation is actually set up to invoice in, and the draft is refused, with the real list, if it is not one of them. Omit it only when the user did not say: the credit note is then raised in the organisation's own base currency. | |
| contactId | Yes | The Xero contact this credit note is for. Get this from list_xero_contacts first - never invent one. If the contact does not exist in Xero yet, use create_xero_contact first, wait for it to be approved and executed, then use the contactId it produced. | |
| lineItems | Yes | ||
| reference | No | Free-text reference shown on the credit note. Per Xero, this is only used for ACCRECCREDIT - omit it for an ACCPAYCREDIT (there, the credit note's own auto-assigned number is what shows as its reference instead). | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| lineAmountTypes | No | How to read every unitAmount below. "Exclusive" (the default) = the amounts do NOT include tax and Xero adds it on top - this is what "$1,500 plus GST" means. "Inclusive" = the amounts ALREADY include tax and Xero works the tax out of them - this is what "$1,500 including GST", "$1,500 inc GST" or "$1,500 all up" means. "NoTax" = no tax is calculated at all. If the user says which one they mean, say so here rather than adjusting the numbers yourself. | Exclusive |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses the central behavior: no direct Xero write occurs, a human must approve via Invio, the connector cannot self-approve, and even an approved result is only a DRAFT credit note. It also explains currency validation refusal and date-conversion risks.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core approval-proposal behavior and structured around key risks such as contacts, currency, tax handling, and dates. It is lengthy and occasionally repetitive, but most sentences carry important behavioral guidance for this high-risk mutation tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the approval workflow, no output schema, and 8-parameter mutation surface, the description is complete enough for correct invocation. It covers prerequisites, approval semantics, draft-only outcome, currency handling, tax interpretation, and date-conversion hazards.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already high at 88%, but the description adds meaningful semantics for date ambiguity, currency validation, contactId provenance, lineAmountTypes tax interpretation, and ACCRECCREDIT versus ACCPAYCREDIT. Some parameter guidance is repeated from the schema, but the added cross-field context is substantial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it proposes creating a credit note in this Xero organisation. It immediately distinguishes the action from true creation by saying it only queues a pending change and never touches Xero itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage conditions: use list_xero_contacts before contactId, use create_xero_contact and wait for approval if the contact does not exist, and rely on the approvalUrl response field for human approval. It also clearly says not to describe the result as done, issued, or created.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_invoicecreate_xero_invoiceAInspect
Proposes creating a new invoice in this Xero organisation - it does NOT create anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Tell the user what you are proposing (contact, line items, total) and that it needs their approval in Invio before it goes anywhere - do not describe it as done, sent, or created. contactId must come from list_xero_contacts (never invented); if the contact doesn't exist yet, propose it with create_xero_contact first and wait for that to be approved and executed. Once a human approves it in Invio, it is created in Xero in the state you asked for (status) - or, if you say nothing, AUTHORISED: approved and ready to send, with nothing left for anyone to fill in. That is what an ordinary invoicing request means, and approving the change in Invio is already the approval - do not pass status "DRAFT" out of caution, that only makes the user approve the same invoice again by hand in Xero. Pass status "DRAFT" only when the user actually says they want to check or edit it in Xero first. Either way, THIS CONNECTOR NEVER EMAILS THE INVOICE TO THE CUSTOMER - sending it is a separate action a person takes inside Xero, and you have no tool for it, so never tell a user their customer has been sent anything. For a bill (ACCPAY) there is no customer and nothing to send: it is money this business owes, and AUTHORISED means ready to pay. You CAN state a currency (currency, e.g. "NZD") when the user names one - it is checked against the organisation's own configured currencies, and refused with the real list if it is not one of them, so a currency is never silently swapped for the base currency. You CAN also say whether the amounts include tax (lineAmountTypes): use "Inclusive" for "$1,500 including GST", "Exclusive" (the default) for "$1,500 plus GST", "NoTax" for no tax at all. Never adjust the numbers yourself to fake either one. DATES: date and dueDate are strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts an invoice a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Invoice date, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| type | Yes | ACCREC = a sales invoice (money owed TO this business by the contact). ACCPAY = a bill (money this business owes the contact). | |
| status | No | What state the invoice lands in inside Xero once a human approves this in Invio. Defaults to "AUTHORISED" - approved and ready for them to send from Xero, with nothing left to fill in - because approving this change in Invio is already the approval, and that is what an ordinary "invoice this customer" request means. Do not leave this as "DRAFT" out of caution: doing so makes the user approve the same invoice a second time, by hand, in Xero. Pass "DRAFT" only when the user actually says they want to check or edit it in Xero first - it then lands unapproved and they have to approve it there too. Either way this connector never emails the invoice to the customer; that stays a deliberate action a person takes in Xero. A bill (ACCPAY) has no customer and nothing to send: AUTHORISED means ready to pay. | AUTHORISED |
| dueDate | No | Due date, YYYY-MM-DD. Set it whenever the user says one ("due in 30 days", "by the end of the month"). Omit it and this connector derives one from the organisation's own default payment terms in Xero and tells you which terms it used - but an organisation that has set no default terms cannot have one derived, and you will be told that too, in which case ask the user for a due date rather than leaving it blank. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| currency | No | The currency this invoice is raised in, e.g. "NZD". Set this whenever the user names a currency or a currency symbol ("NZ$1,500", "invoice them in USD") - it is checked against the currencies this organisation is actually set up to invoice in, and the draft is refused, with the real list, if it is not one of them. Omit it only when the user did not say: the invoice is then raised in the organisation's own base currency. | |
| contactId | Yes | The Xero contact this invoice is for. Get this from list_xero_contacts first - never invent one. If the contact doesn't exist in Xero yet, use create_xero_contact first, wait for it to be approved and executed, then use the contactId it produced. | |
| lineItems | Yes | ||
| reference | No | Free-text reference shown on the invoice (e.g. a PO number). | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| lineAmountTypes | No | How to read every unitAmount below. "Exclusive" (the default) = the amounts do NOT include tax and Xero adds it on top - this is what "$1,500 plus GST" means. "Inclusive" = the amounts ALREADY include tax and Xero works the tax out of them - this is what "$1,500 including GST", "$1,500 inc GST" or "$1,500 all up" means. "NoTax" = no tax is calculated at all. If the user says which one they mean, say so here rather than adjusting the numbers yourself. | Exclusive |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only say readOnlyHint=false, idempotentHint=false, destructiveHint=false, and openWorldHint=true; the description supplies the real behavioral context on top of that. It explains the human-approval gate with the approvalUrl, the fact that this connector never emails the customer, how the accountCode is auto-filled or refused, and how a currency mismatch is refused with the real list. None of that contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is stated up front and the DATES block is clearly signposted, but the text is roughly 600 words and repeats the bare-numeric-date warning that the date and dueDate schema fields already carry. Repetition weakens focus on a definition this long.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter mutation with a human-approval step and no output schema, the description covers the whole lifecycle: the pending change, the approval link, the default status, the tax-type handling, the currency refusal, and the date-format edge case. An agent has everything it needs in order to call this tool correctly and to tell the user what happens next.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 90%, so the baseline is 3, and this description earns an extra point by explaining how the parameters interact: AUTHORISED requires a real accountCode on every line, and currency is checked against the organisation's configured currencies. Much of the material is repeated from the field descriptions, but the cross-field consequences add real meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ("Proposes creating a new invoice in this Xero organisation") and immediately distinguishes itself from a direct write: "it does NOT create anything in Xero itself, and never will on its own." It also implicitly separates this tool from approve_xero_pending_change by saying a human must approve the queued change.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use rules: contactId must come from list_xero_contacts and never be invented, and create_xero_contact should be used first if the contact does not exist. It also draws a sharp line between the default AUTHORISED state and the DRAFT state ("Pass status \"DRAFT\" only when the user actually says they want to check or edit it in Xero first"), which is exactly the alternative-choice guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_leave_applicationcreate_xero_leave_applicationAInspect
Proposes a DRAFT leave application for one employee/period, for Australian, New Zealand or United Kingdom organisations - it does NOT touch Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. employeeId must come from list_xero_payroll_employees (never invented), and must currently be ACTIVE - this refuses plainly for a terminated employee. leaveTypeId must come from list_xero_payroll_leave_types (never invented) - call that tool first if you do not already have a real id for the leave type the user named. description is required (max 50 characters) and is shown to the human approver; title is an OPTIONAL, Australia-only short title, silently ignored for New Zealand/United Kingdom. Do NOT compute or pass an hours/units figure - none exists on this tool, because Xero itself works out the number of units automatically from the employee's own payroll calendar; guessing at one here would only be wrong. Once approved, the leave application is IMMEDIATELY USABLE in Xero (the same status an ordinary, already-actioned leave application carries on every region this connector serves) - unlike create_xero_timesheet/create_xero_pay_run, there is no further Xero-side draft state left for a human to review afterwards, so approving this change in Invio is the only approval this leave application ever needs.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | A short title for the leave (e.g. "Annual Leave") - AUSTRALIA ONLY. New Zealand and the United Kingdom have no separate title field at all on this operation - this is silently ignored for those two regions if given. | |
| endDate | Yes | End of the leave, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| startDate | Yes | Start of the leave, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| employeeId | Yes | Get this from list_xero_payroll_employees first - never invent one. | |
| description | Yes | A short description of the leave (e.g. "Annual leave - family holiday"), up to 50 characters. Required by Xero itself for New Zealand and the United Kingdom, and required here for Australia too, even though Xero itself does not require it there - so every leave application a human reviews names what it is for. | |
| leaveTypeId | Yes | Get this from list_xero_payroll_leave_types first - never invent one. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the non-read-only, non-destructive, non-idempotent, open-world profile, and the description goes well beyond them: it queues a pending change that never touches Xero on its own, cannot self-approve, surfaces an approvalUrl, refuses for terminated employees, and leaves no residual Xero-side draft after approval. The only gap is that it doesn't state failure/refusal shape beyond 'refuses plainly' or what a partial/duplicate submission does for a non-idempotent mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core behaviour is front-loaded in the first clause and most of the length is load-bearing operational detail rather than filler. It is still a single dense semicolon-chained block where the prerequisite and units instructions could be separated for scanability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully names the approvalUrl return field and explains the end-to-end approval lifecycle, which is what an agent most needs. It is undercut slightly by the dangling DATES reference the schema points to, which the description never supplies, so date-format ambiguity is left unresolved despite being flagged.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning on top: employeeId must be an ACTIVE employee id, description is shown to the human approver (max 50), title is AU-only and silently ignored elsewhere, and no units field exists because Xero derives units. However, the startDate/endDate schema entries instruct the agent to 'Follow the DATES instruction in this tool's description' and no such DATES guidance exists in the description, leaving ambiguous numeric dates unaddressed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes a DRAFT leave application for one employee/period') plus the exact regional scope (AU/NZ/UK). It also explicitly contrasts itself with create_xero_timesheet and create_xero_pay_run, so an agent can place it among siblings without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit prerequisites (employeeId from list_xero_payroll_employees, leaveTypeId from list_xero_payroll_leave_types), a negative constraint ('never invented', must be ACTIVE), and an explicit anti-instruction ('Do NOT compute or pass an hours/units figure'). It also names the human-approval step that must follow, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_manual_journalcreate_xero_manual_journalAInspect
Proposes a manual journal (a general-purpose double-entry adjustment - reallocating an expense between accounts, recording a bank fee, writing off a small balance, and similar) in this Xero organisation - it does NOT create anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Every line needs a real accountCode from list_xero_accounts - unlike an invoice line, a journal line has no default account to fall back to, so never invent one. lineAmount is SIGNED: positive = a debit, negative = a credit - this is Xero's own convention, and getting it backwards silently swaps a debit for a credit in a real ledger. Every line together must sum to exactly zero - an unbalanced entry is rejected before anything is queued, with the exact imbalance named so you can fix it. Tell the user plainly which accounts are debited and which are credited, by how much, and that it needs their approval in Invio before it goes anywhere - never describe it as posted or done. Even once approved, this only ever creates a DRAFT journal inside Xero - a human still posts it themselves from inside Xero, this connector never does that. You CAN also say whether a taxed line's amount includes tax (lineAmountTypes): use "Inclusive" for "$1,500 including GST", "Exclusive" for "$1,500 plus GST", "NoTax" for no tax at all. This only changes anything on a line that also names a taxType - a line with no taxType is unaffected either way. Omit it and Xero applies its own default for a manual journal, which this connector does not claim to know. Never adjust the amounts yourself to fake a tax treatment. DATES: date is strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts a manual journal a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Date the journal is posted, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| lineItems | Yes | At least two lines, each with a signed lineAmount (positive = debit, negative = credit) and a real accountCode. The lineAmounts across every line must sum to exactly zero - this is checked before anything is queued, not left for Xero to reject after approval. | |
| narration | Yes | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| lineAmountTypes | No | How Xero reads every lineAmount below on any line that names a taxType. "Exclusive" = the amounts do NOT include tax and Xero adds it on top - "$1,500 plus GST". "Inclusive" = the amounts ALREADY include tax and Xero works the tax out of them - "$1,500 including GST", "$1,500 inc GST", "$1,500 all up". "NoTax" = no tax is calculated on any line. Set this whenever the entry has a tax dimension at all (a GST or VAT correction, a BAS adjustment, reallocating a tax-coded expense) and say which one you used. Omit it only for an entry with no tax in it, where Xero applies its own default. Never adjust the amounts yourself to fake a tax treatment, and never assume a bare "$1,500" is one or the other - ask if the user did not say. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Richly discloses behavior beyond the annotations: the call only queues a pending change, a human must approve via the approvalUrl in the response, the agent cannot approve, and even after approval only a DRAFT journal exists in Xero. It also names the validation rule and failure mode (unbalanced entries rejected before queueing with the exact imbalance reported).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the most important fact (it is a proposal, not a write), but the description is very long and repeats material already in the schema field descriptions, notably the date ambiguity warning and the signed lineAmount convention. The tax paragraph is dense and could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a mutation tool with no output schema, the description covers prerequisites (list_xero_accounts), approval lifecycle, validation rules, tax semantics, date interpretation, and user-facing communication obligations. Nothing an agent needs in order to call it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds substantial meaning over the schema despite 80% coverage: lineAmount is signed with debit/credit convention and the consequence of getting it backwards, lines must sum to zero, lineAmountTypes only affects lines that name a taxType, and date ambiguity for bare numeric formats has an explicit resolution policy rather than a guess.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes a manual journal') and immediately defines the resource with concrete examples (reallocating an expense, bank fee, write-off). It also disambiguates from sibling write tools by stressing it 'does NOT create anything in Xero itself', so an agent can tell it apart from create_xero_invoice or create_xero_payment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational guidance: get accountCode from list_xero_accounts, never invent one, never call this expecting immediate posting, and tell the user it needs their approval. It contrasts a journal line with an invoice line to explain the schema difference. It stops short of naming when an agent should pick a journal over e.g. create_xero_invoice for a given real-world scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_paymentcreate_xero_paymentADestructiveInspect
Proposes recording a payment against an existing, AUTHORISED invoice in this Xero organisation - it does NOT touch Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Tell the user what you are proposing (which invoice, the amount and currency, which bank account, the date) and that it needs their approval in Invio before it goes anywhere - do not describe it as recorded, applied, or done. invoiceId must come from list_xero_invoices or get_xero_invoice (never invented). For the bank account, give EXACTLY ONE of accountCode or bankAccountName, both from list_xero_accounts (look for type BANK) - never invent either one, and never reuse an invoice line item's accountCode, which is very likely a revenue account, not a bank account. Use accountCode when that account has a real code; use bankAccountName (its exact name) when list_xero_accounts shows it as code: null - a bank account added through Xero's own "Add Bank Account" commonly has no code at all, and that is not a reason to guess one. UNLIKE EVERY OTHER CHANGE THIS CONNECTOR CAN DRAFT, a payment has no draft state in Xero at all - the moment a human approves this, it is applied immediately and the invoice is genuinely, immediately less owed. It can only be reversed by deleting the payment directly inside Xero itself - this connector has no tool that can do that, so make sure the user actually wants this recorded before they approve it. DATES: date is strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts a payment a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Date the payment was made, YYYY-MM-DD. Cannot be in the future - Xero can only record a payment that has already happened, never a scheduled one, and this is checked against the organisation's own current date (its own timezone, not the server's or your own). If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| amount | Yes | How much was paid, in the invoice's OWN currency - never convert it into a different one. Must not exceed what is currently still owed on the invoice (its AmountDue); a smaller amount is a valid PARTIAL payment and is allowed. | |
| currency | No | The currency you believe this payment is in, e.g. "NZD" - OPTIONAL, and NOT something this tool sets on the payment (a payment has no currency of its own; it is always in the invoice's own currency). If you provide this, it is checked against the invoice's actual currency and the draft is refused if they do not match - use it as a sanity check when the user names a currency, not to convert anything. Omit it if you are not sure. | |
| invoiceId | Yes | The Xero invoice this payment is against. Get this from list_xero_invoices or get_xero_invoice first - never invent one. The invoice must currently be AUTHORISED in Xero (a DRAFT invoice cannot receive a payment) and the amount must not exceed what is currently still owed on it (its AmountDue) - both are re-checked against Xero live, both when this is drafted and again when a human approves it, so a figure that was valid when you drafted it can still be refused later if the invoice has moved in the meantime (another payment, a credit note, a direct edit in Xero). | |
| reference | No | Free-text reference for the payment (e.g. "Direct debit", a bank reference). | |
| accountCode | No | This tenant's own chart-of-accounts code for the BANK account the money was received into (or paid out of) - e.g. "090". Get one from list_xero_accounts first (look for type BANK), never guess - not every bank account has one (list_xero_accounts shows code: null for an account Xero itself gave no code). Give EXACTLY ONE of accountCode or bankAccountName: accountCode when the account has a real code, bankAccountName (its exact name instead) when it does not. Whichever you give, it must be a BANK account and ACTIVE in Xero - both are checked live, and the draft is refused with the real reason if either is not true. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| bankAccountName | No | This tenant's own exact name for the BANK account, for when it has no code in Xero at all (see accountCode's own description). Get it from list_xero_accounts first (look for type BANK) - it must match a real BANK account's name exactly (matched case-insensitively, but never a guess, an abbreviation, or a partial name). Give EXACTLY ONE of accountCode or bankAccountName, never both, never neither. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond annotations: the pending-change/human-approval model, that a payment has no draft state and is applied immediately on approval with no connector-level reversal, live re-checking of AUTHORISED status and AmountDue at draft and approval time, and the future-date prohibition. This far exceeds the destructiveHint/openWorldHint hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the most important fact (proposal, not execution) and organizes details into clear blocks (approval, accounts, DATES). Given the destructive, irreversible nature the length is largely justified, though there is some repetition between the description and the schema's parameter descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a destructive, non-idempotent mutation tool: it covers the approval/irreversibility model, currency and amount constraints, account selection, date ambiguity, and partial-payment behavior. With no output schema, the approvalUrl return field is even referenced, so nothing an agent needs to call or narrate correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning beyond the schema: the day-first locale convention that governs how to interpret bare numeric dates, and the exact-one-of accountCode/bankAccountName rule keyed to the org's code:null behavior. Some overlap with schema prose, but the locale disambiguation is genuine added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes recording a payment against an existing, AUTHORISED invoice') and immediately clarifies the crucial distinction that it does NOT touch Xero but queues a pending change. An agent can distinguish this from create_xero_invoice and other create_* siblings without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing rules: invoiceId must come from list_xero_invoices or get_xero_invoice, bank account from list_xero_accounts (type BANK), and clear when-to-use-accountCode-vs-bankAccountName logic based on whether code is null. It also states the approval prerequisite and that the agent cannot self-approve.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_pay_runcreate_xero_pay_runAInspect
Proposes a DRAFT pay run for one payroll calendar, for Australian or New Zealand organisations - it does NOT touch Xero itself, and never will on its own. Refuses plainly for the United Kingdom: Xero's own Payroll API documents no way to create a pay run there at all (only reading existing ones and creating pay run CALENDARS) - a United Kingdom pay run is generated inside Xero itself, from the pay calendar, and a human needs to open Payroll in Xero directly to start one. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. payrollCalendarId must come from list_xero_payroll_employees (any employee on that calendar) - never invented. Xero itself computes the period start/end and payment date from the calendar, so none of those are asked for here. The created pay run starts as a Xero-side DRAFT once approved - a human remains free to review it, check the totals, and only later use post_xero_pay_run (a SEPARATE, irreversible step, Australia only) to actually pay it - this tool never posts anything itself.
| Name | Required | Description | Default |
|---|---|---|---|
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| payrollCalendarId | Yes | Get this from any employee on that calendar via list_xero_payroll_employees. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=false and destructiveHint=false; the description supplies the far more consequential context: the call queues a pending change requiring human approval via the approvalUrl field, the agent cannot self-approve, and the resulting Xero object starts as a DRAFT. It also discloses a hard regional limitation the annotations cannot express. No contradiction with the annotation set.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core fact (drafts a proposal, does not touch Xero) and every sentence carries real information - regional refusal, approval gate, ID provenance, draft state, next step. Some redundancy ('does NOT touch Xero itself, and never will on its own') and a single dense paragraph cost it the top mark.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation tool with no output schema, the description covers everything an agent needs: what is created, what state it lands in, who must approve, where the approval link lives, the regional restriction, and the follow-up tool. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining the negative space - Xero computes period start/end and payment date from the calendar, so those parameters are deliberately absent - and by reinforcing the provenance rule for payrollCalendarId. It adds meaning rather than restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes a DRAFT pay run for one payroll calendar') with scope (AU/NZ orgs) and immediately distinguishes it from the write-side sibling by noting it does not touch Xero itself. Read alongside list_xero_pay_runs and post_xero_pay_run in the sibling list, an agent can pick correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not-to-use ('Refuses plainly for the United Kingdom' with the reason), explicit prerequisite (payrollCalendarId must come from list_xero_payroll_employees, never invented), and explicit hand-off to post_xero_pay_run as a separate irreversible step. Alternatives and exclusions are both named, not inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_quotecreate_xero_quoteAInspect
Proposes creating a new quote in this Xero organisation - it does NOT create anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Tell the user what you are proposing (contact, line items, total) and that it needs their approval in Invio before it goes anywhere - do not describe it as created, sent, or delivered. contactId must come from list_xero_contacts (never invented); if the contact doesn't exist yet, propose it with create_xero_contact first and wait for that to be approved and executed. Even once approved, Xero's "SENT" status is only an internal label - this connector has no way to email or deliver the quote to the customer at any status, and never will on its own; a human still shares it from within Xero itself, or another channel, whenever they choose to. You CAN state a currency (currency, e.g. "NZD") when the user names one - it is checked against the organisation's own configured currencies, and refused with the real list if it is not one of them, so a currency is never silently swapped for the base currency. You CAN also say whether the amounts include tax (lineAmountTypes): use "INCLUSIVE" for "$1,500 including GST", "EXCLUSIVE" (the default) for "$1,500 plus GST", "NOTAX" for no tax at all. Never adjust the numbers yourself to fake either one. You CAN also set a quoteNumber, reference, expiryDate, title, summary or terms whenever the user gives you one - every one of them is optional and Xero fills in its own sensible default (an auto-assigned number, no expiry, blank text) when omitted. DATES: date and expiryDate are strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts a quote a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | Date the quote was issued, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| terms | No | Terms and conditions text shown on the quote. | |
| title | No | A short title for the quote (e.g. "Kitchen renovation"), shown at the top of it. | |
| status | No | What state the quote lands in inside Xero once a human approves this in Invio. Defaults to "DRAFT". Xero also documents "SENT" as directly creatable, but SENT is only Xero's own internal status label - choosing it does NOT email or deliver the quote to the contact, and this connector has no way to do that at any status. Only pass "SENT" when the user explicitly wants the quote marked that way in Xero (e.g. because they already shared it some other way); otherwise leave this as the default. | DRAFT |
| summary | No | A longer free-text summary of what the quote covers. | |
| currency | No | The currency this quote is raised in, e.g. "NZD". Set this whenever the user names a currency or a currency symbol ("NZ$1,500", "quote them in USD") - it is checked against the currencies this organisation is actually set up to invoice in, and the draft is refused, with the real list, if it is not one of them. Omit it only when the user did not say: the quote is then raised in the organisation's own base currency. | |
| contactId | Yes | The Xero contact this quote is for. Get this from list_xero_contacts first - never invent one. If the contact does not exist in Xero yet, use create_xero_contact first, wait for it to be approved and executed, then use the contactId it produced. | |
| lineItems | Yes | ||
| reference | No | Free-text reference shown on the quote. | |
| expiryDate | No | Date this quote expires, YYYY-MM-DD. Set it whenever the user says one ("valid for 30 days", "expires end of month"). If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| quoteNumber | No | A specific quote number to use, if the user names one. Omit this and Xero assigns the next number in its own sequence automatically - that is the right choice unless the user explicitly asks for a particular number. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| lineAmountTypes | No | How to read every unitAmount below. "EXCLUSIVE" (the default) = the amounts do NOT include tax and Xero adds it on top - this is what "$1,500 plus GST" means. "INCLUSIVE" = the amounts ALREADY include tax and Xero works the tax out of them - this is what "$1,500 including GST", "$1,500 inc GST" or "$1,500 all up" means. "NOTAX" = no tax is calculated at all. If the user says which one they mean, say so here rather than adjusting the numbers yourself. | EXCLUSIVE |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false): it discloses the human-approval queue, that the agent cannot self-approve, that approvalUrl in the response is the approval link, that no email/delivery happens at any status, that currency is validated against configured org currencies and refused with the real list, and that accountCode is auto-filled only when exactly one default exists. That is precisely the mutation-risk context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly: the single most important fact (this creates nothing until a human approves) is the opening clause. It is long, and some beats repeat ('and never will on its own' appears twice, the bare-date caution appears in both description and three schema fields), but given the ambiguity and irreversibility risks, most sentences do earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter mutation queued behind human approval with no output schema, the description covers what an agent needs to call it correctly and to speak to the user accurately — proposal summary content, the approval URL, the 'do not say created/sent/delivered' instruction, date conversion, tax-inclusivity, and the currency refusal path. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 92%, so the baseline is 3; the description nonetheless adds meaning the schema does not — the locale convention that this account writes day-first, so a bare '9/8' means 9 August, plus the requirement to state the reading aloud and to ask when the user's own wording conflicts. The lineAmountTypes and currency explanations largely restate the schema enums/patterns, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('proposes creating a new quote in this Xero organisation') and immediately disambiguates what the tool does NOT do — it does not create anything in Xero, it queues a pending change. That distinguishes it cleanly from real-write siblings like create_xero_invoice and from read siblings like get_xero_quote/list_xero_quotes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: contactId must come from list_xero_contacts, and if the contact doesn't exist, propose create_xero_contact first and wait for execution. It also gives conditional guidance for status (SENT only when the user explicitly wants that label), currency, lineAmountTypes, and optional fields — when to set them versus let Xero default.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_xero_timesheetcreate_xero_timesheetAInspect
Proposes a DRAFT timesheet for one employee/period, for Australian, New Zealand or United Kingdom organisations - it does NOT touch Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. employeeId and payrollCalendarId must both come from list_xero_payroll_employees (never invented) - use that SAME employee's own payrollCalendarId field. lines is date-keyed: one entry per day actually worked, each naming an earningsRateId and how many hours. For Australia, use that SAME employee's own ordinaryEarningsRateId (from list_xero_payroll_employees) unless the user names a different rate. For New Zealand and the United Kingdom, an employee record carries no earnings rate of its own - call list_xero_payroll_earnings_rates first and use the RegularEarnings-type rate unless the user names a different one. For New Zealand and the United Kingdom, startDate/endDate must span the employee's WHOLE payroll-calendar period (e.g. Monday to Sunday on a weekly calendar), not just the days actually worked - a shorter period was refused live even though every line inside it was valid; days with no hours simply carry no line (observed live 12 September 2026, not stated in Xero's own spec). The created timesheet starts as a Xero-side DRAFT once approved - a human remains free to review or change it inside Xero afterwards, unlike post_xero_pay_run. This tool cannot say whether Xero will accept the earnings rate or the calendar for this employee - a mismatch is refused, cleanly, only once a human approves.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | Yes | One entry per day actually worked - omit days with no hours rather than including a zero. | |
| endDate | Yes | End of the timesheet period, YYYY-MM-DD. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. For New Zealand and the United Kingdom, this period must span the employee's WHOLE payroll-calendar period (for example, Monday to Sunday on a weekly calendar), not just the days actually worked - a shorter period was refused live even though every line inside it was valid. Days with no hours simply carry no line at all; the period itself still has to cover the full calendar cycle. Observed live 12 September 2026, not stated in Xero's own API specification. | |
| startDate | Yes | Start of the timesheet period, YYYY-MM-DD (AU: exactly 7 days including endDate). If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. For New Zealand and the United Kingdom, this period must span the employee's WHOLE payroll-calendar period (for example, Monday to Sunday on a weekly calendar), not just the days actually worked - a shorter period was refused live even though every line inside it was valid. Days with no hours simply carry no line at all; the period itself still has to cover the full calendar cycle. Observed live 12 September 2026, not stated in Xero's own API specification. | |
| employeeId | Yes | Get this from list_xero_payroll_employees first - never invent one. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| payrollCalendarId | Yes | Get this from the SAME employee's own payrollCalendarId field on list_xero_payroll_employees - never invent one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: it discloses that the call creates only a queued pending change, that a human must approve before Xero is touched, that the agent cannot self-approve, that the resulting record is a Xero-side DRAFT (unlike post_xero_pay_run), and that invalid earnings-rate/calendar combinations fail only at approval time. Annotation hints (readOnlyHint=false, destructiveHint=false, openWorldHint=true, idempotentHint=false) are consistent and the description adds the missing causal detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the most important fact (draft, human approval required, Xero untouched) and every sentence carries operational content. It is long and single-block, and repeats the NZ/UK whole-calendar-period rule that already appears twice in the schema, which costs some readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-param, no-output-schema mutation tool it covers the approval lifecycle, return field (approvalUrl), region branches and known live-observed quirks well. However, the schema says to 'Follow the DATES instruction in this tool's description' for ambiguous numeric dates, and no such instruction exists here — leaving a real ambiguity-handling gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description still adds cross-parameter logic — region-dependent selection of earningsRateId, reusing the same employee's ordinaryEarningsRateId for AU, and the whole-payroll-period rule for NZ/UK dates. Much of this duplicates the schema's own field descriptions, so it is additive but not uniquely informative.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes a DRAFT timesheet for one employee/period') plus the supported regions and the explicit scope limit ('does NOT touch Xero itself'). It also distances itself from the sibling post_xero_pay_run, so an agent can tell the two apart without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear prerequisites and ordering: employeeId and payrollCalendarId must come from list_xero_payroll_employees (same employee), and NZ/UK require list_xero_payroll_earnings_rates first. It also names the human-approval path (approvalUrl, approve_xero_pending_change context) and contrasts behaviour with post_xero_pay_run. It stops short of an explicit 'do not use this when...' exclusion, but the routing guidance is otherwise concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_balance_sheetget_xero_balance_sheetARead-onlyInspect
Balance Sheet report from Xero for the current organisation, as at a date. Read-only. columns gives the as-at period label(s); rows are flattened from Xero's nested section layout (section names the enclosing group, e.g. "Assets" or "Liabilities"; rowType "SummaryRow" marks a subtotal/total, not a line item). currency comes from this organisation's own Xero settings, never assumed - state it whenever relaying a figure from this report. If date was supplied, Xero reports the balance sheet as at the END OF THAT MONTH, not the exact day given - say "as at [end of month]", not the literal date requested. This organisation's financial year is NOT necessarily the calendar year (added 11 September 2026 - see lib/xero/financial-year.ts). financialYear in the result names the organisation's real financial year end and its exact current/previous dates, or says the year end is unknown. Never answer "this financial year", "last financial year", or "year to date" from the calendar year or the organisation's country - use financialYear's current.toDate (or previous.toDate) as date, and state the period you actually used when relaying a figure.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | As-at date, YYYY-MM-DD. Xero reports this as at the END of the month containing this date, not the exact day. Omit for today. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the simple 'readOnlyHint: true' annotation by explaining deep behavioral quirks, such as how Xero flattens nested data into 'columns' and 'rows,' and the complex logic regarding financial year definitions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While long, the description is highly efficient. Every sentence is dedicated to solving a specific ambiguity (date interpretation, data structure, terminology), preventing potential operational errors during invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of financial reporting and Xero's unique data structure, the description is extremely complete. It covers the data source, the date reporting methodology, and the required output style.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description provides vital semantic meaning beyond the schema. It specifies that the 'date' field implies an 'as-at end of month' report, and clarifies the role of the 'organisation' parameter in multi-tenant scenarios.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The tool's purpose is immediately clear: retrieving a Balance Sheet report from Xero. It is specific and distinct from other listed sibling tools like P&L or general report queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides crucial usage guidelines by detailing how Xero interprets the request (e.g., stating that date input results in an 'as at the end of month' report) and strictly forbidding common calendar-based phrasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_credit_noteget_xero_credit_noteARead-onlyInspect
Full detail on one Xero credit note, including line items - creditNoteId must be a Xero CreditNoteID (a GUID) from list_xero_credit_notes, never an Invio id. Read-only. The currency and every amount come straight from this credit note as Xero stored it - never restate them in a different currency or assume they match Invio's.
| Name | Required | Description | Default |
|---|---|---|---|
| creditNoteId | Yes | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, and the description adds genuinely new behavioral context: amounts and currency are as Xero stored them and must not be restated or assumed to match Invio's. It does not cover failure behavior (e.g., not-found or cross-org access), which keeps it short of 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with what is returned, then the ID constraint, then the currency caveat. Every sentence carries decision-relevant information, though the currency warning is slightly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description correctly states what is returned (full detail plus line items) and pre-empts the main downstream misinterpretation about currency and amounts. Missing only edge-case behavior such as not-found handling or multi-org ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 50% schema coverage the description must compensate, and it does for creditNoteId by naming the exact provenance and format (Xero CreditNoteID GUID from list_xero_credit_notes, never an Invio id). The organisation parameter's conditional multi-org rule lives only in the schema, so the description does not fully close the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Full detail on one Xero credit note') plus the scope it returns ('including line items'), which separates it cleanly from list_xero_credit_notes and get_xero_invoice. An agent knows exactly what it gets back.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to list_xero_credit_notes as the source of the ID and warns that an Invio id will not work, which is the main misuse failure mode. No explicit 'when not to use' or comparison to sibling getters like get_xero_quote, but the context is clear enough to select correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_group_reportget_xero_group_reportARead-onlyInspect
Profit and Loss or Balance Sheet for SEVERAL Xero organisations at once, side by side: one row per account, one column per organisation, and a Total column. Read-only. Every figure and every total is added up on Invio's server - relay the returned numbers, never add, subtract or round them yourself. THIS IS A SIDE-BY-SIDE SUM, NOT A CONSOLIDATION. Intercompany balances (loans, sales or recharges between these organisations) are NOT eliminated and are counted on both sides; accounts are matched only by exact account code, or by exact name where an account has no code - there is NO account mapping, so differently-named or differently-numbered accounts stay as separate rows; and NO currency is converted. Never call the result consolidated statements: say "combined" or "side by side", and say plainly that intercompany items are still in it. SINGLE CURRENCY ONLY: if the chosen organisations do not all report in the same base currency the call is refused and each organisation's currency is listed - tell the person, and offer to run it for the organisations that share a currency. By default it covers EVERY organisation this connector token may use within the account's plan limit (organisations outside the limit are named in warnings); pass companies - display names exactly as list_xero_organisations shows them - to choose some. A team member restricted to certain organisations only ever gets those. IF ANY ONE ORGANISATION CANNOT BE READ (access revoked, a missing report permission, a rate limit, a timeout) THE WHOLE CALL FAILS and names it, with the reason - there is NO partial total. Tell the person which organisation failed and why; only if they agree to leave it out, call again with companies naming just the others. report "profit_and_loss" takes fromDate and toDate TOGETHER (YYYY-MM-DD) or neither (Xero then gives the CURRENT calendar month) - never one alone; "balance_sheet" takes date (Xero reports it as at the END of that month, not the exact day - say "as at [end of month]") and uses only the as-at column per organisation, not Xero's prior-year comparison column. One date range is applied to every organisation, but organisations can have different financial year ends: organisationDetails[].financialYear shows each one's - for "this financial year", only use this tool if they agree, otherwise say they differ. Each row's matchedBy says how it was matched ("account_code", "account_name", "report_label" for subtotals, or "single_organisation" when only one organisation has it); values lines up with columns (organisations in order, Total last) and a null means that organisation has no figure on that row - not zero. Always state the currency and the period when relaying a figure, and report every entry in warnings and every row conflicts to the person - do not smooth them over. Where one organisation is wanted on its own, use get_xero_profit_and_loss or get_xero_balance_sheet instead. Up to 30 organisations per call.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | balance_sheet only. As-at date, YYYY-MM-DD. Xero reports the balance sheet as at the END of the month containing this date, not the exact day. Omit for today. | |
| report | Yes | Which report to add up across the organisations: "profit_and_loss" or "balance_sheet". | |
| toDate | No | profit_and_loss only. End date, YYYY-MM-DD. Supply together with fromDate, or omit both. Never alone. | |
| fromDate | No | profit_and_loss only. Start date, YYYY-MM-DD. Supply together with toDate, or omit both (Xero then uses the CURRENT calendar month). Never alone. | |
| companies | No | Which organisations to include, by display name exactly as list_xero_organisations shows them. Omit to include EVERY organisation this connector token may use within the account's plan limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint/openWorldHint; the description carries the real behavioral burden and does so thoroughly: server-side arithmetic that must not be re-derived, no intercompany elimination, no account mapping, no currency conversion, single-currency refusal with per-org currency listing, all-or-nothing failure with no partial totals, and reporting of `warnings`/`conflicts`. This is exactly the context annotations cannot supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly — the identity of the tool, its read-only nature and the not-a-consolidation warning come before any mechanics. It is a dense, long block, though, and some rules (the date-pairing rules for profit_and_loss and balance_sheet) restate the schema verbatim and could be trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter, output-schema-less aggregation tool whose failure modes are non-obvious, the description covers everything an agent needs: date semantics, matching semantics, null-versus-zero, currency constraints, partial-failure policy, output field meaning, and the correct user-facing vocabulary. There is no meaningful gap left for the caller to guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and much of the description's parameter text (date pairing, end-of-month behaviour, display names, 30-org cap) duplicates the schema verbatim. It does add genuine meaning beyond the schema, though: that `companies` selection is bounded by the org's base currency, that restricted team members only ever see their own orgs, and that `matchedBy`/`values` positionally line up with `columns` with null meaning no figure rather than zero.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb-resource-scope statement: side-by-side P&L or Balance Sheet across several Xero organisations, one row per account, one column per org plus Total. It explicitly contrasts itself with get_xero_profit_and_loss and get_xero_balance_sheet, so an agent can pick the right sibling without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names when to use it (multi-org) versus the single-org siblings, plus concrete decision rules: omit `companies` for all orgs, pass `companies` by display name to narrow, retry with a reduced `companies` list only if the person agrees to drop the failed org. It even covers the 'different financial year ends' case and tells the agent to ask first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_invoiceget_xero_invoiceARead-onlyInspect
Full detail on one Xero invoice, including line items - invoiceId must be a Xero InvoiceID (a GUID) from list_xero_invoices, never an Invio invoice id. Read-only. The currency and every amount come straight from this invoice as Xero stored it - never restate them in a different currency or assume they match Invio's.
| Name | Required | Description | Default |
|---|---|---|---|
| invoiceId | Yes | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so 'Read-only' is partly redundant. The description still adds real context beyond annotations: it specifies that currency and amounts are exactly as Xero stored them and must not be restated or assumed to match Invio's values, which is a meaningful data-fidelity caveat for an agent relaying numbers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with what is returned, then the id constraint, then the data-fidelity warning. Every sentence earns its place; only the 'Read-only' clause is slightly wasted given the annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does enough to set expectations: full invoice detail including line items, with currency/amounts as stored by Xero. For a two-parameter read tool with annotation coverage, the remaining gap (exact fields returned, error behavior for bad ids) is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: `organisation` is documented in the schema, but `invoiceId` carries only a uuid pattern with no prose. The description fills exactly that gap, insisting the value is a Xero InvoiceID GUID sourced from list_xero_invoices and not an Invio invoice id — critical disambiguation. It says nothing extra about `organisation`, but the schema already handles that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Full detail on one Xero invoice, including line items') and implicitly contrasts with list_xero_invoices by naming it as the source of the id. An agent can tell this is the single-record detail read versus the list sibling without inspecting either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to obtain `invoiceId` from list_xero_invoices and warns against an Invio invoice id, which routes usage clearly. It doesn't state exclusions against other siblings (e.g. get_xero_credit_note, get_xero_quote), so it stops short of full alternative coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_leave_balancesget_xero_leave_balancesARead-onlyInspect
This organisation's employee leave balances (annual leave, personal/sick leave and any other leave types Xero has set up) - by name, in the units Xero tracks them in (usually Hours, or Dollars for some New Zealand leave types). Read-only, for Australian, New Zealand and United Kingdom organisations (this refuses plainly for any other country). Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no payroll data. Pass employeeId to get one employee (from list_xero_payroll_employees); omit it for every active employee. For Australia that means up to 100, one page only - use employeeId for anyone beyond that. For New Zealand and the United Kingdom, "every employee" is capped at 25 (leave balances are a separate call per employee for those two regions, unlike Australia) - truncated: true on the result means more active employees exist than were fetched; say so and suggest employeeId for anyone missing rather than presenting the list as complete. Each balance carries negative: true when the employee has taken more of that leave type than they have accrued - point those out plainly, do not just report the raw number. This tool cannot say whether a leave request has been approved, paid, or reported to any tax authority - only the current balance Xero holds.
| Name | Required | Description | Default |
|---|---|---|---|
| employeeId | No | One employee, by their Xero EmployeeID. Omit for every employee. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| includeInactive | No | Include terminated employees too. Omit or false for active employees only (Xero's own EmployeeStatus: ACTIVE or TERMINATED). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint/openWorldHint, it discloses supported countries, refusal behavior for unsupported countries or incomplete payroll setup/admin access, pagination and truncation limits, and negative balance semantics. It also states what the tool cannot determine, such as leave approval or tax reporting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and every major clause carries useful operational information, but it is a single dense paragraph with several long run-on sentences. The content earns its place, though segmentation would improve readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of an output schema and the tool's regional/pagination complexity, the description is complete: it covers return shape, units, negative balances, truncation, prerequisites, and limitations. An agent has enough information to call it correctly and interpret common edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful employeeId semantics: where to get it, what omitting it means, and how regional caps affect fetching all employees. It does not add much for organisation or includeInactive beyond the schema, so it is not a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact resource: employee leave balances by name and units, with annual/personal/other leave types. It clearly distinguishes this from leave-request approval/payment tools and points to list_xero_payroll_employees as the source for employeeId.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage rules: pass employeeId for one employee, omit it for every active employee, and use employeeId beyond Australia's one-page cap. It also explains the NZ/UK 25-employee cap, what truncated:true means, and how to respond when payroll setup or admin access is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_outstanding_receivablesget_xero_outstanding_receivablesARead-onlyInspect
Who owes this business money in Xero right now, and how much - aggregated per contact from unpaid and partially-paid sales invoices (Type ACCREC, Status AUTHORISED). Read-only. Chosen over Xero's own AgedReceivablesByContact report because that report requires naming ONE contact per call and cannot answer an organisation-wide question. Amounts are grouped by currency (a Xero organisation can invoice in more than one) - if currencies has more than one entry, report each currency total separately rather than adding them together. truncated: true means more unpaid invoices exist than this tool scanned; say so rather than presenting the totals as exhaustive. unusableAmountCount (when greater than 0) means that many AUTHORISED sales invoices had no reliable amount-due figure from Xero and were EXCLUDED from every total, count and contact below - say so too, and never treat them as paid off just because they are absent from the numbers. OVERDUE MEANS THE DUE DATE IS STRICTLY BEFORE overdueAsOf, the calendar day this call was measured against: an invoice due ON that day is NOT overdue and is not in overdueTotal, because the customer still has that whole day to pay. timeZone is the zone that day was computed in and timeZoneSource says where it came from: 'organisation' means it is the organisation's own timezone from Xero, and any other value means Xero did not give one and the day was computed in UTC instead, so an invoice due within a day of now may be classified against a date up to a day away from the organisation's own. Do not recompute overdue yourself from oldestDueDate and your own clock - your clock is not the organisation's.
| Name | Required | Description | Default |
|---|---|---|---|
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is consistent with the stated "Read-only". Beyond annotations, the description discloses the pagination/scan limit behind `truncated`, the exclusion of invoices with no reliable amount due, the strict-before rule for overdue, and the timezone source fallback to UTC — all behavioural traits annotations do not carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, and every subsequent sentence carries real semantics rather than filler. It is dense and runs long — several 'do not do X' warnings could be tightened — but nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain the return shape, and it does: `currencies`, `truncated`, `overdueTotal`, `overdueAsOf`, `timeZone`, `timeZoneSource`, `unusableAmountCount`, `oldestDueDate`. It also warns against recomputing overdue from the agent's own clock, which is exactly the failure mode this tool would otherwise invite.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one optional parameter (`organisation`), and the schema already documents it at 100% coverage, including the omit-when-single-organisation guidance. The description adds nothing further to the parameter itself — correct baseline is 4 for a near-zero-param tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a plain-language question the tool answers ("Who owes this business money in Xero right now, and how much") and then specifies the exact data source and filters: aggregated per contact, unpaid/partially-paid ACCREC invoices with Status AUTHORISED. This is specific enough to distinguish it from list_xero_invoices and from Xero's own receivables reporting, which it explicitly names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative (AgedReceivablesByContact) and states the concrete reason it loses here — that report requires naming ONE contact per call and cannot answer an organisation-wide question. It also tells the agent how to interpret edge cases (`truncated`, multiple currencies, `unusableAmountCount`) rather than leaving them to guess.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_pay_run_summaryget_xero_pay_run_summaryARead-onlyInspect
What one pay run cost all-in, its status (DRAFT or POSTED), and a comparison against the PREVIOUS pay run of the SAME payroll calendar: each employee paid in both runs, with their net pay and net change; everyone flagged with largeChange: true when that change is 20% or more either way (this connector's own threshold, not Xero's); anyone paid in this run but not the previous one (newThisRun); anyone paid in the previous run but not this one (notPaidThisRun - could mean terminated, on unpaid leave, or simply not rostered this cycle; this tool cannot tell which). Omit payRunId for the most recent pay run. Read-only, for Australian, New Zealand and United Kingdom organisations (this refuses plainly for any other country - see list_xero_payroll_employees for the same gate). Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no payroll data. wages/tax/super on the pay run itself are Australia only; New Zealand and the United Kingdom instead report totalCost - see list_xero_pay_runs for why. A large swing in net pay often reflects a change in hours worked, but can equally be a bonus, an allowance, leave taken or a tax change - say that it moved, not why. THIS TOOL CANNOT SAY WHETHER A PAY RUN HAS ACTUALLY BEEN PAID OUT OR REPORTED TO ANY TAX AUTHORITY (there is no ATO/IRD/HMRC filing status in any of the three regions' Payroll APIs, and never will be) - only what Xero itself has recorded for the pay run.
| Name | Required | Description | Default |
|---|---|---|---|
| payRunId | No | One pay run, by its Xero PayRunID. Omit for the most recent pay run. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnly/openWorld, so the description carries the real behavioral load and does: region gating, the Payroll-setup and payroll-admin prerequisites, the fact that failure is a hard refusal not an empty result, and the important disclosure that largeChange is the connector's own 20% threshold rather than Xero's. It also draws explicit epistemic boundaries (cannot distinguish terminated vs unpaid leave vs not rostered; cannot report payment or ATO/IRD/HMRC filing status), which prevents confidently wrong answers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The lead clause is well front-loaded (cost, status, comparison), but the rest is a single dense paragraph of ~250 words where region field differences, prerequisite failures, and interpretation caveats run together without segmentation. Nearly every sentence is useful, but the lack of structure makes it harder to scan than the content warrants.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must describe the return shape and does so thoroughly: per-employee net pay and net change, largeChange flagging, newThisRun/notPaidThisRun sets, and the wages/tax/super versus totalCost split by region. Combined with the refusal semantics, an agent has everything needed to call it and interpret or explain the result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and both parameters are already documented in-schema (payRunId omit-for-latest, organisation only when multi-org). The description's 'Omit payRunId for the most recent pay run' largely restates the schema rather than adding syntax, defaults, or edge cases beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a very specific verb+resource: the all-in cost of one pay run, its DRAFT/POSTED status, and a per-employee comparison against the previous run of the same calendar. It is unmistakable against siblings like list_xero_pay_runs (enumeration) and create_xero_pay_run/post_xero_pay_run (mutation), and it even names the comparison sets (newThisRun, notPaidThisRun) it returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete selection rules: omit payRunId for the most recent run, only pass organisation when the connection spans multiple orgs, and it plainly states the tool refuses outside AU/NZ/UK and when Payroll setup or admin access is missing, instructing the agent to report the refusal rather than imply empty data. It points to list_xero_pay_runs and list_xero_payroll_employees for related context, though it never explicitly says 'use list_xero_pay_runs to enumerate runs first' — the sibling routing is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_profit_and_lossget_xero_profit_and_lossARead-onlyInspect
Profit and Loss report from Xero for the current organisation, for a date range. Read-only. columns gives the period label(s) for the numbers in each row; rows are flattened from Xero's nested section layout (section names the enclosing group, e.g. "Income" or "Operating Expenses"; rowType "SummaryRow" marks a subtotal/total, not a line item - do not double-count a SummaryRow alongside the rows it totals). currency comes from this organisation's own Xero settings, never assumed from anything about the Invio account asking the question - state it whenever relaying a figure from this report. fromDate and toDate must be supplied TOGETHER or OMITTED TOGETHER - never just one; supplying only one is rejected rather than silently widened (see each argument's own description for why). This organisation's financial year is NOT necessarily the calendar year (added 11 September 2026 - see lib/xero/financial-year.ts). financialYear in the result names the organisation's real financial year end and its exact current/previous dates, or says the year end is unknown. Never answer "this financial year", "last financial year", or "year to date" from the calendar year or the organisation's country - use financialYear's dates as fromDate/toDate, and state the period you actually used when relaying a figure.
| Name | Required | Description | Default |
|---|---|---|---|
| toDate | No | End date, YYYY-MM-DD. Must be supplied together with fromDate, or omitted together with it - never alone, for the identical reason. Omit both to get the CURRENT calendar month. | |
| fromDate | No | Start date, YYYY-MM-DD. Must be supplied together with toDate, or omitted together with it - never alone (Xero would default toDate to the end of the CURRENT month, not the month fromDate is in). Omit both to get the CURRENT calendar month. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantive behavior: currency is sourced from the organisation's own Xero settings and must be stated when relaying figures, a lone date argument is rejected rather than silently widened, and the organisation's financial year may not be the calendar year with financialYear in the result resolving it. It also warns against double-counting SummaryRow alongside the rows it totals — real, non-obvious semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The critical scoping rules are front-loaded, but the together-or-omitted rule appears in the description and again in both parameter descriptions, and the parenthetical cross-reference '(see each argument's own description for why)' plus the changelog artifacts '(added 11 September 2026 - see lib/xero/financial-year.ts)' are internal noise that does not help an agent invoke the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so: it explains columns as period labels, rows as flattened sections with rowType semantics, currency provenance, and financialYear contents. Combined with the invocation constraints, an agent has enough to call it and to report results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns above that by tying fromDate/toDate to financialYear's dates as the authoritative source for named periods, which the schema does not say. The `organisation` parameter is left entirely to the schema, and the columns/rows discussion describes returns rather than inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb+resource (retrieve the Profit and Loss report from Xero) and its scope (current organisation, date range), which is clearly distinct from the create/list/approve siblings. It stops short of naming the adjacent reporting siblings (get_xero_balance_sheet, get_xero_group_report), so an agent must infer which report type fits a given request.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit constraints on invocation: fromDate and toDate must be supplied or omitted together, omitting both yields the current calendar month, and 'this financial year'/'year to date' must be derived from the returned financialYear rather than the calendar year or country. No guidance on when to pick this report over the balance sheet or group report siblings, which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_projectget_xero_projectARead-onlyInspect
Full detail on one Xero Projects job, including what it has cost and what it has earned so far - projectId must be a Xero ProjectID (a GUID) from list_xero_projects, never guessed. Read-only. Covers time logged against tasks (totalTaskAmount), expenses logged (totalExpenseAmount), what has already been invoiced versus what is still to invoice (taskAmountInvoiced/taskAmountToBeInvoiced and the expense equivalents, plus the combined projectAmountInvoiced), any deposit taken and applied, and any credit notes raised against this project. Every money figure carries its own currency straight from Xero - never restate it in a different currency or assume it matches Invio's. If this call fails with an unauthorized/401-style error, it can mean this Xero organisation's plan does not include Xero Projects, or that this connection's Xero Projects access needs to be reconnected - say so rather than treating it as a generic failure.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
'Read-only' merely restates readOnlyHint, but the description adds substantial context the annotations cannot: the 401 may mean the Xero plan lacks Projects or the connection needs reconnecting, and every money figure carries its own Xero currency that must not be restated. Those are non-obvious failure and interpretation behaviors an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, with constraints and currency/error caveats after. The long enumeration of cost and invoice fields is dense but earns its place as a stand-in for the missing output schema; it could be tightened by grouping the invoiced/to-invoice pairs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description deliberately names the return fields (totalTaskAmount, totalExpenseAmount, projectAmountInvoiced, deposits, credit notes) so the agent knows what the response contains. ID sourcing, currency semantics, and failure modes are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (only `organisation` is documented in the schema); the description compensates by pinning `projectId` to a Xero ProjectID GUID sourced from list_xero_projects. It does not address `organisation`, but the schema already explains the single-vs-multi-org rule.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opening clause gives a specific verb and resource ('Full detail on one Xero Projects job') plus the scope of what is returned (cost, earned). It is clearly distinguishable from the sibling list_xero_projects, which is named as the only legitimate source of the ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states that `projectId` must come from list_xero_projects and 'never guessed', which is a real usage constraint. It also tells the agent how to interpret a 401 rather than accept a generic failure, though it never states when to prefer a sibling over this tool beyond the ID-sourcing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_xero_quoteget_xero_quoteARead-onlyInspect
Full detail on one Xero quote, including line items, title, summary and terms - quoteId must be a Xero QuoteID (a GUID) from list_xero_quotes, never an Invio id. Read-only. The currency and every amount come straight from this quote as Xero stored it - never restate them in a different currency or assume they match Invio's. A status of SENT means Xero has this quote marked as sent - it does NOT prove the quote was ever actually emailed or delivered to the contact.
| Name | Required | Description | Default |
|---|---|---|---|
| quoteId | Yes | ||
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond what readOnlyHint/openWorldHint already declare: it warns that currency and amounts are authoritative as Xero stored them and must never be restated or converted, and it clarifies that a SENT status does not prove delivery. Both are non-obvious behavioral caveats an agent could not infer from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each carrying distinct payload: purpose/contents first, then the ID constraint, then data-fidelity and status caveats. No filler and the primary purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still tells the agent what comes back (line items, title, summary, terms) and how to interpret amounts and status. Nothing an agent needs to call this correctly and interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema documents only 50% of parameters (organisation has a description; quoteId has format/pattern but no prose). The description compensates by explaining what quoteId actually is and where to obtain it, which is the more important half. The organisation parameter is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: "Full detail on one Xero quote", and enumerates what detail means (line items, title, summary, terms). This cleanly separates it from list_xero_quotes and the many get_xero_* siblings that target different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The ID provenance rule ("must be a Xero QuoteID (a GUID) from list_xero_quotes, never an Invio id") effectively routes the agent to the listing tool first and blocks a common wrong-ID failure. It gives clear use context but no explicit when-not-to-use case, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_changeslist_pending_changesARead-onlyInspect
Lists the changes YOU (or another assistant on this account) have proposed against Xero - across every organisation this token may reach, not just the current one. Read-only; nothing is created or changed. Three groups: "pending" rows are still awaiting approval or rejection; "needsAttention" rows are not (a write that failed, or one stuck mid-execution) but are worth mentioning because something the person authorised did not visibly happen; "history" is the most recent already-resolved rows (approved-but-not-yet-sent, sent, rejected, expired, or cancelled) - use it to answer "what happened to the thing I approved last week" rather than telling the user to go check Xero. A row whose approval window has simply run out is reported here too, as status "expired" - Invio moves it into history on its own within about an hour, and this tool already reports it that way immediately, before that background sweep gets to it; it never counts as still "pending" and never counts toward maxOpenPendingChanges below. A failed or stranded row in needsAttention/history carries errorMessage/errorCode explaining why, and a sent one carries result with the id/number Xero assigned. Every row carries approvalUrl - the same link a draft-creating tool's own result carries - point the user at it rather than inventing a path. Use this when asked "what am I waiting to approve" or "what happened to X", after drafting several changes in one conversation to summarise what is now queued, or before drafting another change against the same invoice/contact to check whether an earlier one is still unresolved. If truncated is true, more pending/needsAttention changes matched than were returned - say so rather than presenting the two lists as everything waiting, and suggest approving or rejecting some before asking again. maxOpenPendingChanges is the most "pending" changes this account may have open at once before drafting a new one is refused - if pending.length is getting close to it, mention that to the user before it becomes a failed draft.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses rich behavioral details: the three groups' semantics, the 'expired' status and its immediate reporting before the background sweep, the presence of errorMessage/errorCode on failed rows, the result field on sent rows, and the approvalUrl linkage. It also explains truncation behavior and the maxOpenPendingChanges constraint. This far exceeds what annotations provide and fully informs the agent of side effects and edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long (~200 words) but every sentence carries essential information given the tool's complexity (three groups, special statuses, truncation, quota). It is structured logically: purpose, group definitions, special cases, usage guidance, and actionable notes. No fluff; each sentence earns its place. For a zero-parameter tool that returns complex data, this is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description carries the full burden of explaining the tool's behavior. It covers the three return groups, the meaning of fields like errorMessage, result, and approvalUrl, the expiration handling, truncation semantics, and the pending-changes quota. It leaves nothing an agent needs to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters (input schema is empty), so the baseline is 4. The description doesn't need to add parameter semantics, but it does clarify the output structure (groups, fields, statuses) which indirectly helps understand what the tool returns. Since there are no parameters, no additional value is required, and the description appropriately omits parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('lists') and resource ('changes YOU (or another assistant) have proposed against Xero'), and explicitly defines three output groups (pending, needsAttention, history). It distinguishes itself from sibling tools like approve_xero_pending_change and the creation tools by focusing on listing proposed changes across all organisations. The inclusion of 'across every organisation this token may reach' adds a precise scope that leaves no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use conditions: 'Use this when asked "what am I waiting to approve" or "what happened to X", after drafting several changes in one conversation to summarise what is now queued, or before drafting another change against the same invoice/contact to check whether an earlier one is still unresolved.' It also gives a negative directive: avoid telling the user to check Xero for history, since this tool covers it. This is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_accountslist_xero_accountsARead-onlyInspect
This organisation's chart of accounts from Xero. Read-only; nothing is created or changed. Some accounts, most often a bank account, have code: null - Xero genuinely has no code for them; use that account's exact name instead wherever a tool accepts one (create_xero_payment's own bankAccountName), never invent a code for it. Use this BEFORE proposing an accountCode on a create_xero_invoice or update_xero_invoice line item - accountCode must be a real code from this list, never invented or guessed (an invented code is rejected before you can even propose the change). If none obviously fits, omit accountCode entirely: for a DRAFT invoice a human fills it in later in Xero; for an AUTHORISED invoice (the default), this connector fills in the organisation's own single active default account automatically when there is exactly one, or asks you to choose from this list when there is more than one. taxType here is each account's OWN default tax type - a useful hint, but not the exhaustive list of every tax rate this organisation has configured, so a line item is free to use a different valid one; if unsure, omit taxType too. Prefer accounts with status ACTIVE for a new line item - an ARCHIVED code still exists but Xero may refuse to post to it, and on an AUTHORISED invoice this connector refuses one outright rather than risk that.
| Name | Required | Description | Default |
|---|---|---|---|
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint/openWorldHint; the description adds real behavioral context beyond them: null `code` values are genuinely absent in Xero, invented codes are rejected pre-proposal, ARCHIVED accounts may be refused by Xero and are refused outright by this connector on AUTHORISED invoices. `taxType` is scoped as a per-account default rather than the org's exhaustive rate list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool is and its read-only nature, then the operational rules. The long middle sentence following the null-`code` explanation is dense and could be split, but every sentence carries actionable content rather than repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by explaining the shape of the returned data (`code`, `name`, `taxType`, `status`) and how each field should be used downstream. An agent has everything it needs to call this and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter (`organisation`) at 100% schema description coverage, so the schema already carries its meaning (display name, omit when single org). The description adds nothing about it, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: this organisation's chart of accounts from Xero, plus an explicit read-only statement. It is immediately distinguishable from the many create_/update_/get_ siblings because it frames itself as the lookup source those tools depend on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit ordering ('Use this BEFORE proposing an accountCode on a create_xero_invoice or update_xero_invoice line item'), names the fallback when nothing fits (omit accountCode), and explains what happens in each case (DRAFT filled by human, AUTHORISED auto-filled or prompted). It also names create_xero_payment's bankAccountName as the place to use `name` instead of `code`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_contactslist_xero_contactsARead-onlyInspect
List contacts (customers and/or suppliers) from Xero for the current organisation. Read-only; nothing is created or changed. Where present, accountsReceivableOutstanding/Overdue come straight from Xero for that contact - never sum these yourself across contacts to answer "who owes me the most", use get_xero_outstanding_receivables instead, which already aggregates that correctly (including across pages and currencies). status is this contact's own Xero status - "ACTIVE" or "ARCHIVED" - relayed as Xero has it, never filtered out; mention it if relevant (e.g. before suggesting this contact for a new invoice or contact update) rather than assuming every listed contact is currently usable.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| includeArchived | No | Include archived contacts. Defaults to false (active contacts only). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint=true, so the 'Read-only; nothing is created or changed' sentence is largely redundant. What does add value beyond annotations is the disclosure that accountsReceivableOutstanding/Overdue are raw per-contact figures from Xero (not to be aggregated by the caller) and that `status` is relayed unfiltered, including ARCHIVED, so a listed contact may not be usable. Pagination behaviour and the page cap are left to the schema, keeping it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and read-only status, then the cross-tool disambiguation, then the status caveat. Every sentence carries information, but the final status sentence is long and slightly repetitive of the includeArchived wording; it could be tightened without losing the warning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the key returned fields (accountsReceivableOutstanding/Overdue, status) and their provenance and semantics, and by warning about archived entries. Nothing an agent needs to call this correctly or interpret the response is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description goes beyond it by explaining the practical consequence of `includeArchived` (archived contacts are never filtered out once included, and their `status` must be surfaced) and by defining the `status` vocabulary (ACTIVE/ARCHIVED). It does not clarify the `page` or `organisation` semantics further, which the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List contacts ... from Xero') plus scope ('customers and/or suppliers', 'current organisation'), and explicitly routes the aggregation case to get_xero_outstanding_receivables. An agent can distinguish it from create_xero_contact/update_xero_contact and the receivables tool without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-not: never sum accountsReceivable* across contacts for 'who owes me the most', use get_xero_outstanding_receivables instead. It also gives an explicit downstream usage rule for `status` (mention it before suggesting a contact be invoiced or updated) and states includeArchived defaults to active-only, so the agent knows the shape of the result set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_credit_noteslist_xero_credit_notesARead-onlyInspect
List credit notes from Xero for the current organisation - ACCRECCREDIT (against a sales invoice, reduces what a customer owes) or ACCPAYCREDIT (against a bill, reduces what this business owes a supplier), optionally filtered by status, by issue date range (fromDate/toDate, both inclusive), and by reference (exact match with reference, or a partial case-insensitive match with referenceContains - use exactly one, never both). Read-only; nothing is created or changed. Each credit note carries its OWN currency straight from Xero - never assume it matches this user's Invio business currency. Returns up to 100 credit notes for the requested page; if pageCount shows more pages than were returned, say so rather than implying this is the full list. remainingCredit is how much of each credit note has NOT yet been applied against an invoice or refunded. The result always echoes back exactly which filters were applied (appliedFilters) - relay that, not just your own memory of what you asked for. Use get_xero_credit_note for full line-item detail on one credit note.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number - Xero returns up to 100 credit notes per page. Omit for page 1. | |
| type | No | ACCRECCREDIT = credit notes against sales invoices. ACCPAYCREDIT = credit notes against bills. Omit for both. | |
| status | No | Filter to one Xero credit note status (e.g. AUTHORISED, PAID). Omit for every status. | |
| toDate | No | Only include records dated ON OR BEFORE this issue date, YYYY-MM-DD (inclusive - this IS the last date included, not the day after). | |
| fromDate | No | Only include records dated ON OR AFTER this issue date, YYYY-MM-DD (inclusive). Filters on the issue Date, never the due date. | |
| reference | No | Exact match on the Reference field. Use this when you know the reference verbatim - cannot be combined with referenceContains. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| referenceContains | No | Case-insensitive PARTIAL match on the Reference field (e.g. "1234" matches a reference containing "PO-1234"). Use this when you only know part of the reference. Cannot be combined with reference - if you know the exact text, use reference instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation it adds real context: nothing is created or changed, the 100-per-page cap with pageCount guidance, the warning to relay appliedFilters rather than memory, and the caveat that each credit note carries its own currency. It does not clarify auth/scope requirements or rate limits, so it stops short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and type definitions, and every sentence carries operational content (pagination, currency caveat, appliedFilters, sibling pointer). It is a single dense paragraph that slightly restates the type meanings already in the schema enum descriptions, keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description explains the key return semantics (remainingCredit, appliedFilters, pageCount) so an agent can interpret results correctly. For an 8-param, filter-only read tool this covers everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 8 params; the description nonetheless adds value by reinforcing inclusive fromDate/toDate semantics, the exact-vs-partial reference distinction, and the mutual exclusion rule. It adds marginal but genuine meaning on top of the schema rather than repeating it wholesale.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('List credit notes from Xero for the current organisation') with an immediate disambiguation of the two types (ACCRECCREDIT vs ACCPAYCREDIT) including their business meaning. It also names the sibling it is not (get_xero_credit_note), so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit exclusivity rule: 'use exactly one, never both' for reference vs referenceContains, with the condition that selects each ('when you know the reference verbatim' vs 'only know part'). It also routes to get_xero_credit_note for line-item detail and states that omitted filters mean 'both types' / 'every status'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_invoiceslist_xero_invoicesARead-onlyInspect
List invoices from Xero for the current organisation - sales invoices (ACCREC) or bills (ACCPAY), optionally filtered by status, by issue date range (fromDate/toDate, both inclusive), and by reference (exact match with reference, or a partial case-insensitive match with referenceContains - use exactly one, never both). Read-only; nothing is created, sent or changed. Each invoice carries its OWN currency straight from Xero - never assume it matches this user's Invio business currency. Returns up to 100 invoices for the requested page; if pageCount shows more pages than were returned, say so rather than implying this is the full list. The result always echoes back exactly which filters were applied (appliedFilters) - relay that, not just your own memory of what you asked for. Use get_xero_invoice for full line-item detail on one invoice.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number - Xero returns up to 100 invoices per page. Omit for page 1. | |
| type | No | ACCREC = sales invoices (money owed TO this business). ACCPAY = bills (money this business owes). Omit for both. | |
| status | No | Filter to one Xero invoice status (e.g. AUTHORISED for approved-and-unpaid, PAID for settled). Omit for every status. | |
| toDate | No | Only include records dated ON OR BEFORE this issue date, YYYY-MM-DD (inclusive - this IS the last date included, not the day after). | |
| fromDate | No | Only include records dated ON OR AFTER this issue date, YYYY-MM-DD (inclusive). Filters on the issue Date, never the due date. | |
| reference | No | Exact match on the Reference field. Use this when you know the reference verbatim - cannot be combined with referenceContains. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| referenceContains | No | Case-insensitive PARTIAL match on the Reference field (e.g. "1234" matches a reference containing "PO-1234"). Use this when you only know part of the reference. Cannot be combined with reference - if you know the exact text, use reference instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, yet the description adds substantive behavior: a 100-per-page cap, pageCount-driven pagination meaning it is not necessarily the full list, and the appliedFilters echo that must be relayed rather than reconstructed. It also warns that each invoice carries its own Xero currency, which the annotations cannot convey. Only slight deduction for restating 'read-only; nothing is created' which the annotation already covers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense paragraph that front-loads the core purpose and document types before filters and caveats, with no filler sentences. It loses a point for duplicating schema-level guidance (reference vs referenceContains exclusivity) and for packing several agent-directed instructions into a single run-on block.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With eight optional parameters and no output schema, the description carries the burden well: it describes the return shape (per-invoice currency, pageCount, appliedFilters) and the pagination ceiling, which is exactly what an agent needs to interpret results without an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents inclusivity, the YYYY-MM-DD pattern, the mutual exclusivity of reference/referenceContains, and the organisation-omission rule. The description largely restates these rather than adding new meaning such as reference collation behavior or pageCount signaling thresholds, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list invoices from Xero) and immediately enumerates the two document families (ACCREC sales invoices vs ACCPAY bills), so an agent understands exactly what the result set contains. It also names the sibling get_xero_invoice as the detailed-single-record alternative, distinguishing itself without the schema being opened.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing is given: use get_xero_invoice for full line-item detail on one invoice. It also states the exclusive choice between reference and referenceContains ('use exactly one, never both') and the condition selecting each. Filter-omission semantics (omit status for every status, omit type for both) tell the agent when not to narrow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_organisationslist_xero_organisationsARead-onlyInspect
List the Xero organisations this connector token is currently authorised to read AND that this call is permitted to know about (organisation names only - never an internal id). Account-wide: it does not take an organisation argument and answers the same regardless of which organisation you were just discussing - use it to find the exact name to pass as organisation on another tool, when this connection reaches more than one. withinPlanLimit: false on an entry means it is authorised on Xero but outside this account's current Xero-connector plan limit - a call naming that organisation will be refused; say so plainly rather than trying it anyway. A restricted connector token may not see every organisation on the account - that is by design, not an omission. organisations may come back empty - status says exactly why, never leave that unexplained: "not_connected" (no active Xero connection at all - Xero has not been connected in Settings, or the connection was disconnected), "no_organisations" (Xero is connected but currently authorises zero organisations on it - reconnecting in Settings is the fix), "none_authorised_for_you" (organisations exist on this connection, but this specific connector token is restricted to a set that does not include any of them - ask the account owner to check Settings > Xero > Team), or "connected" (the ordinary case, whether or not the list happens to be empty for another reason).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint, so the description carries the burden of behavioral detail. It explains account-wide behavior, restricted-token visibility, the plan-limit distinction, and the complete set of possible `status` values with their meanings, going well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense and front-loaded: the core purpose comes first, followed by consequential edge cases and status meanings. Every sentence earns its place by carrying operationally important guidance rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain return semantics, and it does: it names the `organisations` and `status` fields, explains `withinPlanLimit: false`, and enumerates all status values and their fixes. It is complete enough for an agent to know what to expect and how to react to every outcome.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4 per the rubric. The description adds relevant context by explicitly stating the tool takes no `organisation` argument and is account-wide, which clarifies why parameter-free invocation is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List the Xero organisations this connector token is currently authorised to read AND that this call is permitted to know about.' It clarifies it returns names only, never internal IDs, and is account-wide, which distinguishes it from the many list_xero_* siblings that target other resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use it: to find the exact organisation name to pass as `organisation` on another tool when the connection reaches more than one organisation. It also gives operational when-not-to guidance by explaining that organisations with `withinPlanLimit: false` will be refused and should be described plainly rather than attempted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_paymentslist_xero_paymentsARead-onlyInspect
List payments already recorded in Xero for the current organisation, optionally filtered by status (AUTHORISED or DELETED), by which invoice they were applied to, and by date range (fromDate/toDate, both inclusive). Read-only; nothing is created or changed - to RECORD a new payment, use create_xero_payment instead. amount is in the linked invoice's own currency, never assume it matches this user's Invio business currency. invoiceId/invoiceNumber are present only when this payment was applied to an invoice specifically - Xero also lets a payment be applied to a credit note, a prepayment or an overpayment, and this tool relays whichever is true rather than guessing. Returns up to 100 payments for the requested page; if pageCount shows more pages than were returned, say so rather than implying this is the full list. The result always echoes back exactly which filters were applied (appliedFilters) - relay that, not just your own memory of what you asked for.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number - Xero returns up to 100 payments per page. Omit for page 1. | |
| status | No | Filter to one Xero payment status: AUTHORISED (the normal, recorded state) or DELETED (reversed). Omit for both. | |
| toDate | No | Only include payments dated ON OR BEFORE this date, YYYY-MM-DD (inclusive). | |
| fromDate | No | Only include payments dated ON OR AFTER this date, YYYY-MM-DD (inclusive). | |
| invoiceId | No | Filter to payments applied to one specific invoice. Omit for every invoice. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past readOnlyHint/openWorldHint: discloses the 100-per-page cap, the pageCount-may-exceed-returned caveat, the appliedFilters echo, the currency-of-linked-invoice trap, and that payments may be applied to credit notes/prepayments/overpayments rather than invoices. These are real behavioral traits an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Six sentences, each carrying distinct information, with the read-only assertion and sibling routing front-loaded. Dense but every clause (currency, invoice-application, pagination, appliedFilters) survives a 'does it earn its place' test; minor trim possible in the invoice-application sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must carry return-shape burden and does: page size, pageCount, appliedFilters echo, conditional invoiceId fields, and currency semantics. An agent has everything needed to call and interpret correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning beyond it: fromDate/toDate both inclusive, status filter is AUTHORISED vs DELETED, and invoiceId/invoiceNumber presence is conditional on payment application type. It does not restate the page/organisation semantics the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) plus resource (payments recorded in Xero) and scope (current organisation), then explicitly contrasts with create_xero_payment. An agent can distinguish it from all 35 siblings without reading any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the write case elsewhere: 'to RECORD a new payment, use create_xero_payment instead.' Also gives the condition for filtering (status, invoice, date range), so when-to-use and when-not-to-use are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_payroll_earnings_rateslist_xero_payroll_earnings_ratesARead-onlyInspect
This organisation's payroll earnings rates (Ordinary Time, Overtime and similar) - name, earnings type, rate type and, where set, the rate itself (a per-unit rate, a multiplier of the ordinary earnings rate, or a fixed amount - only one of the three applies, depending on rateType). Read-only, for Australian, New Zealand and United Kingdom organisations. For Australia, each employee's own ordinaryEarningsRateId (from list_xero_payroll_employees) remains the right default for that employee's own ordinary hours - use this tool when you need a DIFFERENT rate (overtime, an allowance, and similar), since Australia's full list is now readable too, not just the one rate an employee record carries. Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no payroll data. Use this before drafting a New Zealand or United Kingdom timesheet (create_xero_timesheet) - each timesheet line needs a real earningsRateId, and an employee record for those two regions carries no earnings rate of its own to fall back on. When the user has not named a specific rate, use the one whose earningsType is RegularEarnings (New Zealand/United Kingdom) for ordinary hours worked; say so rather than guessing at a name. Returns up to 100 rates for the requested page.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, and the description adds substantial context beyond them: region eligibility (AU/NZ/UK), the requirement that Xero Payroll setup be complete and the connecting user have held payroll administrator access, and the important failure-mode disclosure that a hard refusal must not be reported as an empty list. It also states the 100-item page cap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and region scope are front-loaded, and the longer sentences carry genuinely load-bearing content (auth prerequisites, failure semantics, default-rate rule). It is dense to the point of being a single wall of text with limited visual separation, which slightly hurts scanability, but little is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with no output schema and full schema coverage, the description covers everything an agent needs: what comes back, which regions work, what preconditions can cause failure, how to report a refusal, and how to pick a default rate. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both page and organisation are already documented, establishing a baseline of 3. The description adds useful return-shape context tied to pagination ('up to 100 rates for the requested page'), which helps the agent size its paging strategy beyond what the schema alone conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource and enumerates the returned fields (name, earningsType, rateType, rate), including the rateType-dependent semantics of the rate value. It clearly separates itself from list_xero_payroll_employees by explaining that this tool exposes the full rate list rather than an employee's single default rate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing rules: use list_xero_payroll_employees' ordinaryEarningsRateId for an employee's own ordinary hours, and use this tool when a DIFFERENT rate is needed (overtime, allowance). It also mandates calling this before drafting NZ/UK timesheets because each line needs a real earningsRateId, and prescribes a default selection rule (earningsType=RegularEarnings) when the user names no rate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_payroll_employeeslist_xero_payroll_employeesARead-onlyInspect
This organisation's payroll employees - name, employment status, and (Australia only) whether Xero has a super fund on file for them and their ordinary earnings rate id. Read-only, for Australian, New Zealand and United Kingdom organisations (this refuses plainly for any other country - Xero's Payroll API covers no other region). Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no payroll data. Active employees only unless includeInactive is set. Employment status comes straight from Xero for Australia; for New Zealand and the United Kingdom, Xero sends no status field at all, so it is derived here from whether Xero has recorded an end date - still accurate, just not Xero's own word for it. Super/pension fund membership is ONLY available for Australia from this tool - for New Zealand and the United Kingdom that fact is simply not returned (never a guessed "no fund"), say so rather than assuming everyone lacks one. NEVER returns a tax file number, a bank account or a home address - this tool does not read them from Xero at all. Does NOT know, and cannot answer, whether an employee has been paid, or whether anything has been reported to the ATO (Australia), IRD (New Zealand) or HMRC (United Kingdom) - Xero has no API for lodgement or payment status in any of the three. Returns up to 100 employees for the requested page; treat a full page of 100 as possibly incomplete and ask for the next page rather than assuming it is everyone.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| includeInactive | No | Include terminated employees too. Omit or false for active employees only (Xero's own EmployeeStatus: ACTIVE or TERMINATED). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantial context beyond them: regional API coverage, two distinct hard-refusal preconditions (payroll setup complete, connecting user held payroll admin), the active-only filter, per-country caveats on how employment status is derived, super fund data being Australia-only, and explicit non-disclosure of TFN, bank account and address. This is exactly the extra behavioural context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what is returned and the region gate, and almost every sentence carries operational consequence. It is dense rather than padded, though the 'still accurate, just not Xero's own word for it' aside and the repeated 'this refuses plainly' framing could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the returned fields, the optional super fund data, the omitted sensitive fields, and the pagination shape. The main gaps an agent would hit — unsupported regions, incomplete payroll setup, absent NZ/UK super data, and partial pages — are all pre-answered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters including includeInactive's semantics. The description adds one genuinely useful fact not in the schema — the 100-records-per-page page size — but says nothing further about page bounds or the organisation parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens by naming the exact resource (this organisation's payroll employees) and the specific fields returned (name, employment status, super fund presence, ordinary earnings rate id), which cleanly separates it from siblings like list_xero_payroll_earnings_rates and list_xero_payroll_leave_types. Scope qualifiers (AU/NZ/UK, active-only default) sharpen the identity further.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit about when it applies (three supported countries), when it refuses and how to report that refusal rather than implying zero employees, how to use includeInactive, and how to handle a full page of 100. It also states outright what the tool cannot answer (payment status, ATO/IRD/HMRC lodgement), which steers the agent away from misusing it. No sibling is named, but no viable alternative exists for this resource.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_payroll_leave_typeslist_xero_payroll_leave_typesARead-onlyInspect
This organisation's payroll leave types (Annual Leave, Sick Leave and similar) - name, whether it is paid, whether it shows on a payslip and, where Xero reports it, whether it is currently active. Read-only, for Australian, New Zealand and United Kingdom organisations. Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no leave types. Use this BEFORE drafting a leave application (create_xero_leave_application) - a leave application needs a real leaveTypeId, and Xero has no way to guess one from a name alone. When the user has not named a specific leave type, ask rather than guessing - "Annual Leave" and "Sick Leave" are common names but this connector never assumes one exists under that exact name for every organisation. Returns up to 100 leave types for the requested page.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations: discloses geographic scope (AU, NZ, UK), two prerequisites (completed Payroll setup, connector user holding payroll admin access at connect time), a failure mode that refuses plainly instead of returning an empty list, and a 100-item page cap. The refusal guidance is especially valuable because the agent is told how to interpret and report the error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what is returned, then prerequisites, then the call-ordering rationale — a logical sequence where each sentence carries information. It is on the long side and the 'ask rather than guessing' point is restated twice, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by listing the returned attributes and the page-size limit, and it covers prerequisites, failure behavior, and how to proceed downstream. An agent has everything needed to call it correctly and interpret an error.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both 'page' (1-based, omit for page 1) and 'organisation' (omit when only one org) fully documented inline, so baseline 3 applies. The description adds only the page-size cap of 100, which is useful but marginal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (this organisation's payroll leave types) and enumerates the fields returned (name, paid, payslip visibility, active status). It is clearly distinguishable from sibling tools like list_xero_payroll_earnings_rates and create_xero_leave_application without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the downstream tool it precedes (create_xero_leave_application) and why (a real leaveTypeId is required and cannot be guessed from a name). It also gives a negative rule: when the user has not named a specific leave type, ask rather than assuming a common name exists for every organisation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_pay_runslist_xero_pay_runsARead-onlyInspect
This organisation's recent pay runs - period, payment date, status (DRAFT or POSTED) and organisation-wide totals. Read-only, for Australian, New Zealand and United Kingdom organisations (this refuses plainly for any other country). Also requires Xero's own Payroll setup to be complete for the organisation, and the Xero user who connected to have held payroll administrator access at the time - if either is missing this refuses plainly rather than returning an empty list, so report that rather than implying the organisation has no payroll data. Most recent first. netPay (amount actually paid to employees) is reported by every region; Australia additionally breaks out wages/deductions/tax/super, while New Zealand and the United Kingdom instead report totalCost (the full cost to the employer, including employer-side tax/super/NI that Australia reports separately) - do not assume a field is zero just because it is absent, it may simply not be something this region's own Xero API reports at that level. Use get_xero_pay_run_summary for per-employee detail and a comparison against the previous pay run of the same calendar. Returns up to 100 pay runs for the requested page. This tool cannot say whether a POSTED pay run has actually been paid out or reported to any tax authority - Xero has no API for either, in any region.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. Most recent pay runs come first. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses regional eligibility, payroll setup and admin-access prerequisites, plain refusal behavior, pagination size, field availability differences by region, and an important limitation about POSTED pay runs. It even warns not to interpret absent regional fields as zero.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded and every sentence carries operational value: scope, regional constraints, refusal semantics, field differences, alternative tool, pagination, and a critical limitation. There is no filler or repeated schema text beyond what is necessary for safe interpretation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape, regional field differences, pagination behavior, refusal semantics, and the important inability to determine whether a POSTED pay run has actually been paid or reported. An agent has enough context to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters at 100% coverage, including page numbering and the organisation display name. The description adds only limited parameter-specific meaning, notably the 100-pay-run page size and most-recent-first ordering, so it does not need to carry the parameter explanation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource (list recent pay runs) and immediately names the key returned fields: period, payment date, status, and organisation-wide totals. It also distinguishes itself from the sibling get_xero_pay_run_summary by scoping that sibling to per-employee detail and prior-period comparison.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative tool and the condition that selects it: use get_xero_pay_run_summary for per-employee detail and comparison against the previous pay run. It also gives clear usage constraints by region and explains how to interpret refusal cases rather than treating them as empty payroll data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_projectslist_xero_projectsARead-onlyInspect
List job/project-costing projects from Xero Projects for the current organisation - the jobs or engagements time, expenses and invoices get tracked against, e.g. "the house on Richmond Road" or a client engagement. Read-only; nothing is created or changed. Optionally filter to one contact (contactId, a Xero ContactID from list_xero_contacts) and/or one state (INPROGRESS or CLOSED). Each project carries its OWN currency straight from Xero - never assume it matches this user's Invio business currency, and every money figure names its own currency alongside its value. Each result includes a headline estimate/invoiced/still-to-invoice figure; use get_xero_project for the full cost-and-earned breakdown on one project. If this call fails with an unauthorized/401-style error, it can mean this Xero organisation's plan does not include Xero Projects, or that this connection's Xero Projects access needs to be reconnected - say so rather than treating it as a generic failure.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. Omit for page 1. | |
| state | No | Filter to one project state: INPROGRESS (still running) or CLOSED. Omit for both. | |
| pageSize | No | Projects per page, 1-500. Omit for Xero's own default of 50. | |
| contactId | No | Filter to projects for one Xero contact. Omit for every contact. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description corroborates with "Read-only; nothing is created or changed." It adds genuine behavioral context annotations cannot carry: every project has its own currency independent of the Invio business currency, and a 401/unauthorized failure may mean the Xero plan lacks Projects or the connection needs reconnecting rather than a generic error. It stops short of describing pagination behavior beyond the schema fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and scope before the caveats, and nearly every clause carries operational value. Slightly overlong: the currency warning is stated twice ("Each project carries its OWN currency..." and "every money figure names its own currency alongside its value"), which could be tightened into one sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing what each result carries (headline estimate/invoiced/still-to-invoice figures, per-project currency) and by pre-explaining the most likely failure mode. An agent has everything needed to call this correctly and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: contactId is tied to a Xero ContactID obtainable from list_xero_contacts, and state is characterized as INPROGRESS/CLOSED with the omit-for-both default. page and pageSize are left entirely to the schema, which documents them adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource ("List job/project-costing projects from Xero Projects for the current organisation") and immediately grounds it with what a project represents ("the jobs or engagements time, expenses and invoices get tracked against"). It also explicitly distinguishes itself from the sibling get_xero_project, which returns the full breakdown for one project.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use routing: this tool for the list view, get_xero_project for the full cost-and-earned breakdown on a single project. It also states the filtering conditions (one contact, one state, or neither) and where a valid contactId comes from (list_xero_contacts).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_xero_quoteslist_xero_quotesARead-onlyInspect
List quotes from Xero for the current organisation, optionally filtered by status, by one contact, by an exact quote number, or by issue-date range (fromDate/toDate) or expiry-date range (expiryFromDate/expiryToDate) - all inclusive. Read-only; nothing is created or changed. Each quote carries its OWN currency straight from Xero - never assume it matches this user's Invio business currency. Returns up to 100 quotes for the requested page. Xero does NOT report a total page or item count for this endpoint (unlike invoices and credit notes) - if this call returns exactly 100 quotes, say there may be more and ask for the next page rather than treating 100 as the whole list; a shorter result IS the complete list for whatever filters were applied. The result always echoes back exactly which filters were applied (appliedFilters) - relay that, not just your own memory of what you asked for. Use get_xero_quote for full line-item detail on one quote.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number - Xero returns up to 100 quotes per page. Omit for page 1. | |
| status | No | Filter to one Xero quote status (e.g. DRAFT, SENT, ACCEPTED). Omit for every status. | |
| toDate | No | Only include quotes issued ON OR BEFORE this date, YYYY-MM-DD (inclusive). | |
| fromDate | No | Only include quotes issued ON OR AFTER this date, YYYY-MM-DD (inclusive). Filters the issue date, never the expiry date. | |
| contactId | No | Filter to quotes for one specific contact. | |
| quoteNumber | No | Filter to an exact quote number (e.g. "QU-0001"). | |
| expiryToDate | No | Only include quotes expiring ON OR BEFORE this date, YYYY-MM-DD (inclusive). | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| expiryFromDate | No | Only include quotes expiring ON OR AFTER this date, YYYY-MM-DD (inclusive). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description adds important behavioral details: quotes carry their own currency from Xero, the endpoint does not report total counts, exactly 100 results may mean more pages exist, and appliedFilters is echoed in the response.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and filters, then moves into critical behavioral caveats around currency and pagination. Every sentence carries useful operational information, and the structure makes the important warnings easy to find.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter list tool with no output schema, the description is complete enough to use correctly. It covers filtering, pagination ambiguity, returned currency behavior, appliedFilters echoing, and the sibling tool for detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter meanings are already fully documented in the schema. The description summarizes the filter groups and inclusive date behavior, but it does not add significant semantic detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: list Xero quotes for the current organisation, with optional filters. It also distinguishes this tool from the sibling get_xero_quote by explaining that the sibling is for full line-item detail on one quote.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains when to use this tool, which filters are available, and when to switch to get_xero_quote for single-quote detail. It also gives explicit pagination guidance for the ambiguous case where exactly 100 quotes are returned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_xero_pay_runpost_xero_pay_runADestructiveInspect
Proposes moving an EXISTING DRAFT pay run to POSTED, Australian organisations only (this refuses plainly for New Zealand and the United Kingdom - Xero has no documented way to post a pay run for either region through its API). It does NOT touch Xero itself, and never will on its own - this queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field). THIS CANNOT BE UNDONE ONCE APPROVED: Xero's own Payroll API has no way to move a POSTED pay run back to DRAFT, ever - tell the user this plainly before they approve it, in these words, not a softened version. POSTING A PAY RUN DOES NOT LODGE ANYTHING WITH THE ATO AND DOES NOT PAY ANYONE - Single Touch Payroll lodgement, and the actual bank transfer to employees, both happen entirely outside this connector, through whatever process this business already uses; say so if asked whether wages have "gone out" or been "reported" - this tool cannot know either. confirm must be true, set only after the person has explicitly said, in their own words, to post this specific pay run.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. Set this ONLY after the person using this account has explicitly said, in their own words, to post this specific pay run - posting cannot be undone through Xero's API once approved, never infer consent from context. | |
| payRunId | Yes | Get this from list_xero_pay_runs or get_xero_pay_run_summary - must currently be DRAFT. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and openWorldHint=true, and the description goes well beyond them: it explains this queues a pending change rather than touching Xero, that posting is irreversible through Xero's Payroll API, and that STP lodgement and wage payment happen entirely outside the connector. It also warns that regions NZ/UK will refuse plainly, which is a real behavioral trait an agent needs before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is long, but the length is earned: purpose and scope are front-loaded, then irreversibility, then the STP/payment misconceptions. A couple of meta-instructions to the agent ('in these words, not a softened version') are borderline but serve the destructive nature of the call.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, irreversible, queued mutation with no output schema, the description covers everything an agent needs: region restriction, the approval queue model, irreversibility, and the downstream processes this tool does not perform. Nothing material is left to guesswork.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the schema already documents all three parameters including the explicit-consent semantics for confirm and the DRAFT precondition for payRunId. The description reinforces consent and region scoping but adds no syntax or format detail the schema lacks, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('moving an EXISTING DRAFT pay run to POSTED') and draws a hard boundary against create_xero_pay_run by insisting the pay run already exists. The regional limitation (AU only; refuses NZ/UK) further pins down what the tool will and won't do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Preconditions are explicit: the pay run must currently be DRAFT, confirm must be true only after explicit user consent, and organisation is omitted when only one org is reachable. It frames the follow-on approval step ('a human must explicitly approve' via approvalUrl) but never names the sibling approve_xero_pending_change tool directly, leaving that hop to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reject_xero_pending_changereject_xero_pending_changeADestructiveIdempotentInspect
Rejects a change YOU (or another assistant on this account) have proposed to Xero, so it is discarded and never reaches Xero - nothing was ever sent, there is nothing to undo, and this cannot be reversed once called. Call this ONLY after the person using this account has clearly said, in their own words, to discard THIS specific change - never infer that from silence, from a change of topic, or from them simply not mentioning it again. Make sure they know what they are turning down first (call list_pending_changes if you do not already have its summary in this conversation), then call this with confirm: true. reason is optional context for why, if they gave one - Invio does not currently store or display it anywhere, so only mention it back to them in this conversation, never claim it was recorded. Rejecting in Invio's own Settings > MCP > Xero screen remains available at all times and works exactly the same either way.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional - why this is being rejected, if the person gave a reason. Invio does not currently store or display this anywhere - mention it back to them in this conversation if useful, never claim it was recorded against the change. | |
| confirm | Yes | Must be true. Set this ONLY after the person using this account has explicitly said, in their own words, to approve (or reject) this specific change - never infer consent from context, and never pass true speculatively "to see what happens". | |
| pendingChangeId | Yes | The pendingChangeId of the row to act on - from list_pending_changes' own result, or the pendingChangeId a draft-creating tool (create_xero_invoice etc.) just returned. Never invent one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by explaining the consequence model: nothing was ever sent, there is nothing to undo, and the action cannot be reversed once called. It also discloses that reason is not stored or displayed anywhere and that the equivalent Settings > MCP > Xero path remains available, so the agent won't overstate what the call accomplishes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the action and its irreversibility come first, then the consent gate, then parameter guidance, then the UI alternative. A few clauses (the reason-disclosure sentence, the Settings > MCP > Xero note) are repeated in substance from the schema, which trims the score slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive pending-change tool with no output schema and full schema coverage, it supplies everything an agent needs: prerequisites, consent bar, irreversibility, post-call honesty about reason, and a fallback path. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds procedural meaning by tying confirm to a consent gate and sequencing it after informing the user ("Make sure they know what they are turning down first ... then call this with confirm: true"). The reason guidance largely restates the schema's own description, so it is reinforcement rather than new semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Rejects a change ... proposed to Xero") and immediately scopes the effect: the change is discarded and never reaches Xero. It implicitly but unmistakably distinguishes itself from the sibling approve_xero_pending_change and from the list tools that surface these rows.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use conditions (only after the account holder has clearly said, in their own words, to discard THIS change) and explicit when-not conditions (never from silence, a change of topic, or them not mentioning it). It also names the prerequisite alternative: call list_pending_changes first if the summary is not already in conversation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_xero_contactupdate_xero_contactAInspect
Proposes a change to an EXISTING Xero contact - it does NOT change anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. contactId must come from list_xero_contacts (never invented). Provide at least one of name, emailAddress, or phone - only the fields you provide change, everything else on the contact is left exactly as it is.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New name. Omit to leave unchanged. | |
| phone | No | New phone number. Omit to leave unchanged. | |
| contactId | Yes | Get this from list_xero_contacts first, never guess. | |
| emailAddress | No | New email. Omit to leave unchanged. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=true — a generic write profile. The description adds the essential behavioral fact that this enqueues a pending change requiring human approval and that nothing is written to Xero until then, plus partial-update semantics ('only the fields you provide change, everything else is left exactly as it is'). That is substantial context beyond the annotations and does not conflict with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The most important fact — this is a proposal, not a write — is front-loaded, and the parameter rules follow in a tight sequence. It is a dense multi-clause passage; a small amount of repetition ('it does NOT change anything in Xero itself, and never will on its own') could be trimmed, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by naming the return field the agent needs (approvalUrl) and the human-approval workflow that follows. For a five-parameter, non-destructive queued write, an agent has everything needed to call it correctly and to explain the outcome to a user.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline would be 3, but the description adds a real constraint the schema does not encode: a cross-field rule that at least one of name, emailAddress, or phone must be provided, since only contactId is required in the schema. It also reinforces the contactId provenance rule and the omit-to-leave-unchanged semantics for organisation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Proposes a change to an EXISTING Xero contact') and immediately clarifies the critical distinction that it does not mutate Xero directly, unlike a direct update. The word 'Proposes' plus the explicit non-mutation framing separates it cleanly from create_xero_contact and update_xero_invoice siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit preconditions: contactId must come from list_xero_contacts and never be invented; at least one of name/emailAddress/phone must be supplied; organisation is only needed for multi-org connections. It also explains the downstream approval path (human approves via the connector's approvalUrl, the agent cannot self-approve), leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_xero_employeeupdate_xero_employeeAInspect
Proposes a change to ONE employee's first name, last name, email, phone/mobile, or home address - and STRUCTURALLY NOTHING ELSE - for Australian, New Zealand or United Kingdom organisations. It does NOT touch Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. employeeId must come from list_xero_payroll_employees (never invented). Provide at least one of firstName, lastName, email, phone, mobile, or address - only the fields you provide change, everything else about the employee is left exactly as it is. For Australia, phone and mobile are two separate fields and both may be set independently. For New Zealand and the United Kingdom there is only ONE phone number field in Xero - use either phone or mobile (not both to two different values); doing so refuses before anything is drafted. This tool has NO field for bank details, tax numbers, tax settings, pay templates, salary or rates, KiwiSaver/super, date of birth, start date, or termination date - none of those can ever be changed through this connector, by design.
| Name | Required | Description | Default |
|---|---|---|---|
| No | New email address. Omit to leave unchanged. | ||
| phone | No | New phone number. For Australia this is a SEPARATE field from mobile - both may be set independently. For New Zealand and the United Kingdom there is only ONE phone field in Xero - use either phone or mobile, never both to two different values (this is refused before anything is drafted if you do). | |
| mobile | No | New mobile number. Australia has a genuinely separate Mobile field from phone. For New Zealand and the United Kingdom this maps onto the SAME single phone field as phone - use either phone or mobile, never both to two different values. | |
| address | No | New home address - only the fields you provide inside it change, the rest of the address is left exactly as it is. state is Australia-only, suburb is New Zealand-only; both are silently ignored for the other regions. | |
| lastName | No | New last name. Omit to leave unchanged. | |
| firstName | No | New first name. Omit to leave unchanged. | |
| employeeId | Yes | Get this from list_xero_payroll_employees first - never invent one. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only say readOnlyHint=false and destructiveHint=false, which alone would leave the agent guessing whether the write is immediate. The description closes that gap decisively: it does not touch Xero, it queues a pending change, a human must approve via the response's approvalUrl, and the agent cannot self-approve. It also discloses the refusal behavior for conflicting phone/mobile values in NZ/UK, which is behavioral information available nowhere else.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The key operating model (proposal, not execution) is front-loaded in the first two sentences, which is exactly right for a tool whose biggest misconception is that it writes to Xero directly. It is dense and long, with capitalized emphasis and some duplication of the phone/mobile and address rules that already appear in the schema, which costs a point but not more.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining the return value, and it does by naming the approvalUrl field and the pending-change lifecycle it participates in. Combined with the region matrix and the employeeId provenance rule, an agent has everything needed to call this correctly and to know what happens next.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the per-field meanings are already documented, including the AU-vs-NZ/UK phone/mobile split. The description still adds value the schema lacks: the 'at least one mutable field' requirement (the schema only requires employeeId), and the note that only supplied fields change while everything else is preserved. It largely restates the region rules already present in the phone/mobile schema descriptions, which keeps it below a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (proposes a change to ONE employee) and enumerates the exact mutable field set, explicitly bounding it with 'STRUCTURALLY NOTHING ELSE.' An agent can immediately distinguish this from update_xero_contact or the create_* payroll tools without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit prerequisites (employeeId must come from list_xero_payroll_employees, never invented), an invocation constraint (provide at least one of the six fields), and negative guidance on what is out of scope (bank details, tax, pay templates, KiwiSaver, dates) because no such fields exist by design. It also explains the downstream approval step that follows, so the agent knows this is not a terminal call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_xero_invoiceupdate_xero_invoiceAInspect
Proposes a change to an EXISTING Xero invoice - it does NOT change anything in Xero itself, and never will on its own. This queues a pending change that a human must explicitly approve (your Xero MCP connector - the exact link is this response's own approvalUrl field) before Xero is touched at all; you have no way to approve it yourself. Only works on invoices that are still DRAFT or SUBMITTED in Xero - get_xero_invoice tells you the current status first. Cannot change which contact the invoice is for, or its type - void it and create a new one for that. If you include lineItems at all, it REPLACES every line item on the invoice; to change one, list all of them, or Xero will delete the ones you don't mention. Tell the user exactly what you are proposing to change and that it needs their approval in Invio - never describe it as done. You can also change the invoice currency (currency, checked against the currencies this organisation is actually set up to invoice in) and how its amounts are read (lineAmountTypes: "Exclusive", "Inclusive" or "NoTax"). Omit either to leave it exactly as it is - neither is reset to a default when you leave it out. Changing lineAmountTypes re-interprets EVERY amount already on the invoice and so changes its total: only send it when the user actually asked for that, and say plainly that the total will move. DATES: date and dueDate are strict YYYY-MM-DD, so you always have to convert whatever the user actually said. A date carrying a month name ("8 Sep", "Sept 8th"), a weekday ("last Tuesday"), or an already-unambiguous full date ("2026-09-08") is yours to convert normally. A BARE NUMERIC date with no month name - "9/8", "08/09", "9-8" - is the one that is not: it means 9 August to most of the world and 8 September in the United States, and getting it wrong puts an invoice a month out in a way nobody skimming the approval card will catch. This Invio account is based in a country that writes the DAY first, so read a bare "9/8" as 9 August, not 8 September. Say in plain words how you read it ("I read 9/8 as 9 August") so the user can correct you before they approve. If their own wording points the other way anywhere in the same request, ask them which they meant instead of picking.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | New invoice date, YYYY-MM-DD. Omit to leave unchanged. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| dueDate | No | New due date, YYYY-MM-DD. Omit to leave unchanged. If the user wrote a bare numeric date with no month name ("9/8", "08/09"), do NOT settle it on your own judgement - it is 9 August to most of the world and 8 September in the US, and nothing downstream of this field can tell which you meant once it is a date. Follow the DATES instruction in this tool's description. | |
| currency | No | New currency for the invoice, e.g. "NZD". Checked against the currencies this organisation is actually set up to invoice in. Omit to leave the invoice in whatever currency it is already in - this never resets it to the organisation's base currency. | |
| invoiceId | Yes | Get this from list_xero_invoices or get_xero_invoice first, never guess. | |
| lineItems | No | If you include this at all, it REPLACES every line item on the invoice - Xero deletes any line item you do not list here. To change one line item, list ALL of them (the ones you are not changing too), never just the one that changed. Omit this field entirely to leave every line item as it is. | |
| reference | No | New reference text. Omit to leave unchanged. | |
| organisation | No | The Xero organisation to use, by its display name. Only needed if this connection reaches more than one organisation - omit it when there is only one. | |
| lineAmountTypes | No | Change how this invoice reads its unitAmounts: "Exclusive" (amounts exclude tax), "Inclusive" (amounts already include tax), or "NoTax". Omit to leave it exactly as it is. Changing this re-interprets EVERY amount already on the invoice and so changes its total - only set it when the user actually asks for that (e.g. "those figures were meant to include GST"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnly=false/openWorld=true; the description supplies the whole approval mechanic (pending change, human approves via the response's approvalUrl, agent cannot self-approve) that an agent could not otherwise infer. It also discloses the lineItems replace-all semantics and that omitted currency/lineAmountTypes are never reset to defaults, which is exactly the surprising behavior annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded well: the first sentence carries the single most important fact (nothing is changed until a human approves). But it runs very long and the DATES paragraph spends ~150 words on a rule already spelled out in two schema fields, and the lineItems replace-all rule appears verbatim in both description and schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, yet the description tells the agent what comes back (an approvalUrl) and how to narrate the result to the user ('never describe it as done'), closing the loop an agent would otherwise have to guess. For an 8-parameter mutation-queueing tool, nothing needed for correct calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the description largely repeats field docs (currency validation, lineAmountTypes enum, lineItems replacement). It does add cross-field consequence – that lineAmountTypes re-interprets EVERY existing amount and moves the total – but that is essentially restated from the schema. The long DATES section is duplicated in the date/dueDate schema descriptions, so it earns little extra credit here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource+scope: 'Proposes a change to an EXISTING Xero invoice', and immediately distinguishes it from create_xero_invoice ('EXISTING') and from approve_xero_pending_change ('you have no way to approve it yourself'). An agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the precondition ('Only works on invoices that are still DRAFT or SUBMITTED - get_xero_invoice tells you the current status first') and the hard exclusions ('Cannot change which contact the invoice is for, or its type - void it and create a new one for that'), naming the sibling to use instead. It also tells the agent what to say to the user, which is part of correct invocation for a queued-approval tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
create_xero_invoice1 field changed- changed
Input schema / properties / status / descriptionPrevious value: -"What state the invoice lands in inside Xero once a human approves this in Invio. Defaults to \"AUTHORISED\" - approved and ready for them to send from Xero, with nothing left to fill in - because approving this change in Invio is already the approval, and that is what an ordinary \"invoice this customer\" request means. Do not leave this as \"DRAFT\" out of caution: doing so makes the user approve the same invoice a second time, by hand, in Xero. Pass \"DRAFT\" only when the user actually says they want to check or edit it in Xero first - it then lands unapproved and they have to approve it there too. Either way this connector never emails the invoice to the customer; that stays a deliberate action a person takes in Xero."New value: +"What state the invoice lands in inside Xero once a human approves this in Invio. Defaults to \"AUTHORISED\" - approved and ready for them to send from Xero, with nothing left to fill in - because approving this change in Invio is already the approval, and that is what an ordinary \"invoice this customer\" request means. Do not leave this as \"DRAFT\" out of caution: doing so makes the user approve the same invoice a second time, by hand, in Xero. Pass \"DRAFT\" only when the user actually says they want to check or edit it in Xero first - it then lands unapproved and they have to approve it there too. Either way this connector never emails the invoice to the customer; that stays a deliberate action a person takes in Xero. A bill (ACCPAY) has no customer and nothing to send: AUTHORISED means ready to pay."
36 tool updates
- Changed
approve_xero_pending_change1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
create_xero_contact2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / emailAddress / patternAdded value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
- Changed
create_xero_credit_note3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / lineItems / items / additionalPropertiesRemoved value: -false
- Changed
create_xero_invoice3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / lineItems / items / additionalPropertiesRemoved value: -false
- Changed
create_xero_leave_application3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / employeeId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - added
Input schema / properties / leaveTypeId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
create_xero_manual_journal2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / lineItems / items / additionalPropertiesRemoved value: -false
- Changed
create_xero_pay_run2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / payrollCalendarId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
create_xero_payment2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / invoiceId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
create_xero_quote3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / lineItems / items / additionalPropertiesRemoved value: -false
- Changed
create_xero_timesheet5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / employeeId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / lines / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / lines / items / properties / earningsRateId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - added
Input schema / properties / payrollCalendarId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_balance_sheet1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get_xero_credit_note2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / creditNoteId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_group_report7 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / date / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / date / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / date / typeAdded value: +"string" - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
get_xero_invoice2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / invoiceId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_leave_balances2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / employeeId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_outstanding_receivables1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get_xero_pay_run_summary2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / payRunId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_profit_and_loss4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
get_xero_project2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / projectId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
get_xero_quote2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / quoteId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
list_xero_accounts1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_contacts1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_credit_notes4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
list_xero_invoices4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
list_xero_pay_runs1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_payments5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / invoiceId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
list_xero_payroll_earnings_rates1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_payroll_employees1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_payroll_leave_types1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
list_xero_projects2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
list_xero_quotes11 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / expiryFromDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / expiryFromDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / expiryFromDate / typeAdded value: +"string" - removed
Input schema / properties / expiryToDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / expiryToDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / expiryToDate / typeAdded value: +"string" - removed
Input schema / properties / toDate / $refRemoved value: -"#/properties/fromDate" - added
Input schema / properties / toDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / toDate / typeAdded value: +"string"
- Changed
post_xero_pay_run2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / payRunId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
reject_xero_pending_change1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
update_xero_contact3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contactId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - added
Input schema / properties / emailAddress / patternAdded value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
- Changed
update_xero_employee3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / email / patternAdded value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - added
Input schema / properties / employeeId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
- Changed
update_xero_invoice6 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / dueDate / $refRemoved value: -"#/properties/date" - added
Input schema / properties / dueDate / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / dueDate / typeAdded value: +"string" - added
Input schema / properties / invoiceId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - removed
Input schema / properties / lineItems / items / additionalPropertiesRemoved value: -false
1 tool update
- Added
get_xero_group_report
37 tool updates
- First observed
approve_xero_pending_change - First observed
create_xero_contact - First observed
create_xero_credit_note - First observed
create_xero_invoice - First observed
create_xero_leave_application - First observed
create_xero_manual_journal - First observed
create_xero_pay_run - First observed
create_xero_payment - First observed
create_xero_quote - First observed
create_xero_timesheet - First observed
get_xero_balance_sheet - First observed
get_xero_credit_note - First observed
get_xero_invoice - First observed
get_xero_leave_balances - First observed
get_xero_outstanding_receivables - First observed
get_xero_pay_run_summary - First observed
get_xero_profit_and_loss - First observed
get_xero_project - First observed
get_xero_quote - First observed
list_pending_changes - First observed
list_xero_accounts - First observed
list_xero_contacts - First observed
list_xero_credit_notes - First observed
list_xero_invoices - First observed
list_xero_organisations - First observed
list_xero_pay_runs - First observed
list_xero_payments - First observed
list_xero_payroll_earnings_rates - First observed
list_xero_payroll_employees - First observed
list_xero_payroll_leave_types - First observed
list_xero_projects - First observed
list_xero_quotes - First observed
post_xero_pay_run - First observed
reject_xero_pending_change - First observed
update_xero_contact - First observed
update_xero_employee - First observed
update_xero_invoice
Publisher details
- Operator
- Bakhtiyar Duganov trading as Invio (New Zealand) · Publisher source
- Operator website
- https://www.invio.co.nz/xero-mcp
- Vendor relationship
- Not available
- Documentation
- https://www.invio.co.nz/guides/xero-mcp-setup
- Trust center
- Not available
- Restrictions
- Paid plan after a 7-day free trial (no card needed). Requires an Invio account and a Xero organisation you can authorise. Write actions wait in an approval queue until the account owner or an approver approves them.
Related MCP Connectors
Connect Xero to AI agents with secure read or write access across multiple organisations.
Read-only by architecture: ask AI about your Xero data, across multiple entities at once.
Read-only by architecture: ask AI about QuickBooks, Xero and NetSuite, across every entity.
Double entry accounting run by your own AI: books, VAT figures, invoices, month close (UK, DE, AT).
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables natural-language interaction with Xero accounting data, including invoices and intents, with role-based access control and audit trail.385 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to read an organisation's contacts, invoices and bills, payments, chart of accounts and financial reports, and — only on explicit request — to create contacts, invoices and payments or change an invoice's status.Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables accountants to connect Xero, read accounting data, analyze, and execute controlled draft operations after explicit confirmation, with Xero as the source of truth.-
- AlicenseAqualityCmaintenanceEnables natural language interaction with Xero accounting data, managing contacts, invoices, and accounts across multiple organisations via OAuth2.12MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.