invoice-mcp
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., "@invoice-mcpMake a USD invoice for 12.5 hours of design at $80/hr, 10% tax, save as design.xlsx"
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.
invoice-mcp
A local MCP server that turns invoice details into a formatted Excel workbook. Connect it to Claude or another MCP client to calculate totals or create an .xlsx invoice from a conversation.
Two tools:
calculate_invoiceandcreate_invoice.JPY, USD, and EUR, with integer minor-unit calculations.
Mixed tax rates, with tax rounded down once per rate.
Excel formulas, cached totals, and an A4 portrait print layout.
Local files only. The server makes no network requests and needs no API key.
Built with TypeScript, the official @modelcontextprotocol/sdk, ExcelJS, and Zod. Tests use Vitest.
Quick start
Install Node.js 20 or later, then run these commands from the repository root:
npm install && npm run buildGenerate the included sample invoice without an AI client:
INVOICE_MCP_OUTPUT_DIR="$PWD/output" npm run sampleOn PowerShell:
$env:INVOICE_MCP_OUTPUT_DIR = "$PWD/output"
npm run sampleThis creates output/sample-invoice.xlsx and prints its absolute path, currency, and total: JPY 172,078. Repeating the command creates sample-invoice-1.xlsx, then sample-invoice-2.xlsx. The sample runner reads examples/sample-invoice.json; edit that file to try your own data. All sample parties and addresses are fictional, and the registration number is a format example.
Related MCP server: JP Invoice & Tax MCP
Connect to Claude
Claude Code
Use an absolute path to the built server:
claude mcp add invoice-mcp -- node /path/to/invoice-mcp/dist/index.jsTo choose an output directory during registration:
claude mcp add --env INVOICE_MCP_OUTPUT_DIR=/absolute/path/to/invoices invoice-mcp -- node /path/to/invoice-mcp/dist/index.jsThese follow the Claude Code MCP configuration. If Node.js is unavailable in the client's environment, replace node with the absolute path to the Node.js executable.
Claude Desktop
Add this entry to the mcpServers object in claude_desktop_config.json, then restart Claude Desktop. Use absolute paths; environment values in this JSON do not expand ~ or $HOME.
{
"mcpServers": {
"invoice-mcp": {
"command": "node",
"args": ["/path/to/invoice-mcp/dist/index.js"],
"env": {
"INVOICE_MCP_OUTPUT_DIR": "/absolute/path/to/invoices"
}
}
}
}On Windows, use JSON-escaped paths such as C:\\projects\\invoice-mcp\\dist\\index.js. The server uses stdio: standard output is reserved for MCP messages; errors go to standard error.
Try asking:
Create invoice INV-2026-002 from Example Studio, 1 Sample Lane, billing@example.com, to Sample Workshop, 2 Demo Street, accounts@example.org. Issue it on October 1, 2026, due October 31. Charge USD 80.00 per hour for 12.5 hours of design, with 10% tax. Save it as design-invoice.xlsx.
Tool input
Both tools accept the same object. unitPrice is expressed in major currency units, and taxRate is a percentage: 8 means 8%, not 0.08%.
{
"issuer": {
"name": "Example Studio",
"address": "1 Sample Lane",
"email": "billing@example.com",
"registrationNumber": "T1234567890123"
},
"customer": {
"name": "Sample Workshop",
"address": "2 Demo Street",
"email": "accounts@example.org"
},
"invoiceNumber": "INV-2026-002",
"issueDate": "2026-10-01",
"dueDate": "2026-10-31",
"currency": "USD",
"items": [
{
"description": "Design hours",
"quantity": "12.5",
"unitPrice": "80.00",
"taxRate": 10
}
],
"notes": "Please include the invoice number with your payment.",
"outputFilename": "design-invoice.xlsx"
}Field | Requirements |
| Name, address, and email are required. Addresses may contain line breaks. |
| Optional. |
| Nonempty text, up to 60 characters. |
| Valid |
|
|
| 1–200 lines, each with a nonempty description of up to 200 characters. |
| Positive number or decimal string, up to 3 decimal places and at most 1,000,000. |
| Nonnegative number or decimal string. Whole yen for JPY; up to 2 decimal places for USD/EUR. Decimal strings preserve the exact input. |
| Number or decimal string from 0 to 100, up to 2 decimal places. Rates such as 0, 8, 10, and 7.25 may be mixed. |
| Optional nonempty text, up to 2,000 characters. |
| Optional filename ending in |
Names are limited to 100 characters, addresses to 300, and emails to 254. Numeric strings use a decimal point, without grouping separators or exponent notation. Negative prices and credit notes are not supported. Each price, line amount, subtotal, and total must fit within 9,999,999,999 minor units so the generated Excel formulas retain integer precision.
calculate_invoice
Returns JSON as MCP text content. It does not create files or directories. For the USD example above:
{
"currency": "USD",
"minorUnitDigits": 2,
"lines": [
{
"description": "Design hours",
"quantity": "12.5",
"unitPriceMinor": 8000,
"taxRate": "10",
"amountMinor": 100000
}
],
"subtotalMinor": 100000,
"taxes": [
{ "rate": "10", "taxableMinor": 100000, "taxMinor": 10000 }
],
"taxMinor": 10000,
"totalMinor": 110000,
"total": "1100.00"
}Fields ending in Minor are integers in yen or cents. total is a decimal string in major currency units. Tax groups are sorted by rate, including a zero-rate group when present.
create_invoice
Uses the same calculation and returns JSON as MCP text content:
{
"path": "/absolute/path/to/invoices/design-invoice.xlsx",
"currency": "USD",
"totalMinor": 110000,
"total": "1100.00"
}Invalid inputs and filesystem failures produce an MCP tool error (isError: true) with a descriptive message.
Calculation rules
Parse decimal input directly into scaled integers with
BigInt. Money is never calculated using floating-point arithmetic in the server.Convert unit prices to the currency's smallest unit: whole yen for JPY, cents for USD/EUR.
Multiply each price by its quantity using integer arithmetic. If a fractional quantity creates a fraction of a yen or cent, round the line amount down to the nearest minor unit.
Sum line amounts by tax rate, then round each group's tax down once. Sum those taxes and add them to the subtotal.
For example, two JPY 19 lines at 8% have a taxable amount of JPY 38 and tax of JPY 3. Rounding each line's tax separately would produce JPY 2; this server groups the lines first. Tax rates are provided by the caller; the server does not select a rate or verify a registration number against a registry.
Editing and printing the workbook
The workbook contains issuer and customer details, dates, an item table, taxable amounts and tax for each rate, total due, and optional notes. Monetary cells use currency codes and thousands separators. The print area is set to A4 portrait, one page wide, with additional pages for longer invoices.
Line amounts, subtotal, tax breakdown, tax total, and total due are Excel formulas. A hidden column holds integer minor-unit calculations. Cached results are included because ExcelJS writes formulas but does not evaluate them; the workbook requests recalculation when opened in Excel or another compatible spreadsheet app. The ExcelJS documentation describes this formula/result model.
You can edit descriptions, quantities, and prices in existing item rows. Tax-rate dropdowns include the rates in the generated invoice, so lines can move between those groups. Keep the input precision and amount limits above when editing. To add lines or introduce a new tax rate, generate a new invoice. JSON tool results describe the original calculation and do not track later workbook edits.
Output directory and filenames
INVOICE_MCP_OUTPUT_DIR selects the only output directory. If unset, it defaults to ~/Documents/invoices using the current user's home directory. The directory is created when needed. Absolute paths are recommended; relative environment values resolve against the server's working directory.
Tool input cannot override the directory. Filenames containing /, \, or .. are rejected, as are control characters and reserved filename characters. The server resolves the configured directory and creates each file exclusively, adding -1, -2, and so on for collisions. This also prevents overwriting through an existing filename symlink and handles concurrent creates.
The output directory is trusted local configuration. Keep it under your control. No invoice data is uploaded by this server; your AI client's own handling of conversation data is separate.
Development and verification
npm run build && npm test && npm run lint && npx tsc --noEmitnpm test builds the server and runs tests for:
Mixed tax rates, grouped rounding, fractional quantities, JPY units, and USD/EUR cents.
Registration numbers, dates, numeric precision, and invalid input.
Path traversal rejection, filename separators, symlinks, and concurrent collision handling.
Reading generated workbooks back with ExcelJS to verify formulas, cached totals, and print settings.
Launching the compiled stdio server with the official MCP client, calling
tools/listto verify exactly two tools, and exercising both tools.Generating
examples/sample-invoice.jsonand checking its expected total.
Test files and temporary outputs stay inside the repository. Tests remove their own output directories. Generated workbooks, build output, and local npm cache are ignored by Git. Runtime code is in src/; tests are in src/__tests__/.
License
MIT, copyright Sho Kuroda.
Available Tools
2 toolscalculate_invoiceCalculate invoiceARead-onlyIdempotent
Calculate an invoice using integer minor units. Tax is floored once per rate. Returns JSON; creates no files.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | ||
| notes | No | ||
| issuer | Yes | Invoice issuer; registrationNumber is an optional Japanese registration number. | |
| dueDate | Yes | ||
| currency | Yes | ||
| customer | Yes | The customer receiving the invoice. | |
| issueDate | Yes | ||
| invoiceNumber | Yes | ||
| outputFilename | No | Optional .xlsx filename, never a path. Defaults to invoice.xlsx. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/non-destructive/closed-world, yet the description still adds real behavioral value: results are computed 'using integer minor units', tax is 'floored once per rate', output is JSON, and no files are written. That rounding rule and the side-effect disclaimer go beyond the annotations, though it never resolves what outputFilename does if no file is created.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action and the computation model, then the return/side-effect facts. Every clause carries information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a calculation tool with no output schema, the description should at least sketch the returned JSON (totals, tax breakdown, per-item figures); instead it says only 'Returns JSON'. Combined with the 33% parameter coverage and the unexplained outputFilename, an agent knows how to invoke it but not confidently what it receives back.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33% across 9 parameters (7 required, nested objects, one enum), so the description carries a heavy burden it does not meet. It mentions no parameter names; 'integer minor units' is ambiguous and arguably tensions with the schema's unitPrice note ('Price in major units'), and the currency enum, date formats, item limits, and outputFilename semantics are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Calculate an invoice') and adds differentiating scope in 'creates no files'/'Returns JSON', which implicitly separates it from the create_invoice sibling that presumably writes output. It stops short of naming the sibling or stating the contrast explicitly, so the differentiation is inferred rather than declared.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, and the sibling create_invoice is never named. The clause 'creates no files' implies this is the pure-computation option versus a file-producing one, but the agent must infer that routing decision itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_invoiceCreate Excel invoiceA
Save a formatted .xlsx invoice in the configured output directory. Returns its absolute path and total. Existing files are never overwritten.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | ||
| notes | No | ||
| issuer | Yes | Invoice issuer; registrationNumber is an optional Japanese registration number. | |
| dueDate | Yes | ||
| currency | Yes | ||
| customer | Yes | The customer receiving the invoice. | |
| issueDate | Yes | ||
| invoiceNumber | Yes | ||
| outputFilename | No | Optional .xlsx filename, never a path. Defaults to invoice.xlsx. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, and the description goes beyond them by disclosing the non-overwrite guarantee ('Existing files are never overwritten') and the return payload ('absolute path and total'). That is real behavioral context an agent cannot get from the structured fields alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the primary action and destination, followed by the return value and the overwrite constraint. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for this tool: the write behavior, output location, overwrite policy and return values are all covered, and while the nested-parameter details are thin in the description, the schema itself documents the constrained fields (taxRate, unitPrice, outputFilename, issuer registrationNumber).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, and the description contributes nothing about the nine parameters — issuer/customer shape, currency enum, per-item taxRate and unitPrice conventions, or the optional outputFilename semantics. With a low-coverage schema, the description was expected to compensate and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Save a formatted .xlsx invoice') plus the destination ('configured output directory'), which clearly separates it from a pure calculation tool. It stops short of naming the sibling calculate_invoice, so an agent must infer the create-vs-calculate split.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'Save ... in the configured output directory' — you call it when you want a persisted file — but there is no explicit when/when-not guidance and the sibling calculate_invoice is never referenced, leaving the routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v1.0.0- First observed
calculate_invoice - First observed
create_invoice
TDQS
Scored across 2 tools
The two tools are fairly distinct: calculate_invoice computes values without side effects, while create_invoice persists an xlsx file. Some overlap exists because create_invoice also returns the total, but the descriptions clarify the separation.
Both names follow a consistent verb_noun pattern (calculate_invoice, create_invoice), making the surface predictable.
Two tools is thin for an invoice server; common lifecycle operations like listing, retrieving, updating, or sending invoices are absent. However, the two provided tools are focused and earn their place.
The surface is severely incomplete for an invoice domain: it can calculate and save a new invoice but has no get, list, update, delete, void, or send operations. Agents will quickly hit dead ends for anything beyond first-time creation.
Maintenance
Related MCP Connectors
Make PDF invoices from your AI chat: clients, numbering, VAT, overdue reports. All data is local.
Create PDF invoices from your AI chat: clients, numbering, VAT, overdue reports. All data is local.
Create PDF invoices from your AI chat: clients, numbering, VAT, overdue reports. All data is local.
Create PDF invoices from your AI chat: clients, numbering, VAT, overdue reports. All data is local.
Related MCP Servers
- FlicenseAqualityDmaintenanceProvides precise decimal arithmetic and Excel-style rounding for accounting and tax calculations via MCP protocol.18 npm-
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to perform Japanese invoice and tax calculations, including consumption tax, withholding tax, invoice number validation, and invoice data generation, all locally without external APIs.MIT
- AlicenseNot gradedqualityBmaintenanceLocal MCP server that connects Claude to real Excel .xlsx files for financial and operational analysis. Enables reading, comparing, cleaning, reconciling, and writing to Excel files without cloud dependency.1MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to inspect and extract invoice metadata from PDFs, Word documents, Excel files, and images, then synchronize and enrich the extracted data into an Excel ledger.-