Skip to main content
Glama

camt053-mcp: An MCP Server for ISO 20022 Bank Statements

PyPI Version Python Versions License Tests Quality OpenSSF Scorecard OpenSSF Best Practices Documentation

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 →

Contents

Related MCP server: Pactus

Overview

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.

This package is part of the camt053 suite — a set of independently installable packages that share the camt053.services layer:

  • camt053 — the core library (CLI + REST API)

  • 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.

Server

Scope

Surface

Install

Use it when

camt053-mcp

ISO 20022 camt.053/camt.052 bank statements: parse, validate, filter, reverse; MT940/MT942 migration; CBPR+ readiness; journal export

24 MCP tools · 4 prompts · 3 resources

pip install camt053-mcp

You work with bank-to-customer statements end to end — this package, the suite's flagship

iso20022-mcp

Unified gateway: search / describe / validate / generate / parse meta-tools routed across the pain · pacs · camt · acmt families

7 meta-tools

pip install "iso20022-mcp[all]"

You want one entry point to every message family

reconcile-mcp

Matches expected pain.001 payments against observed camt.053 entries — exact, partial, one-to-many, many-to-one, every match scored and explained

7 MCP tools

pip install reconcile-mcp

You need explainable statement/payment reconciliation

structured-address-fix-mcp

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

iso20022-readiness-suite-mcp

Orchestration gateway: detect → structurally validate → clearing-profile lint → readiness score, plus automated remediation and pacs.002 bank-response simulation — a meta-client over the foundational servers

4 MCP tools

pip install iso20022-readiness-suite-mcp

You want one high-level readiness / orchestration entry point over the suite

iso20022-bank-profile-mcp

Manages, validates and serves bank-specific clearing profiles / rule packs (CBPR+, SEPA_Instant, FedNow, Generic); premium rule-pack entitlement gating

4 MCP tools

pip install iso20022-bank-profile-mcp

You lint payments against your own institution's market practice

iso20022-evidence-pack-mcp

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.

python -m pip install camt053-mcp
python -m venv venv
source venv/bin/activate        # macOS/Linux
venv\Scripts\activate           # Windows
python -m pip install -U camt053-mcp

Quick Start

For the 10-minute install → MCP client config → first conversation tutorial, see docs/quickstart.md.

Launch the server over stdio (the FastMCP default transport):

camt053-mcp

Register it with any MCP client (e.g. Claude Desktop) by adding it to the client's configuration:

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

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:

CAMT053_MCP_TOKEN=<secret> camt053-mcp --transport=http --bind=0.0.0.0:8080

See Multi-tenant HTTP deployment and the deployment cookbook.

Tools

All tools delegate to the shared camt053.services layer, so they behave identically to the CLI and REST API.

  • list_message_types — List the 3 supported camt.05x message types

  • list_return_reasons — List the ISO external return reason codes

  • get_required_fields — Required input fields for a message type

  • get_input_schema — Full input JSON Schema for a message type

  • validate_records — Validate flat records against a message type

  • validate_identifier — Validate an IBAN, BIC, or LEI

  • validate_statement — Validate a statement against its XSD and detect its type

  • convert_mt940_to_camt053 — MT940 → camt.053 migration: convert legacy SWIFT MT940 statement text into a camt.053 structure

  • convert_mt942 — MT942 → camt.052 migration: convert legacy SWIFT MT942 interim transaction report text into a camt.052 structure

  • check_cbpr_readiness — Flag CBPR+ Nov 2026 cliff issues in a statement

  • get_cbpr_cutover_date — Return the official CBPR+ cutover date (2026-11-16)

  • cite_rulebook — Quote a curated SEPA / CBPR+ / HVPS+ rulebook clause

  • 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:

{"total": 42, "offset": 10, "limit": 5, "entries": [/* ... */]}

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.

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:

search_rulebook_vector("structured address requirement", top_k=3)
{
  "query": "structured address requirement",
  "returned": 3,
  "results": [
    {
      "scheme": "HVPS+",
      "version": "2026",
      "clause": "structured-address-alignment",
      "title": "HVPS+ aligns with CBPR+ structured-address rule",
      "score": 0.702729,
      // ...
    }
  ]
}

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:

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.

See docs/vector-search.md for the retrieval design and its limits.

Using the tools

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.

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>"""


async def main() -> None:
    async def call(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 is None:
            # 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 is None:
                content = result[0] if isinstance(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:

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:

Package

Role

camt053

Core library + CLI + FastAPI REST API

camt053-mcp

Model Context Protocol server (this package)

camt053-lsp

Language Server Protocol server (for editors)

camt053-writer-xlsx

Excel .xlsx writer for parsed statements

camt053-loader-mt940

SWIFT MT940 → camt.053 loader

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.

Development

camt053-mcp uses Poetry and mise.

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):

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.

Documentation

Part of the ISO 20022 MCP Suite — open-source, Apache-2.0 licensed MCP servers for banking and financial-services AI agents:

Server

Purpose

pain001-mcp

Generate & validate ISO 20022 pain.001 payment files (v03–v12, pain.008, SEPA) with rulebook checks

pacs008-mcp

Generate, validate, parse & scheme-check ISO 20022 pacs.008 FI-to-FI credit transfers + Nov-2026 address linting

acmt001-mcp

Generate & validate ISO 20022 acmt account-management messages

noyalib-mcp

Lossless YAML 1.2 parsing, formatting & validation (Rust, 100% spec compliance)


MCP Registry

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


License

Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.

Contributing

Contributions are welcome — see the contributing instructions. Thanks to all contributors.

Acknowledgements

Built on the camt053 ISO 20022 Bank Statement library and the Model Context Protocol Python SDK.

Available Tools

24 tools
check_cbpr_readinessCheck CBPR+ Nov 2026 readinessA
Read-onlyIdempotent

Check a camt.053 statement against the CBPR+ Nov 2026 acceptance rules.

Use this to audit a statement for the business-rule changes (schema
version, structured postal addresses) enforced from the Nov 2026 cutover.
For plain XSD schema validity use ``validate_statement`` instead; for just
the cutover date use ``get_cbpr_cutover_date``.

A coordinated CBPR+ / Fedwire / CHAPS / T2 cutover lands on
**14-16 November 2026**: unstructured-only postal addresses get rejected,
``camt.110/111`` exceptions and investigations become mandatory, and T2S
R2026.NOV upgrades camt.053 / 054 to schema revision MR2026.

This tool walks the supplied payload and reports every issue that will
fail the Nov 2026 acceptance rules:

* **Schema version** vs the CBPR+ current set (``camt.053.001.08`` /
  ``camt.053.001.13``); ``.02``-``.07`` are flagged as deprecated
  warnings; unknown / non-camt.053 namespaces as errors.
* **Postal addresses**: every ``<PstlAdr>`` is classified as fully
  structured, hybrid, or **unstructured-only** (``<AdrLine>`` without
  ``<TwnNm>`` + ``<Ctry>`` siblings, the Nov 2026 reject case).

Returns a dictionary ``{"cbpr_ready": bool, "schema_version": str | None,
"checked_at": ISO-8601 UTC, "cutover_date": "2026-11-16",
"issues": [...], "summary": {...}}``. ``cbpr_ready`` is ``True`` iff no
``severity="error"`` issue was raised. An ``{"error": ...}`` envelope
is returned instead if the XML is malformed or refused by the
hardened pre-flight (DOCTYPE / ENTITY / oversized payload).

Args:
    xml: The raw camt.05x statement XML as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.05x statement XML document as a string, audited against the CBPR+ Nov 2026 acceptance rules (schema version and structured postal addresses). Rejected by the hardened pre-flight if it carries a DOCTYPE/ENTITY or is oversized.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description details the tool's behavior: it walks the payload, reports issues, returns a structured dictionary with error envelopes for malformed input, and specifies the pre-flight checks (DOCTYPE/ENTITY/oversized). No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed and well-structured with bullet points and bold text, but it is somewhat lengthy. Every sentence adds value, but it could be slightly more concise without losing critical information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully explains the return structure (dictionary with keys like cbpr_ready, schema_version, issues, etc.) and covers error cases. The single parameter is well-documented, and all behavioral aspects are addressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, but the description adds value by explaining the pre-flight rejection criteria and the audit context (e.g., 'audited against the CBPR+ Nov 2026 acceptance rules'). This goes beyond the schema's simple 'raw XML document' description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks a camt.053 statement against CBPR+ Nov 2026 acceptance rules. It uses a specific verb-resource pair ('check a statement') and distinguishes itself from related tools like validate_statement and get_cbpr_cutover_date.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool (audit for business-rule changes) and provides alternative tools for other cases (validate_statement for XSD validity, get_cbpr_cutover_date for cutover date alone). It gives clear, actionable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cite_rulebookCite payments rulebook clauseA
Read-onlyIdempotent

Return a curated payments-rulebook citation for a single clause.

Use this to quote one specific rule (with its canonical source URL) once
you know the ``scheme``/``version``/``clause``. To discover which clauses
exist first, call ``list_rulebook_clauses``.

Looks up one well-known rule across the SEPA, CBPR+, and HVPS+
rulebooks and returns a short summary together with the canonical
source URL so an agent can quote the rule and the operator can
verify it against the official document.

The registry is a curated convenience layer, not a verbatim
reproduction of copyrighted text. Always defer to ``source_url``
for authoritative wording before relying on a citation for
compliance or contractual decisions; the returned ``disclaimer``
field repeats this for the calling agent.

Args:
    scheme: One of ``"SEPA"``, ``"CBPR+"``, or ``"HVPS+"`` (case
        sensitive).
    version: The rulebook version (e.g. ``"2025"`` or ``"2026"``).
    clause: A kebab-case clause identifier from
        ``list_rulebook_clauses``.

Returns:
    A citation dict ``{"scheme", "version", "clause", "title",
    "summary", "source_url", "as_of", "disclaimer"}`` or an
    ``{"error": ...}`` payload if the citation is not in the
    registry.
ParametersJSON Schema
NameRequiredDescriptionDefault
clauseYesA kebab-case clause identifier (e.g. 'iban-only') as returned by list_rulebook_clauses for the chosen scheme and version.
schemeYesThe payments-rulebook scheme to cite (case-sensitive). Must be exactly one of: 'CBPR+', 'HVPS+', 'SEPA' (see list_rulebook_clauses).
versionYesThe rulebook version, e.g. '2025' or '2026'. Use list_rulebook_clauses to see which versions exist per scheme.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint as safe. The description adds crucial behavioral context: the registry is a curated convenience layer, not a verbatim reproduction; always defer to source_url; the disclaimer field repeats this. This goes beyond annotations to explain limitations and usage boundaries.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized into paragraphs with clear sections. It is concise (about 150 words) with no redundant sentences. Every sentence adds value: purpose, usage context, parameter guidance, and caveats. Front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 3 required params with full schema coverage, annotations, and no output schema, the description compensates by explicitly listing the return dict fields ('a citation dict {scheme, version, clause, title, summary, source_url, as_of, disclaimer}'). This gives the agent a complete picture of what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by clarifying case sensitivity for 'scheme', giving examples for 'version', and explaining that 'clause' should be a kebab-case identifier from list_rulebook_clauses. It connects parameters to the sibling tool, making the API more intuitive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a clear verb+resource: 'Return a curated payments-rulebook citation for a single clause.' It distinguishes itself from the sibling tool 'list_rulebook_clauses' by instructing the agent to use that first to discover clauses, showing a specific usage path.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('once you know the scheme/version/clause') and when not to ('To discover which clauses exist first, call list_rulebook_clauses'). It also provides guidance on deferring to the source URL for authoritative wording, which is critical for compliance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

classify_entryClassify entry via LLM samplingA
Read-only

Classify one statement entry into a category via MCP LLM Sampling.

Use this when you want a semantic, model-driven label for an entry (payroll,
fee, refund, …) rather than a deterministic rule match. Because it delegates
an LLM completion to the client it is open-world and non-idempotent; for the
fixed candidate categories it chooses from, call
``list_classify_entry_categories`` first.

Uses the **MCP Sampling** protocol primitive: the server (this
process) asks the *client* (the agent's host application) to
perform an LLM completion on the server's behalf, then receives
the model's structured response. Keeps every LLM call in the
operator's existing model contract (privacy, billing, audit).

The model is asked to choose exactly one category from
``categories`` (or :data:`camt053_mcp.classify.DEFAULT_CATEGORIES`
if ``None`` is passed) and return a structured
``{category, confidence, explanation}`` payload.

Clients that do not support Sampling will get an
``{"error": "..."}`` envelope and can fall back to a rules-only
classifier.

Args:
    ctx: The MCPServer Context (auto-injected; provides
        ``session.create_message``).
    entry: A statement entry dict (the shape returned by
        ``parse_statement`` / ``list_entries``).
    categories: The candidate categories. ``None`` uses the
        built-in default list (12 common payment buckets).

Returns:
    ``{"category", "confidence", "explanation"}`` on success or
    ``{"error": "..."}`` on Sampling failure / malformed model
    response / out-of-vocabulary category.
ParametersJSON Schema
NameRequiredDescriptionDefault
entryYesA single statement entry dict, in the shape returned by parse_statement / list_entries, to classify into one category.
categoriesNoThe candidate categories the model must choose exactly one from. None (the default) uses the built-in default list exposed by list_classify_entry_categories.

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description provides significant behavioral context: it explains the open-world, non-idempotent nature, the delegation to the client via MCP Sampling (with privacy/billing/audit implications), the error envelope format, and the success/failure return structure. Annotations already provide openWorldHint=true, idempotentHint=false, and readOnlyHint=true, which the description aligns with and expands upon (e.g., mentioning the error envelope and the need for client support). The description adds value beyond annotations but does not explicitly cover failure modes like rate limiting or retry behavior, which is minor.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is comprehensive but well-organized: it starts with a one-sentence summary, then adds usage context, a detailed protocol explanation, and finally structured Args/Returns sections. Every paragraph adds meaningful information without redundancy. The structure with clear section headers makes it scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a 2-parameter tool with nested objects, complex behavioral implications (delegating to client via Sampling, error cases), and no output schema, the description covers everything an agent needs: input expectations, prerequisites, failure modes, return format, and the non-idempotent nature. The description is thorough and leaves no critical gaps for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with detailed descriptions for both parameters. The description adds significant context on top: it specifies the exact shape of 'entry' (as returned by parse_statement / list_entries), explains the meaning of 'categories' (including the default None behavior and the built-in default list), and describes the return payload structure. It also clarifies the relationship with list_classify_entry_categories. This goes well beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (classify), the resource (one statement entry), and the mechanism (via MCP LLM Sampling). It distinguishes this from deterministic rule matching and explicitly contrasts with sibling list_classify_entry_categories. The purpose is immediately understandable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('when you want a semantic, model-driven label rather than a deterministic rule match'), mentions an important prerequisite (call list_classify_entry_categories first to get the fixed categories), and describes fallback behavior for clients without Sampling support. This is exemplary guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_mt940_to_camt053Convert legacy MT940 to camt.053A
Read-onlyIdempotent

Convert a legacy SWIFT MT940 statement into a camt.053 structure.

Use this as the Phase-1 migration wedge: SWIFT MT940 customer statements
retire in **November 2028**, so this tool bridges the gap by turning raw
MT940 text into the same JSON-serialisable camt.053 document shape that
``parse_statement`` returns (group header plus statements, each with its
account, balances, and entries). Downstream tools (``list_entries``,
``filter_entries``, ``classify_entry``, ``export_journal``) then work on the
result unchanged.

Wraps the ``camt053-loader-mt940`` library's ``parse_mt940``; the MT parsing
itself is delegated (no MT grammar is reimplemented here). The resulting
``ParsedDocument`` is serialised with the same ``to_dict()`` the server's
other parse tools use, so agents get a consistent structure. Nothing is read
from or written to disk.

Returns the converted document as a JSON-serialisable dict, or an
``{"error": ...}`` payload if the MT940 text cannot be parsed (e.g. a
missing ``:20:`` reference or a malformed balance / statement line).

Args:
    mt940_text: The raw MT940 statement text as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
mt940_textYesThe raw legacy SWIFT MT940 statement text as a string (``:20:`` / ``:25:`` / ``:28C:`` / ``:60F:`` / ``:61:`` / ``:86:`` / ``:62F:`` fields). Passed verbatim from the bank or ERP; no file path is accepted.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Description adds value beyond annotations: explains library delegation, no disk I/O, error return format with specific examples. Annotations already declare read/hint/idempotent; description reinforces safety and adds technical detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, well-structured into migration context and technical details. Slightly verbose but every sentence earns its place. Could be tightened slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all relevant aspects: purpose, usage context, error handling, relationship to siblings, technical implementation. Lacks detailed output structure but references parse_statement's shape and mentions return type.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a detailed description for the single parameter. Description's Args section mostly repeats the schema but adds context about expected MT940 fields. Baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Verb 'convert' + specific resources 'legacy MT940' and 'camt.053' clearly state the tool's function. Distinguishes from sibling 'parse_statement' by framing as a migration wedge for legacy format.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly recommends use as Phase-1 migration wedge with retirement date November 2028. States that downstream tools work on result unchanged, implying alternatives like 'parse_statement' for native camt.053.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_mt942Convert legacy MT942 to camt.052A
Read-onlyIdempotent

Convert a legacy SWIFT MT942 interim report into a camt.052 structure.

Use this as the Phase-1 migration wedge for intraday reporting: SWIFT MT94x
messages retire in **November 2028**, so this tool bridges the gap by
turning raw MT942 *Interim Transaction Report* text into the same
JSON-serialisable camt.052 (Bank-to-Customer Account **Report**) document
shape the server's parse tools return (group header plus statements, each
with its account, balances, and entries). MT942 is the intraday sibling of
MT940: where MT940 maps to camt.053 (end-of-day statement), MT942 maps to
camt.052, so the resulting ``message_type`` is ``camt.052.001.08``.
Downstream tools (``list_entries``, ``filter_entries``, ``classify_entry``,
``export_journal``) then work on the result unchanged.

Wraps the ``camt053-loader-mt942`` library's ``parse_mt942``; the MT parsing
itself is delegated (no MT grammar is reimplemented here). The resulting
``ParsedDocument`` is serialised with the same ``to_dict()`` the server's
other parse tools use, so agents get a consistent structure. Nothing is read
from or written to disk.

**Documented model limitation.** The ``camt053`` typed model is
camt.053-statement-oriented: it has no dedicated field for camt.052's
floor-limit (``<Lmt>``) or transaction-summary (``<TxsSummry>``) blocks.
Rather than drop that data, the loader surfaces it on the balance list using
clearly proprietary ``type_code`` values so consumers can recognise and
filter them: ``:34F:`` floor limits become ``FLIMD`` / ``FLIMC`` balances,
and ``:90D:`` / ``:90C:`` entry-count summaries become ``SUMD:<count>`` /
``SUMC:<count>`` balances (the ISO ``NbOfNtries`` count is encoded after the
colon; the sum is the balance ``amount``). See the loader's README.

Returns the converted document as a JSON-serialisable dict, or an
``{"error": ...}`` payload if the MT942 text cannot be parsed (e.g. a
missing ``:20:`` reference or a malformed floor-limit / summary / statement
line).

Args:
    mt942_text: The raw MT942 interim transaction report text as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
mt942_textYesThe raw legacy SWIFT MT942 interim transaction report text as a string (``:20:`` / ``:25:`` / ``:28C:`` / ``:34F:`` / ``:13D:`` / ``:61:`` / ``:86:`` / ``:90D:`` / ``:90C:`` fields). Passed verbatim from the bank or ERP; no file path is accepted.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare idempotent, read-only, non-destructive. Description adds significant details: wraps library, delegates parsing, returns dict or error, no disk access, and documents the model limitation with proprietary type_code values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with sections, front-loaded purpose. Slightly long due to detailed proprietary type_code explanation, but each sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive for a tool with parsing complexity and model limitation. Covers output format, error cases, and integration with downstream tools despite no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers 100% of the single parameter. Description adds meaning: specifies raw text format, lists expected field tags, and explicitly says no file path.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool converts MT942 to camt.052, with a specific verb-resource pair. Distinguishes from sibling tool convert_mt940_to_camt053 by explaining the mapping and use as a migration wedge.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes the context as Phase-1 migration wedge for intraday reporting during the MT94x phase-out. Notes downstream tools. Lacks explicit when-not-to-use, but context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detect_statement_anomaliesDetect statement anomaliesA
Read-onlyIdempotent

Screen a camt.05x statement for deterministic, rule-based anomalies.

Use this as a fast, explainable first pass over an incoming statement
before deeper review or reversal. It applies three fixed heuristics over
the parsed entry list (see ``list_entries``) and never calls out to a model
or the network, so the same statement always yields the same result:

* **Duplicate references** (severity ``HIGH``) -- two or more entries share
  an end-to-end id (or, absent one, an entry reference), a classic
  double-payment signal.
* **Unusual fee deductions** (severity ``MEDIUM``) -- a fee/charge debit
  whose amount exceeds a fixed fraction (25%) of the largest ordinary
  transaction amount on the statement.
* **Velocity spikes** (severity ``LOW``/``MEDIUM``) -- a booking-date window
  whose entry count runs far above the statement's median per-window count.

Returns ``{"anomalies": [{"type", "severity", "detail", "entry_refs"}],
"checked_entries": <int>}``; ``anomalies`` is empty for a clean statement.
Returns an ``{"error": ...}`` payload instead if the XML cannot be parsed.

Args:
    statement_xml: The raw statement XML as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
statement_xmlYesThe raw camt.05x statement XML document as a string, with its root camt <Document> element. Every booked entry across all its statements is screened; no file path is accepted.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description adds meaningful behavioral detail: it never calls a model or network, is deterministic, applies three fixed heuristics with severity levels, and returns an error payload on unparseable XML. This gives the agent a precise model of what the tool will and will not do.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed but tightly organized: purpose, usage context, deterministic guarantee, three bulleted heuristics, and return shape. Every sentence adds necessary information, and the bullet list makes the heuristic rules easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully specifies the return payload shape, including the empty-anomalies case and the error case. It also references list_entries for context and documents the single input parameter via the schema, making the tool complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers the single parameter fully, including the requirement for raw XML with a root camt <Document> element and the exclusion of file paths. The description's Args section mostly restates this, adding no new parameter-level meaning beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Screen a camt.05x statement for deterministic, rule-based anomalies.' It clearly distinguishes this from sibling tools like parse_statement, validate_statement, and classify_entry by framing it as a fast, explainable first-pass anomaly detector over parsed entries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use it: 'as a fast, explainable first pass over an incoming statement before deeper review or reversal.' It does not name specific alternative tools or state when not to use it, but the context is clear enough for an agent to select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_journalExport statement to journal entriesA
Read-onlyIdempotent

Export a camt.053 statement as accounting-platform journal-entry payloads.

Use this to reshape a statement's booked entries into ready-to-POST Xero or
QuickBooks payloads (the tool builds the payloads only; it does not call any
external API or write files). To discover the valid ``target`` values first,
call ``list_export_journal_targets``.

Parses the supplied statement and re-shapes every booked entry
into a target-specific journal-entry payload ready for direct
POST to the accounting platform's REST API.

Supported targets (see ``camt053_mcp.export_journal.SUPPORTED_TARGETS``):

* ``"xero"`` - returns a list of Xero ``BankTransactions``
  payloads. Each entry maps to ``{Type, Reference, Date,
  BankAccount, Contact, LineAmountTypes, CurrencyCode,
  LineItems}``; CRDT entries become ``Type=RECEIVE`` and DBIT
  entries ``Type=SPEND``.
* ``"qbo"`` - returns a list of QuickBooks Online
  ``JournalEntry`` payloads. Each entry produces a balanced
  two-line journal (one to the bank account, one to a clearing
  account; sign flipped on debit entries).

Operator-specific values (account codes, contact identifiers,
realm IDs) appear as ``"OPERATOR_FILL"`` placeholders so the
operator knows exactly what still needs wiring. The response's
``placeholder_count`` field reports the total.

NetSuite + SAP S/4HANA targets are tracked as a follow-up in #17.

Args:
    xml: The raw camt.053 statement XML as a string.
    target: One of ``"xero"`` or ``"qbo"`` (default ``"xero"``).

Returns:
    ``{"target", "entries", "placeholder_count", "placeholder_field"}``
    on success, or ``{"error": ...}`` on failure (unsupported
    target / malformed XML / parse refusal).
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.053 statement XML document as a string; its booked entries are reshaped into journal-entry payloads.
targetNoThe accounting platform to shape journal-entry payloads for. Must be exactly one of: 'qbo', 'xero' (see list_export_journal_targets).xero

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds significant behavioral detail beyond annotations: it clarifies the tool does not call external APIs nor write files, describes the per-target output structure (Xero BankTransactions, QBO JournalEntry), explains placeholder fields, and notes unsupported targets. This fully compensates for the lack of detailed annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with a clear purpose first, followed by usage note, target details, and return format. It is slightly lengthy but every sentence contributes value. No unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's two parameters and lack of output schema, the description fully specifies the input, output structure (including fields like placeholder_count), constraints (unsupported targets), and prerequisites. It leaves no ambiguity for an agent invoking the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds value by explaining the behavior per target, the placeholder concept, and that valid target values can be discovered via a sibling tool, going beyond the enum list in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it exports a camt.053 statement as journal-entry payloads. It distinguishes itself by noting it does not call external APIs or write files, and it references the sibling tool 'list_export_journal_targets' for discovering valid targets, differentiating from that tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description indicates when to use the tool (to reshape statements into payloads for Xero or QBO) and advises calling 'list_export_journal_targets' first. It implicitly excludes actual posting, but doesn't explicitly state when not to use it or list alternatives beyond the sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filter_entriesFilter entries by reason codeA
Read-onlyIdempotent

List only the statement entries carrying a given return reason code.

Use this to preview exactly which entries a reversal would touch before
calling ``generate_reversal`` with the same ``reason_code``. For every entry
regardless of reason code use ``list_entries`` instead.

When ``limit`` is ``None`` (the default) the full list of matching entries
is returned, preserving the behaviour expected by existing callers. When
``limit`` is given, a paginated envelope ``{"total", "offset", "limit",
"entries"}`` is returned instead, exposing the ``offset:offset + limit``
slice. A negative ``offset`` or ``limit`` yields an ``{"error": ...}``
payload.

Args:
    xml: The raw statement XML as a string.
    reason_code: The ISO external return reason to match (default
        ``"AC04"`` Closed Account).
    offset: The zero-based index of the first entry to return (paginated
        mode only; default ``0``).
    limit: The maximum number of entries to return, or ``None`` for the
        full list (default ``None``).
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.05x statement XML document as a string; only its entries carrying the given return reason code are returned.
limitNoMaximum number of matching entries to return, starting at offset. None (the default) returns the full unpaginated list; a non-None value returns a {total, offset, limit, entries} envelope. Must be non-negative.
offsetNoZero-based index of the first matching entry to return. Applies only when limit is given; must be non-negative. Defaults to 0.
reason_codeNoAn ISO external return reason code, e.g. 'AC04' Closed Account. Must be exactly one of: 'AC01', 'AC02', 'AC03', 'AC04', 'AC06', 'AC13', 'AC14', 'AG01', 'AG02', 'AM01', 'AM02', 'AM03', 'AM04', 'AM05', 'AM06', 'AM07', 'AM08', 'AM09', 'BE01', 'BE05', 'CNOR', 'DNOR', 'DT01', 'ED01', 'ED05', 'FF01', 'MD01', 'MD06', 'MD07', 'MS02', 'MS03', 'NARR', 'NOAS', 'NOOR', 'RC01', 'RR01', 'RR02', 'RR03', 'RR04', 'SL01', 'TM01' (see list_return_reasons).AC04

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. Description adds critical behavioral details: the effect of limit=None (returns full list) vs non-None (pagination envelope), and error payload for negative offset/limit. This adds context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Approximately 150 words, well-structured: purpose sentence, usage tip, pagination behavior explanation, then bullet-like Args. Front-loaded with key info, no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 4 params (1 required), output schema exists, and annotations cover safety, the description fully documents both output modes (full list and paginated envelope) and error conditions. It also relates to sibling tools. Complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers all 4 params with descriptions (100% coverage), baseline 3. The description's Args section adds practical usage details: explains xml as 'raw statement XML', reason_code default 'AC04', and clarifies pagination behavior for offset and limit. This adds moderate value beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'List only the statement entries carrying a given return reason code.' It distinguishes from sibling 'list_entries' (all entries) and directly relates to 'generate_reversal' (preview before reversal). This is a specific verb+resource+scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit usage advice: 'Use this to preview exactly which entries a reversal would touch before calling generate_reversal' and 'For every entry regardless of reason code use list_entries instead.' Provides clear context and alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_reversalGenerate reversal documentA
Read-onlyIdempotent

Generate a validated camt.053.001.14 reversal document from a statement.

This is the headline one-shot workflow: pass an incoming statement and a
return-reason code and get back the reversal XML (nothing is written to
disk). Preview which entries will be reversed first with ``filter_entries``
using the same ``reason_code``.

This is the headline one-shot workflow: parse the incoming camt.053, pick
the entries with the requested return reason (e.g. AC04 Closed Account),
and emit a validated camt.053.001.14 reversal statement.

Returns the validated XML document as a string, or an ``{"error": ...}``
payload (serialized) if generation fails.

Args:
    xml: The raw incoming statement XML as a string.
    reason_code: The ISO external return reason to reverse (default
        ``"AC04"``).
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw incoming camt.053 statement XML document as a string; the entries carrying reason_code are reversed into a new camt.053.001.14 document.
reason_codeNoAn ISO external return reason code, e.g. 'AC04' Closed Account. Must be exactly one of: 'AC01', 'AC02', 'AC03', 'AC04', 'AC06', 'AC13', 'AC14', 'AG01', 'AG02', 'AM01', 'AM02', 'AM03', 'AM04', 'AM05', 'AM06', 'AM07', 'AM08', 'AM09', 'BE01', 'BE05', 'CNOR', 'DNOR', 'DT01', 'ED01', 'ED05', 'FF01', 'MD01', 'MD06', 'MD07', 'MS02', 'MS03', 'NARR', 'NOAS', 'NOOR', 'RC01', 'RR01', 'RR02', 'RR03', 'RR04', 'SL01', 'TM01' (see list_return_reasons).AC04

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint. Description adds that it returns validated XML or error, and that no data is written to disk. Some redundancy but adequate transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description contains duplication: the 'headline one-shot workflow' is stated twice with similar wording. The Args section repeats schema info. Could be more concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 2 parameters and output schema, the description explains input, output format, and workflow well. It references sibling tools. Minor gap: no mention of input validation or prerequisites.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions. The description adds minimal extra context (ISO reason code, default AC04, reference to list_return_reasons). Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool generates a validated camt.053.001.14 reversal document from a statement. It distinguishes from sibling tools like filter_entries (preview) and list_return_reasons.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states it's a one-shot workflow: pass xml and reason_code to get reversal XML, nothing written to disk. Recommends using filter_entries for preview first. Provides clear guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cbpr_cutover_dateGet CBPR+ cutover dateA
Read-onlyIdempotent

Return the official CBPR+ / Nov 2026 cutover date as ISO 8601.

Use this to quote the enforcement date directly, without parsing a
document. To actually audit a statement against the rules that take effect
on that date, call ``check_cbpr_readiness`` instead.

The cutover (``2026-11-16``) is the date after which the rules checked
by ``check_cbpr_readiness`` are enforced by the major clearing systems;
payments that fail will be rejected at receive-time. Surfaced as a
discrete tool so agents can quote it directly without having to call
a readiness check first.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds valuable behavioral context: it returns the specific date (2026-11-16), explains its enforcement significance, and notes that payments failing after that date are rejected. This enriches the agent's understanding beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, front-loaded with the core purpose, followed by usage guidelines and background context. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (no parameters, no output schema), yet the description provides complete context: the date's format, its role in enforcement, differentiation from the readiness tool, and the rationale for its existence. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is effectively 100%. Baseline is 4, and the description does not need to add parameter details. It appropriately focuses on the output and usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (Return), resource (official CBPR+ / Nov 2026 cutover date), and output format (ISO 8601). It distinguishes itself from the sibling tool check_cbpr_readiness by noting that this tool returns the date for quoting purposes, not for auditing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is provided: 'Use this to quote the enforcement date directly, without parsing a document.' and 'To actually audit a statement against the rules that take effect on that date, call check_cbpr_readiness instead.' This clearly tells when and when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_input_schemaGet input JSON SchemaA
Read-onlyIdempotent

Return the full JSON Schema for a message type's flat input record.

Use this to learn every field, its type, and its constraints before
assembling records, or to drive a form/UI. For just the required-field
names use ``get_required_fields``; to actually check records against this
schema use ``validate_records``.

Args:
    message_type: A supported ISO 20022 camt.05x message type.
ParametersJSON Schema
NameRequiredDescriptionDefault
message_typeYesA supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types).

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds context about returning a 'full JSON Schema for a flat input record', but does not disclose any additional behavioral traits beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences front-load the purpose, followed by clear usage guidance and parameter description. No superfluous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single parameter, no output schema, and low complexity, the description fully covers what the tool does, when to use it, and the parameter's meaning, leaving no gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with the schema already describing the 'message_type' parameter. The description adds value by referencing 'list_message_types' for valid values and clarifying its use in the context of ISO 20022 camt.05x messages.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Return' and the resource 'full JSON Schema for a message type's flat input record'. It distinguishes from siblings by mentioning 'get_required_fields' and 'validate_records'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use ('to learn every field... or to drive a form/UI') and when not to ('For just the required-field names... to actually check records...'), naming alternative tools directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_required_fieldsGet required input fieldsA
Read-onlyIdempotent

List only the required input field names for a camt message type.

Use this for a quick checklist of the mandatory columns before building
reversing-entry records. When you need full type/format constraints (not
just which fields are required), call ``get_input_schema`` instead.

Args:
    message_type: A supported ISO 20022 camt.05x message type.
ParametersJSON Schema
NameRequiredDescriptionDefault
message_typeYesA supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the behavioral safety is clear. The description adds context about returning only field names, which is transparent. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise: two sentences plus a pointer to the alternative tool. It is front-loaded with the action and resource, and every sentence serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (1 parameter with full enum, output schema exists), the description covers purpose, usage, and alternatives completely. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a detailed enum description. The description adds the usage purpose (for building reversing-entry records) but essentially restates the parameter type. This provides marginal added value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists required input field names for a camt message type. It distinguishes from the sibling get_input_schema by explaining the difference, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use this tool (quick checklist for reversing-entry records) and when to use the alternative get_input_schema (for full type/format constraints). This gives clear guidance to the AI agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_tenant_contextGet tenant scoping contextA
Read-onlyIdempotent

Return the multi-tenant scoping context of the current call.

Use this to confirm which tenant/account scope the server attributes
the session to. On the streamable-HTTP transport (D7, #42) the
``tenant`` field carries the value of the optional
``Camt053-Account`` request header the caller sent; over stdio (or
when the caller sent no header) it is ``None``. The same value is
stamped as the ``scope`` on the server's audit log, so an agent can
verify its calls are attributed to the right tenant.

The lookup is read-only and deterministic for a given request:
nothing is validated or mutated, and no external system is touched.

Args:
    ctx: The MCPServer Context (auto-injected; carries the underlying
        HTTP request, when there is one).

Returns:
    ``{"service": "camt053-mcp", "tenant": str | None}``.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations, which already declare read-only, idempotent, and non-destructive hints. It adds concrete behavioral details: the operation is deterministic for a given request, validates nothing, mutates nothing, and touches no external system. It also explains the transport-specific behavior (header vs. None) and the audit-log stamping. This rich context significantly aids the agent in predicting the tool's behavior and side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is succinct yet comprehensive. It front-loads the purpose in the first sentence, then systematically covers usage, transport behavior, side-effectfulness, the argument, and the return format. Every sentence earns its place, and there is no redundancy or filler. The structure is logical and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with no output schema, the description is fully complete. It specifies the exact return payload ({"service": "camt053-mcp", "tenant": str | None}), the behavior under different transports, and the audit-log relationship. An agent has all the information needed to invoke the tool correctly and interpret its result without any further lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema is empty. The description explicitly notes that the 'ctx' argument is auto-injected and carries the underlying HTTP request when present, which clarifies the only (implicit) input. Since there are no user-supplied parameters to document, this is complete. The description adds meaning beyond the empty schema by explaining the auto-injected context, so a baseline of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb-resource pair: 'Return the multi-tenant scoping context of the current call.' This clearly identifies the tool's function and distinguishes it from the sibling tools, none of which deal with tenant context retrieval. The purpose is unambiguous, so an agent can easily recognize when to use this tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case: 'Use this to confirm which tenant/account scope the server attributes the session to.' It also explains transport-dependent behavior and how the value maps to the audit log, giving an agent context on when this tool is relevant. However, it does not explicitly mention when not to use it or name alternatives, though no sibling appears to serve a similar purpose. Since the guidance is clear but lacks explicit exclusion language, it earns a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_classify_entry_categoriesList classifier categoriesA
Read-onlyIdempotent

List the default candidate categories the classify_entry tool uses.

Use this to quote the built-in category vocabulary to a user before running
the LLM classifier. This is a static list lookup (no model call); to
actually classify an entry, call ``classify_entry``.

Operators can override the list per call; this tool exposes the
default the prompt template ships with so an agent can quote them
to the user before invoking the classifier.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false. The description adds valuable context that the tool is a static list lookup with no model call, and that it exposes the default list. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no redundant information, front-loaded with main purpose, then usage context and clarification against sibling tool. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, an existing output schema (not shown), and low complexity, the description covers purpose, usage, and behavioral traits completely. It explains why you would call this tool and how it fits with classify_entry.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, and the input schema has 100% coverage. The description explains what the tool returns (list of default categories), which adds meaning beyond the schema. Baseline of 4 for zero params is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists the default candidate categories used by classify_entry, with specific verb 'list' and resource 'default candidate categories'. It distinguishes itself from the sibling classify_entry by noting it's a static lookup versus a model call.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: 'Use this to quote the built-in category vocabulary to a user before running the LLM classifier.' Also clearly excludes its use for classification: 'to actually classify an entry, call classify_entry.' Provides context about operator overrides.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_entriesList all statement entriesA
Read-onlyIdempotent

List every booked entry across all statements in a camt.05x document.

Use this to get the flat, paginable entry list from a statement. To keep
only the entries carrying a given return-reason code use ``filter_entries``;
for the full nested document structure use ``parse_statement``.

When ``limit`` is ``None`` (the default) the full list of entries is
returned. When ``limit`` is given, a paginated envelope ``{"total",
"offset", "limit", "entries"}`` is returned instead, exposing the
``offset:offset + limit`` slice. A negative ``offset`` or ``limit`` yields
an ``{"error": ...}`` payload.

Args:
    xml: The raw statement XML as a string.
    offset: The zero-based index of the first entry to return (paginated
        mode only; default ``0``).
    limit: The maximum number of entries to return, or ``None`` for the
        full list (default ``None``).
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.05x statement XML document as a string; every booked entry across all its statements is returned.
limitNoMaximum number of entries to return, starting at offset. None (the default) returns the full unpaginated list; a non-None value returns a {total, offset, limit, entries} envelope. Must be non-negative.
offsetNoZero-based index of the first entry to return. Applies only when limit is given; must be non-negative. Defaults to 0.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior. Description adds pagination mechanics, envelope structure, error handling for negative offset/limit, and default limit behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise and well-structured: purpose sentence, usage guidance, then parameter behavior with Args section. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers pagination modes, error handling, and key parameter defaults. With output schema present, no need to explain return values further. Complete for this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. Description adds value by detailing the paginated envelope format ('{"total","offset","limit","entries"}') and explaining default behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states 'List every booked entry across all statements in a camt.05x document' with a clear verb and resource. It explicitly distinguishes from sibling tools filter_entries and parse_statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Use this to get the flat, paginable entry list' and distinguishes from filter_entries and parse_statement for specific use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_export_journal_targetsList journal export targetsA
Read-onlyIdempotent

List the accounting-platform targets the export_journal tool supports.

Use this to tell a user which ``target`` values ``export_journal`` accepts
before invoking it. This lists export destinations only; for the LLM
classifier's category vocabulary use ``list_classify_entry_categories``.

Returns the sorted list of valid ``target`` arguments accepted by
``export_journal`` (``["qbo", "xero"]`` today). NetSuite and SAP
S/4HANA support is a tracked follow-up.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive. Description adds that it returns a sorted list of currently two values, and notes future support tracking, providing behavioral context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five concise sentences, each adding value: purpose, usage guidance, differentiation, return details, and future outlook. Front-loaded with main action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and presence of output schema (though not detailed), description covers purpose, usage, and return format adequately. Does not need to elaborate on return structure due to output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters in schema, baseline score 4 applies. Description adds no parameter explanation needed and correctly implies no arguments required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly identifies verb 'list' and resource 'accounting-platform targets'. Distinguishes from sibling tool 'list_classify_entry_categories' by specifying its different purpose (category vocabulary vs. export destinations).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states to use before invoking export_journal to inform user of valid target values. Contrasts with sibling tool but does not explicitly state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_message_typesList camt.05x message typesA
Read-onlyIdempotent

List every supported ISO 20022 camt.05x message type and its name.

Use this first, before any validation or generation call, to discover the
exact ``message_type`` strings this server accepts. For the return-reason
codes rather than message types, call ``list_return_reasons`` instead.

Returns a list of ``{"message_type": ..., "name": ...}`` dictionaries, one
per supported message type (e.g. ``camt.053.001.14``).
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the agent knows this is a safe, read-only, idempotent operation. The description adds the return format (list of dictionaries with 'message_type' and 'name' keys) and example value ('camt.053.001.14'), which is useful but does not contradict or significantly extend behavioral disclosure beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences long. Each sentence serves a distinct purpose: (1) states the primary action, (2) gives workflow placement, (3) distinguishes from a sibling, (4) describes the return format. There is no redundant or extraneous text. The information is front-loaded and well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters, annotations covering safety and idempotency, and an existing output schema), the description fully explains what the tool does, when to use it, and what it returns. It also references a related tool for completeness. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

This tool has zero parameters and schema coverage is 100%, so the schema already fully documents the input. The description adds meaning about the return format and usage context, which is sufficient for a parameterless tool. Baseline for zero parameters is 4, and the description meets that bar.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the verb ('list') and the resource ('every supported ISO 20022 camt.05x message type and its name'). It distinguishes from the sibling tool 'list_return_reasons' by specifying that this tool is for message types, not return-reason codes. The purpose is precise and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance: 'Use this first, before any validation or generation call, to discover the exact ``message_type`` strings this server accepts.' It also tells when to use an alternative: 'For the return-reason codes rather than message types, call ``list_return_reasons`` instead.' This leaves no ambiguity about the tool's role in the workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_return_reasonsList ISO return reason codesA
Read-onlyIdempotent

List every known ISO external return reason code with its name.

Use this to discover the ``reason_code`` values that ``filter_entries`` and
``generate_reversal`` accept (e.g. ``AC04`` Closed Account). For the
supported message types rather than reason codes, use ``list_message_types``.

Returns a list of ``{"code": ..., "name": ...}`` dictionaries (e.g.
``{"code": "AC04", "name": "Closed Account Number"}``).
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Description adds return format (list of {code, name} dictionaries) beyond annotations that already indicate readOnly, idempotent, non-destructive. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with main purpose, no fluff. Each sentence adds value (purpose, usage, alternative, return format).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with output schema, description fully explains what is returned with example. No gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so baseline is 4. Description does not need to add parameter info.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it lists ISO return reason codes with names, and distinguishes from sibling tool list_message_types by specifying different use cases.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use (to discover reason_code values for filter_entries and generate_reversal) and when not (use list_message_types for message types). Includes concrete example.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rulebook_clausesList rulebook clausesA
Read-onlyIdempotent

List the curated rulebook clauses the server can cite, optionally filtered.

Use this to browse the citation registry and pick a ``clause`` id; then pass
that id to ``cite_rulebook`` to fetch the full summary and source URL.

Returns the full registry, optionally filtered by ``scheme`` and /
or ``version``. Use the resulting ``clause`` values as input to
``cite_rulebook``.

Args:
    scheme: Restrict to one scheme (e.g. ``"SEPA"``). ``None``
        returns all schemes.
    version: Restrict to one version (e.g. ``"2026"``). ``None``
        returns all versions.
ParametersJSON Schema
NameRequiredDescriptionDefault
schemeNoRestrict the listing to one scheme. When given, must be exactly one of: 'CBPR+', 'HVPS+', 'SEPA'. None (the default) returns clauses for all schemes.
versionNoRestrict the listing to one rulebook version, e.g. '2026'. None (the default) returns clauses for all versions.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint. The description adds that the tool returns the full registry optionally filtered, and that the output feeds into another tool. No contradictions, and adds moderate context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise and well-structured: first sentence states purpose, then usage context with workflow, then parameter args. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, the description need not detail return structure. It sufficiently covers purpose, usage, parameter details, and its role in a broader workflow, making it complete for a simple listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, baseline 3. The description adds value by explaining how parameters filter the listing and that 'None' returns all, and explicitly links the output clause values as input to cite_rulebook, enhancing semantic understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and the resource 'curated rulebook clauses', with optional filtering. It distinguishes itself from sibling tools like cite_rulebook by positioning itself as a precursor to obtain clause IDs for that tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs when to use: 'Use this to browse the citation registry and pick a clause id; then pass that id to cite_rulebook'. Provides a clear workflow and mentions the return type.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

parse_statementParse camt.05x statement XMLA
Read-onlyIdempotent

Parse an incoming camt.05x statement XML string into structured data.

Use this to turn a raw statement into a navigable dict (header, statements,
accounts, balances, entries). To pull just the flat entry list use
``list_entries``; to only check the document is schema-valid use
``validate_statement``.

Returns the parsed document as a JSON-serialisable dict (group header plus
statements, each with its account, balances, and entries), or an
``{"error": ...}`` payload if the XML cannot be parsed.

Args:
    xml: The raw statement XML as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.05x statement XML document as a string, with its root camt <Document> element. Returned verbatim from the bank; no file path is accepted.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and idempotentHint=true. The description adds return format (JSON-serialisable dict or error) and clarifies input constraints (no file path). No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose, alternatives, and return value. No redundant sentences. Very concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description adequately explains the return structure and error handling. It covers the main use case. Could mention potential size limits or performance, but not critical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The parameter description adds meaning beyond schema: it specifies the XML must have root element, is verbatim from bank, and rejects file paths. Adds clear value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb 'Parse' and resource 'camt.05x statement XML' and distinguishes from siblings like 'list_entries' and 'validate_statement'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use this tool (to get structured data) and when to use alternatives like list_entries or validate_statement, with specific names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_rulebook_vectorSearch rulebook clauses by similarityA
Read-onlyIdempotent

Search the curated rulebook clauses by lexical-vector similarity.

Use this when you know *what* a rule is about but not its exact
``scheme``/``version``/``clause`` id: describe it in natural language and
get back the closest curated clauses, each with a similarity ``score``.
Then pass the winning ``scheme``/``version``/``clause`` to
``cite_rulebook`` for the full citation, or browse everything with
``list_rulebook_clauses``.

Retrieval is a **deterministic lexical-vector cosine** search over the
same curated SEPA / CBPR+ / HVPS+ summaries that back ``cite_rulebook``
(no external, copyrighted, or auth-gated rulebook text is indexed). Each
clause and the query are hashed into a fixed 256-dimension term-frequency
vector (whole words plus character 3/4-grams, BLAKE2b-bucketed so results
are reproducible across processes) and ranked by cosine distance with
``sqlite-vec``. It is offline and does **not** use a large neural
embedding model, so the same query always yields the same ranking and no
model download or network call happens at query time.

``sqlite-vec`` ships in the optional ``[vector]`` extra and is imported
lazily; when it is not installed this returns a graceful
``{"error": ...}`` payload asking the operator to
``pip install 'camt053-mcp[vector]'`` rather than failing to import.

Args:
    query: The natural-language search string.
    top_k: The maximum number of clauses to return (default ``5``,
        clamped to the corpus size).

Returns:
    ``{"query", "top_k", "returned", "method", "results", "disclaimer"}``
    where ``results`` is the ranked list of clause dicts (each with an
    added ``score``), or an ``{"error": ...}`` payload on a bad argument
    or a missing ``[vector]`` extra.
ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA natural-language search string (e.g. 'structured address requirement' or 'instant payment settlement time'). Matched against the curated SEPA / CBPR+ / HVPS+ clause summaries.
top_kNoMaximum number of clauses to return, ranked most-similar first. Clamped to the corpus size; must be positive. Defaults to 5.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations (readOnlyHint, idempotentHint, destructiveHint=false) already cover safety, and the description adds substantial behavior beyond that: deterministic/reproducible ranking, offline operation with no network call, no neural embedding model, and the graceful error when the optional [vector] extra is missing. It even explains the BLAKE2b/256-dim vector mechanics that guarantee identical results across processes. No contradiction with annotations — the deterministic claim aligns with idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: the one-line purpose and usage guidance come first, followed by behavioral detail and args. It is longer than average, with the technical vector/hashing explanation verging on verbose, but that detail earns its place by substantiating the determinism and offline guarantees an agent needs to trust the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates fully: the Returns section details the payload shape (query/top_k/returned/method/results/disclaimer), the ranked-clause format with added score, and both error modes (bad argument, missing [vector] extra). Combined with sibling routing and dependency caveats, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents both query and top_k richly, including the default 5 and clamping behavior. The description's Args section merely mirrors the schema without adding new meaning, which matches the baseline-3 rubric for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb, resource, and method: 'Search the curated rulebook clauses by lexical-vector similarity.' It also distinguishes itself from siblings by naming cite_rulebook (full citation after finding the id) and list_rulebook_clauses (browse everything), so an agent can immediately tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it: 'Use this when you know *what* a rule is about but not its exact scheme/version/clause id'. It then routes to the exact alternatives (cite_rulebook for citation, list_rulebook_clauses for browsing). This is textbook when/when-not guidance with named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_identifierValidate IBAN, BIC or LEIA
Read-onlyIdempotent

Validate a single financial identifier (IBAN, BIC, or LEI).

Use this for a one-off identifier check with a clear pass/fail. To validate
identifiers embedded across a whole batch of records, prefer
``validate_records`` rather than calling this per field.

Returns ``{"kind": str, "value": str, "valid": bool}``.

Args:
    kind: One of ``"iban"``, ``"bic"``, or ``"lei"`` (case-insensitive).
    value: The identifier value to check.
ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesThe financial identifier type to validate (case-insensitive). Must be exactly one of: 'bic', 'iban', 'lei'.
valueYesThe identifier value to check, matching the chosen kind (e.g. an IBAN, an 8- or 11-character BIC, or a 20-character LEI). Whitespace/case handling follows the underlying validator.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive. The description adds return format (JSON with kind, value, valid) and emphasizes clear pass/fail outcome. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, well-structured with clear sections, and every sentence adds value. No superfluous text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with no output schema, the description covers purpose, usage, return format, and argument details. Complete and sufficient for an agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and includes detailed descriptions (e.g., case-insensitivity for kind, examples for value). The description's Args section adds minimal new information beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool validates a single financial identifier (IBAN, BIC, or LEI), using specific verbs and resources. It distinguishes itself from the sibling validate_records by specifying single vs batch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use (one-off check) and when not to (batch), and provides the alternative validate_records. This meets the criteria perfectly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_recordsValidate records against schemaA
Read-onlyIdempotent

Validate flat records against a message type's input JSON Schema.

Use this on in-memory reversing-entry records to catch structural/type
errors per row before generation. To validate a whole camt.05x *document*
(XML) against its XSD instead, use ``validate_statement``.

Returns a report ``{"valid": bool, "total": int, "valid_count": int,
"errors": [...]}``.

Args:
    message_type: A supported ISO 20022 camt.05x message type.
    records: One or more flat reversing-entry records to validate.
ParametersJSON Schema
NameRequiredDescriptionDefault
recordsYesOne or more flat reversing-entry records (each a dict of field name to value) to validate row-by-row against the message type's input JSON Schema.
message_typeYesA supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types).

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, non-destructive, idempotent behavior. Description adds return format ('report with valid, total, valid_count, errors'), which provides useful context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise paragraphs: purpose, usage guidance, return format, then parameter descriptions. No fluff, well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter tool with no output schema and clear annotations, the description covers purpose, usage, return structure, and parameter details. Complete and sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%. Description adds context for both parameters: message_type explains supported values and references list_message_types; records explains they are flat and per row. This adds value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Validate flat records against a message type's input JSON Schema,' specifying action and resource. It distinguishes from sibling 'validate_statement' by noting that tool is for documents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use ('in-memory reversing-entry records per row before generation') and when not ('whole document... use validate_statement'), providing clear alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_statementValidate statement against XSDA
Read-onlyIdempotent

Validate an incoming camt.05x statement XML against its XSD schema.

Use this to confirm a document is well-formed and schema-valid before
processing it. This checks XSD conformance only; for the Nov 2026 CBPR+
business rules use ``check_cbpr_readiness``, and to extract the data use
``parse_statement``.

Detects the document's message type, validates it against the matching
ISO 20022 schema, and returns a report ``{"valid": bool, "message_type":
str, "errors": [...]}``. A well-formed but schema-invalid document yields
``valid=False`` with a populated ``errors`` list (and the detected
``message_type``); a valid one yields ``valid=True`` with no errors.

Returns an ``{"error": ...}`` payload instead if the XML cannot be parsed
(e.g. it is malformed or is not a camt ``Document``).

Args:
    xml: The raw statement XML as a string.
ParametersJSON Schema
NameRequiredDescriptionDefault
xmlYesThe raw camt.05x statement XML document as a string, with its root camt <Document> element. Validated against the matching ISO 20022 XSD; no file path is accepted.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. Description adds details about detecting message type, validating against matching schema, and return format including error payload. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is well-structured, efficient, and front-loaded. First sentence gives the main action. Uses clear formatting for the return value. No unnecessary sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Fully explains input, behavior, output format, and error cases. No output schema but the return structure is described clearly. Complete for the tool's purpose given annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a clear description for the single parameter 'xml'. Description reinforces what the parameter is but adds no additional semantics beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Validate' and the resource 'incoming camt.05x statement XML against its XSD schema'. It distinguishes from siblings by explicitly naming alternatives like check_cbpr_readiness and parse_statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use: 'to confirm a document is well-formed and schema-valid before processing it'. Also states what it does not do and provides alternatives: 'for the Nov 2026 CBPR+ business rules use check_cbpr_readiness, and to extract the data use parse_statement'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.0.16
    • Addeddetect_statement_anomalies
    • Addedsearch_rulebook_vector
  2. 1 tool updatev0.0.14
    • Addedget_tenant_context
  3. 11 tool updates
    • Changedcite_rulebook2 fields changed
      • changedInput schema / properties / scheme / description
        Previous value: -"The rulebook scheme to cite: one of 'SEPA', 'CBPR+', or 'HVPS+' (case-sensitive)."New value: +"The payments-rulebook scheme to cite (case-sensitive). Must be exactly one of: 'CBPR+', 'HVPS+', 'SEPA' (see list_rulebook_clauses)."
      • addedInput schema / properties / scheme / enum
        Added value: +[
        +  "CBPR+",
        +  "HVPS+",
        +  "SEPA"
        +]
    • Addedconvert_mt940_to_camt053
    • Addedconvert_mt942
    • Changedexport_journal2 fields changed
      • changedInput schema / properties / target / description
        Previous value: -"The accounting platform to shape payloads for: 'xero' (BankTransactions) or 'qbo' (QuickBooks Online JournalEntry). Defaults to 'xero'; call list_export_journal_targets for the current valid values."New value: +"The accounting platform to shape journal-entry payloads for. Must be exactly one of: 'qbo', 'xero' (see list_export_journal_targets)."
      • addedInput schema / properties / target / enum
        Added value: +[
        +  "qbo",
        +  "xero"
        +]
    • Changedfilter_entries2 fields changed
      • changedInput schema / properties / reason_code / description
        Previous value: -"The ISO external return reason code to match, e.g. 'AC04' Closed Account (the default). Call list_return_reasons for the full set of accepted codes."New value: +"An ISO external return reason code, e.g. 'AC04' Closed Account. Must be exactly one of: 'AC01', 'AC02', 'AC03', 'AC04', 'AC06', 'AC13', 'AC14', 'AG01', 'AG02', 'AM01', 'AM02', 'AM03', 'AM04', 'AM05', 'AM06', 'AM07', 'AM08', 'AM09', 'BE01', 'BE05', 'CNOR', 'DNOR', 'DT01', 'ED01', 'ED05', 'FF01', 'MD01', 'MD06', 'MD07', 'MS02', 'MS03', 'NARR', 'NOAS', 'NOOR', 'RC01', 'RR01', 'RR02', 'RR03', 'RR04', 'SL01', 'TM01' (see list_return_reasons)."
      • addedInput schema / properties / reason_code / enum
        Added value: +[
        +  "AC01",
        +  "AC02",
        +  "AC03",
        +  "AC04",
        +  "AC06",
        +  "AC13",
        +  "AC14",
        +  "AG01",
        +  "AG02",
        +  "AM01",
        +  "AM02",
        +  "AM03",
        +  "AM04",
        +  "AM05",
        +  "AM06",
        +  "AM07",
        +  "AM08",
        +  "AM09",
        +  "BE01",
        +  "BE05",
        +  "CNOR",
        +  "DNOR",
        +  "DT01",
        +  "ED01",
        +  "ED05",
        +  "FF01",
        +  "MD01",
        +  "MD06",
        +  "MD07",
        +  "MS02",
        +  "MS03",
        +  "NARR",
        +  "NOAS",
        +  "NOOR",
        +  "RC01",
        +  "RR01",
        +  "RR02",
        +  "RR03",
        +  "RR04",
        +  "SL01",
        +  "TM01"
        +]
    • Changedgenerate_reversal2 fields changed
      • changedInput schema / properties / reason_code / description
        Previous value: -"The ISO external return reason code whose entries are reversed, e.g. 'AC04' Closed Account (the default). Preview the matches with filter_entries using the same code; call list_return_reasons for all accepted codes."New value: +"An ISO external return reason code, e.g. 'AC04' Closed Account. Must be exactly one of: 'AC01', 'AC02', 'AC03', 'AC04', 'AC06', 'AC13', 'AC14', 'AG01', 'AG02', 'AM01', 'AM02', 'AM03', 'AM04', 'AM05', 'AM06', 'AM07', 'AM08', 'AM09', 'BE01', 'BE05', 'CNOR', 'DNOR', 'DT01', 'ED01', 'ED05', 'FF01', 'MD01', 'MD06', 'MD07', 'MS02', 'MS03', 'NARR', 'NOAS', 'NOOR', 'RC01', 'RR01', 'RR02', 'RR03', 'RR04', 'SL01', 'TM01' (see list_return_reasons)."
      • addedInput schema / properties / reason_code / enum
        Added value: +[
        +  "AC01",
        +  "AC02",
        +  "AC03",
        +  "AC04",
        +  "AC06",
        +  "AC13",
        +  "AC14",
        +  "AG01",
        +  "AG02",
        +  "AM01",
        +  "AM02",
        +  "AM03",
        +  "AM04",
        +  "AM05",
        +  "AM06",
        +  "AM07",
        +  "AM08",
        +  "AM09",
        +  "BE01",
        +  "BE05",
        +  "CNOR",
        +  "DNOR",
        +  "DT01",
        +  "ED01",
        +  "ED05",
        +  "FF01",
        +  "MD01",
        +  "MD06",
        +  "MD07",
        +  "MS02",
        +  "MS03",
        +  "NARR",
        +  "NOAS",
        +  "NOOR",
        +  "RC01",
        +  "RR01",
        +  "RR02",
        +  "RR03",
        +  "RR04",
        +  "SL01",
        +  "TM01"
        +]
    • Changedget_input_schema2 fields changed
      • changedInput schema / properties / message_type / description
        Previous value: -"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14'. Call list_message_types first to discover the exact accepted values."New value: +"A supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types)."
      • addedInput schema / properties / message_type / enum
        Added value: +[
        +  "camt.052.001.14",
        +  "camt.053.001.14",
        +  "camt.054.001.14"
        +]
    • Changedget_required_fields2 fields changed
      • changedInput schema / properties / message_type / description
        Previous value: -"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14'. Call list_message_types first to discover the exact accepted values."New value: +"A supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types)."
      • addedInput schema / properties / message_type / enum
        Added value: +[
        +  "camt.052.001.14",
        +  "camt.053.001.14",
        +  "camt.054.001.14"
        +]
    • Changedlist_rulebook_clauses2 fields changed
      • changedInput schema / properties / scheme / description
        Previous value: -"Restrict the listing to one scheme ('SEPA', 'CBPR+', or 'HVPS+'). None (the default) returns clauses for all schemes."New value: +"Restrict the listing to one scheme. When given, must be exactly one of: 'CBPR+', 'HVPS+', 'SEPA'. None (the default) returns clauses for all schemes."
      • addedInput schema / properties / scheme / enum
        Added value: +[
        +  "CBPR+",
        +  "HVPS+",
        +  "SEPA"
        +]
    • Changedvalidate_identifier2 fields changed
      • changedInput schema / properties / kind / description
        Previous value: -"The identifier type to validate: one of 'iban', 'bic', or 'lei' (case-insensitive)."New value: +"The financial identifier type to validate (case-insensitive). Must be exactly one of: 'bic', 'iban', 'lei'."
      • addedInput schema / properties / kind / enum
        Added value: +[
        +  "bic",
        +  "iban",
        +  "lei"
        +]
    • Changedvalidate_records2 fields changed
      • changedInput schema / properties / message_type / description
        Previous value: -"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14', whose input JSON Schema the records are checked against. Call list_message_types to discover accepted values and get_input_schema to see the constraints."New value: +"A supported ISO 20022 camt.05x message type string. Must be exactly one of: 'camt.052.001.14', 'camt.053.001.14', 'camt.054.001.14' (see list_message_types)."
      • addedInput schema / properties / message_type / enum
        Added value: +[
        +  "camt.052.001.14",
        +  "camt.053.001.14",
        +  "camt.054.001.14"
        +]
  4. 14 tool updatesv0.0.12
    • Changedcheck_cbpr_readiness1 field changed
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.05x statement XML document as a string, audited against the CBPR+ Nov 2026 acceptance rules (schema version and structured postal addresses). Rejected by the hardened pre-flight if it carries a DOCTYPE/ENTITY or is oversized."
    • Changedcite_rulebook3 fields changed
      • addedInput schema / properties / clause / description
        Added value: +"A kebab-case clause identifier (e.g. 'iban-only') as returned by list_rulebook_clauses for the chosen scheme and version."
      • addedInput schema / properties / scheme / description
        Added value: +"The rulebook scheme to cite: one of 'SEPA', 'CBPR+', or 'HVPS+' (case-sensitive)."
      • addedInput schema / properties / version / description
        Added value: +"The rulebook version, e.g. '2025' or '2026'. Use list_rulebook_clauses to see which versions exist per scheme."
    • Changedclassify_entry2 fields changed
      • addedInput schema / properties / categories / description
        Added value: +"The candidate categories the model must choose exactly one from. None (the default) uses the built-in default list exposed by list_classify_entry_categories."
      • addedInput schema / properties / entry / description
        Added value: +"A single statement entry dict, in the shape returned by parse_statement / list_entries, to classify into one category."
    • Changedexport_journal2 fields changed
      • addedInput schema / properties / target / description
        Added value: +"The accounting platform to shape payloads for: 'xero' (BankTransactions) or 'qbo' (QuickBooks Online JournalEntry). Defaults to 'xero'; call list_export_journal_targets for the current valid values."
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.053 statement XML document as a string; its booked entries are reshaped into journal-entry payloads."
    • Changedfilter_entries4 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of matching entries to return, starting at offset. None (the default) returns the full unpaginated list; a non-None value returns a {total, offset, limit, entries} envelope. Must be non-negative."
      • addedInput schema / properties / offset / description
        Added value: +"Zero-based index of the first matching entry to return. Applies only when limit is given; must be non-negative. Defaults to 0."
      • addedInput schema / properties / reason_code / description
        Added value: +"The ISO external return reason code to match, e.g. 'AC04' Closed Account (the default). Call list_return_reasons for the full set of accepted codes."
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.05x statement XML document as a string; only its entries carrying the given return reason code are returned."
    • Changedgenerate_reversal2 fields changed
      • addedInput schema / properties / reason_code / description
        Added value: +"The ISO external return reason code whose entries are reversed, e.g. 'AC04' Closed Account (the default). Preview the matches with filter_entries using the same code; call list_return_reasons for all accepted codes."
      • addedInput schema / properties / xml / description
        Added value: +"The raw incoming camt.053 statement XML document as a string; the entries carrying reason_code are reversed into a new camt.053.001.14 document."
    • Changedget_input_schema1 field changed
      • addedInput schema / properties / message_type / description
        Added value: +"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14'. Call list_message_types first to discover the exact accepted values."
    • Changedget_required_fields1 field changed
      • addedInput schema / properties / message_type / description
        Added value: +"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14'. Call list_message_types first to discover the exact accepted values."
    • Changedlist_entries3 fields changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of entries to return, starting at offset. None (the default) returns the full unpaginated list; a non-None value returns a {total, offset, limit, entries} envelope. Must be non-negative."
      • addedInput schema / properties / offset / description
        Added value: +"Zero-based index of the first entry to return. Applies only when limit is given; must be non-negative. Defaults to 0."
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.05x statement XML document as a string; every booked entry across all its statements is returned."
    • Changedlist_rulebook_clauses2 fields changed
      • addedInput schema / properties / scheme / description
        Added value: +"Restrict the listing to one scheme ('SEPA', 'CBPR+', or 'HVPS+'). None (the default) returns clauses for all schemes."
      • addedInput schema / properties / version / description
        Added value: +"Restrict the listing to one rulebook version, e.g. '2026'. None (the default) returns clauses for all versions."
    • Changedparse_statement1 field changed
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.05x statement XML document as a string, with its root camt <Document> element. Returned verbatim from the bank; no file path is accepted."
    • Changedvalidate_identifier2 fields changed
      • addedInput schema / properties / kind / description
        Added value: +"The identifier type to validate: one of 'iban', 'bic', or 'lei' (case-insensitive)."
      • addedInput schema / properties / value / description
        Added value: +"The identifier value to check, matching the chosen kind (e.g. an IBAN, an 8- or 11-character BIC, or a 20-character LEI). Whitespace/case handling follows the underlying validator."
    • Changedvalidate_records2 fields changed
      • addedInput schema / properties / message_type / description
        Added value: +"A supported ISO 20022 camt.05x message type string, e.g. 'camt.053.001.14', whose input JSON Schema the records are checked against. Call list_message_types to discover accepted values and get_input_schema to see the constraints."
      • addedInput schema / properties / records / description
        Added value: +"One or more flat reversing-entry records (each a dict of field name to value) to validate row-by-row against the message type's input JSON Schema."
    • Changedvalidate_statement1 field changed
      • addedInput schema / properties / xml / description
        Added value: +"The raw camt.05x statement XML document as a string, with its root camt <Document> element. Validated against the matching ISO 20022 XSD; no file path is accepted."
  5. 19 tool updatesv0.0.11
    • First observedcheck_cbpr_readiness
    • First observedcite_rulebook
    • First observedclassify_entry
    • First observedexport_journal
    • First observedfilter_entries
    • First observedgenerate_reversal
    • First observedget_cbpr_cutover_date
    • First observedget_input_schema
    • First observedget_required_fields
    • First observedlist_classify_entry_categories
    • First observedlist_entries
    • First observedlist_export_journal_targets
    • First observedlist_message_types
    • First observedlist_return_reasons
    • First observedlist_rulebook_clauses
    • First observedparse_statement
    • First observedvalidate_identifier
    • First observedvalidate_records
    • First observedvalidate_statement

TDQS

A4.2/5.0

Scored across 24 tools

Disambiguation4/5

Each tool targets a distinct resource or action, with parse, validate, convert, list/filter, reverse, export, classify, CBPR, and rulebook tools cleanly separated. The only mild risk is distinguishing convert_mt942 from convert_mt940_to_camt053 and validate_records from validate_statement, but the descriptions remove the ambiguity.

Naming Consistency4/5

Nearly every tool follows a consistent snake_case verb_noun pattern such as list_*, get_*, validate_*, and generate_*. The minor deviation is convert_mt942 lacking the explicit target suffix that convert_mt940_to_camt053 includes.

Tool Count3/5

At 24 tools the server sits in the heavy 16–25 band, and while the broad scope covers migration, validation, CBPR, rulebook lookup, export, and classification, several small list-lookup and constant-returning helpers inflate the count. The size is defensible but borders on over-scoping for a single MCP server.

Completeness4/5

The core statement workflow is well covered: parsing, validating, listing/filtering entries, detecting anomalies, generating reversals, exporting journals, classifying entries, and checking CBPR readiness. A minor gap is that get_input_schema and validate_records prepare flat records for generation, but no tool directly consumes those records since generate_reversal takes XML instead.

Maintenance

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    An MCP server that gives AI agents deterministic, verified access to ISO 8583 field specs, MTI decoding, jPOS packager XML generation, deploy descriptor validation, message building, and jPOS documentation search.
    7
    4
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Pactus is an MCP server for parsing and validating ISO 20022 payment messages directly from chat. It exposes nine tools that let AI assistants inspect or validate pacs.008, pacs.002, pain.001, and camt.053 messages — the message types at the centre of the CBPR+ migration — without leaving the conversation.
    9
    2
    MIT
  • F
    license
    A
    quality
    A
    maintenance
    A Model Context Protocol server that exposes the pain001 ISO 20022 Customer Credit Transfer Initiation library as agent tools, enabling AI assistants to generate and validate standardized payment XML messages.
    21
    1
    -
  • F
    license
    A
    quality
    A
    maintenance
    An MCP server that exposes the pacs008 ISO 20022 FI-to-FI Customer Credit Transfer library as tools for AI agents and assistants, enabling generation, validation, and parsing of pacs.008 credit transfer XML messages.
    16
    1
    -