mcp-server-smallinvoice
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-smallinvoice list my unpaid invoices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@aiwerk/mcp-server-smallinvoice
MCP server for smallinvoice.ch — Swiss SME invoicing and accounting (146 tools, OAuth2 BYOC).
Install
npx -y @aiwerk/mcp-server-smallinvoiceRelated MCP server: bexio-mcp
Configure
Variable | Required | Description |
| ✅ | OAuth2 client ID — smallinvoice Home → Users → API V2 → New client |
| ✅ | OAuth2 client secret |
| ✅ | Initial refresh token from the OAuth bootstrap flow (rotates per call) |
| optional | Pre-loaded access token; lazily refreshed if absent or expired |
| optional | Path to persist rotating tokens (default: |
| optional | Set to |
| optional | Set to |
| optional | Directory for pre-write snapshots (default: |
| optional | Set to |
| optional | Request timeout in ms (default: |
MCP client config example (Claude Desktop / OpenClaw)
{
"mcpServers": {
"smallinvoice": {
"command": "npx",
"args": ["-y", "@aiwerk/mcp-server-smallinvoice"],
"env": {
"SMALLINVOICE_CLIENT_ID": "your-client-id",
"SMALLINVOICE_CLIENT_SECRET": "your-client-secret",
"SMALLINVOICE_REFRESH_TOKEN": "your-initial-refresh-token"
}
}
}
}Auth setup
Requires smallinvoice Starter plan or higher (CHF 15/mo). The free tier blocks API access.
In your smallinvoice account: Home → Users → API V2 → New client
Grant type: Authorization Code
Redirect URI:
http://127.0.0.1:8765/callback(must be registered in the client config)Copy
client_idandclient_secret
Run the authorization URL in your browser:
https://api.smallinvoice.com/v2/auth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&scope=profile+contact+contact_reminder+letter+configuration+catalog+invoice+offer+delivery_note+order_confirmation+project+cost_unit+working_hours+activity+effortLog in and approve. You receive a
code.Exchange the code for tokens:
curl -X POST https://api.smallinvoice.com/v2/auth/access-tokens \ -H 'Content-Type: application/json' \ -d '{"grant_type":"authorization_code","client_id":"...","client_secret":"...","code":"...","redirect_uri":"http://127.0.0.1:8765/callback"}'The response contains
access_tokenandrefresh_token.Set
SMALLINVOICE_REFRESH_TOKENto the returnedrefresh_token. The server persists new tokens automatically after each refresh.
Token file is source of truth after first refresh. Once the server performs its first token rotation, the persisted
SMALLINVOICE_TOKEN_FILEtakes priority overSMALLINVOICE_REFRESH_TOKENenv var. If you rotate the refresh token manually, update or delete the token file.
Tools
146 tools total across 6 groups.
Group | Count | Representative tools |
auth | 2 |
|
contacts | 42 |
|
catalog | 22 |
|
receivables | 47 |
|
reporting | 23 |
|
configuration | 10 |
|
All delete_* tools are marked destructiveHint: true. All list_* / get_* / download_* tools are readOnlyHint: true.
Important notes
Refresh token rotation. Smallinvoice revokes the old refresh token the moment it issues a new one. The server uses atomic write (content fsync + atomic rename + dir fsync best-effort) to persist the new token before using it. If the process crashes after the API rotation but before persist completes, the OAuth chain is broken — re-run the bootstrap flow from step 2 above.
Cross-process refresh safety. Multiple MCP server instances sharing the same token file are protected by an O_EXCL file lock. A double-check after acquiring the lock avoids redundant refreshes when another process already rotated the token.
SMALLINVOICE_DRY_RUN=1. All write tools (create_*, update_*, delete_*, change_*, send_*, record_*) return a stub response without contacting smallinvoice:
{ "_dry_run": true, "_would_call": { "method": "POST", "path": "/receivables/invoices", "body": { ... } } }Use this when testing against a production account.
Pre-write snapshots. Before each mutating operation, the current entity state is fetched and saved to ~/.aiwerk/smallinvoice-snapshots/. The tool result includes a _snapshot field with the file path.
PUT / PATCH — snapshots the entity being updated
DELETE — snapshots each entity being deleted (batch-aware: all IDs fetched in parallel, saved as one JSON file with partial-failure tolerance)
send_by_email / send_by_post — snapshots the parent document before sending ⚠️ IRREVERSIBLE: sends real email/post — pre-state snapshotted under
~/.aiwerk/smallinvoice-snapshots/Sub-resource POST (e.g.
record_invoice_payment,create_contact_account) — snapshots the parent entity before modifying it
Disable snapshots with SMALLINVOICE_NO_SNAPSHOT=1. By default, a snapshot failure blocks the write (fail-closed). Set SMALLINVOICE_SNAPSHOT_FAIL_OPEN=1 to downgrade to a warning and continue.
Rate limit. The actual limit is 360 requests/minute (not 1000 as stated in the public documentation). The server logs a warning to stderr when X-Rate-Limit-Remaining drops below 30.
Date formats. Use YYYY-MM-DD for date fields and YYYY-MM-DD HH:MM:SS for timestamp fields (no timezone — Europe/Zurich assumed).
License
MIT — AIWerk
Available Tools
146 toolsassign_contact_groupsC
Assigns groups to specified contact
Inputs: contact_id (required), groups_ids (required).
change_delivery_note_statusB
Changes status of specified delivery note
Inputs: delivery_note_id (required), status (required), date_time.
change_invoice_statusC
Changes status of specified invoice
Inputs: invoice_id (required), status (required), date_time.
change_letter_statusA
Changes status of specified letter
Inputs: letter_id (required), status (required), date_time.
change_offer_statusC
Changes status of specified offer
Inputs: offer_id (required), status (required), date_time.
change_order_confirmation_statusB
Changes status of specified order confirmation
Inputs: order_confirmation_id (required), status (required), date_time.
change_project_statusA
Updates status for specified project
Inputs: project_id (required), status (required).
create_bank_accountB
Creates new bank account
Inputs: description (required), iban (required), default, bank_name, +3 more.
create_contactC
Creates new contact
Inputs: relation (required), type (required), name (required), main_address (required), +22 more.
create_contact_accountB
Creates new account for specified contact
Inputs: contact_id (required), type (required), number (required), default, +2 more.
create_contact_addressB
Creates new address for specified contact
Inputs: contact_id (required), country (required), street (required), postcode (required), +6 more.
create_contact_groupB
Creates new contact group
Inputs: name (required).
create_contact_personA
Creates new person for specified contact
Inputs: contact_id (required), name (required), surname (required), gender (required), +9 more.
create_cost_unitC
Creates new cost unit
Inputs: name (required), type (required), number, description.
create_delivery_noteC
Creates new delivery note
Inputs: contact_id (required), contact_address_id (required), date (required), currency (required), +15 more.
create_effortC
Creates new effort
Inputs: entity_type (required), entity_id (required), duration (required), date (required), +4 more.
create_exchange_rateC
Creates new currency exchange rate
Inputs: currency_from (required), currency_to (required), rate (required).
create_invoiceC
Creates new invoice
Inputs: contact_id (required), contact_address_id (required), date (required), due (required), +28 more.
create_letterC
Creates new letter
Inputs: contact_id (required), contact_address_id (required), date (required), language (required), +9 more.
create_offerC
Creates new offer
Inputs: contact_id (required), contact_address_id (required), date (required), valid_until (required), +17 more.
create_order_confirmationC
Creates new order confirmation
Inputs: contact_id (required), contact_address_id (required), date (required), currency (required), +15 more.
create_productC
Creates new product
Inputs: name (required), including_vat (required), vat (required), unit_id (required), +8 more.
create_product_categoryB
Creates new product category
Inputs: name (required), accounting_account_number.
create_projectC
Creates new project
Inputs: contact_id (required), name (required), start_date (required), number, +3 more.
create_reminderC
Creates new reminder
Inputs: contact_id (required), date_time (required), title (required), interval_value (required), +2 more.
create_serviceC
Creates new service
Inputs: name (required), including_vat (required), vat (required), unit_id (required), +7 more.
create_service_categoryC
Creates new service category
Inputs: name (required), accounting_account_number.
create_working_hoursA
Creates new working hours entry
Inputs: date (required), time_start (required), time_end (required), user_id.
delete_bank_accountsADestructive
Deletes specified bank accounts
Inputs: accounts_ids (required).
delete_contact_accountsCDestructive
Deletes specified accounts
Inputs: contact_id (required), accounts_ids (required).
delete_contact_addressesBDestructive
Deletes specified addresses
Inputs: contact_id (required), addresses_ids (required).
delete_contact_groupsCDestructive
Deletes specified groups
Inputs: groups_ids (required).
delete_contact_peopleBDestructive
Deletes specified people
Inputs: contact_id (required), people_ids (required).
delete_contactsADestructive
Deletes specified contacts
Inputs: contact_ids (required).
delete_cost_unitsBDestructive
Deletes specified cost units
Inputs: cost_unit_ids (required).
delete_delivery_notesCDestructive
Deletes specified delivery notes
Inputs: delivery_note_ids (required).
delete_effortsBDestructive
Deletes specified efforts
Inputs: effort_ids (required).
delete_exchange_ratesADestructive
Deletes specified currency exchange rates
Inputs: exchange_ids (required).
delete_invoice_paymentBDestructive
Deletes specified invoice's payments
Inputs: invoice_id (required), payment_ids (required).
delete_invoicesCDestructive
Deletes specified invoices
Inputs: invoice_ids (required).
delete_lettersCDestructive
Deletes specified letters
Inputs: letter_ids (required).
delete_offersADestructive
Deletes specified offers
Inputs: offer_ids (required).
delete_order_confirmationsBDestructive
Deletes specified order confirmations
Inputs: order_confirmation_ids (required).
delete_product_categoriesBDestructive
Deletes specified product categories
Inputs: category_ids (required).
delete_productsCDestructive
Deletes specified products
Inputs: product_ids (required).
delete_projectsBDestructive
Deletes specified projects
Inputs: project_ids (required).
delete_remindersCDestructive
Deletes reminders
Inputs: reminders_ids (required).
delete_service_categoriesCDestructive
Deletes specified service categories
Inputs: category_ids (required).
delete_servicesCDestructive
Deletes specified services
Inputs: service_ids (required).
delete_working_hoursBDestructive
Deletes specified working hours entries
Inputs: time_ids (required).
download_delivery_note_pdfBRead-only
Gets pdf of specified delivery note
Inputs: delivery_note_id (required).
download_invoice_pdfARead-only
Gets pdf of specified invoice
Inputs: invoice_id (required), options.
download_letter_pdfBRead-only
Gets pdf of specified letter
Inputs: letter_id (required).
download_offer_pdfCRead-only
Gets pdf of specified offer
Inputs: offer_id (required).
download_order_confirmation_pdfBRead-only
Gets pdf of specified order confirmation
Inputs: order_confirmation_id (required).
get_activityARead-only
Returns data of specified activity entry
Inputs: activity_id (required), with.
get_bank_accountBRead-only
Returns data of specified bank account
Inputs: account_id (required), with.
get_contactCRead-only
Returns data of specified contact
Inputs: contact_id (required), with.
get_contact_accountCRead-only
Returns data of specified account
Inputs: contact_id (required), account_id (required), with.
get_contact_addressBRead-only
Returns data of specified address
Inputs: contact_id (required), address_id (required), with.
get_contact_groupBRead-only
Returns data of specified contact group
Inputs: group_id (required), with.
get_contact_personBRead-only
Returns data of specified person
Inputs: contact_id (required), person_id (required), with.
get_cost_unitBRead-only
Returns data of specified cost unit
Inputs: cost_unit_id (required).
get_delivery_noteARead-only
Returns data of specified delivery note
Inputs: delivery_note_id (required), with.
get_delivery_note_previewBRead-only
Gets preview of specified delivery note
Inputs: delivery_note_id (required), page, size.
get_effortBRead-only
Returns data of specified effort
Inputs: effort_id (required), with.
get_exchange_rateBRead-only
Returns data of specified currency exchange rate
Inputs: exchange_id (required).
get_invoiceBRead-only
Returns data of specified invoice
Inputs: invoice_id (required), with.
get_invoice_paymentARead-only
Returns data of specified invoice's payment
Inputs: invoice_id (required), payment_id (required), with.
get_invoice_previewBRead-only
Gets preview of specified invoice
Inputs: invoice_id (required), page, size.
get_isrBRead-only
Returns data of specified ISR
Inputs: isr_id (required), with.
get_letterBRead-only
Returns data of specified letter
Inputs: letter_id (required), with.
get_letter_previewBRead-only
Gets preview of specified letter
Inputs: letter_id (required), page, size.
get_offerBRead-only
Returns data of specified offer
Inputs: offer_id (required), with.
get_offer_previewBRead-only
Gets preview of specified offer
Inputs: offer_id (required), page, size.
get_order_confirmationBRead-only
Returns data of specified order confirmation
Inputs: order_confirmation_id (required), with.
get_order_confirmation_previewBRead-only
Gets preview of specified order confirmation
Inputs: order_confirmation_id (required), page, size.
get_ownerARead-only
Returns data of authenticated resource owner
Inputs: no named parameters.
get_productARead-only
Returns data of specified product
Inputs: product_id (required), with.
get_product_categoryARead-only
Returns data of specified product category
Inputs: category_id (required), with.
get_profileARead-only
Returns data of authenticated user's profile
Inputs: no named parameters.
get_projectBRead-only
Returns data of specified project
Inputs: project_id (required), with.
get_reminderARead-only
Returns data of specified reminder
Inputs: reminder_id (required), with.
get_serviceBRead-only
Returns data of specified service
Inputs: service_id (required), with.
get_service_categoryBRead-only
Returns data of specified service category
Inputs: category_id (required), with.
get_unitCRead-only
Returns data of specified unit
Inputs: unit_id (required), with.
get_working_hoursBRead-only
Returns data of specified working hours entry
Inputs: time_id (required), with.
list_activitiesBRead-only
Returns list of activities entries
Inputs: with, q, filter, limit, +1 more.
list_bank_accountsARead-only
Returns list of bank accounts
Inputs: with, q, filter, limit, +1 more.
list_contact_accountsBRead-only
Returns list of accounts for specified contact
Inputs: contact_id (required), with, q, filter, +2 more.
list_contact_addressesBRead-only
Returns list of addresses for specified contact
Inputs: contact_id (required), with, q, filter, +2 more.
list_contact_groupsCRead-only
Returns list of contact groups
Inputs: with, q, filter, limit, +1 more.
list_contact_peopleBRead-only
Returns list of people for specified contact
Inputs: contact_id (required), with, q, filter, +2 more.
list_contactsCRead-only
Returns list of contacts
Inputs: with, q, filter, limit, +1 more.
list_cost_unitsBRead-only
Returns list of cost units
Inputs: q, filter, limit, offset.
list_delivery_notesBRead-only
Returns list of delivery notes
Inputs: with, q, filter, limit, +1 more.
list_effortsCRead-only
Returns list of efforts
Inputs: with, q, filter, limit, +1 more.
list_exchange_ratesBRead-only
Returns list of currency exchange rates
Inputs: q, filter, limit, offset.
list_invoice_paymentsARead-only
Returns list of payments for specified invoice
Inputs: invoice_id (required), with, q, filter, +2 more.
list_invoicesBRead-only
Returns list of invoices
Inputs: with, q, filter, limit, +1 more.
list_isrsCRead-only
Returns list of ISRs
Inputs: with, q, filter, limit, +1 more.
list_lettersBRead-only
Returns list of letters
Inputs: with, q, filter, limit, +1 more.
list_offersBRead-only
Returns list of offers
Inputs: with, q, filter, limit, +1 more.
list_order_confirmationsBRead-only
Returns list of order confirmations
Inputs: with, q, filter, limit, +1 more.
list_product_categoriesBRead-only
Returns list of product categories
Inputs: with, q, filter, limit, +1 more.
list_productsCRead-only
Returns list of products
Inputs: with, q, filter, limit, +1 more.
list_projectsBRead-only
Returns list of projects
Inputs: with, q, filter, limit, +1 more.
list_remindersCRead-only
Returns list of reminders
Inputs: with, q, filter, limit, +1 more.
list_service_categoriesBRead-only
Returns list of service categories
Inputs: with, q, filter, limit, +1 more.
list_servicesCRead-only
Returns list of services
Inputs: with, q, filter, limit, +1 more.
list_unitsBRead-only
Returns list of units
Inputs: with, q, filter, limit, +1 more.
list_working_hoursBRead-only
Returns list of working hours entries
Inputs: with, q, filter, limit, +1 more.
record_invoice_paymentA
Creates new payment for specified invoice
Inputs: invoice_id (required), type (required), amount (required), date (required), +2 more.
remove_contact_groupsB
Removes groups from specified contact
Inputs: contact_id (required), groups_ids (required).
send_delivery_note_by_emailA
Sends specified delivery note by email (SENDS REAL EMAIL — irreversible)
Inputs: delivery_note_id (required), subject (required), body (required), recipients (required), +1 more.
send_delivery_note_by_postA
Sends specified delivery note by post (SENDS BY POST — irreversible)
Inputs: delivery_note_id (required), palette (required), print (required), speed (required).
send_invoice_by_emailA
Sends specified invoice by email (SENDS REAL EMAIL — irreversible)
Inputs: invoice_id (required), subject (required), body (required), recipients (required), +2 more.
send_invoice_by_postA
Sends specified invoice by post (SENDS BY POST — irreversible)
Inputs: invoice_id (required), palette (required), print (required), speed (required).
send_letter_by_emailB
Sends specified letter by email (SENDS REAL EMAIL — irreversible)
Inputs: letter_id (required), subject (required), body (required), recipients (required), +1 more.
send_letter_by_postA
Sends specified letter by post (SENDS BY POST — irreversible)
Inputs: letter_id (required), palette (required), print (required), speed (required).
send_offer_by_emailA
Sends specified offer by email (SENDS REAL EMAIL — irreversible)
Inputs: offer_id (required), subject (required), body (required), recipients (required), +1 more.
send_offer_by_postA
Sends specified offer by post (SENDS BY POST — irreversible)
Inputs: offer_id (required), palette (required), print (required), speed (required).
send_order_confirmation_by_emailA
Sends specified order confirmation by email (SENDS REAL EMAIL — irreversible)
Inputs: order_confirmation_id (required), subject (required), body (required), recipients (required), +1 more.
send_order_confirmation_by_postA
Sends specified order confirmation by post (SENDS BY POST — irreversible)
Inputs: order_confirmation_id (required), palette (required), print (required), speed (required).
update_bank_accountB
Updates specified bank account
Inputs: account_id (required), default, description, bank_name, +4 more.
update_contactC
Updates specified contact
Inputs: contact_id (required), number, relation, type, +22 more.
update_contact_accountC
Updates specified account
Inputs: contact_id (required), account_id (required), default, type, +3 more.
update_contact_addressB
Updates specified address
Inputs: contact_id (required), address_id (required), default, country, +7 more.
update_contact_groupC
Updates specified group
Inputs: group_id (required), name.
update_contact_personC
Updates specified person
Inputs: contact_id (required), person_id (required), default, name, +10 more.
update_cost_unitC
Updates specified cost unit
Inputs: cost_unit_id (required), number, name, description, +1 more.
update_delivery_noteB
Updates specified delivery note
Inputs: delivery_note_id (required), number, contact_id, contact_address_id, +16 more.
update_effortC
Updates specified effort
Inputs: effort_id (required), duration, date, activity_id, +3 more.
update_exchange_rateB
Updates specified currency exchange rate
Inputs: exchange_id (required), currency_from, currency_to, rate.
update_invoiceB
Updates specified invoice
Inputs: invoice_id (required), number, contact_id, contact_address_id, +29 more.
update_invoice_paymentB
Updates specified invoice's payment
Inputs: invoice_id (required), payment_id (required), notes.
update_letterC
Updates specified letter
Inputs: letter_id (required), contact_id, contact_address_id, contact_prepage_address_id, +10 more.
update_offerC
Updates specified offer
Inputs: offer_id (required), number, contact_id, contact_address_id, +18 more.
update_order_confirmationC
Updates specified order confirmation
Inputs: order_confirmation_id (required), number, contact_id, contact_address_id, +16 more.
update_productB
Updates specified product
Inputs: product_id (required), number, name, description, +9 more.
update_product_categoryC
Updates specified product category
Inputs: category_id (required), name, accounting_account_number.
update_projectC
Updates specified project
Inputs: project_id (required), number, contact_id, name, +4 more.
update_reminderB
Updates specified reminder
Inputs: reminder_id (required), contact_id, date_time, title, +3 more.
update_serviceC
Updates specified service
Inputs: service_id (required), number, name, description, +8 more.
update_service_categoryB
Updates specified service category
Inputs: category_id (required), name, accounting_account_number.
update_working_hoursB
Updates specified working hours entry
Inputs: time_id (required), user_id, date, time_start, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 146 tools
Most tools are cleanly separated by resource prefix (e.g., list_invoices, create_product), making selection straightforward. Minor ambiguity exists between get_owner and get_profile, and between activities/efforts/working_hours, which could confuse agents in time-tracking contexts.
The naming pattern is highly consistent: list_/create_/get_/update_/delete_ plus standardized document actions like download_*_pdf, get_*_preview, and send_*_by_email. Small deviations such as record_invoice_payment and singular delete_invoice_payment break the pattern slightly but do not undermine overall predictability.
At 146 tools, this is an extreme overload for an MCP server, far beyond the 25+ threshold and even the 50+ extreme case. Even though the domain is broad, the enormous surface area will overwhelm agents and create selection overhead, suggesting the need for consolidation or dynamic tool discovery.
The server covers the core invoicing/ERP lifecycle well, with full CRUD on contacts, products, invoices, offers, delivery notes, and projects, plus domain-specific actions like PDF generation and sending. Missing mutability for units, ISRs, and activities are notable but minor gaps that do not block primary workflows.
Related MCP Connectors
Free hosted MCP for invoices, estimates, clients, items and PDFs. OAuth authorization required.
MCP server for MOCO business software: time tracking, projects, budgets, and invoicing via API
MCP server for Quaderno — tax-rate calculation, invoices, contacts, products, receipts & expenses.
MCP server for Codat — companies, connections, invoices, bills and financial statements.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceMCP server for Holded — invoicing, accounting, CRM, projects, and team77 npm1MIT
- AlicenseAqualityCmaintenanceMCP server for the bexio API, enabling interaction with contacts, sales, accounting, projects, and more through 35 tools. Supports both PAT and OAuth authentication with read-only mode and tool group filtering.3523 npm4MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that acts as a secure, multi-tenant proxy to the InvoiceShelf API, enabling AI assistants to manage invoices, estimates, customers, payments, expenses, and more with 109 tools and TOON compression for efficient token usage.GPL 3.0
- AlicenseBqualityBmaintenanceMCP server for VoxFactura enabling AI assistants to query business data (invoices, expenses, project margins, clients, VAT) and create draft quotes or mark invoices paid via a scoped API, with no direct client sends.25MIT