mad-invoice-mcp
Enables creation and management of invoices with JSON storage and LaTeX-based PDF rendering. Supports draft creation and professional PDF generation through customizable LaTeX templates.
README
Mechatronics Advisory & Design – invoiceMCP server
<img width="2048" height="786" alt="logo" src="https://github.com/user-attachments/assets/203a5a7b-4802-4edc-8250-ddaf7143186c" />
MAD invoiceMCP: Creating, storing, and rendering invoices as JSON + LaTeX + PDF. Designed for single-company workflows with local storage in .mad_invoice/ (no external database required).
What it does:
- Create and manage invoices via MCP tools
- Render professional PDFs with LaTeX
- Track payment status and generate invoice numbers
- Support for German §19 UStG (small business) and VAT
Why:
- "Kraft" wasen't fexible enough
- the others where overkill or required web space
- The re-kp project had already done half the groundwork
Setup: Choose your path
Pick the setup that matches your situation:
Supported clients
| Client | Type | OS | Status | Usage |
|---|---|---|---|---|
| OpenWebUI (with MAD shim) | Web UI (MCP over SSE) | Linux, macOS, Windows | Supported | Everyday |
| Claude Desktop | Desktop app (MCP stdio) | macOS, Windows | Supported | Everyday |
| Continue.dev | IDE extension (MCP stdio) | Linux, macOS, Windows | Supported | Dev |
| Cline | IDE extension (MCP stdio) | Linux, macOS, Windows | Supported | Dev |
| Claude Code (VS Code) | IDE extension (MCP stdio) | Linux, macOS, Windows | Supported | Dev |
Path A: MCP stdio (local pdflatex)
When to use: You have or can install TeX Live 2024+ locally.
# 1. Install dependencies
pip install -r requirements.txt
# 2. Start MCP server (stdio)
MCP_ENABLE_WRITES=1 python -m bridge --transport stdio
The server auto-discovers pdflatex in:
- System PATH
~/.local/texlive/*/bin/*/pdflatex/usr/local/texlive/*/bin/*/pdflatex
Manual override for custom locations:
export PDFLATEX_PATH=/path/to/your/pdflatex
MCP_ENABLE_WRITES=1 python -m bridge --transport stdio
Path B: MCP stdio (via Docker)
When to use: You don't have TeX Live, or want to avoid version issues (TeX Live 2022 has known bugs).
# 1. Build image (includes TeX Live 2025)
docker build -t mad-invoice-mcp .
# 2. Run MCP server via Docker
docker run --rm -i \
-e MCP_ENABLE_WRITES=1 \
-v $(pwd)/.mad_invoice:/app/.mad_invoice \
mad-invoice-mcp python -m bridge --transport stdio
What this does:
- Bundles TeX Live 2025 (no local installation needed)
- Mounts
.mad_invoice/so data persists on your host - Runs stdio through the container
Path C: Web UI / Development
When to use: You want the web interface or are developing the server itself.
# Local development server
./bin/dev # starts uvicorn on 127.0.0.1:8000
MCP_ENABLE_WRITES=1 ./bin/dev # with write operations enabled
Or via Docker:
docker run --rm -p 8000:8000 \
-e MCP_ENABLE_WRITES=1 \
-v $(pwd)/.mad_invoice:/app/.mad_invoice \
mad-invoice-mcp
Access web UI at http://localhost:8000/invoices
Requirements
- Python 3.11+ (for local setup)
- pdflatex (TeX Live 2024+ recommended, or use Docker)
- MCP_ENABLE_WRITES=1 environment variable to enable write operations
Advanced usage: See ADVANCED.md for SSE transport, OpenWebUI integration, and production deployment.
MCP Client Configuration
Everyday clients: OpenWebUI (via the MAD shim) and Claude Desktop. IDE-based clients below (Continue.dev, Cline, Claude Code) are supported for development workflows only.
Claude Desktop (Local)
Add to your Claude Desktop config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%/Claude/claude_desktop_config.json on Windows):
{
"mcpServers": {
"mad-invoice": {
"command": "python",
"args": ["-m", "bridge.cli", "--transport", "stdio"],
"cwd": "/absolute/path/to/mad-invoice-mcp",
"env": {
"MCP_ENABLE_WRITES": "1"
}
}
}
}
Note: Replace /absolute/path/to/mad-invoice-mcp with your actual project path.
Claude Desktop (Docker)
For Docker-based setup (no local TeX Live needed):
{
"mcpServers": {
"mad-invoice": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/absolute/path/to/.mad_invoice:/app/.mad_invoice",
"-e", "MCP_ENABLE_WRITES=1",
"mad-invoice-mcp",
"python", "-m", "bridge.cli", "--transport", "stdio"
]
}
}
}
Important:
- Build the image first:
docker build -t mad-invoice-mcp . - Replace
/absolute/path/to/.mad_invoicewith where you want invoices stored - On Windows, use:
C:/Users/YourName/.mad_invoice:/app/.mad_invoice
Cline / Continue.dev
Similar stdio configuration in your MCP settings:
{
"mad-invoice": {
"command": "python",
"args": ["-m", "bridge.cli", "--transport", "stdio"],
"cwd": "/absolute/path/to/mad-invoice-mcp",
"env": {
"MCP_ENABLE_WRITES": "1"
}
}
}
MCP Tools
The server exposes these tools for LLM/MCP clients:
Draft vs. Final Workflow
Invoices follow a draft → final lifecycle:
- Draft (
status="draft"): Fully editable, can be deleted - Final (
status="final"): Immutable "sargnagel" - only PDF rendering and reading allowed
create_invoice_draft(invoice: Invoice)
Create and save a new invoice (always starts as draft).
Key fields for LLMs:
supplier.name: Natural person name (required)supplier.business_name: Optional trade/brand name (renders as second line)small_business=True: German §19 UStG (no VAT)small_business=False: Setvat_rate(e.g.,0.19)id,invoice_number,status: Ignored; backend forcesstatus="draft"and auto-numbers using the yearly sequence
Returns: {invoice_path, index_path}
update_invoice_draft(invoice_id: str, invoice: Invoice)
Update the complete content of a draft invoice.
Restrictions:
- Only works for
status="draft" - Cannot edit finalized invoices
Use this to correct mistakes or make changes before finalizing.
Returns: {invoice, invoice_path, index_path}
delete_invoice_draft(invoice_id: str)
Permanently delete a draft invoice.
Restrictions:
- Only works for
status="draft" - Cannot delete finalized invoices
- Irreversible operation
Returns: {deleted_invoice_id, deleted_path, index_path}
render_invoice_pdf(invoice_id: str)
Render invoice to PDF using LaTeX template.
Works for both draft and final invoices.
Returns: {pdf_path, tex_path}
update_invoice_status(invoice_id, payment_status, status?)
Update payment tracking and lifecycle status.
payment_status: open | paid | overdue | cancelled
status: draft | final (one-way: cannot change final → draft)
Use status="final" to finalize an invoice (makes it immutable).
Returns: {invoice, invoice_path, index_path}
generate_invoice_number(separator="-")
Generate next invoice number (format: YYYY-####).
Pass separator="" or null for no separator.
Returns: {invoice_number, sequence_path}
get_invoice_template(language="de" | "en")
Get localized example invoice payload with field documentation.
Returns: Example Invoice object
Data storage
Invoices are stored locally (gitignored by default):
.mad_invoice/
invoices/<invoice-id>.json # Individual invoices
index.json # Quick lookup index
sequence.json # Invoice number counters
build/<invoice-id>/invoice.pdf # Rendered PDFs
Override storage location:
export MAD_INVOICE_ROOT=/custom/path
Invoice data model
Party (supplier/customer)
name: Natural person or company name (required)business_name: Optional trade/brand name (e.g., "M.A.D. Solutions")- Address:
street,postal_code,city,country - Contact:
email,phone,tax_id
LineItem
description: Service/product descriptionquantity: Amount (default: 1.0)unit: Unit of measure (default: "Std.")unit_price: Price per unit (can be negative for discounts)
Invoice
- IDs:
id,invoice_number - Dates:
invoice_date,due_date,date_styledate_style="iso": ISO-8601 (YYYY-MM-DD)date_style="locale": human-friendly; German (DD.MM.YYYY) or English (Month DD, YYYY)- Defaults: German →
locale, English →iso
- Status:
status(draft/final),payment_status(open/paid/overdue/cancelled) - Parties:
supplier,customer - Items:
items[] - VAT:
small_business(bool),vat_rate(0-1) - Text:
intro_text,outro_text,payment_terms - Footer:
footer_bank,footer_tax - Language:
language("de" | "en")
VAT handling
Small business mode (small_business=True):
- German §19 UStG (no VAT)
- Shows
small_business_noteon invoice - Only subtotal displayed
Regular mode (small_business=False):
- Set
vat_rate(0-1, e.g.,0.19) - Calculates VAT amount
- Shows gross total (subtotal + VAT)
LaTeX template customization
Edit templates/invoice.tex directly for branding (logo, colors, layout).
Placeholders use format: %%VARIABLE%% (e.g., %%INVOICE_NUMBER%%)
Web UI endpoints
GET /invoices– Invoice overviewGET /invoices/{id}– Detail viewPOST /invoices/{id}/render– Render PDFPOST /invoices/{id}/mark-paid– Mark as paid
Development
# Install dependencies
pip install -r requirements.txt
# Run tests (if available)
pytest
# Development server with auto-reload
./bin/dev
Troubleshooting
"pdflatex not found"
- Install TeX Live 2024+: https://tug.org/texlive/
- Or use Docker (Path B above)
- Or set
PDFLATEX_PATHfor custom locations
"Write operations disabled"
- Set
MCP_ENABLE_WRITES=1environment variable
Port 8000 already in use
- Change port:
uvicorn bridge.app:create_app --factory --port 8001
Configuration
Environment variables:
MCP_ENABLE_WRITES: Enable write operations (default:0)MAD_INVOICE_ROOT: Storage location (default:<project-root>/.mad_invoice/)PDFLATEX_PATH: Custom pdflatex binary path (auto-discovered if not set)
Storage location priority:
MAD_INVOICE_ROOTenvironment variable (if set)- Project root +
.mad_invoice/(default)
License & Contributing
See repository for details.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Neon Database
MCP server for interacting with Neon Management API and databases