Lee estados de cuenta de bancos mexicanos en PDF y entrega un JSON estructurado que no te identifica.
100 % local · cifras conciliadas · hecho para agentes de IA
Sitio del proyecto · Instalación · Uso · Privacidad · Guía para agentes de IA
Subir un estado de cuenta a un asistente de IA expone tu nombre, domicilio, RFC, número de tarjeta, CLABE y los datos de las personas a las que les transfieres. mxbank lee el PDF en tu computadora, extrae saldos y movimientos, elimina todo lo que te identifica, valida que las cifras cuadren y solo entonces emite el JSON.
mxbank extract estado.pdf > estado.json # este archivo ya se puede compartir con una IAUn adaptador de howware. Los howwares (tu saber hacer puesto a trabajar con IA, sin app) lo usan para leer estados de cuenta: finanzas-personales, facturacion, la facturación para independientes, y arrendamiento, las rentas para caseros. No tiene reglas de ningún trabajo: entrega movimientos conciliados; qué significa cada uno lo decide el howware con su dueño.
- Características
- Bancos soportados
- Instalación
- Uso
- Salida
- Privacidad
- Uso con agentes de IA
- Desarrollo
- Documentación
- Hoja de ruta
- Licencia
- 100 % local: sin red, sin telemetría y sin archivos temporales. El PDF nunca sale de tu máquina.
- Privacidad por diseño: la salida se construye campo por campo a partir de una lista cerrada. Un escáner final revisa el JSON completo y, si encuentra algo sospechoso, no emite nada.
- Cifras verificadas: cada estado se concilia contra sus saldos y contra los totales que reporta el propio banco.
- Hecho para IA: JSON en stdout, diagnósticos en stderr, errores también en JSON, códigos de salida estables, sin prompts interactivos y JSON Schema publicado.
- Tarjetas de crédito completas: pago mínimo, pago para no generar intereses, CAT, meses sin intereses, compras en moneda extranjera y parcialidades.
| Banco | Producto | Layout | Validado con |
|---|---|---|---|
| BBVA México | Cuenta de débito (p. ej. Nómina) | 2024.1 | 4 estados reales: conciliación, totales y saldo por día exactos |
| BBVA México | Tarjeta de crédito | 2025.1 | 4 estados reales: conciliación y totales exactos |
| BanCoppel | Cuenta de débito digital | 2025.1 | 1 estado real: conciliación, totales y saldo por movimiento exactos |
Si un PDF no corresponde a un formato soportado, mxbank lo rechaza con el código 20 o 21; nunca intenta adivinar. ¿Quieres otro banco? Lee cómo agregar uno.
Requiere Python 3.12+ y uv.
git clone https://github.com/howware/mx-bank-statement-reader.git
cd mx-bank-statement-reader
uv sync
uv run mxbank --helpPara tenerlo disponible como comando global:
uv tool install .
mxbank --helpmxbank extract estado.pdf --pretty # un estado de cuenta
mxbank extract carpeta/ --ndjson > movimientos.jsonl # todos los PDFs de una carpeta
mxbank extract estado.pdf --privacy strict # sin últimos 4 dígitos ni nombre de archivo
mxbank extract estado.pdf --include-concepts # incluye conceptos de transferencias (redactados)
mxbank detect estado.pdf # solo identifica banco y producto
mxbank audit cualquier_archivo.json # busca datos personales antes de compartir algo
mxbank schema # JSON Schema de la salida
mxbank banks # formatos soportadosPDF con contraseña y seudónimos estables entre meses. Los secretos se pasan por variable de entorno, nunca como argumento, para que no queden en el historial de la terminal:
export MXBANK_PDF_PASSWORD='...'
export MXBANK_KEY='una-llave-larga-y-privada'
mxbank extract estado.pdf --password-env MXBANK_PDF_PASSWORD --pseudonym-key-env MXBANK_KEYCon la misma llave, la misma cuenta o contraparte recibe el mismo seudónimo (ACC_…, PERSONA_…) en todos los meses, así puedes agrupar sin revelar quién es.
| Código | Significado |
|---|---|
| 0 | Éxito |
| 2 | Argumentos inválidos |
| 10 | Archivo no encontrado o no es PDF |
| 11 | PDF protegido: falta la contraseña o es incorrecta |
| 12 | El PDF no tiene texto (escaneo; requiere OCR) |
| 20 | Banco no reconocido |
| 21 | Confianza de detección baja |
| 30 | La conciliación no cuadra (solo con --fail-on-unbalanced) |
| 40 | Se detectó posible información personal en la salida; no se emitió nada |
Extracto real generado a partir del PDF sintético de las pruebas, con datos ficticios:
{
"schema_version": "1.1",
"ok": true,
"statement_id": "ST_5c0e9a41d27b8f36",
"document": { "bank": "bbva", "product": "credit", "product_name": "TARJETA AZUL BBVA (CREDITO)", "currency": "MXN" },
"account": { "account_ref": "ACC_92d5", "account_last4": "3210", "holder_type": "individual" },
"period": { "start": "2026-08-15", "end": "2026-09-14", "days": 31 },
"credit": {
"credit_limit": "50000.00", "available_credit": "45535.00",
"cut_off_date": "2026-09-14", "payment_due_date": "2026-10-08",
"minimum_payment": "900.00", "no_interest_payment": "1965.00", "cat_percent": "75.3"
},
"transactions": [
{ "id": "TX_8d41f0b27c9e3a65", "date": "2026-08-18", "description": "AMAZON", "type": "card_purchase", "amount": "-1200.00",
"merchant": "AMAZON", "card_type": "digital" },
{ "date": "2026-08-20", "description": "NETFLIX", "type": "card_purchase", "amount": "-299.00",
"original_currency": "USD", "original_amount": "15.00", "exchange_rate": "19.93" },
{ "date": "2026-08-25", "description": "BMOVIL.PAGO TDC", "type": "card_payment", "amount": "13000.00" }
],
"validation": { "reconciled": true, "difference": "0.00", "bank_totals_match": true },
"privacy": {
"removed": { "holder_name": 2, "address": 1, "rfc": 1, "card_number": 1, "clabe": 1, "client_number": 1 },
"residual_scan": "passed"
}
}- Montos como texto decimal (
"1200.00"), para no perder precisión.amountnegativo = salida de dinero. - Fechas ISO-8601.
nullsignifica que el dato no viene en el documento; nunca se inventa. statement_id,transactions[].ideinstallment_plans[].idson identificadores estables (HMAC con tu llave): con la misma--pseudonym-key-envpuedes reimportar estados, incluso los que se enciman, sin duplicar movimientos. Ver docs/03 §7.- El esquema completo se obtiene con
mxbank schema; la semántica de cada campo está en docs/03-esquema-salida.md.
| Dato | Tratamiento |
|---|---|
| Nombre, domicilio, RFC, CURP, número de cliente, sucursal | Se eliminan |
| Número de cuenta / crédito | Seudónimo estable (ACC_…) + últimos 4 dígitos (se omiten en --privacy strict) |
Tarjeta completa, CLABE, sufijo Tarjeta Digital ***1234 |
Se eliminan |
| Contrapartes de transferencias (terceros) | Seudónimo (PERSONA_…, CUENTA_…); nunca el nombre ni la cuenta |
| Claves de rastreo y referencias | Se eliminan |
| Conceptos libres de transferencias | Se omiten; con --include-concepts se incluyen redactados |
| Comercio, monto y fecha de cada movimiento | Se conservan: es el propósito de la herramienta |
Cómo se garantiza:
- Lista cerrada: el modelo de salida no tiene campos donde quepa el encabezado del estado de cuenta.
- Diccionario del documento: las palabras del nombre y domicilio del titular se buscan en todo texto emitido. Si aparecen, por ejemplo la colonia en el nombre de una sucursal, se reemplazan por
[DATO]. - Patrones validados: CLABE (dígito verificador), tarjeta (Luhn), RFC, CURP, correo y números de 4+ dígitos.
- Escáner residual fail-closed: revisa el JSON final completo; ante la duda sale con el código 40 y no emite nada.
Modelo de amenaza, perfiles y riesgos residuales: docs/04-privacidad-y-redaccion.md.
Aviso:
mxbankse ofrece tal cual, sin garantías, y reduce drásticamente la información personal que compartes, pero ninguna herramienta automática es infalible. Revisa la salida antes de enviarla a terceros (mxbank auditayuda) y verifica las cifras contra el estado de cuenta original. No es asesoría legal, financiera ni fiscal. Si procesas estados de cuenta de otras personas, cumplir la ley de protección de datos es tu responsabilidad. Lee el aviso legal y advertencias de uso completo.
mxbank está pensado para que un agente lo invoque como herramienta: el agente ejecuta mxbank extract, lee el JSON y razona sobre los movimientos sin ver nunca el PDF. Las reglas, los códigos de salida y un ejemplo están en docs/AGENT.md, listos para copiarse a las instrucciones de un agente.
El repositorio incluye el skill mxbank. Claude Code lo carga solo cuando le pides revisar, resumir o graficar un estado de cuenta, y con él la sesión sabe:
-
usar
mxbank extracten lugar de abrir el PDF; -
que pagos a la tarjeta y traslados a meses no son gasto;
-
cómo detectar cargos recurrentes;
-
cómo verificar las sumas contra el banco antes de responder.
-
Dentro de un clon del repositorio ya está disponible; no hay que hacer nada.
-
Para tenerlo en todas tus sesiones, instálalo en tu usuario:
# macOS / Linux mkdir -p ~/.claude/skills/mxbank && curl -fsSL https://raw.githubusercontent.com/howware/mx-bank-statement-reader/main/.claude/skills/mxbank/SKILL.md -o ~/.claude/skills/mxbank/SKILL.md
# Windows (PowerShell) New-Item -ItemType Directory -Force "$HOME\.claude\skills\mxbank" | Out-Null; Invoke-WebRequest https://raw.githubusercontent.com/howware/mx-bank-statement-reader/main/.claude/skills/mxbank/SKILL.md -OutFile "$HOME\.claude\skills\mxbank\SKILL.md"
Reinicia Claude Code y pide, por ejemplo: "analiza mis gastos del estado de cuenta
~/estados/tarjeta_sep.pdf". Para actualizar el skill, vuelve a ejecutar el mismo comando.
Si desarrollas el proyecto con una IA, las reglas están en AGENTS.md.
uv sync # dependencias, incluidas las de desarrollo
uv run pytest -q # pruebas sobre PDFs sintéticos
uvx ruff check src tests tools # lint
git config core.hooksPath tools/git-hooks # activa la guardia de commits (obligatorio)- Los estados de cuenta reales van en
corpus/odocs/Estados/, que están ignorados por git. - La guardia de commits (tools/check_no_pii.py) bloquea PDFs, esas carpetas y cualquier CLABE, tarjeta, RFC, CURP o correo. CI la ejecuta sobre todos los archivos del repositorio.
- Las pruebas usan PDFs sintéticos (tests/synthetic/) que imitan cada layout con datos ficticios; las CLABE y tarjetas de prueba tienen dígito verificador válido para que una fuga se detecte de verdad.
- Los valores ficticios que deben pasar la guardia se declaran en .pii-allowlist.
- Estudia el layout sin exponer datos:
uv run python tools/layout_dump.py corpus/estado.pdf --out corpus/layout.txt. El volcado enmascara cada dígito y cada palabra que no sea vocabulario bancario; revísalo antes de compartirlo.--reveal-tx-first-linemuestra las letras de la primera línea de cada movimiento. - Documenta el layout en
docs/bancos/<banco>-<producto>.mdusando solo formas enmascaradas. - Implementa un parser en
src/mxbank/parsers/(contrato en parsers/base.py) y regístralo enparsers/__init__.py. - Crea un PDF sintético en
tests/synthetic/y sus pruebas: valores extraídos, conciliación y fuga de datos. - Valida contra PDFs reales viendo solo métricas:
uv run python tools/corpus_check.py corpus/.
src/mxbank/
cli.py comandos de la CLI
pipeline.py PDF → parser → validación → redacción → escaneo residual
loader.py palabras con coordenadas, agrupadas en renglones
parsers/ un módulo por banco y producto
privacy/ detectores, diccionario, seudónimos, escáner residual
validate/ conciliación contable
models/ raw.py (interno, con PII) y statement.py (salida pública)
tools/ volcado enmascarado, métricas de corpus, guardia de git
tests/ pruebas y generadores de PDFs sintéticos
docs/ análisis, especificación, esquema, privacidad y layouts por banco
| Documento | Contenido |
|---|---|
| 01 · Análisis | Problema, datos personales en un estado de cuenta, marco legal, alternativas, requisitos |
| 02 · Especificación técnica | Arquitectura, CLI, parsers, pruebas, estado de implementación |
| 03 · Esquema de salida | Forma y semántica del JSON |
| 04 · Privacidad y redacción | Modelo de amenaza, capas, detectores, perfiles, riesgos residuales |
| 05 · Decisiones | Decisiones tomadas y preguntas abiertas |
| AGENT.md | Guía para agentes de IA |
| Layouts | BBVA débito · BBVA crédito · BanCoppel débito |
| CHANGELOG | Historial de versiones |
| Aviso legal · Seguridad | Límites de responsabilidad, advertencias de uso y reporte privado de problemas |
- Más bancos: Banorte, Santander, Nu y otros, conforme haya estados reales para validar.
- Consolidado multi-mes (
--consolidate) y detección de cargos recurrentes. - Categoría semántica opcional por movimiento (supermercado, streaming, gasolina…).
- Servidor MCP que exponga las mismas herramientas.
- OCR para estados de cuenta escaneados.
Apache 2.0: se distribuye tal cual, sin garantías, y el autor no es responsable por daños derivados de su uso. Este proyecto no está afiliado ni respaldado por BBVA México, BanCoppel ni ninguna otra institución financiera; los nombres de los bancos solo identifican los formatos que la herramienta puede leer. Ver NOTICE, el aviso legal y advertencias de uso y cómo reportar un problema de privacidad sin exponer datos.