contabridge-mcp
This server lets you convert, validate, build, and export bookkeeping/journal and bank-statement data between Spanish accounting formats and QuickBooks/Xero, with free format/account/pricing helpers.
Convert libro diario files among A3, ContaPlus CSV/ASCII, generic CSV, QuickBooks IIF/CSV, and Xero CSV, with auto-detection, account resizing/mapping, renumbering, date styles, Xero tax rates, and strict validation.
Validate journals for import: balanced entries, debit/credit line rules, PGC account groups, fiscal year, mixed subaccount lengths, and optional parsed entries.
Turn Norma 43 bank statements into journal entries using ordered rules, suspense account for unmatched movements, multi-account mapping, value dates, and export to supported formats.
Build journal entries from supplied data and export them to any supported format, refusing unbalanced entries before charging.
Convert Norma 43 statements into Xero or QuickBooks Online bank statement CSVs.
Use free helpers to resize/expand Spanish subaccounts, detect import format, view tool pricing, and check remaining credits.
Converts bookkeeping journals to and from Sage ContaPlus / Sage 50 formats, including the Diario CSV of 142 fields and XDiario ASCII, with import-compatible output and validation of ContaPlus-style journal checks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@contabridge-mcp convert this A3 SUENLACE.DAT to ContaPlus CSV with 8-digit accounts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
contabridge-mcp
An MCP server that moves bookkeeping between Spanish accounting programs and QuickBooks / Xero, built for AI agents that work for gestorías and accounting firms with many clients. It does not store any data between calls, and every result is deterministic.
Tool | Credits | What it does |
| 2 | Converts a libro diario between a3ASESOR/a3ECO/a3CON ( |
| 3 | Books issued and received invoices (and rectificativas) with VAT, recargo de equivalencia and IRPF split out (430/700/477, 600/472/4751/400). Checks base + IVA - IRPF = total; invoices that do not add up go to |
| 3 | Turns a Norma 43 statement, the bank's CSV export or a movements list into journal entries against the 572 subaccount. Pending invoices ( |
| 3 | Reads a digital bank statement PDF (selectable text: Revolut, Wise, N26, CaixaBank, BBVA, Santander... downloaded from online banking) deterministically, with no OCR and no AI. Checks every row against the running balance (previous balance + amount = printed balance) and opening + in - out = closing; rows that do not add up are flagged, rows whose sign cannot be proven go to |
| 2 | Writes entries the agent composed (invoices, payroll, accruals) in any of the formats. |
| 1 | Turns a Norma 43 statement into a bank statement CSV for Xero (precoded template) or QuickBooks Online (3 columns). |
| 1 | Runs the checks A3 and ContaPlus run on import: balanced entries, debit or credit on each line (never both), PGC groups, fiscal year, mixed account lengths. |
| 0 | Free helpers. |
Output files are returned as content and as content_base64. The base64 version is Windows-1252 with CRLF line endings (UTF-8 with BOM for CSV), which is what these programs import.
Charging works like this:
A file that would be rejected (unbalanced, unreadable, missing columns) is refused before any credits are charged.
A failure after charging is refunded.
Formats and sources
A3: "Enlace contable de entrada. Descripción de registros" (Wolters Kluwer). Record type 0, format 5 (512 bytes) and format 4 (256 bytes). When reading, invoice records (types 1, 2 and 9) are skipped and reported in a warning.
ContaPlus: "Protocolo de comunicación de programas de gestión con ContaPlus" (Sage, 2023). Writes Asien, Fecha, SubCta, Contra, Concepto, Documento, MonedaUso=2, EuroDebe and EuroHaber. The fixed-width ASCII variant (32 fields) uses the same layout as the open-source BulmaGés exporter.
ContaSol: "Importación Excel / Calc" (Software DELSOL, GIP.C.01.10 rev. 9, 2023), Apuntes file
APU.ods, columns A to Q, no header row, MonedaE, Diario0. The.odsbytes are deterministic. Import it in ContaSol from Utilidades > Importaciones. Subaccounts must have the company's digits: passaccount_digits.QuickBooks Desktop IIF:
GENERAL JOURNALtransactions (!TRNS/!SPL/!ENDTRNS, tab separated). Debits are positive and credits negative, so the TRNS amount is minus the sum of its SPL lines. Other IIF lists (accounts, customers) are skipped with a warning.QuickBooks Online: "Import journal entries" CSV with
Journal No., Journal Date, Account Name, Debits, Credits, Description, Name.Xero: "Import a manual journal" template (
*Narration, *Date, Description, *AccountCode, *TaxRate, *Amount, tracking). Lines with the same Narration and Date form one journal.xero_tax_ratesets the TaxRate as named in that organisation (UKNo VAT, AUBAS Excluded, NZNo GST, USTax Exempt).QuickBooks and Xero dates follow
date_style:mdy(default for QuickBooks),dmy(default for Xero) oriso. Amounts use a decimal point, and a comma is always read as a thousands separator. Their accounts are names or codes, so they are validated against their own chart, not the PGC. Useaccount_mapto translate them when converting to or from A3/ContaPlus.CSV: columns are detected in Spanish and English (
fecha,cuenta,debe,haber,importe+d/h…), or set withcolumn_map. A file without an entry number is grouped into entries by accumulating lines until they balance.
Related MCP server: ledgerkit-mcp
Install
All you need is your KeyFlint license (LIC-...). The gateway URL, its public key and the checkout link have defaults.
Claude Desktop, one click: download contabridge-mcp-X.Y.Z.mcpb from the latest release, double-click it and paste your license. No terminal, no JSON.
Claude Code:
claude mcp add contabridge -e KEYFLINT_LICENSE=LIC-... -- uvx contabridge-mcpCursor, Windsurf, Claude Desktop (JSON):
{
"mcpServers": {
"contabridge": {
"command": "uvx",
"args": ["contabridge-mcp"],
"env": { "KEYFLINT_LICENSE": "LIC-..." }
}
}
}Optional: KEYFLINT_URL, KEYFLINT_PUBLIC_KEYS (fetched from the gateway and cached in ~/.keyflint/keyring.json when unset), KEYFLINT_CHECKOUT_URL.
Hosted mode: CONTABRIDGE_TRANSPORT=http contabridge-mcp --http (license per request, Authorization: Bearer LIC-...).
Tuning: CONTABRIDGE_PRICES (convert_journal=3,bank_to_journal=5), CONTABRIDGE_MAX_BYTES.
Visual cards (MCP Apps)
In Claude, ChatGPT, VS Code and Goose every paid tool and credits_balance renders as an interactive card in the
chat: credit balance with a refill bar and a buy button, or a result summary (key figures, issues, table preview and
credits charged). It is the ui://contabridge/card.html resource, self-contained with no network access. Other clients
keep getting the same JSON as before.
Claude skill
skills/contabridge/SKILL.md (zipped in distribution/contabridge-skill.zip) tells the agent which tool to use, which account length to ask for, and how to save the file.
Tests
pip install -e '.[test]' && pytestThe tests use a fake KeyFlint gateway and locally signed licenses, so they need no network. A3 and ContaPlus layouts are checked position by position against the official specifications.
License
Business Source License 1.1. Source available; production use needs a KeyFlint license (or must be non-commercial). Each version becomes Apache 2.0 four years after release. See LICENSE.
Available Tools
11 toolsbank_statement_csvConvert bank statement to bank-feed CSVARead-onlyIdempotentInspect
Turn a Norma 43 (Cuaderno 43) statement into a bank statement CSV that Xero or QuickBooks Online import.
target: xero (precoded statement: *Date, *Amount, Payee, Description, Reference) or quickbooks (3 columns: Date, Description, Amount). Amounts are signed (abono +, cargo -). date_style: mdy | dmy | iso (default mdy for QuickBooks, dmy for Xero). account: last digits of one bank account when the file holds several.
Inputs: target (required), account, content, date_style, +1 more. Returns: object
bank_to_journalBook Norma 43 bank statement as journalARead-onlyIdempotentInspect
Turn a bank statement (Norma 43, the bank's Excel/CSV export, or a movements list) into journal entries.
One entry per movement: abono -> Debe bank / Haber counterpart; cargo -> Debe counterpart / Haber bank.
The counterpart comes from the first matching rule; with no match it goes to suspense_account
(default 555 'partidas pendientes de aplicación', padded to the bank account length) and the movement is
listed in unmatched, so nothing is guessed.
Args: bank_account: The 572 subaccount of the bank, e.g. "57200001" (for QuickBooks/Xero: that program's bank account name or code, and suspense_account is then required). target_format: csv (default) | a3 | contaplus_csv | contaplus_ascii | contasol | quickbooks_iif | quickbooks_csv | xero_csv. content / content_base64: The .n43 file (base64 for CP850/Latin-1 bytes), or the bank's CSV export (Excel saved as CSV: a header row with fecha + importe, or cargo + abono, and concepto). movements: Instead of a file, [{"date": "2026-03-05", "amount": "-121.00", "text": "IBERDROLA"}] for statements read from Excel or PDF (+ money in, - money out). open_items: Pending invoices to settle FIRST, before rules: [{"account": "43000012", "amount": "1210.00", "reference": "F-2026-031", "name": "Talleres Ruiz", "date": "2026-02-28"}]. Signed as the bank sees it (+ cobro de cliente, - pago a proveedor). A movement is booked against the customer/supplier subaccount only on the same amount AND a unique reference or name in the bank text (or a unique amount within window_days). Ties are listed in open_items.ambiguous and never guessed. invoices_to_journal returns these items ready to pass here. rules: Ordered list, first match wins. Each: {"account": "62800000", "contains": ["IBERDROLA"] or "regex": "...", "common_concept": "03" (AEB concept, e.g. 03 recibos, 04 transferencias, 12 comisiones), "direction": "cargo"|"abono", "concept": optional fixed text}. Text matching is case-insensitive over the movement description (own concept + record-23 texts). bank_accounts: For files with several bank accounts: {IBAN or last digits: "57200002"}. use_value_date: Date entries by value date instead of operation date. account_digits / account_split: Resize every subaccount (see convert_journal). start_entry_number: First entry number (default 1).
Inputs: bank_account (required), rules, content, a3_format, +15 more. Returns: object
build_journalBuild journal import fileARead-onlyIdempotentInspect
Write journal entries you composed (e.g. from invoices or a payroll summary) as an import file.
entries: [{"date": "2026-03-31", "number": 1 (optional), "lines": [{"account": "64000000", "debit": "1500.00", "concept": "Nómina marzo"}, {"account": "47510000", "credit": "225.00"}, ...]}]. Entries must balance: an unbalanced entry is refused before any charge, with the difference. target_format accepts every format of convert_journal, including quickbooks_iif, quickbooks_csv and xero_csv (date_style / xero_tax_rate as there).
Inputs: entries (required), target_format (required), a3_format, date_style, +7 more. Returns: object
convert_journalConvert journal between accounting programsARead-onlyIdempotentInspect
Convert a libro diario (journal) between Spanish accounting programs.
Formats: a3 (a3ASESOR/a3ECO/a3CON SUENLACE.DAT, apuntes tipo 0), contaplus_csv (Sage ContaPlus / Sage 50
Diario CSV, 142 fields), contaplus_ascii (XDiario.txt fixed width), contasol (ContaSol APU.ods, destination only:
save content_base64 as APU.ods and import it in Utilidades > Importaciones), csv (spreadsheet with header:
Holded, Excel, any ERP; columns auto-detected, override with column_map), quickbooks_iif (QuickBooks
Desktop general journal), quickbooks_csv (QuickBooks Online journal import), xero_csv (Xero manual
journal import). The source is auto-detected. QuickBooks/Xero accounts are names or codes, not PGC
subaccounts: use account_map to translate them when converting to or from A3/ContaPlus.
Args: target_format: a3 | contaplus_csv | contaplus_ascii | contasol | csv | quickbooks_iif | quickbooks_csv | xero_csv. content: The file as text. content_base64: raw bytes as base64 (Latin-1/CP1252 files with Ñ). source_format: auto (default) or one of the formats. account_digits: Resize every subaccount to this length (ContaPlus uses a fixed length, e.g. 8); also expands '430.1' shorthand. 0 keeps them. account_split: Where zeros are inserted/removed when resizing (default 4: 4300001 -> 43000001). account_map: Exact account renames applied first, e.g. {"5720001": "57200005"}. start_entry_number: Renumber entries from this number (ContaPlus requires numbers; A3 does not use them). company_code: A3 company code (1-99999). a3_format: 5 (512-byte records, current) or 4 (256, old). column_map: For csv sources, e.g. {"debit": "Importe D", "account": "Cta"}. Keys: number, date, account, account_name, debit, credit, amount, dh, concept, document. csv_delimiter: For csv source/target; auto-detected on read, ';' on write. decimal_comma: csv output with decimal comma (Spanish Excel). fiscal_year: flag dates outside it. strict: Refuse to write a file with validation errors (default), so the target program never rejects it. date_style: Dates in QuickBooks/Xero files, read and write: mdy (US, QuickBooks default), dmy (UK/AU/NZ, Xero default) or iso. xero_tax_rate: TaxRate written on every Xero line, as named in that Xero organisation (UK "No VAT", AU "BAS Excluded", NZ "No GST", US "Tax Exempt").
Inputs: target_format (required), strict, content, a3_format, +13 more. Returns: object
credits_balanceCheck credit balanceBRead-onlyInspect
Remaining credits on your KeyFlint license. Free.
Inputs: no named parameters. Returns: object
detect_formatDetect accounting file formatBRead-onlyIdempotentInspect
Tell which accounting import format a file is (a3, contaplus_csv, contaplus_ascii, csv, quickbooks_iif, quickbooks_csv, xero_csv). Free.
Inputs: content, content_base64. Returns: object
invoices_to_journalBook invoices with VAT as journalARead-onlyIdempotentInspect
Book issued and received invoices (facturas emitidas y recibidas) as journal entries with VAT split out.
Read each invoice (PDF, photo, Facturae, email) yourself and pass its figures; this tool does the bookkeeping deterministically. Per invoice: {"kind": "issued"|"received", "number": "F-2026-031", "date": "2026-02-28", "nif": "B12345678", "name": "Talleres Ruiz SL", "taxes": [{"base": "1000.00", "rate": "21", "vat": "210.00" (optional, checked), "recargo_rate": "5.2" (optional)}], "irpf_rate": "15" or "irpf_amount": "150.00" (optional), "total": "1060.00" (optional but recommended: checked), "account": "43000012" (optional), "counterpart_account": "62300000" (optional, default 700 / 600), "concept": optional}. Shortcut for one VAT rate: "base" + "vat_rate". Negative amounts = factura rectificativa (sides swap).
Issued: Debe 430 total (+ 473 IRPF retenido por el cliente) / Haber 700 base + 477 IVA. Received: Debe 600
base + 472 IVA / Haber 4751 IRPF + 400 total. Tax is recomputed (base x rate, half up); a 1-cent difference
with the invoice total is absorbed in the largest tax line, more than that sends the invoice to review
with the reason, unbooked. Duplicates (same kind + NIF + number) also go to review.
Args: accounts: Override default roots {customers 430, suppliers 400, sales 700, purchases 600, vat_output 477, vat_input 472, irpf_withheld 4751, irpf_suffered 473}. party_accounts: {NIF: subaccount}, e.g. {"B12345678": "43000012"}. Invoices with no account are booked to the generic 430/400 and listed in generic_party_account so the accountant assigns them. vat_accounts: {rate: subaccount}, e.g. {"21": "47700021", "10": "47700010", "re5.2": "47700052"}. target_format / account_digits / company_code / ...: as in build_journal.
Returns the import file, vat_summary (base and cuota per rate for the libro registro / modelo 303),
vat_register (one row per invoice and rate), review and open_items to pass to bank_to_journal.
Inputs: invoices (required), accounts, a3_format, date_style, +10 more. Returns: object
pdf_bank_to_journalBook bank statement PDF as journalARead-onlyIdempotentInspect
Read a digital bank statement PDF (Revolut, Wise, N26, CaixaBank, BBVA, Santander... downloaded from online banking, with selectable text) and turn it into journal entries or a Norma 43 file.
Deterministic: the movements table is located by its header (Fecha, Concepto, Cargo/Abono or Importe, Saldo)
and each value is read from its column. No OCR and no AI: scanned PDFs are refused, not guessed. Every row is
checked: previous balance + amount = printed balance, and opening + money in - money out = closing balance.
Rows that do not add up are booked but listed in flagged_rows with status "mismatch"; rows whose sign
(cargo/abono) cannot be proven go to status "review" and are NOT booked. Check balance_check.balanced.
Args: content_base64: The PDF file bytes in base64. target_format: contasol (APU.ods, default) | a3 | contaplus_csv | contaplus_ascii | csv | quickbooks_iif | quickbooks_csv | xero_csv | norma43 (a .n43 file to import in any program that reads Cuaderno 43). bank_account: The 572 subaccount of the bank (default 57200001). rules / suspense_account / open_items / window_days: As in bank_to_journal. strict_balance: true refuses to produce any file (and charges nothing) unless every row and the closing balance add up. account_ccc: For norma43 when the PDF has no Spanish IBAN: 20-digit CCC for record 11. holder: Account holder name for the Norma 43 header (optional).
Inputs: content_base64 (required), rules, holder, a3_format, +15 more. Returns: object
pricingShow tool pricesARead-onlyInspect
Credit price of each tool and where to buy credits. Free.
Inputs: no named parameters. Returns: object
resize_accountResize PGC subaccountARead-onlyIdempotentInspect
Resize or expand a Spanish subaccount code. Free. '430.1' -> '43000001'; 4300001 (7) -> 43000001 (8).
Inputs: digits (required), account (required), split. Returns: object
validate_journalValidate journal before importARead-onlyIdempotentInspect
Check a journal file the way A3/ContaPlus check it on import, before you send it.
Reports unbalanced entries (with the difference), lines with both or neither debit and credit, non-numeric
accounts or accounts outside PGC groups 1-9, mixed subaccount lengths and dates outside fiscal_year.
valid is false when any error is found. include_entries returns the first 50 entries parsed.
QuickBooks/Xero files are checked against their own chart (any non-empty account), not the PGC.
Inputs: content, column_map, date_style, fiscal_year, +4 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Each tool has a distinct input source (existing file, composed entries, bank statement file, bank PDF, invoice figures), so the journal-producing tools are mostly separable. However, bank_statement_csv vs convert_journal's `csv` target, and pdf_bank_to_journal vs bank_to_journal, are close enough that an agent could pick wrong; resize_account also duplicates a convert_journal argument.
The core domain tools follow a clean verb_noun pattern (convert_journal, validate_journal, build_journal, bank_to_journal, detect_format, resize_account). Minor deviations: bank_statement_csv is a noun phrase and the meta tools pricing / credits_balance are noun-only, breaking the pattern slightly.
11 tools is well within the sweet spot, and every tool maps to a real step in the Spanish accounting import workflow (detect, validate, convert, build, bank, invoices, plus free utility/credit tools). No filler tools are present.
The surface covers detection, validation, format conversion, banking, invoicing, and account helpers, which is strong lifecycle coverage for a conversion server. The notable gap is a full structured-extraction/parse tool (validate_journal only returns the first 50 entries), so reading an arbitrary journal back into data is a partial dead end.
Maintenance
Related MCP Connectors
Parse Spanish Norma 43 bank statements, reconcile against invoices, validate IBAN/NIF/SEPA ids.
Spanish Veri*factu invoicing: create invoices, expenses and VAT returns from your AI assistant.
Spanish autónomo bookkeeping and AEAT tax forms 303, 130, 390, 100: your model reads the documents
Open-source AI accounting skills verified by licensed accountants (tax, VAT, payroll).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to read and write Cynco accounting data, including querying books, creating invoices, reconciling transactions, and generating financial reports.8 npm1MIT
- AlicenseAqualityDmaintenanceEnables AI agents to interact with a double-entry ledger, offering tools for account management, balanced journal entries, balance queries, trial balance, and penny-perfect allocation. Built with safety by construction: no update/delete tools, idempotent posting, and an append-only journal.7MIT

BeeL MCP serverofficial
AlicenseAqualityBmaintenanceEnables 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.136480 npm2MIT- AlicenseAqualityBmaintenanceEnables AI assistants to interact with Quipu accounting data via natural language, including invoicing, expenses, contacts, and Spanish VAT reporting.1849 npmMIT