Local MCP server that serves and validates bank-specific ISO 20022 clearing profiles.
Local MCP server that serves and validates bank-specific ISO 20022 clearing profiles. It provides access to ISO 20022 clearing profile data, with validation behavior tied to bank-specific “clearing profiles,” supporting use in payments and profile management workflows.
🛠️ Key Features
Serves bank-specific ISO 20022 clearing profiles
Validates those clearing profiles
Local MCP server
🚀 Use Cases
ISO 20022 payments workflows requiring clearing profile data
Bank-specific clearing profile validation in payments systems
Profile-focused integration where ISO 20022 clearing configurations are needed
⚡ Developer Benefits
MCP tooling around ISO 20022 clearing profile access and validation
Targets developers working with payments, clearing, and profiles
Built around topics including ISO 20022 and clearing
⚠️ Limitations
Source data does not specify available tools, tool count, methods, or detailed I/O formats
Source data does not confirm coverage beyond bank-specific ISO 20022 clearing profiles
A fully local, closed-world Model Context Protocol server that
manages, validates, and serves bank-specific ISO 20022 clearing profiles /
rule packs — the market-practice rules that sit beyond structural XSD
validation. It is a foundational member of the
ISO 20022 MCP Suite and a sibling of
iso20022-readiness-suite-mcp,
whose readiness gateway can consume the profiles this server serves.
The November 2026 milestones. As the major schemes (CBPR+, HVPS+, T2,
FedNow) tighten their ISO 20022 requirements — structured postal addresses
chief among them — a payment that was fine yesterday can be rejected
tomorrow. iso20022-bank-profile-mcp turns those scheme rules into
versioned, agent-callable clearing profiles: list_profiles and
get_profile serve them, lint_payload evaluates a payload against one,
and validate_profile_definition vets a bank-supplied rule pack. v0.0.2,
stdio by default (plus an optional OAuth 2.1 HTTP transport), 4 read-only
tools, premium rule-pack entitlement gating, Python 3.10+.
The Model Context Protocol (MCP) is an open standard that lets AI agents
and assistants discover and call external tools in a uniform way.
iso20022-bank-profile-mcp owns the market-practice profile layer of the
ISO 20022 MCP Suite: the scheme-specific and bank-specific rules a payment must
satisfy to clear, which live above the XSD and vary by clearing system.
A clearing profile is pure data — a profile_id, its market_practice,
the messages it supports, and a list of declarative custom_rules. The server
ships open baseline profiles (Generic, CBPR+, SEPA_Instant, FedNow) and
exposes four read-only tools to discover them, fetch them in full, lint a
payload against one, and validate a candidate rule pack.
It is a fully local, closed-world server: no network surface, no
sub-servers, no meta-client. Every tool computes from the bundled profile data
and returns typed, JSON-serialisable output; on any failure — a bad input, an
unparseable payload, an unknown profile — it returns an {"error": ...}
payload rather than raising into the client transport. XML payloads are parsed
with defusedxml only (no XXE / billion-laughs).
flowchart TD
A["MCP client<br/>(Claude Desktop, IDE, agent)"] -->|stdio| B["iso20022-bank-profile-mcp<br/>(clearing-profile server)"]
B --> C["ProfileEngine<br/>(bundled JSON + register() seam)"]
C --> D["Generic"]
C --> E["CBPR+"]
C --> F["SEPA_Instant"]
C --> G["FedNow"]
H["iso20022-readiness-suite-mcp<br/>(readiness gateway)"] -.consumes profiles.-> B
The ISO 20022 MCP Suite
iso20022-bank-profile-mcp is one of a set of coordinated, vendor-neutral MCP
servers for the ISO 20022 migration. Dependency ranges are kept aligned across
the suite, so the servers co-install cleanly in a single Python environment.
Parse bank statements (MT940/MT942 and camt) into structured, agent-friendly data
pip install bankstatementparser-mcp
Where the foundational servers each do one message job well and the readiness
gateway composes them, this server owns the clearing profiles: it manages,
validates, and serves the market-practice rule packs the rest of the suite
lints against.
Install
iso20022-bank-profile-mcp runs on macOS, Linux, and Windows and
requires Python 3.10+ and pip. It pulls in the MCP SDK, pydantic,
and defusedxml automatically — all published on PyPI.
sh
python -m pip install iso20022-bank-profile-mcp
Or run it without installing, straight from PyPI, with
uvx:
sh
uvx iso20022-bank-profile-mcp
Using an isolated virtual environment (recommended)
The command speaks MCP on stdin/stdout — it is meant to be launched by an MCP
client, not used interactively. The agent can then call the tools below.
You can also invoke the tools in-process — without a transport — straight
through the FastMCP instance. This mirrors what an agent receives over stdio;
everything is local, so no other servers are needed:
python
import asyncio
from iso20022_bank_profile_mcp import server
asyncdefmain() -> None:
asyncdefcall(name, args):
result = await server.server.call_tool(name, args)
content = result[0] ifisinstance(result, tuple) else result
return content[0].text if content else""# Which clearing profiles can I target?print(await call("list_profiles", {}))
# -> {"profile_id": "...", "market_practice": "...", "rule_count": ...}, ...# Lint a payload against a profile: a CBPR+ address missing its town.
payload = "<Document><PstlAdr><Ctry>DE</Ctry></PstlAdr></Document>"print(await call("lint_payload",
{"payload_content": payload, "profile_id": "CBPR+"}))
# -> {"profile_id": "CBPR+", "is_compliant": false,# "findings": [{"code": "CBPR_MISSING_TOWN", "locator": "TwnNm", ...}]}
asyncio.run(main())
Tools
All tools return JSON-serialisable data; on a domain, validation, or value
error they return an {"error": ...} payload rather than raising. Every tool
is a pure, local, read-only, idempotent, closed-world lookup — no network, no
sub-servers.
list_profiles — List the available clearing profiles as lightweight summaries (profile_id, market_practice, tier, entitled, supported_messages, rule_count). Use it to discover the profile_id values the other tools accept and see which ones the current caller is entitled to.
get_profile — Return one clearing profile in full, including its rule bodies. On a premium profile the caller must be entitled, otherwise it returns a BP_NOT_ENTITLED error (see Open-core vs premium).
lint_payload — Evaluate a raw ISO 20022 payload against a clearing profile and return the findings (a compliant payload yields none). Like get_profile, a premium profile requires an entitlement or it returns BP_NOT_ENTITLED.
validate_profile_definition — Validate a bank-supplied profile / rule-pack definition supplied as raw JSON, confirming its shape and that every rule uses a known assertion verb.
HTTP transport & authentication
stdio is the default and needs no authentication — one process per operator,
launched by the client, no network surface. For shared, multi-tenant
deployments the server also speaks an optional streamable-HTTP transport:
--bind defaults to 127.0.0.1:8080 (loopback-only), so exposing the server
beyond the host is an explicit opt-in (e.g. --bind=0.0.0.0:8080). The HTTP
transport refuses to start without authentication — it never serves an
unauthenticated endpoint. Two auth modes apply, strongest first:
OAuth 2.1 resource server (RFC 9728) — set
ISO20022_BANK_PROFILE_OAUTH_ISSUER and
ISO20022_BANK_PROFILE_OAUTH_AUDIENCE (both required), with optional
ISO20022_BANK_PROFILE_OAUTH_JWKS_URL (defaults to
<issuer>/.well-known/jwks.json) and ISO20022_BANK_PROFILE_OAUTH_SCOPES.
Every request must carry Authorization: Bearer <jwt>; the token is
validated against the JWKS and its iss / aud / exp / nbf / required
scopes. Failures are rejected 401 / 403 with an RFC 9728
WWW-Authenticate challenge, and protected-resource metadata is served at
/.well-known/oauth-protected-resource. This server validates tokens from
your existing authorization server (Okta, Auth0, Entra ID, …); running the
authorization server is out of scope.
Static dev-mode token — set ISO20022_BANK_PROFILE_TOKEN to a shared
secret; every request must then send Authorization: Bearer <secret>. This
is a single shared secret with no expiry and no scopes — intended for local
development, not production.
An optional X-MCP-Tenant request header is forwarded into the tool-visible
request context for multi-tenant scoping. See
docs/transport.md for the full setup.
How it fits the suite
This server is the profile authority for the ISO 20022 MCP Suite. The
sibling iso20022-readiness-suite-mcp
gateway scores and remediates payments against clearing profiles; those
profiles are exactly what this server manages, validates, and serves. Aligning
on one profile source keeps the readiness gateway and any bank's own tooling
evaluating a payment against the same market-practice rules.
The profile catalogue is extensible at the seam the whole suite shares. The
ProfileEngine loads the open baseline from bundled JSON with
ProfileEngine.from_bundled(), and exposes ProfileEngine.register(profile)
to add (or replace) a profile at runtime. A premium, bank-specific rule
pack is the same shape as a bundled profile — a ClearingProfile with a
profile_id, a market_practice, its supported_messages, and a list of
custom_rules — so a deployment that embeds this server can register its
licensed packs and serve them alongside the open baseline without changing the
tool surface. See docs/profiles.md for the rule
mini-language and the register() seam.
Open-core vs premium
The server is open core: the baseline scheme profiles and the profile
engine are open source and always available. Higher-tier, institution-specific
capabilities are commercial add-ons that plug into the same profile-engine seam
(the engine already exposes a register() hook for runtime-loaded rule packs).
Entitlement gate for premium profiles (tier, scopes, allowlist)
Open Source
Bank-specific / proprietary scheme rule packs
Paid
Stateful profile-version history & audit logs
Paid
Nothing in the open-source tier is time-limited or feature-gated.
How the entitlement gate works
Every clearing profile carries a tier: "open" (the baseline profiles —
unrestricted and always accessible) or "premium" (a licensed rule pack). A
bundled premium sample profile, ACME_Premium, ships so you can exercise
the gate. list_profiles reports each profile's tier and a per-caller
entitled boolean; get_profile and lint_payload on a premium profile
return a BP_NOT_ENTITLED error unless the caller is entitled.
Entitlement is granted by either of two independent sources (ORed):
OAuth scope (HTTP transport) — a token bearing the profile:premium
scope is entitled to every premium profile; a token bearing
profile:<profile_id> is entitled to just that one.
Environment allowlist (stdio / dev) — ISO20022_BANK_PROFILE_ENTITLEMENTS
lists the premium profile_id values (comma- or space-separated) the
operator is licensed for; * grants all of them.
sh
# stdio: license the ACME_Premium sample pack for this process
ISO20022_BANK_PROFILE_ENTITLEMENTS=ACME_Premium iso20022-bank-profile-mcp
The gate ships in this release; the premium rule packs themselves (and
stateful version history / audit logs) remain a paid, out-of-tree concern.
See docs/profiles.md for the full entitlement model.
When not to use iso20022-bank-profile-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).
You need structural XSD validation or message generation. Those live in
the foundational suite servers (iso20022-mcp, camt053-mcp,
pain001-mcp). This server evaluates market-practice rules above the XSD;
it does not parse, generate, or structurally validate messages.
You want an end-to-end readiness score and remediation. That is the job
of iso20022-readiness-suite-mcp, which consumes these profiles. Use it if
you want scoring, remediation, and bank-response simulation composed
together.
You need a long-lived network service without auth. stdio is the default
(one process per operator, no network surface); the optional
HTTP transport exists for shared,
multi-tenant deployments but always requires authentication (OAuth 2.1 or a
static dev-mode token) — it will not serve an unauthenticated endpoint.
You need streaming responses. Tool calls return whole values, not
streams.
git clone https://github.com/sebastienrousseau/iso20022-bank-profile-mcp.git && cd iso20022-bank-profile-mcp
mise install
poetry install
poetry shell
Note: the server is fully local and closed-world, so the test suite runs
with nothing else installed. See CONTRIBUTING.md.
A Makefile orchestrates the quality gates (kept in lockstep with CI):
bash
make check # all gates (REQUIRED before commit): lint + type-check + test
make test# pytest (100% line + branch coverage)
make lint # ruff + black
make type-check # mypy --strict
make security # bandit
Security
iso20022-bank-profile-mcp returns errors as data — every tool catches the
documented domain, validation, and value errors and returns an
{"error": ...} envelope; it never propagates raw exceptions to the MCP
client. Payloads reached through the clearing-profile engine are parsed with
defusedxml only (no XXE / billion-laughs), and the server opens no network
sockets. Reporting practice, supported versions, the attack surface, and the
full supply-chain posture (SLSA L3 provenance, PEP 740 attestations, SBOMs, and
the NIST SP 800-218 SSDF practice mapping) are documented in
SECURITY.md. Vulnerabilities go via GitHub Private
Vulnerability Reporting, not public issues.