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
| Tool | Description |
|---|---|
create_invoice_simple | Create a PDF-only invoice (no embedded XML). |
create_invoice_zugferd2 | Create a ZUGFeRD 2.1 e-invoice (PDF/A-3 with embedded CII XML). |
create_invoice_xrechnung | Create an XRechnung 3.0 e-invoice. Pass schema: "CII" (default) or schema: "UBL". |
All three tools accept invoiceTypeCode to select the document type:
| Code | Type |
|---|---|
380 | Commercial invoice |
381 | Credit note |
384 | Corrected invoice |
326 | Partial 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
| Tool | Description |
|---|---|
list_invoices | List invoices with optional filters (date range, keyword, invoice number). |
get_invoice_status | Get processing status, authority registration, and delivery info. |
download_invoice | Download invoice file as base64. Pass format: "pdf" or format: "xml". |
delete_invoice | Delete an invoice (requires invoiceDeleteMode to be enabled). |
Incoming Invoice Import
Upload and query e-invoices received from suppliers.
| Tool | Description |
|---|---|
import_incoming_invoice | Upload an e-invoice file (base64-encoded). |
list_incoming_imports | List imported invoices with pagination and date filters. |
get_import_validation | Get the validation result (accepted / rejected). |
get_import_status | Get overall processing status. |
get_import_summary | Get seller, amount, tax, dates, and invoice number. |
get_import_content | Get the full structured content (seller + buyer + items + taxes + payment). |
get_import_line_items | Get the line items array. |
get_import_taxes | Get the VAT breakdown. |
get_import_payment_terms | Get payment terms. |
get_import_payment_means | Get payment means (IBAN etc.). |
get_import_seller | Get seller information. |
get_import_buyer | Get buyer information. |
get_import_delivery | Get delivery address. |
list_import_attachments | List attachments embedded in the invoice. |
get_import_attachment | Get a single attachment's metadata. |
Outgoing Invoice Import
Same as incoming import, but for outgoing invoices you uploaded yourself. Uses faktooraId instead of importId.
| Tool | Description |
|---|---|
import_outgoing_invoice | Upload an outgoing e-invoice file (base64-encoded). |
list_outgoing_imports | List outgoing imported invoices. |
get_outgoing_import_validation | Get validation result. |
get_outgoing_import_status | Get processing status. |
get_outgoing_import_summary | Get summary. |
get_outgoing_import_content | Get full structured content. |
get_outgoing_import_line_items | Get line items. |
get_outgoing_import_taxes | Get VAT breakdown. |
get_outgoing_import_payment_terms | Get payment terms. |
get_outgoing_import_payment_means | Get payment means. |
get_outgoing_import_seller | Get seller info. |
get_outgoing_import_buyer | Get buyer info. |
get_outgoing_import_delivery | Get delivery address. |
list_outgoing_import_attachments | List attachments. |
get_outgoing_import_attachment | Get attachment metadata. |
Customers
| Tool | Description |
|---|---|
list_customers | List customers with pagination and keyword filter. |
get_customer | Get a single customer by UUID. |
create_customer | Create a new customer (company or individual). |
update_customer | Update an existing customer. |
delete_customer | Delete a customer. |
generate_customer_number | Generate the next sequential customer number. |
verify_customer_number | Check if a customer number is valid and available. |
import_customers | Import customers from a previously uploaded CSV (fileId). |
Products
| Tool | Description |
|---|---|
list_products | List products with pagination. |
get_product | Get a product by UUID. |
create_product | Create a new product or service. |
update_product | Update a product. |
delete_product | Delete a product. |
verify_product_code | Check if a product code is available. |
Product Bundles
Product bundle tools require the PRODUCT_BUNDLE feature to be enabled on your account.
| Tool | Description |
|---|---|
list_product_bundles | List bundles with pagination. |
get_product_bundle | Get a bundle by UUID. |
create_product_bundle | Create a product bundle. |
update_product_bundle | Update a bundle. |
delete_product_bundle | Delete a bundle. |
Webhooks
| Tool | Description |
|---|---|
list_webhooks | List all webhook subscriptions. |
create_webhook | Subscribe to a webhook event (action + target URL). |
update_webhook | Update a webhook subscription. |
delete_webhook | Delete a webhook subscription. |
Invoice Creation — Required Fields
All three invoice creation tools share the same input schema. The following fields are mandatory:
| Field | Type | Notes |
|---|---|---|
invoiceTypeCode | number | 380 invoice · 381 credit note · 384 corrected invoice · 326 partial invoice |
invoiceNumber | string | Must be unique per account |
issueDate | string | YYYYMMDD format |
buyer.name | string | Company or person name |
buyer.street | string | Street address |
buyer.postcode | string | 5 digits for DE, 4 for AT/CH |
buyer.city | string | |
buyer.country | string | ISO 3166-1 alpha-2 (e.g. DE) |
invoiceItems | array | At least 1 item required |
invoiceItems[].id | string | Unique identifier within the invoice (e.g. "1") |
invoiceItems[].product.name | string | Product or service name |
invoiceItems[].product.quantity | number | |
invoiceItems[].product.unitCode | string | UN/ECE Recommendation 20 unit code (see below) |
invoiceItems[].product.price | number | Net unit price |
invoiceItems[].product.taxes | array | Exactly 1 entry: { typeCode: "VAT", rate: 19 } |
Common unit codes (UN/ECE Recommendation 20)
| Code | Meaning |
|---|---|
HUR | Hour |
C62 | Piece (each) |
DAY | Day |
KGM | Kilogram |
MTR | Metre |
LTR | Litre |
Conditional requirements
invoiceTypeCode: 384(corrected invoice) — must includeinvoiceReferencedDocument: { IssuerAssignedID, issueDateTime }with the original invoice number.- Any line item with
taxes[].categoryCode: "E"(exempt) — requires top-leveltaxExemptionReasonMessage. create_invoice_xrechnung— requires eitherseller.email/contactPerson.emailand eitherbuyer.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 thedata:line from the response body