Skip to content

feat: add invoice attachment list and download tools#126

Open
harryblam wants to merge 4 commits intoXeroAPI:mainfrom
harryblam:feat/invoice-attachment-tools
Open

feat: add invoice attachment list and download tools#126
harryblam wants to merge 4 commits intoXeroAPI:mainfrom
harryblam:feat/invoice-attachment-tools

Conversation

@harryblam
Copy link
Copy Markdown

Summary

Add two new read-only tools for accessing files attached to Xero invoices:

Tool Description
list-invoice-attachments List attachment metadata (filename, MIME type, content length) for a given invoice
get-invoice-attachment-content Download an attachment's content as base64 (requires exact filename and content type from list)

Changes

New files

  • src/handlers/list-xero-invoice-attachments.handler.ts — calls accountingApi.getInvoiceAttachments()
  • src/handlers/download-xero-invoice-attachment.handler.ts — calls accountingApi.getInvoiceAttachmentByFileName(), returns Buffer as base64
  • src/tools/list/list-invoice-attachments.tool.ts — tool definition with invoiceId parameter
  • src/tools/get/get-invoice-attachment.tool.ts — tool definition with invoiceId, fileName, contentType parameters

Modified files

  • src/clients/xero-client.ts — adds accounting.attachments.read to requested scopes; adds invalid_scope error detection with a clear message directing users to update their Custom Connection
  • src/tools/list/index.ts — registers ListInvoiceAttachmentsTool
  • src/tools/get/index.ts — registers GetInvoiceAttachmentTool

Scope requirement

The accounting.attachments.read scope is required for the Xero Attachments API. This scope is added to the client_credentials token request. If a user's Custom Connection doesn't include this scope, the error handler now returns a clear message listing all required scopes instead of a generic auth failure.

Testing

  • Tested against a live Xero Demo Company
  • list-invoice-attachments successfully returns attachment metadata for invoices
  • get-invoice-attachment-content successfully downloads attachments as base64
  • Existing tools continue to work — no breaking changes

Add two new read-only tools for accessing files attached to Xero invoices:

- list-invoice-attachments: list attachment metadata (filename, MIME type, size) for a given invoice
- get-invoice-attachment-content: download an attachment's content as base64

Also adds accounting.attachments.read to the requested scopes and improves
error handling for invalid_scope responses with a clear message directing
users to update their Custom Connection scopes.
Currently, authenticate() fetches a new token from Xero's identity
server on every single tool call. This is wasteful and can trigger
rate limiting on long-running sessions, causing 'Failed to get Xero
token' errors.

This change caches the token and tracks its expiry using the
expires_in value from Xero's response. The token is only refreshed
when it's within 5 minutes of expiring, reducing unnecessary calls
to the identity endpoint from dozens per session to ~1 per 25 minutes.
- Add orderBy, orderDirection, status, type, dateFrom, dateTo, pageSize params
- Build where clause from structured params (type + date range)
- Change default pageSize from 10 to 100
- Add comprehensive negative guidance to list-invoices description
- Add COMMON MISTAKES sections to 7 other paginated list tools
- Fix copy-paste typo in list-bank-transactions description
- Bump version to 0.0.14-fix.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant