Skip to main content

MCP Server

faktoora exposes its public API as an MCP (Model Context Protocol) server, allowing AI assistants and MCP-compatible clients to create invoices, manage customers and products, import e-invoices, and configure webhooks — all through a standardised tool interface.


Endpoint

POST https://api.faktoora.com/api/v1/mcp

Transport: Streamable HTTP (stateless — no session required)

Required headers on every request:

Content-Type: application/json
Accept: application/json, text/event-stream
X-API-KEY: your-api-token

Multi-tenant accounts can pass an optional x-account-id header to switch context.


Authentication

MCP uses the same API key authentication as the rest of the faktoora API. No additional setup is needed — your existing X-API-KEY token grants MCP access.


Connecting an MCP Client

Claude Desktop

Add the following to your claude_desktop_config.json:

{
"mcpServers": {
"faktoora": {
"type": "http",
"url": "https://api.faktoora.com/api/v1/mcp",
"headers": {
"X-API-KEY": "your-api-token"
}
}
}
}

Generic MCP client (SDK)

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const transport = new StreamableHTTPClientTransport(
new URL('https://api.faktoora.com/api/v1/mcp'),
{
requestInit: {
headers: { 'X-API-KEY': 'your-api-token' },
},
},
);

const client = new Client({ name: 'my-app', version: '1.0.0' });
await client.connect(transport);

const { tools } = await client.listTools();
console.log(tools.map(t => t.name));

Available Tools

The server exposes 60 tools across 7 domains.

Invoice Creation

ToolDescription
create_invoice_simpleCreate a PDF-only invoice (no embedded XML).
create_invoice_zugferd2Create a ZUGFeRD 2.1 e-invoice (PDF/A-3 with embedded CII XML).
create_invoice_xrechnungCreate an XRechnung 3.0 e-invoice. Pass schema: "CII" (default) or schema: "UBL".

All three tools accept invoiceTypeCode to select the document type:

CodeType
380Commercial invoice
381Credit note
384Corrected invoice
326Partial invoice

Invoice generation is asynchronous. The tool returns a faktooraId. Use get_invoice_status to poll for completion, then download_invoice to retrieve the file.

Invoice Management

ToolDescription
list_invoicesList invoices with optional filters (date range, keyword, invoice number).
get_invoice_statusGet processing status, authority registration, and delivery info.
download_invoiceDownload invoice file as base64. Pass format: "pdf" or format: "xml".
delete_invoiceDelete an invoice (requires invoiceDeleteMode to be enabled).

Incoming Invoice Import

Upload and query e-invoices received from suppliers.

ToolDescription
import_incoming_invoiceUpload an e-invoice file (base64-encoded).
list_incoming_importsList imported invoices with pagination and date filters.
get_import_validationGet the validation result (accepted / rejected).
get_import_statusGet overall processing status.
get_import_summaryGet seller, amount, tax, dates, and invoice number.
get_import_contentGet the full structured content (seller + buyer + items + taxes + payment).
get_import_line_itemsGet the line items array.
get_import_taxesGet the VAT breakdown.
get_import_payment_termsGet payment terms.
get_import_payment_meansGet payment means (IBAN etc.).
get_import_sellerGet seller information.
get_import_buyerGet buyer information.
get_import_deliveryGet delivery address.
list_import_attachmentsList attachments embedded in the invoice.
get_import_attachmentGet a single attachment's metadata.

Outgoing Invoice Import

Same as incoming import, but for outgoing invoices you uploaded yourself. Uses faktooraId instead of importId.

ToolDescription
import_outgoing_invoiceUpload an outgoing e-invoice file (base64-encoded).
list_outgoing_importsList outgoing imported invoices.
get_outgoing_import_validationGet validation result.
get_outgoing_import_statusGet processing status.
get_outgoing_import_summaryGet summary.
get_outgoing_import_contentGet full structured content.
get_outgoing_import_line_itemsGet line items.
get_outgoing_import_taxesGet VAT breakdown.
get_outgoing_import_payment_termsGet payment terms.
get_outgoing_import_payment_meansGet payment means.
get_outgoing_import_sellerGet seller info.
get_outgoing_import_buyerGet buyer info.
get_outgoing_import_deliveryGet delivery address.
list_outgoing_import_attachmentsList attachments.
get_outgoing_import_attachmentGet attachment metadata.

Customers

ToolDescription
list_customersList customers with pagination and keyword filter.
get_customerGet a single customer by UUID.
create_customerCreate a new customer (company or individual).
update_customerUpdate an existing customer.
delete_customerDelete a customer.
generate_customer_numberGenerate the next sequential customer number.
verify_customer_numberCheck if a customer number is valid and available.
import_customersImport customers from a previously uploaded CSV (fileId).

Products

ToolDescription
list_productsList products with pagination.
get_productGet a product by UUID.
create_productCreate a new product or service.
update_productUpdate a product.
delete_productDelete a product.
verify_product_codeCheck if a product code is available.

Product Bundles

Product bundle tools require the PRODUCT_BUNDLE feature to be enabled on your account.

ToolDescription
list_product_bundlesList bundles with pagination.
get_product_bundleGet a bundle by UUID.
create_product_bundleCreate a product bundle.
update_product_bundleUpdate a bundle.
delete_product_bundleDelete a bundle.

Webhooks

ToolDescription
list_webhooksList all webhook subscriptions.
create_webhookSubscribe to a webhook event (action + target URL).
update_webhookUpdate a webhook subscription.
delete_webhookDelete a webhook subscription.

Invoice Creation — Required Fields

All three invoice creation tools share the same input schema. The following fields are mandatory:

FieldTypeNotes
invoiceTypeCodenumber380 invoice · 381 credit note · 384 corrected invoice · 326 partial invoice
invoiceNumberstringMust be unique per account
issueDatestringYYYYMMDD format
buyer.namestringCompany or person name
buyer.streetstringStreet address
buyer.postcodestring5 digits for DE, 4 for AT/CH
buyer.citystring
buyer.countrystringISO 3166-1 alpha-2 (e.g. DE)
invoiceItemsarrayAt least 1 item required
invoiceItems[].idstringUnique identifier within the invoice (e.g. "1")
invoiceItems[].product.namestringProduct or service name
invoiceItems[].product.quantitynumber
invoiceItems[].product.unitCodestringUN/ECE Recommendation 20 unit code (see below)
invoiceItems[].product.pricenumberNet unit price
invoiceItems[].product.taxesarrayExactly 1 entry: { typeCode: "VAT", rate: 19 }

Common unit codes (UN/ECE Recommendation 20)

CodeMeaning
HURHour
C62Piece (each)
DAYDay
KGMKilogram
MTRMetre
LTRLitre

Conditional requirements

  • invoiceTypeCode: 384 (corrected invoice) — must include invoiceReferencedDocument: { IssuerAssignedID, issueDateTime } with the original invoice number.
  • Any line item with taxes[].categoryCode: "E" (exempt) — requires top-level taxExemptionReasonMessage.
  • create_invoice_xrechnung — requires either seller.email / contactPerson.email and either buyer.email / buyerReference.buyerReferenceId (LeitwegID for B2G).

Seller defaults to the account's own company data. Pass seller explicitly only to override it.


Example: Create a ZUGFeRD Invoice

{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 1,
"params": {
"name": "create_invoice_zugferd2",
"arguments": {
"invoiceTypeCode": 380,
"invoiceNumber": "RE-2024-001",
"issueDate": "20240315",
"dueDate": "20240415",
"currency": "EUR",
"buyer": {
"name": "Acme GmbH",
"street": "Hauptstraße 1",
"postcode": "10115",
"city": "Berlin",
"country": "DE",
"vatId": "DE123456789"
},
"invoiceItems": [
{
"id": "1",
"product": {
"name": "Consulting",
"quantity": 8,
"unitCode": "HUR",
"price": 150.00,
"taxes": [{ "typeCode": "VAT", "categoryCode": "S", "rate": 19 }]
}
}
]
}
}
}

Response:

{
"result": {
"content": [{ "type": "text", "text": "{\"faktooraId\":\"INV-0042\"}" }]
}
}

Generation is asynchronous. Poll get_invoice_status until jobStatus === "done" before downloading.


Example: Create an XRechnung Invoice (B2G)

XRechnung requires a buyerReference.buyerReferenceId (LeitwegID) and a sender email address:

{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 1,
"params": {
"name": "create_invoice_xrechnung",
"arguments": {
"invoiceTypeCode": 380,
"invoiceNumber": "RE-2024-002",
"issueDate": "20240315",
"dueDate": "20240415",
"currency": "EUR",
"contactPerson": {
"email": "billing@mysender.de"
},
"buyerReference": {
"buyerReferenceId": "991-1234512345-06"
},
"buyer": {
"name": "Behörde XY",
"street": "Amtsstraße 5",
"postcode": "10117",
"city": "Berlin",
"country": "DE"
},
"invoiceItems": [
{
"id": "1",
"product": {
"name": "Software-Lizenz",
"quantity": 1,
"unitCode": "C62",
"price": 500.00,
"taxes": [{ "typeCode": "VAT", "categoryCode": "S", "rate": 19 }]
}
}
]
}
}
}

Example: Poll Invoice Status

{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 2,
"params": {
"name": "get_invoice_status",
"arguments": { "faktooraId": "INV-0042" }
}
}

Example: Download Invoice as PDF

{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 3,
"params": {
"name": "download_invoice",
"arguments": { "faktooraId": "INV-0042", "format": "pdf" }
}
}

The response content includes filename, mimeType, size, and base64Content fields.


File Uploads (Import)

Import tools accept base64-encoded file content:

{
"name": "import_incoming_invoice",
"arguments": {
"file": "<base64-encoded XML or PDF>",
"filename": "invoice.xml",
"contentType": "application/xml"
}
}

Supported formats: ZUGFeRD PDF, XRechnung XML, Factur-X PDF. Maximum file size: 20 MB.


Protocol Details

  • MCP version: 2024-11-05
  • Transport: Stateless Streamable HTTP — each request is independent, no session ID required
  • Responses: Server-Sent Events (text/event-stream) — read the data: line from the response body

Next Steps