MCP server: reconcile ISO 20022 camt.053 statements against expected pain.001 payments -- explainable exact, partial, one-to-many and many-to-one matching.

reconcile-mcp: An MCP Server for ISO 20022 Cash Reconciliation

A Model Context Protocol server that matches expected payments(from pain.001 credit transfers) against observed booked entries (from acamt.053 statement) and returns an explainable reconciliation — exactmatches, short/over payments, split settlements (one-to-many), batch credits(many-to-one), and the residual unmatched items on each side, every matchcarrying a score and the reasons it was made.

Latest release: v0.0.1 — 7 MCP tools over stdio, pure-Python matchingengine, deterministic sandbox test-mode, for Python 3.10+. Part of theISO 20022 MCP suite: you own both sides of thematch.

Why this exists

Reconciliation is the treasury team's daily pain: did the money we expectedactually arrive, and which invoice does each credit belong to? It is rarelyone-to-one — customers underpay, settle an invoice in instalments, or a payoutaggregator sends one lump covering a dozen receivables. reconcile-mcp doesthis matching as an agent tool, and — critically for finance — shows itswork: every pairing comes with a numeric score and a plain list of thesignals (reference, amount, date, counterparty) that drove it.

Install

pip install reconcile-mcp
# or run without installing:
uvx reconcile-mcp

MCP client config (e.g. Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "reconcile": {
      "command": "reconcile-mcp"
    }
  }
}

Quick start (zero real data)

The server ships a sandbox test-mode: deterministic scenarios so you canrun the whole flow with no setup and no real cash data. One call gets you afull, explainable result:

run_sandbox_scenario(name="month_end")

returns a realistic mixed close — one clean match, one short payment, one splitsettlement, and an unexpected credit correctly left unmatched:

{
  "summary": {
    "expected_count": 3, "observed_count": 5,
    "matched_expected": 3, "unmatched_observed": 1,
    "matches_by_type": {"exact": 1, "amount_mismatch": 1, "one_to_many": 1},
    "fully_reconciled": false
  },
  "matches": [
    {"type": "amount_mismatch", "expected": ["INV-6002"], "observed": ["ENT-52"],
     "amount_delta": "-99.99", "confidence": "high",
     "reasons": ["reference exact", "amount close (delta -99.99)", "date +/-0d", "counterparty exact"]},
    {"type": "exact", "expected": ["INV-6001"], "observed": ["ENT-51"], "amount_delta": "0.00"},
    {"type": "one_to_many", "expected": ["INV-6003"], "observed": ["ENT-53", "ENT-54"],
     "reasons": ["amount sum of 2 entries"]}
  ],
  "unmatched_observed": ["ENT-55"]
}

List every scenario with list_sandbox_scenarios; load one to inspect or editits inputs with load_sandbox_scenario.

Bring your own data

Records are small canonical objects — id and amount required, everythingelse optional and used to sharpen matching:

{
  "id": "INV-1001",            // your reference / end-to-end id
  "amount": 1200.00,
  "currency": "EUR",           // ISO 4217
  "date": "2026-03-02",        // ISO-8601
  "counterparty": "Acme Ltd",
  "reference": "INV-1001"      // remittance / structured reference
}

Already using the rest of the suite? Feed parsed output straight in — theadapters map it for you:

  • normalize_pain001(document) → the expected side, frompain001-mcp.
  • normalize_camt053(document) → the observed side, fromcamt053-mcp.

Then call reconcile(expected, observed).

Tools

Tool What it does
reconcile Match expected payments against observed entries; full explainable report.
explain_match Score a single expected/observed pair with a per-signal breakdown (tuning aid).
normalize_pain001 Adapt parsed pain.001 output into canonical expected records.
normalize_camt053 Adapt parsed camt.053 output into canonical observed records.
list_sandbox_scenarios List the built-in test-mode scenarios and magic references.
load_sandbox_scenario Return one scenario's expected/observed inputs to inspect or edit.
run_sandbox_scenario Load a scenario and reconcile it in one call — the fastest first run.

How matching works

Each candidate pair is scored on four weighted signals, then classified:

  • Reference (0.45) — exact / partial equality of references and end-to-endids, normalised to bare alphanumerics.
  • Amount (0.35) — exact within tolerance, or a linearly-decaying closenesswith the delta reported.
  • Date (0.10) — proximity within a configurable window; neutral if unknown.
  • Counterparty (0.10) — token-set overlap of names; neutral if unknown.

Assignment is greedy, highest-score-first and fully deterministic (a totaltiebreak order), so the same inputs always produce the same result. Residualsare then tested for one-to-many (a bounded subset-sum: one expected settledby several entries) and many-to-one (one entry covering several expected).

Tune any of it via the options argument: abs_tol / rel_tol,date_window_days, high_threshold, review_threshold, currency_strict,enable_one_to_many, max_combination.

The ISO 20022 MCP suite

reconcile-mcp is the reconciliation layer of a family of vendor-neutral,Python-native ISO 20022 MCP servers:

Development

git clone https://github.com/sebastienrousseau/reconcile-mcp
cd reconcile-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e . && pip install pytest pytest-cov ruff black mypy
pytest                      # 100% branch coverage gate
ruff check reconcile_mcp tests && black --check reconcile_mcp tests && mypy reconcile_mcp

Licence

Licensed under the Apache License, Version 2.0.

mcp-name: io.github.sebastienrousseau/reconcile-mcp

MCP Server · Populars

MCP Server · New

    ROCTUP

    1C Metacode MCP Server

    MCP сервер с встроенным AI агентом для поиска по графу метаданных и кода конфигураций 1С

    Community ROCTUP
    nhevers

    r0x-os

    Official SDK, Claude Code plugin and facilitator docs for r0x, the x402 facilitator for Robinhood Chain.

    Community nhevers
    scarletkc

    Vexor

    A semantic search engine for files and code.

    Community scarletkc
    marmutapp

    SuperBased Observer

    Local-first cost & token tracking for Claude Code, Cursor, Codex & 23 more AI coding agents — proxy-accurate per-model spend, an MCP server your agent can query, and an opt-in team rollup. 100% local, no telemetry.

    Community marmutapp
    Intuition-Lab

    Persome

    Local-first macOS Runtime that turns cross-app activity into an inspectable personal model for MCP agents.

    Community Intuition-Lab