Skip to main content
Glama
XeroAPI

Xero MCP Server

Official

update-invoice

Modify draft invoices in Xero by updating line items, due dates, or references. All line items must be provided to replace existing ones.

Instructions

Update an invoice in Xero. Only works on draft invoices. All line items must be provided. Any line items not provided will be removed. Including existing line items. Do not modify line items that have not been specified by the user. When an invoice is updated, a deep link to the invoice in Xero is returned. This deep link can be used to view the contact in Xero directly. This link should be displayed to the user.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
invoiceIdYesThe ID of the invoice to update.
lineItemsNoAll line items must be provided. Any line items not provided will be removed. Including existing line items. Do not modify line items that have not been specified by the user
referenceNoA reference number for the invoice.
dueDateNoThe due date of the invoice.
dateNoThe date of the invoice.
contactIdNoThe ID of the contact to update the invoice for. Can be obtained from the list-contacts tool.

Implementation Reference

  • Core handler function that authenticates with Xero, checks if invoice is DRAFT, updates via Xero API, and returns success/error.
    export async function updateXeroInvoice( invoiceId: string, lineItems?: InvoiceLineItem[], reference?: string, dueDate?: string, date?: string, contactId?: string, ): Promise<XeroClientResponse<Invoice>> { try { const existingInvoice = await getInvoice(invoiceId); const invoiceStatus = existingInvoice?.status; // Only allow updates to DRAFT invoices if (invoiceStatus !== Invoice.StatusEnum.DRAFT) { return { result: null, isError: true, error: `Cannot update invoice because it is not a draft. Current status: ${invoiceStatus}`, }; } const updatedInvoice = await updateInvoice( invoiceId, lineItems, reference, dueDate, date, contactId, ); if (!updatedInvoice) { throw new Error("Invoice update failed."); } return { result: updatedInvoice, isError: false, error: null, }; } catch (error) { return { result: null, isError: true, error: formatError(error), }; } }
  • Tool-specific handler wrapper that calls core updateXeroInvoice, handles response, generates deep link, and formats MCP response.
    async ( { invoiceId, lineItems, reference, dueDate, date, contactId, }: { invoiceId: string; lineItems?: Array<{ description: string; quantity: number; unitAmount: number; accountCode: string; taxType: string; }>; reference?: string; dueDate?: string; date?: string; contactId?: string; }, //_extra: { signal: AbortSignal }, ) => { const result = await updateXeroInvoice( invoiceId, lineItems, reference, dueDate, date, contactId, ); if (result.isError) { return { content: [ { type: "text" as const, text: `Error updating invoice: ${result.error}`, }, ], }; } const invoice = result.result; const deepLink = invoice.invoiceID ? await getDeepLink(DeepLinkType.INVOICE, invoice.invoiceID) : null; return { content: [ { type: "text" as const, text: [ "Invoice updated successfully:", `ID: ${invoice?.invoiceID}`, `Contact: ${invoice?.contact?.name}`, `Type: ${invoice?.type}`, `Total: ${invoice?.total}`, `Status: ${invoice?.status}`, deepLink ? `Link to view: ${deepLink}` : null, ].join("\n"), }, ], }; },
  • Zod input schema defining parameters for the update-invoice tool, including sub-schemas for lineItems and tracking.
    { invoiceId: z.string().describe("The ID of the invoice to update."), lineItems: z.array(lineItemSchema).optional().describe( "All line items must be provided. Any line items not provided will be removed. Including existing line items. \ Do not modify line items that have not been specified by the user", ), reference: z.string().optional().describe("A reference number for the invoice."), dueDate: z.string().optional().describe("The due date of the invoice."), date: z.string().optional().describe("The date of the invoice."), contactId: z.string().optional().describe("The ID of the contact to update the invoice for. \ Can be obtained from the list-contacts tool."), },
  • Registration of UpdateInvoiceTool in the UpdateTools export array.
    export const UpdateTools = [ UpdateContactTool, UpdateCreditNoteTool, UpdateInvoiceTool, UpdateManualJournalTool, UpdateQuoteTool, UpdateItemTool, UpdateBankTransactionTool, ApprovePayrollTimesheetTool, AddTimesheetLineTool, UpdatePayrollTimesheetLineTool, RevertPayrollTimesheetTool, UpdateTrackingCategoryTool, UpdateTrackingOptionsTool ];
  • Registers all tools from UpdateTools (including update-invoice) to the MCP server.
    UpdateTools.map((tool) => tool()).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler), );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/XeroAPI/xero-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server