list-contacts
Retrieve and search through all contacts in Xero, including suppliers and customers, with pagination support for managing large contact lists.
Instructions
List all contacts in Xero. This includes Suppliers and Customers.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Optional page number to retrieve for pagination. If not provided, the first page will be returned. If 100 contacts are returned, call this tool again with the next page number. | |
| searchTerm | No | Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields |
Implementation Reference
- Core handler function for listing Xero contacts, handling API call and error formatting.export async function listXeroContacts(page?: number, searchTerm?: string): Promise< XeroClientResponse<Contact[]> > { try { const contacts = await getContacts(page, searchTerm); return { result: contacts, isError: false, error: null, }; } catch (error) { return { result: null, isError: true, error: formatError(error), }; } }
- Tool-specific execution handler that invokes the core listXeroContacts and formats the output for MCP response.async (params) => { const { page, searchTerm } = params; const response = await listXeroContacts(page, searchTerm); if (response.isError) { return { content: [ { type: "text" as const, text: `Error listing contacts: ${response.error}`, }, ], }; } const contacts = response.result; return { content: [ { type: "text" as const, text: `Found ${contacts?.length || 0} contacts${page ? ` (page ${page})` : ''}:`, }, ...(contacts?.map((contact) => ({ type: "text" as const, text: [ `Contact: ${contact.name}`, `ID: ${contact.contactID}`, contact.firstName ? `First Name: ${contact.firstName}` : null, contact.lastName ? `Last Name: ${contact.lastName}` : null, contact.emailAddress ? `Email: ${contact.emailAddress}` : "No email", contact.accountsReceivableTaxType ? `AR Tax Type: ${contact.accountsReceivableTaxType}` : null, contact.accountsPayableTaxType ? `AP Tax Type: ${contact.accountsPayableTaxType}` : null, `Type: ${ [ contact.isCustomer ? "Customer" : null, contact.isSupplier ? "Supplier" : null, ] .filter(Boolean) .join(", ") || "Unknown" }`, contact.defaultCurrency ? `Default Currency: ${contact.defaultCurrency}` : null, contact.updatedDateUTC ? `Last Updated: ${contact.updatedDateUTC}` : null, `Status: ${contact.contactStatus || "Unknown"}`, contact.contactGroups?.length ? `Groups: ${contact.contactGroups.map((g) => g.name).join(", ")}` : null, contact.hasAttachments ? "Has Attachments: Yes" : null, contact.hasValidationErrors ? "Has Validation Errors: Yes" : null, ] .filter(Boolean) .join("\n"), })) || []), ], }; },
- Input schema validation using Zod for 'page' and 'searchTerm' parameters.{ page: z.number().optional().describe("Optional page number to retrieve for pagination. \ If not provided, the first page will be returned. If 100 contacts are returned, \ call this tool again with the next page number."), searchTerm: z.string().optional().describe("Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields"), },
- src/tools/list/index.ts:32-58 (registration)Local registration of ListContactsTool within the array of list tools.export const ListTools = [ ListAccountsTool, ListContactsTool, ListCreditNotesTool, ListInvoicesTool, ListItemsTool, ListManualJournalsTool, ListQuotesTool, ListTaxRatesTool, ListTrialBalanceTool, ListPaymentsTool, ListProfitAndLossTool, ListBankTransactionsTool, ListPayrollEmployeesTool, ListReportBalanceSheetTool, ListOrganisationDetailsTool, ListPayrollEmployeeLeaveTool, ListPayrollLeavePeriodsToolTool, ListPayrollEmployeeLeaveTypesTool, ListPayrollEmployeeLeaveBalancesTool, ListPayrollLeaveTypesTool, ListAgedReceivablesByContact, ListAgedPayablesByContact, ListPayrollTimesheetsTool, ListContactGroupsTool, ListTrackingCategoriesTool ];
- src/tools/tool-factory.ts:20-22 (registration)Global registration of all ListTools, including list-contacts, to the MCP server.ListTools.map((tool) => tool()).forEach((tool) => server.tool(tool.name, tool.description, tool.schema, tool.handler), );