MCP server for ISO 20022 camt.053 bank-to-customer statement parsing and reconciliation.
A Model Context Protocol (MCP) server for ISO 20022 camt.053 bank-to-customer statement parsing and reconciliation. Provides modular, extensible parsing and reconciliation workflows for bank statements in camt053 format, enabling integration with AI agents and downstream financial tooling.
๐ ๏ธ Key Features
ISO 20022 camt053 statement parsing and reconciliation
MCP server implementation for model-context workflows
Topics include fintech, bank-statement, and llm integration
Python-based tooling with focus on compatibility and extensibility
Reversing-entry and treasury-oriented use cases
๐ Use Cases
Automated parsing of bank-to-customer statements
Reconciliation workflows for financial operations
AI-agent assisted financial data processing
Integration with Claude or other LM frameworks for modeling contexts
โก Developer Benefits
Clear MCP server structure for model-context protocols
Grounded in ISO 20022 camt053 standards
Reusable components for parsing, validation, and reconciliation
Documentation-oriented repository with readme excerpts and badges
โ ๏ธ Limitations
Source data provides a readme excerpt and badges; detailed API surface not fully enumerated here
Specific implementation details beyond parsing and reconciliation are not described in the excerpt
A Model Context Protocol server that exposes the camt053
ISO 20022 Bank Statement library as tools for AI agents and assistants โ
discover message types and return reasons, inspect input schemas, validate
records and financial identifiers, parse incoming statements, and generate
validated reversing-entry XML, all from your favourite MCP client.
Latest release: v0.0.14 โ OAuth 2.1 resource-server auth (RFC 9728)
on the HTTP transport, Prometheus metrics, a tamper-evident audit chain,
and real-HTTP load benchmarks; 22 MCP tools over stdio or authenticated
streamable HTTP, all backed by the shared camt053.services layer,
for Python 3.10+.
See what's new โ
The Model Context Protocol (MCP) is an open standard that lets AI agents
and assistants discover and call external tools in a uniform way. camt053-mcp
is an MCP server that turns the camt053 library into a set of
first-class agent tools, so an assistant can read and reverse ISO 20022
camt.05x cash-management messages โ the standardised bank-to-customer
account reports, statements, and debit/credit notifications โ directly from a
conversation.
The headline capability is the one-shot reversing-entry workflow: read an
incoming camt.053 statement, find the entries carrying a return reason code
(e.g. AC04 Closed Account), and emit a validated reversing entry.
Every tool is a thin, typed wrapper over camt053.services โ the single shared
facade also used by the CLI and REST API โ so all interfaces behave identically.
Tools return JSON-serialisable data; on an error they return an
{"error": ...} payload rather than raising.
camt053-mcp โ this package, the Model Context Protocol server
camt053-lsp โ the Language Server Protocol server for editors
flowchart LR
A["MCP client<br/>(Claude Desktop, IDE, agent)"] -->|stdio| B["camt053-mcp"]
B -->|delegates to| C["camt053.services"]
C -->|parse + reverse + validate| D["ISO 20022 camt.053 XML"]
The ISO 20022 MCP Suite
camt053-mcp is the bank-statement flagship of eight coordinated,
vendor-neutral MCP servers that together cover the ISO 20022
bank-statement workflow and the November 2026 structured-address
cutover โ statement depth, whole-catalogue routing, reconciliation,
multi-format ingestion, and address remediation. Dependency ranges are kept
aligned across the suite, so the servers co-install cleanly in a single
Python environment: start with one, add the rest as your workflow grows.
ISO 20022 postal-address classification, assessment & remediation for the November 2026 structured-address cutover, plus a high-level orchestration layer โ readiness scoring, clearing-profile linting, and audit evidence (pacs.008 / pain.001 debtor & creditor addresses)
9 MCP tools
pip install structured-address-fix-mcp
You need debtor/creditor addresses cliff-ready ahead of 14 Nov 2026
Compiles readiness findings, remediation diffs and simulated responses into a sealed, Ed25519-signable audit evidence pack
6 MCP tools
pip install iso20022-evidence-pack-mcp
You need tamper-evident audit / certification artifacts
In one line each: camt053-mcp is the bank-statement flagship
(deepest camt.05x surface, stdio + authenticated streamable HTTP);
iso20022-mcp is the generic message toolkit (a handful of verbs
over the whole catalogue); reconcile-mcp is the reconciliation
workflow (did the money we expected actually arrive?);
bankstatementparser-mcp is the ingestion layer (many formats in,
one transaction shape out); and structured-address-fix-mcp is the
postal-address specialist (debtor/creditor addresses cliff-ready for the
Nov 2026 cutover).
The suite also includes per-family servers โ
pain001-mcp
(credit transfer initiation),
pacs008-mcp
(FI-to-FI credit transfers), and
acmt001-mcp
(account management) โ reachable through the iso20022-mcp gateway.
Install
camt053-mcp runs on macOS, Linux, and Windows and requires Python 3.10+
and pip. It pulls in the core camt053 library and the MCP SDK
automatically.
sh
python -m pip install camt053-mcp
Using an isolated virtual environment (recommended)
The agent can then call the tools below to parse incoming statements and
generate validated reversing entries on demand.
For a shared, multi-tenant deployment, the server can also serve
streamable HTTP with mandatory bearer-token auth and optional
per-request Camt053-Account tenant scoping:
list_rulebook_clauses โ List the available rulebook citations (optionally filtered)
search_rulebook_vector โ Find rulebook clauses by natural-language similarity when you do not know the clause id (needs the [vector] extra)
export_journal โ Export statement entries as Xero BankTransactions or QBO JournalEntry payloads
list_export_journal_targets โ List the accounting-platform targets export_journal supports
classify_entry โ Classify a statement entry via MCP Sampling (uses the client's LLM)
list_classify_entry_categories โ List the default categories classify_entry uses
get_tenant_context โ Report the multi-tenant scope of the call (the Camt053-Account header on the HTTP transport; None over stdio)
parse_statement โ Parse an incoming camt.05x statement into data
detect_statement_anomalies โ Screen a statement for duplicate references, unusual fee deductions, and velocity spikes (deterministic rules, no model or network)
list_entries โ List every entry across all statements (paginated)
filter_entries โ Return entries carrying a return reason code (paginated)
generate_reversal โ Generate a validated reversing-entry XML document
Pagination
list_entries and filter_entries accept optional offset (default 0) and
limit (default None) parameters. When limit is omitted they return the
full list, exactly as before. When limit is given they return a paginated
envelope instead:
A negative offset or limit returns an {"error": ...} payload, consistent
with the rest of the server's error convention.
Prompts
Prompt
Purpose
reversal_preview
Guide an agent through a safe, confirm-before-generate reversal workflow
reconcile_against_pain001
Match booked statement entries to the originating pain.001 batch on EndToEndId, surface exceptions
find_duplicate_entries
Flag exact + suspected duplicates on a statement with confidence and next-action hints
match_to_invoice_set
Match incoming credits to an AR invoice ledger (exact + remittance + partial / multi-invoice tiers)
reversal_preview takes an optional reason_code (default "AC04") and
returns a four-step message template: parse the statement, preview the matching
entries with filter_entries, confirm with the operator, then call
generate_reversal. The other three prompts take no parameters and return a
two-message user-prompt + assistant-walkthrough template the agent can replay
verbatim.
Resources
Resources give an agent read-only reference context it can load without
calling a tool. Each resource returns a JSON payload.
Resource URI
Contents
camt053://return-reasons
The ISO external return-reason catalog โ a list of {"code", "name"}
camt053://message-types
The supported camt.05x message types โ a list of {"message_type", "name"}
camt053://session/{session_id}/bank/{bic}
Templated per-(session, bank) context: parsed BIC country/kind, recommended SEPA / CBPR+ / HVPS+ rulebook clauses, Nov 2026 cutover date
Both back onto the shared camt053.services layer, so they stay in sync with
the equivalent list_return_reasons / list_message_types tools. On an error
they return a serialised {"error": ...} payload.
Rulebook search
cite_rulebook needs a scheme, version and clause id. When you know
what a rule is about but not what it is called,
search_rulebook_vector closes that gap:
Take the winning scheme/version/clause and pass it to
cite_rulebook for the full citation.
It is not a neural embedding model. Retrieval is a deterministic
lexical-vector cosine search: each clause and the query are hashed into a
fixed 256-dimension term-frequency vector โ whole words plus character
3- and 4-grams, so address matches addresses without a stemmer โ
bucketed with BLAKE2b rather than Python's salted hash, and ranked with
sqlite-vec. That has three consequences worth knowing:
The same query always returns the same ranking, in every process and
every CI run.
Nothing is downloaded and no network call happens at query time.
It matches wording, not meaning. A query sharing no vocabulary with a
clause will not find it, however related the concepts are.
Only the curated summaries are indexed โ the same ones behind
cite_rulebook. No external, copyrighted, or auth-gated rulebook text is
stored or searched.
Installing it
sqlite-vec ships in an optional extra and is imported lazily, so the
base install pulls in nothing:
sh
python -m pip install 'camt053-mcp[vector]'
Without it the tool returns a plain error payload naming the extra
rather than raising, so a client that calls it on a base install gets a
usable message instead of a stack trace.
There is a second requirement that is easy to miss: your Python must be
built with loadable SQLite extension support. The python.org macOS
installers and several distribution packages ship it disabled, in which
case sqlite-vec installs perfectly and still cannot load. The tool
detects that and says so, naming the build flag
(--enable-loadable-sqlite-extensions) to look for. Homebrew, uv and
pyenv builds normally have it enabled.
You can invoke the tools in-process โ without a transport โ straight through the
FastMCP instance. This mirrors what an agent receives over stdio. The runnable
version of this snippet lives in examples/mcp_tools.py.
python
import asyncio
from camt053_mcp.server import server
# A complete camt.053 statement with one entry returned AC04 (Closed Account).
statement_xml = """<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.14">
<BkToCstmrStmt>
<GrpHdr><MsgId>STMT-MSG-0001</MsgId><CreDtTm>2026-06-15T08:00:00</CreDtTm></GrpHdr>
<Stmt>
<Id>STMT-0001</Id><CreDtTm>2026-06-15T08:00:00</CreDtTm>
<Acct><Id><IBAN>GB29NWBK60161331926819</IBAN></Id><Ccy>EUR</Ccy></Acct>
<Bal><Tp><CdOrPrtry><Cd>CLBD</Cd></CdOrPrtry></Tp>
<Amt Ccy="EUR">10000.00</Amt><CdtDbtInd>CRDT</CdtDbtInd>
<Dt><Dt>2026-06-15</Dt></Dt></Bal>
<Ntry>
<NtryRef>NTRY-0001</NtryRef>
<Amt Ccy="EUR">1500.00</Amt><CdtDbtInd>CRDT</CdtDbtInd>
<Sts><Cd>BOOK</Cd></Sts>
<NtryDtls><TxDtls>
<RtrInf><Rsn><Cd>AC04</Cd></Rsn></RtrInf>
</TxDtls></NtryDtls>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>"""asyncdefmain() -> None:
asyncdefcall(name, args):
result = await server.call_tool(name, args)
# mcp 2.x returns a CallToolResult (read .content); 1.x# returns the content list, or a (content, meta) tuple.
content = getattr(result, "content", None)
if content isNone:
# mcp 2.x returns a CallToolResult (read .content); 1.x# returns the content list, or a (content, meta) tuple.
content = getattr(result, "content", None)
if content isNone:
content = result[0] ifisinstance(result, tuple) else result
return content[0].text if content else""# Validate an identifier.print(await call("validate_identifier",
{"kind": "bic", "value": "NWBKGB2LXXX"}))
# -> {"kind": "bic", "value": "NWBKGB2LXXX", "valid": true}# Page through the matching entries (paginated envelope).print(await call("filter_entries",
{"xml": statement_xml, "reason_code": "AC04",
"offset": 0, "limit": 5}))
# -> {"total": 1, "offset": 0, "limit": 5, "entries": [...]}# Generate a validated reversing-entry document for the AC04 entries.
xml = await call("generate_reversal",
{"xml": statement_xml, "reason_code": "AC04"})
print(xml[:46]) # -> <?xml version="1.0" encoding="UTF-8"?> ...
asyncio.run(main())
Run it directly:
sh
python examples/mcp_tools.py
The camt053 suite
camt053-mcp is part of a set of independently installable packages
built around the camt053 library โ pick whichever ones
your stack needs:
Every tool here is a thin typed wrapper over camt053.services โ
the same facade the CLI, REST API, and LSP use โ so all four
interfaces behave identically.
When not to use camt053-mcp
You have no MCP client. This server only makes sense paired
with an MCP-aware host (Claude Desktop, the IDE plugins, an agent
framework). For scripted / CI use, the camt053 CLI and REST API
cover the same ground without the stdio protocol overhead.
You need to run as a long-lived daemon without an MCP client.
The server does run persistently over the streamable HTTP transport
(--transport=http), but every consumer must still speak MCP
JSON-RPC. For plain REST semantics, use the camt053 FastAPI service.
You need streaming responses. Tool calls return whole values,
not streams. Large statements are paginated through the existing
list_entries(xml, offset, limit) envelope, not chunked over
multiple responses.
You need per-user OAuth flows brokered for you. The HTTP
transport authenticates callers (OAuth 2.1 resource server with
RFC 9728 metadata, or a static bearer token in dev mode) and scopes
requests via the Camt053-Account tenant header, but it does not
run an authorization server: bring your own IdP.
You need to generate pain.001 outbound payment files. Out of
scope; use pain001-mcp.
git clone https://github.com/sebastienrousseau/camt053-mcp.git && cd camt053-mcp
mise install
poetry install
poetry shell
A Makefile orchestrates the quality gates (kept in lockstep with CI):
bash
make check # all gates (REQUIRED before commit)
make test# pytest
make lint # ruff + black
make type-check # mypy --strict
Security
camt053-mcp is a thin wrapper โ every tool delegates to
camt053.services, where the defence-in-depth (defusedxml +
xml_guard byte cap + DOCTYPE / ENTITY pre-flight) lives. Tools
catch (ValueError, Camt053Error) and return an {"error": ...}
envelope per the suite convention; they never propagate raw
exceptions to the MCP client. Reporting practice, supported
versions, and the full supply-chain posture are documented in
SECURITY.md. Vulnerabilities go via GitHub Private
Vulnerability Reporting, not public issues.