MCP (Model Context Protocol) server for the InvoiceXpress API V2. Lets Claude Code — and any other MCP-aware client — operate the Portuguese invoicing platform directly: create invoices, finalise, email customers, generate PDFs, register payments, export SAF-T, and more.
Stop pasting numbers into the dashboard. Tell Claude "create an invoice for Acme Lda for €1230 + VAT, finalise it and email the customer", and it does the right calls.
claude mcp add invoice-express \
--env INVOICE_EXPRESS_ACCOUNT_NAME=your-account-subdomain \
--env INVOICE_EXPRESS_API_KEY=your-api-key \
-- npx -y @digitaldev-lx/mcp-invoice-expressThat's it. Restart Claude Code (or run /mcp to verify the connection) and the 25 tools below are available.
Replace
your-account-subdomainwith the prefix of your dashboard URL — if you log in athttps://acme.app.invoicexpress.com/, the subdomain isacme. Generate the API key at https://www.app.invoicexpress.com/users/api.
If you'd rather commit the configuration to a repo:
{
"mcpServers": {
"invoice-express": {
"command": "npx",
"args": ["-y", "@digitaldev-lx/mcp-invoice-express"],
"env": {
"INVOICE_EXPRESS_ACCOUNT_NAME": "${INVOICE_EXPRESS_ACCOUNT_NAME}",
"INVOICE_EXPRESS_API_KEY": "${INVOICE_EXPRESS_API_KEY}"
}
}
}
}Place the file at the project root, set the env vars in your shell, and the MCP loads automatically when Claude Code is launched from that directory.
The package ships an executable binary called mcp-invoice-express. Any MCP client that speaks stdio can use it:
INVOICE_EXPRESS_ACCOUNT_NAME=acme \
INVOICE_EXPRESS_API_KEY=xxx \
npx -y @digitaldev-lx/mcp-invoice-express| Env var | Required | Default | Description |
|---|---|---|---|
INVOICE_EXPRESS_ACCOUNT_NAME |
✅ | — | Subdomain of your account |
INVOICE_EXPRESS_API_KEY |
✅ | — | API key from https://www.app.invoicexpress.com/users/api |
INVOICE_EXPRESS_TIMEOUT |
15000 |
HTTP timeout in milliseconds | |
INVOICE_EXPRESS_RETRY_TIMES |
3 |
Retries on 429 / 5xx (set 0 to disable) |
|
INVOICE_EXPRESS_RETRY_BACKOFF_MS |
1000 |
Base backoff in ms (exponential thereafter) | |
INVOICE_EXPRESS_LOG_LEVEL |
warn |
silent / error / warn / info / debug (logs go to stderr) |
The server uses one account per instance. To work with multiple InvoiceXpress accounts in parallel, configure multiple MCP servers with different names:
claude mcp add ix-acme \
--env INVOICE_EXPRESS_ACCOUNT_NAME=acme \
--env INVOICE_EXPRESS_API_KEY=xxx \
-- npx -y @digitaldev-lx/mcp-invoice-express
claude mcp add ix-otra \
--env INVOICE_EXPRESS_ACCOUNT_NAME=otraempresa \
--env INVOICE_EXPRESS_API_KEY=yyy \
-- npx -y @digitaldev-lx/mcp-invoice-express"List the draft invoices issued this month and tell me the total."
"Create a fatura for Acme Lda — 4 hours of consulting at €100/h plus 23% IVA.
Finalise it and email it to finance@acme.pt."
"Mark invoice 4523 as paid by bank transfer of €1230 on 2026-05-15."
"Generate the SAF-T XML for April 2026 and save it to ./saft.xml."
"Issue a credit note against invoice 5012 for €100 and email it."
"Has the invoice for client ACM-001 been paid yet?"
The server exposes 25 high-level tools plus a raw fallback for the rest of the API.
| Tool | What it does |
|---|---|
create_invoice |
Create a draft invoice. document_type selects: Invoice, SimplifiedInvoice, InvoiceReceipt, CreditNote, DebitNote, Receipt, CashInvoice, VatMossInvoice. |
find_invoice |
Fetch an invoice (or any other invoice-like document) by id. |
list_invoices |
List with filters (status, dates, free-text). |
change_document_state |
Move through the lifecycle: finalized, settled, canceled, deleted. |
email_document |
Send the document to the customer. |
generate_document_pdf |
Get a temporary 24h pdfUrl (use second_copy: true for the "2.ª via" watermark). |
register_payment |
Record a payment (SAF-T codes: NU/CH/TB/CD/MB/MW/CC/PP/LC/CS/OU). |
list_related_documents |
Documents linked to this one (refunds, receipts, etc). |
| Tool | What it does |
|---|---|
create_estimate |
Quote / Proforma / FeesNote / Estimate (estimate_type). |
list_estimates |
List by type and status. |
| Tool | What it does |
|---|---|
create_guide |
Transport / Shipping / Devolution / Global guide. |
list_guides |
List by type and status. |
| Tool | What it does |
|---|---|
create_purchase_order |
Create a PO for a supplier. |
list_purchase_orders |
List with filters. |
| Tool | What it does |
|---|---|
create_client |
Add a new client. |
find_client |
Lookup by id / name / code / vat (one identifier). |
list_clients |
Paginated list with optional free-text search. |
update_client |
Patch fields on an existing client. |
| Tool | What it does |
|---|---|
create_item |
Add a catalogue item (product/service). |
list_items |
Paginated list. |
update_item |
Patch fields on an existing item. |
| Tool | What it does |
|---|---|
list_taxes |
All taxes configured in the account. |
list_sequences |
All document numbering sequences. |
list_accounts |
All banking/cash accounts. |
| Tool | What it does |
|---|---|
list_treasury_movements |
Cash flow movements (with date/account filters). |
create_treasury_movement |
Register a cash-in or cash-out movement. |
generate_saft |
SAF-T XML for the AT (year + month). |
| Tool | What it does |
|---|---|
invoice_express_request |
Send any request (method, path, query?, body?) to the V2 API for endpoints not covered by the high-level tools. |
Read-only context that Claude can attach automatically:
| URI | Content |
|---|---|
invoice-express://invoices/recent |
The 50 latest invoices (JSON). |
invoice-express://clients |
The first 100 clients (JSON). |
invoice-express://account |
Account name + sequences + taxes + banking accounts. |
| Prompt | Use case |
|---|---|
create_invoice_workflow |
End-to-end: locate/create the client → draft invoice → finalise → email → register payment. Accepts client_hint, items_hint, send_email. |
monthly_close_workflow |
List drafts for a period, finalise with confirmation, summarise totals, generate SAF-T. Accepts year + month. |
In Claude Code:
/prompts # browse available prompts
/prompts create_invoice_workflow # use one
| HTTP status | Mapped error | What it means |
|---|---|---|
401 |
AuthenticationError |
API key missing or wrong; double-check INVOICE_EXPRESS_API_KEY. |
404 |
NotFoundError |
The document/client/etc does not exist. |
400 |
BadRequestError |
Malformed request payload. |
422 |
ValidationError |
Field-level errors (returned to Claude as fieldErrors: { name: [...], ... }). |
429 |
RateLimitError |
Exceeded 780 req/min/account; the server retries automatically up to INVOICE_EXPRESS_RETRY_TIMES. |
5xx |
ServerError |
InvoiceXpress upstream issue; the server retries automatically. |
Tool errors are returned to Claude with isError: true so it can decide whether to retry, ask the user, or surface the failure.
Once installed, run:
/mcp
You should see invoice-express listed as connected, with 28 tools (25 high-level + raw + 2 prompts). Then ask Claude:
"Use list_taxes to show me the IVA configurations of my account."
If the call succeeds, you're good to go.
"INVOICE_EXPRESS_ACCOUNT_NAME is required" — the env vars were not passed in. With claude mcp add, use --env KEY=VALUE. With .mcp.json, set the env vars in your shell or use literal values.
Authentication failed for InvoiceXpress — confirm the API key from the dashboard is current. Generating a new one immediately revokes the previous one.
"connection closed" / process exits immediately — run the binary by hand with the same env vars to see the actual error: INVOICE_EXPRESS_ACCOUNT_NAME=demo INVOICE_EXPRESS_API_KEY=xxx npx -y @digitaldev-lx/mcp-invoice-express. The first line on stderr is the failure message.
Tools list is empty in /mcp — try MCP_TIMEOUT=10000 claude to give the server more time to boot, then re-check /mcp.
Rate limit reached — InvoiceXpress allows 780 requests per minute per account. Heavy bulk operations may temporarily 429; the server retries with exponential backoff (1s → 2s → 4s by default). Increase INVOICE_EXPRESS_RETRY_TIMES if needed.
If you operate InvoiceXpress from a Laravel application (without an MCP), check out digitaldev-lx/laravel-invoice-express. The two share the same architectural decisions (DTOs, error hierarchy, document type routing).
git clone git@github.com:digitaldev-lx/mcp-invoice-express.git
cd mcp-invoice-express
npm install
npm test # vitest
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run build # output → dist/
# Run locally without npm install
INVOICE_EXPRESS_ACCOUNT_NAME=demo INVOICE_EXPRESS_API_KEY=xxx npm run devCI runs lint + typecheck + test on every PR against Node 20 and Node 22. Tags v* trigger an automatic npm publish.
See CONTRIBUTING.md for the workflow.
If you find a security issue, please do not open a public issue. Email geral@digitaldev.pt and we'll respond within 48 hours.
MIT © DigitalDev. See LICENSE.