zatca-mcp

zatca-mcp

An AI-native MCP server for Saudi e-invoicing that generates ZATCA-compliant invoices, QR codes, and XML from natural language, with validation and Phase 2 signing capabilities.

Category
Visit Server

README

<div align="center">

πŸ‡ΈπŸ‡¦ ZATCA MCP

AI-native Saudi e-invoicing β€” generate ZATCA-compliant invoices from natural language.

Python 3.10+ License: Apache 2.0 CI Tests: 127 passing MCP Compatible ZATCA Phase 1 + 2

</div>

<!-- TODO: Record a 30-second demo GIF of Claude Desktop generating a ZATCA invoice via natural language --> <!-- <p align="center"><img src="docs/demo.gif" width="700" alt="Generate a ZATCA-compliant invoice from natural language"></p> -->

<p align="center"><em>"Generate an invoice for 10 hours of consulting at 500 SAR to Al-Rajhi Corp"</em> β†’ compliant XML + QR code in seconds</p>


Why ZATCA MCP?

Saudi Arabia's ZATCA mandate requires all businesses to issue structured electronic invoices β€” Phase 1 (generation) since December 2021, Phase 2 (integration) rolling out across taxpayer waves through 2025. This is a cornerstone of Vision 2030 digital transformation.

The problem: no open-source, AI-native tooling exists for ZATCA e-invoicing. Businesses either pay for proprietary ERP plugins or build compliance from scratch.

This project: the first open-source MCP server for Saudi e-invoicing β€” letting AI agents like Claude generate, validate, and manage ZATCA-compliant invoices through natural conversation.

Features

  • 9 MCP Tools β€” generate, sign, validate, submit invoices + QR codes, CSR, compliance checks, HTML render
  • 3 MCP Resources β€” validation rules, invoice types, sample invoice for AI reference
  • 3 MCP Prompts β€” guided workflows for creating invoices, validating, and credit/debit notes
  • UBL 2.1 XML β€” full namespace-compliant invoice generation per OASIS standard
  • 16-Rule Validation Engine β€” BR-01 through BR-16 business rule checks
  • XAdES-BES Digital Signing β€” ECDSA secp256k1 signatures with certificate embedding
  • ZATCA API Integration β€” async client for compliance, reporting, and clearance endpoints
  • Credit/Debit Notes β€” type codes 381/383 with BillingReference and InstructionNote
  • TLV QR Encoding β€” Phase 1 + Phase 2 tag support (tags 1-8, cryptographic data)
  • Fikra CLI β€” Claude Code-style conversational agent with HTML invoice output
  • 127 Tests β€” unit, integration, signing, API client, resources/prompts, and edge-case coverage
  • CI/CD Pipeline β€” ruff + mypy + pytest across Python 3.10/3.11/3.12 + Phase 2 job
  • Arabic Support β€” full UTF-8 handling for seller/buyer names and addresses
  • Decimal Precision β€” Decimal with ROUND_HALF_UP for all financial math
  • Multi-Rate VAT β€” per-line-item VAT rates (default 15%)

Architecture

graph TD
    subgraph Clients
        A[Claude Desktop]
        B[Claude Code]
        C[Fikra CLI]
    end

    subgraph MCP Server
        D[generate_invoice]
        E[generate_qr_code]
        F[validate_invoice]
        G[decode_qr]
        D2[generate_csr]
        D3[sign_invoice]
        D4[submit_invoice]
        D5[check_compliance]
    end

    subgraph Processing Engine
        H[XML Builder<br/>UBL 2.1]
        I[Validation Engine<br/>16 Business Rules]
        J[TLV Encoder<br/>QR Phase 1 + 2]
        S[Signing Engine<br/>XAdES-BES]
        API[ZATCA API Client<br/>httpx async]
    end

    A -- MCP Protocol --> D
    B -- MCP Protocol --> E
    A -- MCP Protocol --> F
    B -- MCP Protocol --> G

    C -- Direct Call --> H
    C -- Direct Call --> I
    C -- Direct Call --> J
    C -. HTML Pipeline .-> K[Browser Invoice<br/>with QR Image]

    D --> H
    D --> J
    E --> J
    F --> I
    G --> J
    D2 --> S
    D3 --> S
    D4 --> API
    D5 --> API

Quick Start

Install

pip install zatca-mcp              # Phase 1 (generation + validation)
pip install zatca-mcp[phase2]      # Phase 2 (signing + ZATCA API)

Use with Claude Desktop

Add to ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "zatca": {
      "command": "zatca-mcp"
    }
  }
}

Restart Claude Desktop. You can now ask Claude to generate ZATCA-compliant invoices.

Fikra CLI

export ANTHROPIC_API_KEY="sk-ant-..."
pip install zatca-mcp[phase2]
fikra                              # works from any directory

Fikra CLI

A Claude Code-style conversational agent that turns natural language into compliant invoices with professional HTML output.

Features:

  • Gradient ASCII banner with #c8e64a brand theming
  • ❯ prompt with streaming responses
  • ⏺ tool-use indicators (mirrors Claude Code UX)
  • Auto-generates HTML invoices with embedded QR code images
  • Opens invoices in your browser automatically
  • Token usage display (↳ input Β· output tokens)
  • /help /clear /quit commands
     β—‡
    β—‡β—†β—‡
     β—‡       β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—
    β•± β•²      β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘
   β•±   β•²     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘
   ╰───╯     β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘
              β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘
              β•šβ•β•     β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•

  Model: claude-sonnet-4-20250514  |  Tools: 8 ZATCA tools  |  Phase 2 βœ“  |  cwd: ~/zatca-mcp

  Tips: "I sold 10 laptops at 3000 SAR each to TechCo" to get started
        /help for commands, /quit to exit

❯ I just closed a deal with Al-Rajhi Corp for consulting β€” 10 hours at 500 SAR

  ⏺ generate_invoice

  βœ“ Invoice saved & opened in browser
  ~/zatca-mcp/examples/invoices/INV-2026-001_20260217.html

  Great news on closing the deal! I've generated a ZATCA-compliant invoice
  for Al-Rajhi Corp β€” 10 hours of consulting at 500 SAR each.

  **Invoice Summary:**
  - Subtotal: 5,000.00 SAR
  - VAT (15%): 750.00 SAR
  - **Total: 5,750.00 SAR**

  The HTML invoice with embedded QR code is open in your browser.

  ↳ 1,847 input Β· 312 output tokens

Tools API Reference

<details> <summary><code>generate_invoice</code> β€” Create a ZATCA-compliant UBL 2.1 XML e-invoice</summary>

Creates a complete XML invoice following Saudi Arabia's ZATCA e-invoicing standard. Supports Standard (B2B), Simplified (B2C), Credit Note, and Debit Note types. Automatically calculates VAT, line totals, and embeds QR code data.

Parameter Type Required Description
invoice_type string Yes "standard", "simplified", "credit_note", or "debit_note"
invoice_number string Yes Unique identifier (e.g., "INV-2024-001")
issue_date string Yes YYYY-MM-DD format
seller_name string Yes Seller business name
seller_vat string Yes 15-digit VAT number
seller_address string Yes Seller street address
seller_city string Yes Seller city
buyer_name string Yes Buyer/customer name
items string Yes JSON array: [{"name": "...", "quantity": 1, "unit_price": 100.00, "vat_rate": 0.15}]
currency string No ISO currency code (default: "SAR")
buyer_vat string No Required for standard (B2B) invoices
buyer_address string No Buyer street address
buyer_city string No Buyer city
note string No Optional invoice note
billing_reference_id string No Original invoice ID (required for credit/debit notes)
billing_reference_date string No Original invoice date (for credit/debit notes)
instruction_note string No Reason for credit/debit note

Returns: Complete UBL 2.1 XML invoice string with embedded QR code.

</details>

<details> <summary><code>generate_qr_code</code> β€” Generate a TLV-encoded QR code</summary>

Creates a Base64-encoded QR code payload following ZATCA's Tag-Length-Value (TLV) format for Phase 1 and Phase 2 compliance.

Parameter Type Required Description
seller_name string Yes Business/taxpayer name (Arabic or English)
vat_number string Yes 15-digit Saudi VAT number
timestamp string Yes ISO 8601 format (e.g., "2024-01-15T10:30:00Z")
total_amount string Yes Invoice total including VAT (e.g., "1150.00")
vat_amount string Yes Total VAT charged (e.g., "150.00")

Returns: JSON with qr_base64 and decoded_verification data.

</details>

<details> <summary><code>validate_invoice</code> β€” Check invoice XML against ZATCA business rules</summary>

Runs 16 business rule checks including required fields, VAT number format, mathematical accuracy of line totals and VAT calculations, credit/debit note references, and structural integrity of UBL 2.1 XML.

Parameter Type Required Description
invoice_xml string Yes Complete UBL 2.1 XML invoice string

Returns: JSON with is_valid (boolean), errors (list), warnings (list), and checks_run (16).

</details>

<details> <summary><code>generate_csr</code> β€” Generate a ZATCA-compliant Certificate Signing Request</summary>

Generates an ECDSA secp256k1 key pair and a CSR with ZATCA-required subject fields. Requires cryptography (install with pip install zatca-mcp[phase2]).

Parameter Type Required Description
common_name string Yes Certificate CN field
organization string Yes Organization name
organizational_unit string Yes Organization unit
country string No Country code (default: "SA")
serial_number string No ZATCA device serial number
invoice_type string No ZATCA invoice type code (default: "1100")
location string No Business location (default: "Riyadh")
industry string No Business category (default: "IT")

Returns: JSON with csr_pem, private_key_pem, warning, and next_step.

</details>

<details> <summary><code>sign_invoice</code> β€” Digitally sign an invoice with XAdES-BES</summary>

Injects an XAdES-BES digital signature into a UBL 2.1 invoice XML. Rebuilds the QR code with Phase 2 cryptographic tags (6-8). Requires cryptography.

Parameter Type Required Description
invoice_xml string Yes UBL 2.1 XML invoice string to sign
certificate_pem string Yes PEM-encoded X.509 certificate
private_key_pem string Yes PEM-encoded ECDSA private key

Returns: JSON with signed_xml, invoice_hash, qr_base64, and is_phase2_compliant.

</details>

<details> <summary><code>submit_invoice</code> β€” Submit a signed invoice to the ZATCA API</summary>

Submits a signed invoice to the ZATCA Fatoora API for reporting (simplified) or clearance (standard). Requires httpx and pydantic.

Parameter Type Required Description
signed_invoice_xml string Yes Signed UBL 2.1 XML invoice
invoice_hash string Yes Base64-encoded SHA-256 hash
invoice_uuid string Yes Invoice UUID
certificate string Yes Base64-encoded certificate
secret string Yes API secret from CSID
mode string No "reporting" (default) or "clearance"
environment string No "sandbox" (default) or "production"

Returns: ZATCA API response with status, validationResults, warnings, and errors.

</details>

<details> <summary><code>check_compliance</code> β€” Check invoice compliance with ZATCA servers</summary>

Submits an invoice to the ZATCA compliance endpoint for server-side validation. Requires httpx and pydantic.

Parameter Type Required Description
signed_invoice_xml string Yes Signed UBL 2.1 XML invoice
invoice_hash string Yes Base64-encoded SHA-256 hash
invoice_uuid string Yes Invoice UUID
certificate string Yes Base64-encoded certificate
secret string Yes API secret from CSID

Returns: ZATCA compliance validation results.

</details>

<details> <summary><code>decode_qr</code> β€” Decode a ZATCA TLV-encoded QR code string</summary>

Extracts all encoded tag values from an existing ZATCA QR code for verification or inspection.

Parameter Type Required Description
qr_base64 string Yes Base64-encoded TLV string from a ZATCA QR code

Returns: JSON with decoded tag names and their values.

</details>

Programmatic Usage

from zatca_mcp.utils.xml_builder import build_invoice_xml
from zatca_mcp.utils.tlv import encode_tlv
from zatca_mcp.utils.validation import validate_invoice_xml

# Generate invoice
xml = build_invoice_xml(
    invoice_type="simplified",
    invoice_number="INV-2024-001",
    issue_date="2024-01-15",
    seller_name="Fikrah Tech",
    seller_vat="300000000000003",
    seller_address="123 King Fahd Road",
    seller_city="Riyadh",
    buyer_name="Walk-in Customer",
    line_items=[
        {"name": "AI Consulting", "quantity": 10, "unit_price": 500.00},
        {"name": "Setup Fee", "quantity": 1, "unit_price": 1000.00},
    ],
)

# Validate
result = validate_invoice_xml(xml)
print(f"Valid: {result['is_valid']}")  # True
print(f"Checks: {result['checks_run']}")  # 16

# Generate QR code
qr = encode_tlv(
    seller_name="Fikrah Tech",
    vat_number="300000000000003",
    timestamp="2024-01-15T10:00:00Z",
    total_amount="6900.00",
    vat_amount="900.00",
)
print(f"QR: {qr}")

Phase 2: Digital Signing

from zatca_mcp.utils.signing import (
    generate_private_key,
    generate_csr,
    inject_signature,
    hash_invoice,
)

# Generate key pair and CSR
key = generate_private_key()
csr_pem = generate_csr(
    key,
    common_name="My Company",
    organization="My Org",
    organizational_unit="IT",
)
# Submit CSR to ZATCA to get a certificate, then sign:
# signed_xml = inject_signature(xml, cert_pem, key)
# invoice_hash = hash_invoice(xml)

ZATCA Compliance

Validation Rules (16 Business Rules)

Rule Check Description
BR-01 Invoice ID cbc:ID is mandatory
BR-02 Issue Date cbc:IssueDate mandatory, YYYY-MM-DD format
BR-03 Type Code cbc:InvoiceTypeCode must be 388, 381, or 383
BR-04 Currency cbc:DocumentCurrencyCode is mandatory
BR-05 Seller Name Seller RegistrationName is mandatory
BR-06 Seller VAT 15-digit VAT number, starts/ends with 3
BR-07 Buyer Name Buyer RegistrationName is mandatory
BR-08 Buyer VAT (B2B) Required for standard invoice subtype 01*
BR-09 β€” Reserved
BR-10 Line Items At least one cac:InvoiceLine required
BR-11 Line Math qty Γ— price = line extension amount (Β±0.01)
BR-12 Tax Total cac:TaxTotal/cbc:TaxAmount is mandatory
BR-13 Payable Amount cbc:PayableAmount is mandatory
BR-14 Total Cross-Check tax-exclusive + tax = tax-inclusive (Β±0.01)
BR-15 Billing Reference Credit/Debit notes must reference original invoice
BR-16 Instruction Note Credit/Debit notes should include a reason

Invoice Types

Type Code Subtype Use Case
Standard Tax Invoice 388 0100000 B2B transactions
Simplified Tax Invoice 388 0200000 B2C / POS transactions
Standard Credit Note 381 0100000 B2B returns/refunds
Simplified Credit Note 381 0200000 B2C returns/refunds
Standard Debit Note 383 0100000 B2B additional charges
Simplified Debit Note 383 0200000 B2C additional charges

QR Code TLV Tags

Tag Name Phase
1 Seller Name 1
2 VAT Registration Number 1
3 Timestamp 1
4 Invoice Total (with VAT) 1
5 VAT Amount 1
6 Invoice Hash 2
7 ECDSA Signature 2
8 ECDSA Public Key 2

Tags 6-8 are populated by the sign_invoice tool with real cryptographic data (SHA-256 hash, ECDSA signature, public key).

Engineering Quality

  • 127 tests across 7 test modules (TLV, validation, invoice, signing, credit/debit, API client, resources/prompts)
  • CI/CD β€” GitHub Actions: ruff lint + format check, mypy type checking, pytest with coverage across Python 3.10 / 3.11 / 3.12, plus a dedicated Phase 2 job
  • Decimal precision β€” all financial calculations use Decimal with ROUND_HALF_UP, never floating point
  • UBL 2.1 compliance β€” full OASIS namespace declarations (ubl, cac, cbc, ext, ds, xades)
  • Arabic/UTF-8 β€” ensure_ascii=False throughout; Arabic seller/buyer names work correctly
  • Graceful degradation β€” Phase 2 tools return helpful errors if cryptography/httpx not installed

Project Structure

zatca-mcp/
β”œβ”€β”€ src/zatca_mcp/
β”‚   β”œβ”€β”€ server.py              # MCP server β€” 9 tools, 3 resources, 3 prompts
β”‚   β”œβ”€β”€ cli.py                 # Fikra CLI β€” global `fikra` command
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ xml_builder.py     # UBL 2.1 XML invoice generator
β”‚   β”‚   β”œβ”€β”€ validation.py      # 16-rule validation engine
β”‚   β”‚   β”œβ”€β”€ tlv.py             # TLV QR encoder/decoder
β”‚   β”‚   └── signing.py         # XAdES-BES digital signing (Phase 2)
β”‚   └── api/
β”‚       β”œβ”€β”€ __init__.py
β”‚       β”œβ”€β”€ client.py          # ZATCA Fatoora API client (Phase 2)
β”‚       └── models.py          # Pydantic v2 API models (Phase 2)
β”œβ”€β”€ examples/
β”‚   └── fikrah_agent.py        # Legacy entry point (redirects to fikra command)
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ test_invoice.py        # Invoice generation tests
β”‚   β”œβ”€β”€ test_tlv.py            # TLV encoding/decoding tests
β”‚   β”œβ”€β”€ test_validation.py     # Validation engine tests
β”‚   β”œβ”€β”€ test_resources_prompts.py # MCP resources & prompts tests
β”‚   β”œβ”€β”€ test_signing.py        # Digital signing tests (Phase 2)
β”‚   β”œβ”€β”€ test_credit_debit.py   # Credit/debit note tests (Phase 2)
β”‚   └── test_api_client.py     # API client tests (Phase 2)
β”œβ”€β”€ .github/workflows/
β”‚   └── test.yml               # CI pipeline (Phase 1 + Phase 2 jobs)
β”œβ”€β”€ pyproject.toml
└── LICENSE

Development

git clone https://github.com/DoubleH10/zatca-mcp.git
cd zatca-mcp

# Phase 1 only
pip install -e ".[dev]"

# Phase 1 + Phase 2 (signing, API)
pip install -e ".[dev,phase2]"

# Tests
pytest tests/ -v                                    # All tests
pytest tests/ -v -m "not sandbox"                   # Skip live sandbox tests

# Linting & types
ruff check src/ tests/
mypy src/zatca_mcp/ --ignore-missing-imports

# MCP Inspector (interactive testing)
mcp dev src/zatca_mcp/server.py

Roadmap

  • [x] TLV QR code generation (Phase 1 + Phase 2 tags)
  • [x] UBL 2.1 XML invoice generation
  • [x] 16-rule validation engine (BR-01 through BR-16)
  • [x] MCP server with 8 tools
  • [x] Fikra CLI (streaming, HTML invoices, QR images)
  • [x] CI/CD pipeline (ruff + mypy + pytest matrix + Phase 2 job)
  • [x] XAdES-BES digital signing (ECDSA secp256k1)
  • [x] ZATCA API integration (sandbox + production)
  • [x] Certificate management (CSR generation)
  • [x] Credit/debit note support (381/383)
  • [ ] PyPI package publishing
  • [x] MCP Resources & Prompts
  • [ ] HTTP/SSE transport
  • [ ] Arabic RTL invoice template

Built with zatca-mcp

Project Description
Fikrah Agentic AI workforce for financial operations β€” uses this server as its ZATCA compliance backbone

Using zatca-mcp in your project? Open a PR to add it here.

Contributing

Contributions welcome! See CONTRIBUTING.md for setup instructions. Check the good first issues for a place to start.

License

Apache 2.0 β€” see LICENSE

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