Supplier invoices to draft Xero bills per job, for UK trades' AI assistants (test mode)
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add supplier invoices to the book: raw emails with PDF attachments, PDFs (text or scanned), photos, or pasted text, up to 25 per call. Each is read, checked against its own printed total, given its job reference, kept with its original, and checked for price changes against earlier invoices from the same supplier. Duplicates are skipped. Returns one result per document: added, needs_check (did not add up, held back), duplicate or failed.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http supplier-invoice-tool https://supplier-invoice-tool.nerolabs.workers.dev/mcp
Add supplier invoices to the book: raw emails with PDF attachments, PDFs (text or scanned), photos, or pasted text, up to 25 per call. Each is read, checked against its own printed total, given its job reference, kept with its original, and checked for price changes against earlier invoices from the same supplier. Duplicates are skipped. Returns one result per document: added, needs_check (did not add up, held back), duplicate or failed.
| Argument | Type | Description |
|---|---|---|
| invoices* | array |
{
"type": "object",
"required": [
"invoices"
],
"properties": {
"invoices": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Invoice text, or several pasted emails separated by a line of ---."
},
"email": {
"type": "string",
"description": "The whole email as exported (.eml or the raw source), including PDF attachments. Best option."
},
"filename": {
"type": "string"
},
"pdf_base64": {
"type": "string",
"description": "A PDF invoice, base64. Text PDFs and scanned PDFs both work."
},
"image_base64": {
"type": "string",
"description": "A photo of a paper invoice (JPEG or PNG), base64."
},
"job_reference": {
"type": "string",
"description": "Only if the job reference is not on the invoice or the email subject."
},
"supplier_name": {
"type": "string",
"description": "Only if the supplier name is not on the invoice."
}
}
},
"maxItems": 25
}
}
}Put an invoice (or some of its lines) on a job, when the supplier left the reference off or it was wrong.
| Argument | Type | Description |
|---|---|---|
| invoice_id* | string | |
| line_numbers | array | |
| job_reference* | string |
{
"type": "object",
"required": [
"invoice_id",
"job_reference"
],
"properties": {
"invoice_id": {
"type": "string"
},
"line_numbers": {
"type": "array",
"items": {
"type": "number"
}
},
"job_reference": {
"type": "string"
}
}
}A link for the trade to open and sign in to Xero. Test mode: only a Xero Demo Company can be connected.
No arguments.
{
"type": "object",
"properties": {}
}Start here, once per business. Creates the trade's invoice book and returns an API key to send as "Authorization: Bearer <key>" on every other call. Test mode: free, nothing is charged. The same identity (company number) can later sign the trade into Nero Work without a new sign up.
| Argument | Type | Description |
|---|---|---|
| name* | string | Trading name, for example Spark & Sons Electrical Ltd. |
| vat_number | string | |
| company_number | string | Companies House number, if a limited company. Leave out for a sole trader. |
| vat_registered | boolean | Default true. If false, bills are entered gross with no VAT. |
| job_reference_style | string | "number" (recommended when jobs are numbered): JOB-1042, Job 1042 and 1042 are all job 1042. "prefixed": keep JOB-1042 as written. |
| job_reference_prefixes | array | Letters the trade puts before job numbers on orders, for example ["JOB", "HAUS"]. Default JOB, NW, REF. |
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Trading name, for example Spark & Sons Electrical Ltd."
},
"vat_number": {
"type": "string"
},
"company_number": {
"type": "string",
"description": "Companies House number, if a limited company. Leave out for a sole trader."
},
"vat_registered": {
"type": "boolean",
"description": "Default true. If false, bills are entered gross with no VAT."
},
"job_reference_style": {
"enum": [
"number",
"prefixed"
],
"type": "string",
"description": "\"number\" (recommended when jobs are numbered): JOB-1042, Job 1042 and 1042 are all job 1042. \"prefixed\": keep JOB-1042 as written."
},
"job_reference_prefixes": {
"type": "array",
"items": {
"type": "string"
},
"description": "Letters the trade puts before job numbers on orders, for example [\"JOB\", \"HAUS\"]. Default JOB, NW, REF."
}
}
}Forget the Xero connection. Nothing in Xero is changed.
No arguments.
{
"type": "object",
"properties": {}
}The trade's account, settings and Nero identity.
No arguments.
{
"type": "object",
"properties": {}
}A private link to the original email, PDF or scan of one invoice, to show the trade.
| Argument | Type | Description |
|---|---|---|
| invoice_id* | string |
{
"type": "object",
"required": [
"invoice_id"
],
"properties": {
"invoice_id": {
"type": "string"
}
}
}Every invoice in the book for a month, with its lines, status and any problems.
| Argument | Type | Description |
|---|---|---|
| month* | string | YYYY-MM, for example 2026-11. |
{
"type": "object",
"required": [
"month"
],
"properties": {
"month": {
"type": "string",
"description": "YYYY-MM, for example 2026-11."
}
}
}The month at a glance: one draft bill per supplier with a line per job (net, VAT and which invoices), invoices held back to check, lines with no job reference, and price changes with the extra cost they caused. Includes the exact Xero payloads. Sends nothing.
| Argument | Type | Description |
|---|---|---|
| month* | string | YYYY-MM, for example 2026-11. |
{
"type": "object",
"required": [
"month"
],
"properties": {
"month": {
"type": "string",
"description": "YYYY-MM, for example 2026-11."
}
}
}Price changes on the same product code from the same supplier this month, in date order, and the extra they cost.
| Argument | Type | Description |
|---|---|---|
| month* | string | YYYY-MM, for example 2026-11. |
{
"type": "object",
"required": [
"month"
],
"properties": {
"month": {
"type": "string",
"description": "YYYY-MM, for example 2026-11."
}
}
}Put the month's bills into Xero as DRAFT bills, one per supplier, one line per job, with the original invoices attached. Without send: true it is a dry run that shows what would be sent. Running it again updates the same draft (no duplicates). A bill the trade has already approved is never changed; late invoices go on a top up bill. Never approves or pays.
| Argument | Type | Description |
|---|---|---|
| send | boolean | true to really add the drafts. Default false (dry run). |
| month* | string | YYYY-MM, for example 2026-11. |
| suppliers | array | Only these suppliers. |
{
"type": "object",
"required": [
"month"
],
"properties": {
"send": {
"type": "boolean",
"description": "true to really add the drafts. Default false (dry run)."
},
"month": {
"type": "string",
"description": "YYYY-MM, for example 2026-11."
},
"suppliers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Only these suppliers."
}
}
}For an invoice held back as needs_check: accept it as read (it then goes on the bill), or remove it (for example to add a corrected copy). Ask the trade first.
| Argument | Type | Description |
|---|---|---|
| action* | string | |
| invoice_id* | string |
{
"type": "object",
"required": [
"invoice_id",
"action"
],
"properties": {
"action": {
"enum": [
"accept",
"remove"
],
"type": "string"
},
"invoice_id": {
"type": "string"
}
}
}Change how job references are read and how bills are entered in Xero.
| Argument | Type | Description |
|---|---|---|
| settings | object | |
| vat_number | string | |
| company_number | string | |
| job_reference_style | string | |
| job_reference_prefixes | array |
{
"type": "object",
"properties": {
"settings": {
"type": "object",
"properties": {
"xero_tax_type": {
"type": "string",
"description": "Default INPUT2, 20% VAT on expenses."
},
"vat_registered": {
"type": "boolean"
},
"xero_account_code": {
"type": "string",
"description": "Xero account the bills go to. Default 300 (Purchases); falls back to cost of sales if missing."
},
"payment_terms_days": {
"type": "number",
"description": "Days after month end the bill is due. Default 30."
},
"price_alert_percent": {
"type": "number",
"description": "Smallest price change worth flagging. Default 1."
},
"xero_tracking_category": {
"type": [
"string",
"null"
],
"description": "Name of a Xero tracking category (for example Job) to tag each line with its job. Off by default."
}
}
},
"vat_number": {
"type": "string"
},
"company_number": {
"type": "string"
},
"job_reference_style": {
"enum": [
"number",
"prefixed"
],
"type": "string"
},
"job_reference_prefixes": {
"type": "array",
"items": {
"type": "string"
}
}
}
}Whether Xero is connected, and to which organisation.
No arguments.
{
"type": "object",
"properties": {}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 13, 2026.