Skip to main content
Glama

create_invoice

Generate ZUGFeRD-compliant invoice PDFs with embedded e-invoicing data, supporting flexible item entry, VAT, and payment details for automated billing.

Instructions

Create a ZUGFeRD-compliant invoice PDF with structured e-invoicing data.

Each item in the items list should have: description, unitPrice, and optionally quantity, unit (C62=piece, HUR=hour, DAY=day, KGM=kg), vatRate.

Args: invoice_number: Unique invoice number (e.g. "RE-2026-001"). invoice_date: Invoice date in ISO format (e.g. "2026-04-12"). seller_name: Seller company name. seller_street: Seller street address. seller_zip: Seller postal code. seller_city: Seller city. buyer_name: Buyer company name. buyer_street: Buyer street address. buyer_zip: Buyer postal code. buyer_city: Buyer city. items: Line items – each with description, unitPrice, and optionally quantity, unit, vatRate. iban: Payment IBAN. bic: Payment BIC/SWIFT code. payment_terms: Payment terms text. due_date: Payment due date (ISO format). seller_vat_id: Seller VAT ID. seller_country: Seller country code (default: DE). buyer_country: Buyer country code (default: DE). buyer_vat_id: Buyer VAT ID. currency: Currency code (default: EUR). template_name: Template name for the invoice layout. html_content: HTML content for the invoice body.

Returns: Base64-encoded PDF with embedded ZUGFeRD XML.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
invoice_numberYes
invoice_dateYes
seller_nameYes
seller_streetYes
seller_zipYes
seller_cityYes
buyer_nameYes
buyer_streetYes
buyer_zipYes
buyer_cityYes
itemsYes
ibanNo
bicNo
payment_termsNo
due_dateNo
seller_vat_idNo
seller_countryNoDE
buyer_countryNoDE
buyer_vat_idNo
currencyNoEUR
template_nameNo
html_contentNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The create_invoice tool handler: builds a ZUGFeRD-compliant invoice PDF using the DocGen client, accepting invoice metadata, seller/buyer info, line items, payment details, and optional template/html, returning a base64-encoded PDF.
    @mcp.tool()
    def create_invoice(
        invoice_number: str,
        invoice_date: str,
        seller_name: str,
        seller_street: str,
        seller_zip: str,
        seller_city: str,
        buyer_name: str,
        buyer_street: str,
        buyer_zip: str,
        buyer_city: str,
        items: list[dict[str, Any]],
        iban: str | None = None,
        bic: str | None = None,
        payment_terms: str | None = None,
        due_date: str | None = None,
        seller_vat_id: str | None = None,
        seller_country: str = "DE",
        buyer_country: str = "DE",
        buyer_vat_id: str | None = None,
        currency: str = "EUR",
        template_name: str | None = None,
        html_content: str | None = None,
    ) -> str:
        """Create a ZUGFeRD-compliant invoice PDF with structured e-invoicing data.
    
        Each item in the items list should have: description, unitPrice, and optionally
        quantity, unit (C62=piece, HUR=hour, DAY=day, KGM=kg), vatRate.
    
        Args:
            invoice_number: Unique invoice number (e.g. "RE-2026-001").
            invoice_date: Invoice date in ISO format (e.g. "2026-04-12").
            seller_name: Seller company name.
            seller_street: Seller street address.
            seller_zip: Seller postal code.
            seller_city: Seller city.
            buyer_name: Buyer company name.
            buyer_street: Buyer street address.
            buyer_zip: Buyer postal code.
            buyer_city: Buyer city.
            items: Line items – each with description, unitPrice, and optionally quantity, unit, vatRate.
            iban: Payment IBAN.
            bic: Payment BIC/SWIFT code.
            payment_terms: Payment terms text.
            due_date: Payment due date (ISO format).
            seller_vat_id: Seller VAT ID.
            seller_country: Seller country code (default: DE).
            buyer_country: Buyer country code (default: DE).
            buyer_vat_id: Buyer VAT ID.
            currency: Currency code (default: EUR).
            template_name: Template name for the invoice layout.
            html_content: HTML content for the invoice body.
    
        Returns:
            Base64-encoded PDF with embedded ZUGFeRD XML.
        """
        dg = _get_client()
        from docgen.models import InvoiceUnit
    
        inv = dg.invoice()
        inv.number(invoice_number).date(invoice_date)
        inv.seller(
            name=seller_name, street=seller_street, zip=seller_zip,
            city=seller_city, country=seller_country, vat_id=seller_vat_id,
        )
        inv.buyer(
            name=buyer_name, street=buyer_street, zip=buyer_zip,
            city=buyer_city, country=buyer_country, vat_id=buyer_vat_id,
        )
    
        for item in items:
            unit = item.get("unit", "C62")
            inv.item(
                description=item["description"],
                quantity=float(item.get("quantity", 1)),
                unit=InvoiceUnit(unit),
                unit_price=float(item["unitPrice"]),
                vat_rate=float(item.get("vatRate", 19.0)),
            )
    
        if iban:
            inv.bank(iban=iban, bic=bic)
        if payment_terms:
            inv.payment_terms(payment_terms)
        if due_date:
            inv.due_date(due_date)
        inv.currency(currency)
    
        invoice_data = inv.build()
    
        doc = dg.document()
        if html_content:
            doc.html(html_content)
        else:
            doc.html(f"<h1>Rechnung {invoice_number}</h1>")
        if template_name:
            doc.template(template_name)
        doc.invoice(invoice_data)
        doc.as_pdf()
    
        result = doc.generate()
        return base64.b64encode(result).decode()
  • Registration of create_invoice as an MCP tool via the @mcp.tool() decorator on FastMCP instance.
    @mcp.tool()
  • Input schema (type annotations) for create_invoice, defining all parameters, types, and defaults.
    def create_invoice(
        invoice_number: str,
        invoice_date: str,
        seller_name: str,
        seller_street: str,
        seller_zip: str,
        seller_city: str,
        buyer_name: str,
        buyer_street: str,
        buyer_zip: str,
        buyer_city: str,
        items: list[dict[str, Any]],
        iban: str | None = None,
        bic: str | None = None,
        payment_terms: str | None = None,
        due_date: str | None = None,
        seller_vat_id: str | None = None,
        seller_country: str = "DE",
        buyer_country: str = "DE",
        buyer_vat_id: str | None = None,
        currency: str = "EUR",
        template_name: str | None = None,
        html_content: str | None = None,
    ) -> str:
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full behavioral burden. It describes the return format (Base64 PDF with XML) but does not disclose side effects, storage behavior, authentication requirements, or potential rate limits. The lack of behavioral context is significant for a creation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a summary line, an explanation of the items parameter, a parameter list, and return type. It is front-loaded with the main purpose. While somewhat lengthy, every sentence adds value and it avoids tautology.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (22 parameters, no annotations, no output schema details), the description covers the essential aspects: what it does, input parameters, and return format. However, it lacks guidance on error handling, empty items, and authentication needs, limiting completeness slightly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds substantial meaning beyond the schema, which lacks property descriptions. It explains each parameter's purpose, the expected structure of 'items' (description, unitPrice, optional fields with allowed units), and default values for country and currency. This compensates for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it creates a ZUGFeRD-compliant invoice PDF, which is a specific verb+resource combination. This distinguishes it from sibling tools like generate_pdf_from_html or fill_excel_template that produce different document types.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for generating e-invoicing PDFs but does not explicitly state when to use this tool versus alternatives like compose_document or generate_pdf_from_html. No guidance on prerequisites or use cases is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dokmatiq/docgen-sdks'

If you have feedback or need assistance with the MCP directory API, please join our Discord server