🇸🇦 ZATCA MCP
AI-native Saudi e-invoicing — generate ZATCA-compliant invoices from natural language.
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 —
DecimalwithROUND_HALF_UPfor 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
#c8e64abrand 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/quitcommands
◇
◇◆◇
◇ ███████╗██╗██╗ ██╗██████╗ █████╗ ██╗ ██╗
╱ ╲ ██╔════╝██║██║ ██╔╝██╔══██╗██╔══██╗██║ ██║
╱ ╲ █████╗ ██║█████╔╝ ██████╔╝███████║███████║
╰───╯ ██╔══╝ ██║██╔═██╗ ██╔══██╗██╔══██║██╔══██║
██║ ██║██║ ██╗██║ ██║██║ ██║██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
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
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.
Returns: Complete UBL 2.1 XML invoice string with embedded QR code.
Creates a Base64-encoded QR code payload following ZATCA's Tag-Length-Value (TLV) format for Phase 1 and Phase 2 compliance.
Returns: JSON with qr_base64 and decoded_verification data.
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.
Returns: JSON with is_valid (boolean), errors (list), warnings (list), and checks_run (16).
Generates an ECDSA secp256k1 key pair and a CSR with ZATCA-required subject fields. Requires cryptography (install with pip install zatca-mcp[phase2]).
Returns: JSON with csr_pem, private_key_pem, warning, and next_step.
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.
Returns: JSON with signed_xml, invoice_hash, qr_base64, and is_phase2_compliant.
Submits a signed invoice to the ZATCA Fatoora API for reporting (simplified) or clearance (standard). Requires httpx and pydantic.
Returns: ZATCA API response with status, validationResults, warnings, and errors.
Submits an invoice to the ZATCA compliance endpoint for server-side validation. Requires httpx and pydantic.
Returns: ZATCA compliance validation results.
Extracts all encoded tag values from an existing ZATCA QR code for verification or inspection.
Returns: JSON with decoded tag names and their values.
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)
Invoice Types
QR Code TLV Tags
Tags 6-8 are populated by the
sign_invoicetool 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
DecimalwithROUND_HALF_UP, never floating point - UBL 2.1 compliance — full OASIS namespace declarations (
ubl,cac,cbc,ext,ds,xades) - Arabic/UTF-8 —
ensure_ascii=Falsethroughout; Arabic seller/buyer names work correctly - Graceful degradation — Phase 2 tools return helpful errors if
cryptography/httpxnot 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
- TLV QR code generation (Phase 1 + Phase 2 tags)
- UBL 2.1 XML invoice generation
- 16-rule validation engine (BR-01 through BR-16)
- MCP server with 8 tools
- Fikra CLI (streaming, HTML invoices, QR images)
- CI/CD pipeline (ruff + mypy + pytest matrix + Phase 2 job)
- XAdES-BES digital signing (ECDSA secp256k1)
- ZATCA API integration (sandbox + production)
- Certificate management (CSR generation)
- Credit/debit note support (381/383)
- PyPI package publishing
- MCP Resources & Prompts
- HTTP/SSE transport
- Arabic RTL invoice template
Built with zatca-mcp
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