Skip to main content
Glama
caseroclaw

verifactu-qr

by caseroclaw

verifactu-qr

URL del código QR tributario de VeriFactu (AEAT) y validación de NIF/CIF/NIE — sin dependencias, en una sola línea.

listed on awesome-spain

Herramienta en Python para generar la URL que debe llevar el QR obligatorio de las facturas españolas (RD 1007/2023 · Orden HAC/1177/2024) validando antes NIF, número de serie, fecha e importe, con los códigos de error oficiales de la AEAT (2001-2006). Incluye CLI y servidor MCP para agentes de IA.

Mantenido por Plataforma IA, consultora de automatización con IA para pymes en Madrid y toda España. Guía de plazos y preparación: VeriFactu 2027 para pymes.

Instalación

pip install verifactu-qr            # solo librería + CLI (0 dependencias)
pip install "verifactu-qr[svg]"     # + exportar el QR a SVG (segno)

Related MCP server: mcp-europe-business

Uso rápido (CLI)

$ verifactu-qr qr --nif 89890001K --numserie "12345678&G33" --fecha 01-01-2024 --importe 241.4
https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQR?nif=89890001K&numserie=12345678%26G33&fecha=01-01-2024&importe=241.4

# entorno de pruebas, sistema que NO remite registros (no VERI*FACTU) y QR en SVG
$ verifactu-qr qr --nif 89890001K --numserie "12345678&G33" --fecha 01-01-2024 --importe 241.4 \
    --pruebas --no-verifactu --svg qr.svg

$ verifactu-qr validar 89890001K
VALIDO: 89890001K (DNI)

Uso como librería

from verifactu_qr import build_qr_url, nif_valido, url_consulta_json

url = build_qr_url(
    nif="89890001K",
    numserie="12345678&G33",   # se codifica como 12345678%26G33 (URL encoding UTF-8)
    fecha="01-01-2024",        # o un datetime.date
    importe=241.4,             # o "241.40", Decimal
    verifactu=True,            # False -> .../ValidarQRNoVerifactu
    entorno="produccion",      # o "pruebas"
)
print(url)
print(url_consulta_json(url))   # añade &formato=json para parsear la respuesta de la AEAT

Errores con el código oficial: QRError.code ∈ {2001 NIF inválido, 2002 nº de serie demasiado largo, 2003 caracteres no permitidos, 2004 fecha inválida, 2005 importe inválido, 2006 importe demasiado largo}.

Uso como servidor MCP (agentes de IA)

{
  "mcpServers": {
    "verifactu-qr": { "command": "verifactu-qr-mcp" }
  }
}

Herramientas expuestas: verifactu_qr_url, validar_identificacion_fiscal, url_consulta_json. Probarlo a mano:

$ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | verifactu-qr-mcp

Qué cubre y qué no

  • Cubre: los 4 parámetros obligatorios del QR (nif, numserie, fecha, importe), las 4 URLs base (producción/pruebas × VERI*FACTU/no verificable), el URL encoding con la misma semántica que java.net.URLEncoder (el detalle que más falla: & → %26, espacio → +), la validación con dígito de control de NIF/NIE/CIF y los códigos de error de la AEAT.

  • No cubre: la huella (hash) de encadenamiento de registros, la firma electrónica XAdES, el envío SOAP de registros ni el diseño/maquetación del QR dentro del PDF (30-40 mm, nivel M). Para eso, ver pyverifactu o verifactu en PyPI.

Aviso: herramienta no oficial, sin vinculación con la AEAT. Verifica siempre el resultado con el portal de pruebas de la AEAT antes de producción.

Referencias

  • Real Decreto 1007/2023, de 5 de diciembre (BOE-A-2023-24840).

  • Orden HAC/1177/2024, arts. 20 y 21 (contenido del QR: NIF, serie y número, fecha, importe).

  • AEAT, «Características del QR y especificaciones del servicio de cotejo» (sede electrónica).

Los tests incluyen el vector de ejemplo oficial de la AEAT (nif=89890001K, numserie=12345678&G33 → 12345678%26G33, fecha=01-01-2024, importe=241.4).

Tests

PYTHONPATH=src python -m unittest discover -s tests -v

Licencia

MIT — úsalo libremente en tu software de facturación.


English

verifactu-qr builds the URL that Spanish invoices must embed in their mandatory tax QR code (VeriFactu, RD 1007/2023) while validating the Spanish tax ID, invoice number, date and amount, returning the official AEAT error codes. Zero dependencies, plus a CLI and a stdio MCP server so AI agents can generate compliant QR URLs. Maintained by Plataforma IA, an AI automation consultancy based in Madrid, Spain.

Available Tools

3 tools
url_consulta_jsonA

Añade formato=json a una URL de QR para consultar el servicio de la AEAT en JSON (no va dentro del QR).

ParametersJSON Schema
NameRequiredDescriptionDefault
url_qrYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry behavioral disclosure alone. It does disclose the transformation (adding formato=json) and a meaningful constraint (the result is not embedded in the QR), but it is silent on whether a network request to AEAT is actually made, what is returned, or any auth requirement, leaving ambiguity for a service-querying tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the action front-loaded ('Añade formato=json a una URL...'), and the parenthetical constraint earns its place by preventing misuse. Nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with no output schema and no annotations, the description covers purpose and transformation but omits what the call returns (a modified URL vs. service data) and expected input format. Adequate but with clear gaps given structured fields carry none of the load.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is one parameter (url_qr) at 0% schema description coverage. The description identifies the input as 'una URL de QR', which matches the field name and adds a little meaning, but gives no format, encoding, or validation guidance for that string.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete action on a concrete resource: it appends 'formato=json' to a QR URL so the AEAT service is queried in JSON. This goes beyond restating the name. It does not, however, explicitly name or contrast itself with siblings like verifactu_qr_url, so the agent must infer the split from the trailing parenthetical.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the note '(no va dentro del QR)' tells the agent that the modified URL is for querying the service rather than for embedding in the QR, which hints at when to reach for this versus the QR-generating sibling. There is no explicit when-to-use/when-not statement or named alternative, so it stays at the implied level.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validar_identificacion_fiscalA

Comprueba si un NIF, NIE o CIF español tiene formato y dígito de control correctos.

ParametersJSON Schema
NameRequiredDescriptionDefault
identificacionYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses that the check covers both format and check digit and is inherently a non-mutating verification, which is useful. It does not state the return value (e.g., boolean vs. error message), how malformed input is surfaced, or whether it rejects empty strings, so key operational behavior is left implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with zero filler. Every clause earns its place by naming the operation, the identifier types, and the two validation dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter validation tool the description covers the essential purpose, but there is no output schema and no annotations, so return semantics should have been stated and are not. An agent knows what to send but not what to expect back.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the single 'identificacion' parameter has no schema-level description, so the description must compensate. It usefully identifies the accepted input domain (NIF, NIE, CIF), but adds no format guidance (spaces, hyphens, casing, length) to help construct a valid value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Comprueba si') and a precise resource set (NIF, NIE, CIF) plus the exact validation scope (formato y dígito de control). It is unambiguous about what the tool checks, but it never differentiates itself from the sibling tools, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the validation semantics: an agent can infer it should call this when it needs to verify a Spanish tax identifier. However, there is no explicit when-to-use statement, no mention of when not to use it, and no pointer to any alternative among the siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verifactu_qr_urlA

Genera la URL del código QR tributario de una factura española (VeriFactu, RD 1007/2023 y Orden HAC/1177/2024) validando NIF, número de serie, fecha e importe.

ParametersJSON Schema
NameRequiredDescriptionDefault
nifYesNIF del obligado a expedir la factura (9 caracteres)
fechaYesfecha de expedición en formato DD-MM-AAAA
entornoNopor defecto produccion
importeYesimporte total, punto decimal, máximo 12 enteros y 2 decimales
numserieYesserie y número de factura, máximo 60 caracteres
verifactuNotrue si el sistema remite los registros a la AEAT (VERI*FACTU); por defecto true

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden, and it does disclose one concrete behavioral trait: the inputs are validated ('validando NIF, número de serie, fecha e importe'). However it says nothing about failure behavior when validation rejects an input, whether any network/registry call occurs, or auth requirements, leaving meaningful behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the verb first and the resource immediately after; the regulatory citations are dense but arguably earn their place by anchoring the output to a legal standard. No filler or redundant sentences, though the clause structure is somewhat packed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description does identify the return value (a QR URL) and the validated inputs, which is the core an agent needs. The optional entorno and verifactu parameters, which materially change the generated URL, are left entirely to the schema, so it is not fully complete for a regulatory tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters including formats (DD-MM-AAAA, 9 chars, 60 chars) and defaults. The description merely restates the four validated parameters and adds no syntax or constraint detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Genera la URL del código QR tributario de una factura española', grounded in named regulations (VeriFactu, RD 1007/2023, Orden HAC/1177/2024). An agent understands exactly what is produced. It does not explicitly differentiate itself from the sibling url_consulta_json, which is also a URL generator, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the purpose — the agent can infer it is used when a VeriFactu QR URL is needed. There is no explicit when-to-use/when-not-to-use, no prerequisites, and no naming of the sibling url_consulta_json as the alternative, which is a real routing risk given both tools emit URLs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedurl_consulta_json
    • First observedvalidar_identificacion_fiscal
    • First observedverifactu_qr_url

TDQS

B3.4/5.0

Scored across 3 tools

Disambiguation4/5

The three tools target distinct operations: generating a VeriFactu QR URL, validating a Spanish tax ID, and appending format=json for AEAT JSON queries. The two URL-related tools (verifactu_qr_url and url_consulta_json) could be momentarily confused, but the descriptions clearly separate generation from query-format transformation.

Naming Consistency2/5

Names mix Spanish and English and mix verb-first (validar_identificacion_fiscal) with noun-first patterns (verifactu_qr_url, url_consulta_json). Although all use snake_case, the underlying conventions are inconsistent, making the set feel ad hoc.

Tool Count3/5

Three tools is on the thin side for the stated purpose, though the domain (VeriFactu QR generation) is narrow enough that a small surface is defensible. It borders on under-scoped.

Completeness3/5

The core generation and validation workflow is covered, but there is no tool to decode/parse an existing QR URL or validate a full invoice payload, leaving some notable gaps. The JSON-query helper partially compensates but the lifecycle feels incomplete.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Provides access to official Spanish fiscal data and tools based on AEAT and BOE sources, covering income tax, VAT, and regional deductions. It enables AI assistants to answer tax-related queries and verify filing deadlines using verified information.
    10
    13 npm
    13
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    European business compliance suite for AI agents — 28 tools covering tax ID validation (PT, ES, FR, DE, IT, UK, NL), IBAN verification, EU VAT rates, invoice requirements, e-invoicing rules, payment terms, labor calendar helpers, VAT breakdown calculations and invoice schema validation for 18+ European countries.
    28
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Validates EU electronic invoices (Peppol, XRechnung, FatturaPA, etc.) and explains validation error codes, enabling AI coding agents to check invoice validity and get fixes before rejection.
    3
    17 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to issue, correct, and register legally compliant Spanish electronic invoices with AEAT VeriFactu, supporting F1/F2 types, R1–R5 correctives, and NIF validation from Claude, ChatGPT, Cursor, or VS Code.
    131
    20 npm
    2
    MIT