Skip to main content
Glama

Compliance Check

check_compliance
Read-onlyIdempotent

Run a full pre-flight compliance check on an IBAN before sending a SEPA / cross-border payment. USE WHEN: the user is about to send a payment / payout / refund and wants to triage risk first, asks "is this IBAN safe to pay?", asks for sanctions screening, asks if a SEPA Instant transfer will succeed, or needs a numeric risk score for an internal payment-approval workflow. NOT A REGULATED AML/CFT PRODUCT — informational triage only. For regulated screening use Refinitiv, Acuris, or ComplyAdvantage. CHECKS: IBAN validity + sanctions (OFAC list, FATF jurisdictions) + SEPA Instant reachability + VoP (EU 2024/886) participant. RETURNS: the full validate enrichment plus a compliance object with risk_score (0-100, 0 = safest), risk_level (low/medium/elevated/high/critical), sanctions matched_lists + fatf_status, reachability, vop status, and flags[] (e.g. sanctioned_country, fatf_grey_list, emi_issuer, no_vop). COST: $0.02 per call (free: 10 units/IP/day on this transport, one per call and one per IBAN in batch_validate_iban, or a free API key at POST https://api.ibanforge.com/v1/keys/generate for 200 REST calls/month).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ibanYesIBAN to check

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
bicNo
ibanYes
metaYes
sepaNo
errorNo
validYes
issuerNo
countryNo
cost_usdcYesWhat THIS call was billed. Zero on the free MCP tier.
complianceYes
next_stepsNoOrdered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.
error_detailNo
bank_code_checkNo
list_price_usdcNoCatalogue price of the same call on the paid REST/x402 route.
risk_indicatorsNo
official_identityNoWho a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed15 schema fields changed
    • removedOutput schema / properties / bank_code_check / properties / match / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / bank_code_check / properties / match / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / bank_code_check / properties / register / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / bank_code_check / properties / register / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / bic / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "authoritative": {
      -        "description": "Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.",
      -        "type": "boolean"
      -      },
      -      "bank_name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "basis": {
      -        "description": "Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE and BG; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.",
      -        "type": "string"
      -      },
      -      "city": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "code": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "code",
      -      "bank_name",
      -      "city"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "authoritative": {
      +        "description": "Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.",
      +        "type": "boolean"
      +      },
      +      "bank_name": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "basis": {
      +        "description": "Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE and BG; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.",
      +        "type": "string"
      +      },
      +      "city": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "code": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "code",
      +      "bank_name",
      +      "city"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / meta / properties / fatf_as_of / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / meta / properties / fatf_as_of / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / meta / properties / sanctions_as_of / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / meta / properties / sanctions_as_of / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / official_identity / properties / address / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / official_identity / properties / address / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / official_identity / properties / lei / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / official_identity / properties / lei / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / risk_indicators / properties / issuer_type / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / risk_indicators / properties / issuer_type / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  2. Changed2 schema fields changed
    • addedOutput schema / properties / cost_usdc / description
      Added value: +"What THIS call was billed. Zero on the free MCP tier."
    • addedOutput schema / properties / list_price_usdc
      Added value: +{
      +  "description": "Catalogue price of the same call on the paid REST/x402 route.",
      +  "type": "number"
      +}
  3. Changed2 schema fields changed
    • addedOutput schema / properties / bank_code_check / properties / reason
      Added value: +{
      +  "description": "WHY the verdict is not verified, as one token to branch on. Absent when status is verified. not_allocated (a national register denies the code — the only value that licenses \"do not send\") | absent_from_reference_data (our composite map does not carry it; the country register was not consulted) | no_reference_data_for_country | register_names_no_holder (the register defines the code space and publishes no holder — silence, not a denial) | national_register_unavailable (the register this country is normally decided against could not be consulted) | lookup_failed (the lookup could not run: timeout, unreadable database). The last two describe IBANforge, never the beneficiary. Never escalate either into a refusal.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / bic / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "bank_name": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "city": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "code": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "code",
      -      "bank_name",
      -      "city"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "authoritative": {
      +        "description": "Whether this BIC may be stored and settled against. Derived from basis, so the two cannot disagree. NOT bank_code_check.authoritative, which answers a different question — whether a national register was consulted about the BANK CODE. In Switzerland the register confirms the code while the BIC still comes from our curated map.",
      +        "type": "boolean"
      +      },
      +      "bank_name": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "basis": {
      +        "description": "Where the bank code to BIC pairing came from, and therefore what may be done with the BIC. national_register (the country register publishes this BIC for this bank code — today DE, AT, BE and BG; settlement-grade) | curated_map (our maintained bank-code map, exact key, usually right and not an allocation record) | directory_prefix (the bic8 LIKE fallback, which can match several institutions — read bank_code_check.candidates). Outside a national_register basis the BIC is ADVISORY: confirm it with the beneficiary or the bank before storing it as a routing instruction.",
      +        "type": "string"
      +      },
      +      "city": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "code": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "code",
      +      "bank_name",
      +      "city"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  4. Changed1 schema field changed
    • addedOutput schema / properties / official_identity
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Who a central bank says holds the resolved code (ECB by LEI and for FR bank codes, Banco de Espana for ES). Present only on a match — absence is not a negative. INFORMATIONAL ONLY: it never changes valid or bank_code_check, because both publishers relay rather than allocate.",
      +  "properties": {
      +    "address": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "One-line registered address as published."
      +    },
      +    "as_of": {
      +      "description": "Date of the list this row came from. Both lists are republished every business day.",
      +      "type": "string"
      +    },
      +    "attribution": {
      +      "description": "The Banco de Espana citation formula, verbatim. Spanish blocks only.",
      +      "type": "string"
      +    },
      +    "authoritative": {
      +      "description": "Always false. Neither publisher allocates bank codes.",
      +      "type": "boolean"
      +    },
      +    "category": {
      +      "type": "string"
      +    },
      +    "free_of_charge": {
      +      "description": "Both publishers require buyers to be told, on every access, that the data is available free of charge from their own website. Relay it with the answer; do not strip it.",
      +      "type": "string"
      +    },
      +    "lei": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "matched_by": {
      +      "description": "lei | national_code",
      +      "type": "string"
      +    },
      +    "name": {
      +      "description": "The institution's name as the publisher writes it.",
      +      "type": "string"
      +    },
      +    "source": {
      +      "description": "The publisher, cited as their licence requires. Relay it.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "name",
      +    "lei",
      +    "address",
      +    "category",
      +    "matched_by",
      +    "source",
      +    "free_of_charge",
      +    "as_of",
      +    "authoritative"
      +  ],
      +  "type": "object"
      +}
  5. Changed3 schema fields changed
    • changedOutput schema / properties / bank_code_check / properties / authoritative / description
      Previous value: -"True only where the reference set is the national register (CH, LI). Only then does not_in_register mean the code is not allocated."New value: +"True only where the reference set is the national register (CH, LI, DE). Only then does not_in_register mean the code is not allocated."
    • addedOutput schema / properties / bank_code_check / properties / retired
      Added value: +{
      +  "description": "True when an authoritative register is withdrawing the code. Still a verified result: it WAS allocated.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / bank_code_check / properties / superseded_by
      Added value: +{
      +  "description": "The bank code that takes over. Re-paper the beneficiary against it.",
      +  "type": "string"
      +}
  6. Changed1 schema field changed
    • addedOutput schema / properties / next_steps
      Added value: +{
      +  "description": "Ordered advice derived from THIS result: what blocks a payment first, what merely enriches it after. Branch on `code`, never on the prose. `because` names the field that produced the step so the advice is auditable. Empty for an IBAN that failed validation.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "action": {
      +        "description": "An IBANforge call that performs the step, when one exists.",
      +        "type": "string"
      +      },
      +      "because": {
      +        "description": "The response field that produced this step.",
      +        "type": "string"
      +      },
      +      "code": {
      +        "description": "Stable identifier. Branch on this.",
      +        "type": "string"
      +      },
      +      "do": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "code",
      +      "do",
      +      "because"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  7. Changed8 schema fields changed
    • addedOutput schema / properties / bank_code_check
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "as_of": {
      +      "type": "string"
      +    },
      +    "authoritative": {
      +      "description": "True only where the reference set is the national register (CH, LI). Only then does not_in_register mean the code is not allocated.",
      +      "type": "boolean"
      +    },
      +    "candidates": {
      +      "description": "BIC8 the prefix matched; >1 means the BIC may belong to another institution.",
      +      "type": "number"
      +    },
      +    "match": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "description": "register (exact key) | prefix (bic8 LIKE heuristic) | null"
      +    },
      +    "register": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "status": {
      +      "description": "verified | not_in_register | unavailable. A separate verdict on the bank code, so bic:null stops meaning three different things.",
      +      "type": "string"
      +    },
      +    "value": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "value",
      +    "status",
      +    "match",
      +    "register",
      +    "authoritative",
      +    "as_of"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / issuer / properties / classification
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / properties / issuer / required
      Previous value: -[
      -  "type",
      -  "name"
      -]New value: +[
      +  "type",
      +  "name",
      +  "classification"
      +]
    • addedOutput schema / properties / risk_indicators / properties / issuer_type / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / risk_indicators / properties / issuer_type / description
      Added value: +"Null when no institution resolved — it no longer defaults to \"bank\"."
    • removedOutput schema / properties / risk_indicators / properties / issuer_type / type
      Removed value: -"string"
    • addedOutput schema / properties / risk_indicators / properties / sepa_reachable_scope
      Added value: +{
      +  "description": "Scope the reachability holds at. Country-derived, not account-derived.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / risk_indicators / required
      Previous value: -[
      -  "issuer_type",
      -  "country_risk",
      -  "test_bic",
      -  "sepa_reachable",
      -  "vop_coverage"
      -]New value: +[
      +  "issuer_type",
      +  "country_risk",
      +  "test_bic",
      +  "sepa_reachable",
      +  "sepa_reachable_scope",
      +  "vop_coverage"
      +]
  8. Changed8 schema fields changed
    • changedOutput schema / properties / compliance / properties / risk_level / description
      Previous value: -"low | medium | elevated | high | critical"New value: +"low | medium | elevated | high | critical | unassessable. unassessable means the IBAN itself did not validate, so no screening was possible: it is the absence of a verdict, never a favourable one."
    • addedOutput schema / properties / compliance / properties / risk_score / anyOf
      Added value: +[
      +  {
      +    "maximum": 100,
      +    "minimum": 0,
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / compliance / properties / risk_score / description
      Previous value: -"0 = safest, 100 = block."New value: +"0 = safest, 100 = block. null when the IBAN could not be validated: there was nothing to score."
    • removedOutput schema / properties / compliance / properties / risk_score / maximum
      Removed value: -100
    • removedOutput schema / properties / compliance / properties / risk_score / minimum
      Removed value: -0
    • removedOutput schema / properties / compliance / properties / risk_score / type
      Removed value: -"number"
    • addedOutput schema / properties / meta
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "disclaimer": {
      +      "type": "string"
      +    },
      +    "fatf_as_of": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "sanctions_as_of": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "scope": {
      +      "type": "string"
      +    },
      +    "sources": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "scope",
      +    "disclaimer"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "iban",
      -  "valid",
      -  "compliance",
      -  "cost_usdc"
      -]New value: +[
      +  "iban",
      +  "valid",
      +  "compliance",
      +  "meta",
      +  "cost_usdc"
      +]
  9. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "bic": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "bank_name": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "city": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "code": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "code",
      +            "bank_name",
      +            "city"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "compliance": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "flags": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "reachability": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "sct": {
      +              "type": "boolean"
      +            },
      +            "sdd": {
      +              "type": "boolean"
      +            },
      +            "sepa_instant": {
      +              "type": "boolean"
      +            }
      +          },
      +          "required": [
      +            "sepa_instant",
      +            "sct",
      +            "sdd"
      +          ],
      +          "type": "object"
      +        },
      +        "risk_level": {
      +          "description": "low | medium | elevated | high | critical",
      +          "type": "string"
      +        },
      +        "risk_score": {
      +          "description": "0 = safest, 100 = block.",
      +          "maximum": 100,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        "sanctions": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "bank_sanctioned": {
      +              "type": "boolean"
      +            },
      +            "country_sanctioned": {
      +              "type": "boolean"
      +            },
      +            "fatf_status": {
      +              "type": "string"
      +            },
      +            "matched_lists": {
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            }
      +          },
      +          "required": [
      +            "country_sanctioned",
      +            "bank_sanctioned",
      +            "matched_lists",
      +            "fatf_status"
      +          ],
      +          "type": "object"
      +        },
      +        "vop": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "participant": {
      +              "type": "boolean"
      +            },
      +            "status": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "participant",
      +            "status"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "sanctions",
      +        "reachability",
      +        "vop",
      +        "risk_score",
      +        "risk_level",
      +        "flags"
      +      ],
      +      "type": "object"
      +    },
      +    "cost_usdc": {
      +      "type": "number"
      +    },
      +    "country": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "code": {
      +          "type": "string"
      +        },
      +        "name": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "code",
      +        "name"
      +      ],
      +      "type": "object"
      +    },
      +    "error": {
      +      "type": "string"
      +    },
      +    "error_detail": {
      +      "type": "string"
      +    },
      +    "iban": {
      +      "type": "string"
      +    },
      +    "issuer": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "name": {
      +          "type": "string"
      +        },
      +        "type": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "type",
      +        "name"
      +      ],
      +      "type": "object"
      +    },
      +    "risk_indicators": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "country_risk": {
      +          "type": "string"
      +        },
      +        "issuer_type": {
      +          "type": "string"
      +        },
      +        "sepa_reachable": {
      +          "type": "boolean"
      +        },
      +        "test_bic": {
      +          "type": "boolean"
      +        },
      +        "vop_coverage": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "issuer_type",
      +        "country_risk",
      +        "test_bic",
      +        "sepa_reachable",
      +        "vop_coverage"
      +      ],
      +      "type": "object"
      +    },
      +    "sepa": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "member": {
      +          "type": "boolean"
      +        },
      +        "schemes": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "vop_required": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "member",
      +        "schemes",
      +        "vop_required"
      +      ],
      +      "type": "object"
      +    },
      +    "valid": {
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "iban",
      +    "valid",
      +    "compliance",
      +    "cost_usdc"
      +  ],
      +  "type": "object"
      +}
  10. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description does not contradict them. The description adds valuable context beyond annotations: it details the check scope (sanctions, FATF, SEPA Instant reachability, VoP), explains the risk_score range and flags, and explicitly discloses the cost per call ($0.02). This level of disclosure exceeds what annotations alone provide.

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 longer than average but well-structured with labeled sections (USE WHEN, NOT, CHECKS, RETURNS, COST). Key triggers are front-loaded, and the cost and free-tier details are at the end. It earns its length because each section conveys actionable information; however, some details like the free API key URL could be considered marginally ancillary, so it is just short of a perfect score.

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 compliance-checking tool, the description covers the full context an agent needs: when to use it, what it checks, what it returns (including risk score semantics), and its cost. An output schema exists, so return-value explanation is not required, and the description still summarizes the return structure well. No critical information 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?

The only parameter 'iban' has full schema coverage with description 'IBAN to check', so the schema fully documents the parameter. The description does not add additional format requirements or constraints beyond the schema, but it does give context on how the IBAN is used in the checks. Given 100% coverage, the baseline of 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 opens with a specific verb and resource: 'Run a full pre-flight compliance check on an IBAN before sending a SEPA / cross-border payment.' It clearly distinguishes itself from sibling tools by focusing on compliance triage, sanctions screening, and risk scoring, which no other sibling covers. The purpose is unambiguous and operational.

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 lists USE WHEN conditions including specific user intents like 'is this IBAN safe to pay?' and scenarios like SEPA Instant transfer success. It also gives a NOT A REGULATED AML/CFT PRODUCT exclusion and names alternatives (Refinitiv, Acuris, ComplyAdvantage) for regulated screening. This gives an agent clear decision rules for when to invoke this tool versus alternatives.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.5/5.0
Disambiguation4/5

Each tool has a distinct job, and the descriptions provide strong USE WHEN/DO NOT USE cues. The only plausible boundary cases are validate_iban vs batch_validate_iban (single vs bulk) and validate_iban vs check_compliance (general enrichment vs payment-risk triage), but both are clearly signposted.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: validate_iban, check_compliance, lookup_bic, send_feedback, etc. batch_validate_iban reads as a compound verb + object and does not break the convention, and the verb choice also aligns with intent: validate for format checks, check for rule/risk checks, lookup for directory data.

Tool Count5/5

Eight tools are well-scoped for an IBAN validation and payment-intelligence API: single/batch validation, compliance, address rules, reference validation, BIC and Swiss clearing lookups, and feedback. Each tool carries a distinct capability and none feels redundant or padding.

Completeness5/5

The surface covers the full IBAN-informed workflow: validation, enrichment, batch processing, BIC/Swiss clearing resolution, payment-reference pairing, postal-address rail rules, and pre-payment compliance triage. Explicit limitations such as not verifying account existence or payee identity are domain constraints, not missing tools.