pop-mcp

pop-mcp

MCP server for POP โ€” enabling LLMs to generate, submit, and manage Italian e-invoices (FatturaPA/SdI), Peppol invoices, and PDF invoices directly from AI assistants.

Category
Visit Server

README

pop-mcp

MCP (Model Context Protocol) server for POP โ€” enabling LLMs to generate, submit, and manage Italian e-invoices (FatturaPA/SdI), Peppol invoices, and PDF invoices directly from AI assistants.

npm: @getpopapi/pop-mcp

License: MIT Node.js


What is POP?

POP is a cloud service for electronic invoice generation and delivery, supporting:

  • ๐Ÿ‡ฎ๐Ÿ‡น Italian e-invoicing (FatturaPA/SdI) โ€” compliant with D.Lgs. 127/2015
  • ๐Ÿ‡ช๐Ÿ‡บ Peppol โ€” pan-European cross-border B2B invoicing (UBL 2.1)
  • ๐Ÿ“„ PDF invoices โ€” branded, with email delivery
  • โœ… Validation โ€” fiscal codes, VAT numbers, document pre-submission checks
  • ๐Ÿ—„๏ธ Preservation โ€” Italian legal archival (conservazione sostitutiva)

Tools Available (11 total)

Invoice Creation

Tool Endpoint Plan
pop_create_sdi_invoice POST /create-xml Any
pop_create_peppol_invoice POST /create-ubl Any (Basic+ to submit)
pop_create_pdf_invoice POST /create-pdf Any (Basic+ for email)
pop_create_ksef_invoice POST /create-ksef-xml Any (KSeF setup for provider submission)
pop_create_zugferd_invoice POST /create-zugferd Any
pop_sync_zoho_document POST /integration/zoho/sync Zoho connector required

Status & Retrieval

Tool Endpoint Plan
pop_get_invoice_status POST /sdi/document-notifications Any
pop_get_peppol_document POST /peppol/document-get Basic+
pop_get_sdi_document POST /sdi/document-get Basic+

Validation & Advanced SdI

Tool Endpoint Plan
pop_verify_sdi_document POST /sdi/document-verify Basic+
pop_preserve_document POST /sdi/document-preserve Basic+

Prerequisites

  • Node.js >= 18
  • A POP license key
  • For SdI/Peppol submission: active integration on your POP account (Basic/Growth plan)

Authentication

Get Your License Key

New to POP? Visit popapi.io to create your account and get your license key.

API-only users can activate their account and obtain a license_key with this flow:

  1. Open https://popapi.io/otp-login/
  2. Enter your email address
  3. Receive a one-time password (OTP) by email and enter it
  4. Complete the configuration wizard
  5. Open https://popapi.io/ โ†’ Account > API
  6. Copy the default generated license_key

Key Management

  • Your account includes one default license_key, visible under Account > API
  • You can generate additional keys linked to the same account from that same page
  • Every license_key must be treated as a secret credential โ€” do not commit it to source control

Recommended First Steps

  1. Get your license_key
  2. Test it with GET /account-profile
  3. Send one document-generation request with a real payload
  4. Add optional delivery integrations only after local generation works

Installation

From npm (recommended)

npm install -g @getpopapi/pop-mcp

From Source

git clone https://github.com/getpopapi/pop-mcp
cd pop-mcp
npm install
npm run build

Configuration

Set your POP license key as an environment variable:

export POP_API_KEY=your_license_key_here

Optional โ€” use the staging environment:

export POP_ENVIRONMENT=staging

Claude Desktop Setup

Add to your claude_desktop_config.json:

If installed from npm:

{
  "mcpServers": {
    "pop": {
      "command": "pop-mcp",
      "env": {
        "POP_API_KEY": "your_license_key_here"
      }
    }
  }
}

If running from source:

{
  "mcpServers": {
    "pop": {
      "command": "node",
      "args": ["/path/to/pop-mcp/dist/cli.js"],
      "env": {
        "POP_API_KEY": "your_license_key_here"
      }
    }
  }
}

Config file locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Remote MCP (HTTP)

pop-mcp is also available as a remote, generic MCP server at:

https://mcp.popapi.io/mcp

This is a shared, multi-tenant endpoint โ€” unlike the stdio path above, it does not read POP_API_KEY from the server's environment. Every request must carry your own POP license key as a Bearer token:

Authorization: Bearer <your_license_key>

Any MCP-speaking HTTP client can connect: Claude (remote connector), the OpenAI Responses API, n8n, MCP Inspector, or a custom integration โ€” not just Claude Desktop. All invoice, status, advanced, and onboarding tools are available; onboarding tools use their own onboarding_token per call and don't require the Bearer key.

Example with MCP Inspector:

npx @modelcontextprotocol/inspector

Configure it to connect to https://mcp.popapi.io/mcp with header Authorization: Bearer <your_license_key>.

Example with curl (tools/list โ€” every request requires the Bearer header, including this one):

curl -X POST https://mcp.popapi.io/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer your_license_key_here" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

A missing or malformed Authorization header returns a 401 with error_code: "unauthorized_user" before any POP API call is made. An invalid-but-well-formed key is passed straight through to POP's API and surfaces whatever error POP returns (unauthorized_user, insufficient_level, etc.) โ€” the server does not re-validate keys itself.

This endpoint runs as a Vercel serverless function (api/mcp.ts โ†’ src/mcpHandler.ts). To run it locally: npx vercel dev (requires vercel link to the project first).


Tool Reference

The license_key is always injected automatically from POP_API_KEY โ€” never pass it manually.

pop_create_sdi_invoice

Generate an Italian FatturaPA XML document. Optionally submit it to the SdI (Sistema di Interscambio).

MCP inputs:

Parameter Type Required Description
data object โœ… Full invoice data (see Invoice Data Structure)
submit_to_sdi boolean โ€” Set true to submit to SdI. Requires Basic+ plan with active SdI integration. Default: false
integration object โ€” Override integration config. Overrides submit_to_sdi if set.
environment string โ€” Target environment (e.g. "sandbox")

Integration options for integration.use:

  • "sdi-via-pop" or "sdi" โ€” Submit via POP SdI
  • "pop-to-webhook" โ€” Deliver to a webhook (requires id)
  • "fatture-in-cloud" โ€” Deliver to Fatture in Cloud

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields..." },
  "integration": { "use": "sdi-via-pop", "action": "create" }
}

integration is omitted when submit_to_sdi is false and no override is provided (XML-only generation).


pop_create_peppol_invoice

Generate a Peppol UBL 2.1 document. Optionally submit it to the Peppol network.

MCP inputs:

Parameter Type Required Description
data object โœ… Full invoice data. customer_type must be "company" or "freelance"
submit_to_peppol boolean โ€” Set true to submit to the Peppol network. Requires Basic+ plan. Default: false
integration object โ€” Override integration config
environment string โ€” Target environment

Integration options for integration.use:

  • "peppol-via-pop" or "peppol" โ€” Submit via POP Peppol
  • "pop-to-webhook" โ€” Deliver to a webhook (requires id)

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": { "...invoice fields..." },
  "integration": { "use": "peppol-via-pop", "action": "create" }
}

pop_create_pdf_invoice

Generate a branded PDF invoice. Optionally email it to up to 3 recipients.

MCP inputs:

Parameter Type Required Description
data object โœ… Invoice data. Must include data.pdf for PDF-specific settings
send_email boolean โ€” Set true to email the PDF (requires data.pdf.email_invoice, Basic+ plan). Default: false
environment string โ€” Target environment

data.pdf fields:

Field Description
doc_type_title Title shown on document (e.g. "Invoice", "Receipt")
logo_url Company logo URL (HTTPS)
head.store_info_address Supplier address string in header
head.billing[] Customer billing address array
head.shipping[] Shipping address array (optional)
email_invoice.to Up to 3 recipient email addresses
email_invoice.from Reply-to address
footer_text Custom footer message
total_tax Total tax amount as string

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "user_agent": "pop-mcp",
  "user_agent_version": "1.0.0",
  "data": {
    "...invoice fields...",
    "pdf": {
      "doc_type_title": "Invoice",
      "logo_url": "https://example.com/logo.png",
      "head": { "store_info_address": "Via Roma 1, 00100 Roma IT", "billing": [] },
      "total_tax": "22.00",
      "email_invoice": { "to": ["customer@example.com"] }
    }
  }
}

pop_get_invoice_status

Retrieve the SdI processing status and notifications for a submitted invoice.

MCP inputs:

Parameter Type Required Description
uuid string (UUID) โœ… Invoice UUID returned by pop_create_sdi_invoice when submit_to_sdi=true
response_format "markdown" | "json" โ€” Output format. Default: "markdown"
environment string โ€” Target environment

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}

SdI notification statuses: pending ยท accepted ยท rejected ยท delivery

SdI processing is asynchronous and can take minutes to hours. Retry if no notifications are returned yet.


pop_get_peppol_document

Retrieve a Peppol document from the network by UUID.

MCP inputs:

Parameter Type Required Description
uuid string (UUID) โœ… Peppol document UUID from pop_create_peppol_invoice
zone string (2 chars) โ€” Country code of the Peppol access point (e.g. "BE" for Belgium). Required for some regions.
response_format "markdown" | "json" โ€” Output format. Default: "markdown"
environment string โ€” Target environment

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "zone": "IT" }
}

zone is omitted from the payload if not provided.


pop_get_sdi_document

Retrieve an archived SdI (FatturaPA) document from POP storage by UUID.

MCP inputs:

Parameter Type Required Description
uuid string (UUID) โœ… SdI document UUID
response_format "markdown" | "json" โ€” Output format. Default: "markdown"
environment string โ€” Target environment

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}

Requires: Basic+ plan with active SdI integration.


pop_verify_sdi_document

Validate an SdI XML document for compliance before submission. Does not submit the document.

MCP inputs:

Parameter Type Required Description
xml_base64 string โœ… The SdI XML document encoded as a Base64 string
environment string โ€” Target environment

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "skip_business_check": true,
  "integration": { "xml": "<base64-encoded-xml-string>" }
}

Validation checks performed: XML schema conformance ยท fiscal code format ยท VAT number validity ยท required field presence ยท amount consistency

Requires: Basic+ plan with active SdI integration and registered business.


pop_preserve_document

Archive an SdI document in certified long-term digital storage (conservazione sostitutiva). Italian law requires invoices to be preserved for 10 years.

MCP inputs:

Parameter Type Required Description
uuid string (UUID) โœ… UUID of the SdI document to archive
environment string โ€” Target environment

API payload sent:

{
  "license_key": "YOUR_LICENSE_KEY",
  "integration": { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
}

Important: Only call this tool when pop_get_invoice_status returns status RC (Ricevuta di Consegna) or MC (Mancata Consegna). Do not call for statuses NS, EC, SE, or DT.

Requires: Basic+ plan with active SdI integration.


Usage Examples

Generate a Simple Italian Invoice (XML Only)

Ask your AI assistant:

"Create a FatturaPA invoice for 1000โ‚ฌ + 22% VAT to Rossi SRL (VAT IT12345678901, Milan). My company is Bianchi SRL (VAT IT98765432109, Rome), using payment method bank transfer to IBAN IT60X0542811101000000123456."

Submit Invoice to SdI

"Create and submit to SdI an invoice #45 for consulting services, 500โ‚ฌ + 22% VAT to customer Mario Rossi (fiscal code RSSMRA80A01H501U) in Rome."

Check Invoice Status After Submission

"What's the status of SdI invoice with UUID abc123-def456-...?"

Generate PDF with Email Delivery

"Create a PDF invoice for order #123 and email it to customer@example.com."

Verify SdI Document Before Sending

"Verify SdI document with UUID abc123-... for compliance before submission."


Plan Requirements

Feature Free Basic/Growth Pro
XML generation (local) โœ… โœ… โœ…
PDF generation โœ… โœ… โœ…
SdI submission โŒ โœ… โœ…
Peppol submission โŒ โœ… โœ…
PDF email delivery โŒ โœ… โœ…
SdI document verification โŒ โœ… โœ…
Document preservation โŒ โœ… โœ…

Testing

MCP Inspector (Interactive)

npm run inspector
# or
npx @modelcontextprotocol/inspector dist/cli.js

Quick Smoke Test

POP_API_KEY=your_key node -e "
import('./dist/cli.js').catch(e => {
  if (e.message.includes('stdin')) process.exit(0);
  console.error(e); process.exit(1);
});
"

Test Tool Schema Listing

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | POP_API_KEY=test node dist/cli.js

Development

# Run with auto-reload
npm run dev

# Build
npm run build

# Clean build artifacts
npm run clean

Invoice Data Structure

The data parameter for invoice creation follows the FatturaPA structure:

data
โ”œโ”€โ”€ id                    Invoice/order ID (numeric)
โ”œโ”€โ”€ filename              Output filename without extension (e.g. 'IT99900088876_00009')
โ”œโ”€โ”€ type                  "invoice" | "credit_note"
โ”œโ”€โ”€ version               "FPR12" | "FPA12"
โ”œโ”€โ”€ sdi_type              7-char SDI code ('0000000' for private individuals)
โ”œโ”€โ”€ customer_type         "private" | "company" | "freelance" | "pa"
โ”œโ”€โ”€ nature                VAT exemption code (required when rate is 0%, e.g. 'N2.1', 'N6.1')
โ”œโ”€โ”€ transmitter_data
โ”‚   โ”œโ”€โ”€ transmitter_id    { country_id, id_code }
โ”‚   โ”œโ”€โ”€ progressive       Transmission progressive ID (e.g. '00001')
โ”‚   โ”œโ”€โ”€ transmitter_format  "FPR12" | "FPA12"
โ”‚   โ”œโ”€โ”€ sdi_code          7-char code
โ”‚   โ”œโ”€โ”€ transmitter_contact { phone, email }
โ”‚   โ””โ”€โ”€ recipient_pec     PEC email (alternative to sdi_code)
โ”œโ”€โ”€ transfer_lender       Supplier/seller
โ”‚   โ”œโ”€โ”€ personal_data     { tax_id_vat: { country_id, id_code, tax_regime }, company_name }
โ”‚   โ”œโ”€โ”€ place             { address, zip_code, city, province_id, country_id }
โ”‚   โ””โ”€โ”€ contact           { phone, email }
โ”œโ”€โ”€ transferee_client     Customer/buyer
โ”‚   โ”œโ”€โ”€ personal_data     { tax_id_vat, tax_id_code (fiscal code for IT private), company_name }
โ”‚   โ””โ”€โ”€ place             { address, zip_code, city, province_id, country_id }
โ”œโ”€โ”€ invoice_body
โ”‚   โ”œโ”€โ”€ general_data      { doc_type (TD01|TD04), date (YYYY-MM-DD), invoice_number, currency }
โ”‚   โ””โ”€โ”€ total_document_amount
โ”œโ”€โ”€ order_items[]
โ”‚   โ”œโ”€โ”€ description, quantity, unit
โ”‚   โ”œโ”€โ”€ unit_price, total_price
โ”‚   โ”œโ”€โ”€ rate              VAT rate as string (e.g. '22.00')
โ”‚   โ”œโ”€โ”€ total_tax         VAT amount (number)
โ”‚   โ””โ”€โ”€ item_type         "product" | "shipping" | "fee"
โ”œโ”€โ”€ payment_data
โ”‚   โ”œโ”€โ”€ terms_payment     TP01 (instalment) | TP02 (full) | TP03 (advance)
โ”‚   โ”œโ”€โ”€ payment_details   MP01 (Cash) | MP02 (Check) | MP05 (Bank Transfer) | MP08 (Credit Card) | ...
โ”‚   โ”œโ”€โ”€ payment_amount
โ”‚   โ”œโ”€โ”€ beneficiary       Required for MP05 (bank transfer)
โ”‚   โ”œโ”€โ”€ financial_institution  Required for MP05
โ”‚   โ””โ”€โ”€ iban              Required for MP05
โ”œโ”€โ”€ purchase_order_data   (optional) { id, date }
โ”œโ”€โ”€ connected_invoice_data[]  (required for credit notes) { id, date }
โ”œโ”€โ”€ overrides             (optional) { language, bollo_force_apply }
โ””โ”€โ”€ pdf                   (only for pop_create_pdf_invoice)
    โ”œโ”€โ”€ doc_type_title
    โ”œโ”€โ”€ logo_url
    โ”œโ”€โ”€ head              { store_info_address, billing[], shipping[] }
    โ”œโ”€โ”€ total_tax
    โ”œโ”€โ”€ email_invoice     { to[] (max 3), from }
    โ””โ”€โ”€ footer_text

Error Reference

Error Code Meaning Solution
unauthorized_user Invalid license key Check POP_API_KEY
insufficient_level Plan too low Upgrade POP plan
business_not_registered No business profile Register on popapi.io
integration_inactive SdI/Peppol not enabled Activate on popapi.io
pop_api_email_limit >3 email recipients Reduce to max 3
pop_api_email_not_allowed Plan doesn't allow email Upgrade to Basic+

Related Projects


License

MIT ยฉ getpopapi

Recommended Servers

playwright-mcp

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured