Skip to main content
Glama
XeroAPI

Xero MCP Server

Official

update-quote

Modify draft quotes in Xero by updating line items, reference details, and terms. All line items must be provided in the update request.

Instructions

Update a quote in Xero. Only works on draft quotes. 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 a quote is updated, a deep link to the quote in Xero is returned. This deep link can be used to view the quote in Xero directly. This link should be displayed to the user.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
quoteIdYes
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
referenceNo
termsNo
titleNo
summaryNo
quoteNumberNo
contactIdNo
dateNo
expiryDateNo

Implementation Reference

  • Defines the 'update-quote' MCP tool using CreateXeroTool, including input schema, description, and the async handler function that invokes updateXeroQuote, handles response, and provides a deep link.
    const UpdateQuoteTool = CreateXeroTool( "update-quote", "Update a quote in Xero. Only works on draft quotes.\ 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 a quote is updated, a deep link to the quote in Xero is returned. \ This deep link can be used to view the quote in Xero directly. \ This link should be displayed to the user.", { quoteId: z.string(), 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(), terms: z.string().optional(), title: z.string().optional(), summary: z.string().optional(), quoteNumber: z.string().optional(), contactId: z.string().optional(), date: z.string().optional(), expiryDate: z.string().optional(), }, async ( { quoteId, lineItems, reference, terms, title, summary, quoteNumber, contactId, date, expiryDate, } ) => { const result = await updateXeroQuote( quoteId, lineItems, reference, terms, title, summary, quoteNumber, contactId, date, expiryDate, ); if (result.isError) { return { content: [ { type: "text" as const, text: `Error updating quote: ${result.error}`, }, ], }; } const quote = result.result; const deepLink = quote.quoteID ? await getDeepLink(DeepLinkType.QUOTE, quote.quoteID) : null; return { content: [ { type: "text" as const, text: [ "Quote updated successfully:", `ID: ${quote?.quoteID}`, `Contact: ${quote?.contact?.name}`, `Total: ${quote?.total}`, `Status: ${quote?.status}`, deepLink ? `Link to view: ${deepLink}` : null, ].join("\n"), }, ], }; }, );
  • The updateXeroQuote function implements the core logic for updating a Xero quote: authenticates, checks if draft status, updates via Xero API, handles errors, returns structured response.
    export async function updateXeroQuote( quoteId: string, lineItems?: QuoteLineItem[], reference?: string, terms?: string, title?: string, summary?: string, quoteNumber?: string, contactId?: string, date?: string, expiryDate?: string, ): Promise<XeroClientResponse<Quote>> { try { const existingQuote = await getQuote(quoteId); const quoteStatus = existingQuote?.status; // Only allow updates to DRAFT quotes if (quoteStatus !== QuoteStatusCodes.DRAFT) { return { result: null, isError: true, error: `Cannot update quote because it is not a draft. Current status: ${quoteStatus}`, }; } const updatedQuote = await updateQuote( quoteId, lineItems, reference, terms, title, summary, quoteNumber, contactId, date, expiryDate, existingQuote ); if (!updatedQuote) { throw new Error("Quote update failed."); } return { result: updatedQuote, isError: false, error: null, }; } catch (error) { return { result: null, isError: true, error: formatError(error), }; } }
  • Imports UpdateQuoteTool and includes it in the UpdateTools array (line 21) for subsequent registration.
    import UpdateQuoteTool from "./update-quote.tool.js"; import UpdateTrackingCategoryTool from "./update-tracking-category.tool.js"; import UpdateTrackingOptionsTool from "./update-tracking-options.tool.js"; export const UpdateTools = [ UpdateContactTool, UpdateCreditNoteTool, UpdateInvoiceTool, UpdateManualJournalTool, UpdateQuoteTool, UpdateItemTool, UpdateBankTransactionTool, ApprovePayrollTimesheetTool, AddTimesheetLineTool, UpdatePayrollTimesheetLineTool, RevertPayrollTimesheetTool, UpdateTrackingCategoryTool, UpdateTrackingOptionsTool ];
  • Batch registers all tools from UpdateTools (including 'update-quote') on 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