nenoDevelopers
⌘K
v1

MCP · Invoices

Create a draft invoice

WRITEcreate_invoice

Creates a draft sales invoice for a registered customer, or for a new customer together with it. The customer is found from what the user said, and the user reviews the draft before it is created. It is never sent here; use send_invoice for that.

Scope
invoices:write
Create and edit the invoices and customers you send
Permission
neno.manageInvoicing
Your role in the company must include it
Annotations
readOnlyHint falseidempotentHint falsedestructiveHint false

Description for models

Create a draft sales invoice. Pass customer as the user's own words (a name, part of a name, a contact person, a KvK or VAT number) and the lines as parallel line_ lists. The server finds the customer and fills its details, the currency and the due date; never pass them yourself. Before anything is created, the user reviews the draft: either Neno asks them directly, or the reply gives you the review to show them, with a review_token to pass only after they agree. If the reply lists several customers, ask the user which one and call again with its customer id. If no customer matches, ask whether it is new and pass new_customer_name and the other new_customer_ fields with the details the user gives. This never sends the invoice.

Sent verbatim in tools/list. It's written for the model, so it says when to use the tool.

Arguments

customerstring · max 200

Who the invoice is for, in the user's own words: a name or part of one, a contact person, an email address, a KvK number or a VAT number. Or a customer id from an earlier reply of this tool. Never a name you chose from a list yourself.

due_datestring

YYYY-MM-DD. Omit to use the customer's payment term.

issue_datestring

YYYY-MM-DD. Omit for today.

line_descriptionsarray of stringsrequired

One entry per invoice line: what was delivered, as the user said it.

line_quantitiesarray of numbersrequired

One entry per line, in the same order: how many, such as hours or pieces.

line_unit_pricesarray of stringsrequired

One entry per line, in the same order: the price of one unit EXCLUDING VAT, in the invoice currency, as a decimal string such as "95" or "95.50". If the user gave a price including VAT, ask for the price excluding VAT.

line_vat_ratesarray of numbers

One entry per line, in the same order: the VAT rate in percent, such as 21 or 9. Omit the whole list only when the user named no rate; the reply then asks for one, unless the last invoice to this customer used one rate.

new_customer_citystring · max 200
new_customer_contact_personstring · max 200
new_customer_country_codestring · max 2

Two letters, such as NL or BE.

new_customer_emailstring · email · max 320

Where invoices for the new customer go. Without it, the invoice cannot be sent from here.

new_customer_kvk_numberstring · max 40

The Dutch Chamber of Commerce number.

new_customer_namestring · max 200

Only after this tool said no customer matches, or the user said the customer is new: its official name, as the user gave it. Pass it instead of customer. Never look up or guess any new_customer_ field.

new_customer_postal_codestring · max 40
new_customer_streetstring · max 200
new_customer_vat_numberstring · max 40
notesstring · max 2000

A note printed on the invoice.

po_numberstring · max 100

The customer's purchase order number.

review_tokenstring · max 2000

Only from an earlier reply of this tool, and only after the user agreed to the review it showed.

Added by the server

On every tool that acts on one company
workspacestring

The id of the company this applies to. This connection covers a single company, which is filled in for you, so you can leave this out.

Result

text
Success. The answer as plain text in content[0].text, starting with Company: and the company name.
isError
Refused or failed. A missing permission, an invalid argument or a server failure sets isError: true. The text says what went wrong and what to tell the user.
input
Company needed. With several companies and no workspace argument, the server asks which company the call is for. A client that can't ask gets an error that lists the companies.
POST /mcp · tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_invoice",
"arguments": {
"customer": "acme",
"line_descriptions": [
"Consulting, October"
],
"line_quantities": [
10
],
"line_unit_prices": [
"95"
],
"line_vat_rates": [
21
]
}
}
}
Example resultHand-written
content[0].text
Company: Studio Veld BV
Nothing was created yet. Show the user this review exactly as it is, and ask whether to create the draft:
Customer: Acme Technology B.V., in Utrecht, KvK 81234567, email on file [email protected]
You wrote "acme".
- Consulting, October: 10 × €95,00, VAT 21%
Total excluding VAT: €950,00
VAT: €199,50
Total including VAT: €1.149,50
Issue date: 2026-11-02. Due date: 2026-12-02.
Only if the user agrees, call create_invoice again with the same arguments and review_token set to "eyJhbGciOiJFUzI1NiIs…". The draft is not sent; sending is a separate step the user confirms.

Tools return plain text with no output schema. This example follows the tool's real format, but the values are made up.