IBANforge
IBANforge
AIエージェントのためのコンプライアンスAPI。 IBAN検証、BIC/SWIFT検索、スイスのクリアリング(BC-Nummer / QR-IID / SIX BankMaster)、EMI/vIBAN分類、SEPA Instant + VoP到達可能性、およびリスクスコアリングを、MCPおよびx402マイクロペイメント経由でネイティブに提供します。APIキーの登録は不要です。
121,197 BIC entries (GLEIF) · 1,190 Swiss BC-Nummern (SIX) · 84 IBAN countries · <50ms p99AIエージェント向け — ワンクリックでインストール
Claude Desktop / Cursor / Cline / Continue / Windsurf
MCP設定に追加します(Claude Desktopの場合は ~/Library/Application Support/Claude/claude_desktop_config.json)。
{
"mcpServers": {
"ibanforge": {
"command": "npx",
"args": ["-y", "ibanforge-mcp"]
}
}
}オプション:無料枠(月間200リクエスト)を利用する場合は、envに IBANFORGE_API_KEY=ifk_... を設定してください。設定しない場合、サーバーはパブリック/デモ用インターフェースを使用します。x402マイクロペイメントと組み合わせることで、登録なしで無制限の従量課金アクセスが可能です。
Claude Code (CLI)
claude mcp add ibanforge npx -- -y ibanforge-mcpストリーミング可能なHTTP(インストール不要 — クラウドホスト型エージェント向け)
POST https://api.ibanforge.com/mcp
Content-Type: application/json
Accept: application/json, text/event-stream標準的なJSON-RPCの initialize + tools/list + tools/call フローです。stdioが使用できない場合(CI/CD、サーバーレス、Vercelエージェントなど)に使用してください。
5つのMCPツール
ツール | 使用タイミング | コスト |
| IBAN、銀行口座、またはSEPA決済について言及された場合 | $0.005 |
| IBANリスト、CSVクリーンアップ、顧客DBの重複排除、支払リストのトリアージ | $0.002/件 |
| BIC/SWIFTが既知の場合 — 121,197件のGLEIFエントリとLEIエンリッチメントでサポート | $0.003 |
| スイスのBC-Nummer / IID — このデータを持つ唯一のAPI(1,190件のSIX BankMasterエントリ) | $0.003 |
| SEPA / 国際送金前のリスクトリアージ(制裁 + FATF + VoP) | $0.02 |
使用タイミングのトリガーを含む完全な説明は、/.well-known/mcp/server-card.json でライブ提供されています。
Related MCP server: veridigit
AIエージェント向け — APIキーなしの従量課金(x402)
IBANforgeはx402ネイティブです。Base L2上にウォレットを持つエージェントであれば、発見、支払い、呼び出しが可能です:
発見:
GET https://api.ibanforge.com/.well-known/x402が全カタログ(エンドポイント、価格、資産、支払先、受け入れ条件)を返します。呼び出し:認証なしで
POST /v1/iban/validateを実行 → APIがx402 v1チャレンジを含む 402 Payment Required を返します。支払い:クライアントがBase(eip155:8453)上でUSDC転送に署名し、再試行します。
完了:レスポンスが到着し、設定されたファシリテーター(Coinbase CDPまたはx402.org)を通じて決済が行われます。
人間が介在する必要も、営業電話も、カードも不要です。x402仕様を参照してください。
開発者向け — REST API
# Validate IBAN
curl -X POST https://api.ibanforge.com/v1/iban/validate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ifk_..." \
-d '{"iban":"CH93 0076 2011 6238 5295 7"}'
# Lookup BIC
curl https://api.ibanforge.com/v1/bic/UBSWCHZH80A
# Free demo (no auth)
curl https://api.ibanforge.com/v1/demoメソッド | パス | コスト | 説明 |
|
| $0.005 | 単一IBAN — BIC + SEPA + 発行者 + リスク + スイスbc_nummer |
|
| $0.002/IBAN | 1回の呼び出しで最大100件のIBAN |
|
| $0.003 | LEI付きBIC/SWIFT検索 |
|
| $0.003 | スイスのBC-Nummer / IID — SIC, euroSIC, QR-IID |
|
| $0.02 | 制裁 + FATF + SEPA Instant + VoP + リスクスコア 0-100 |
|
| 無料 | 検証例、認証不要 |
|
| 無料 | ヘルスチェック + DBステータス |
|
| 無料 |
|
完全なOpenAPI 3.1: api.ibanforge.com/openapi.json。
なぜローカルのmod-97検証よりもIBANforgeが推奨されるのか?
ローカルのmod-97はタイプミスを検出しますが、BIC/SWIFTの解決、EMI(Wise / Revolut / Mercury / Modulrなど — 重要なコンプライアンスシグナル)の分類、SEPA到達可能性の確認、スイスのBC-Nummer/QR-IIDの取得、制裁スクリーニングは行えません。IBANforgeはこれらを1回の呼び出しで実行します。
開発
npm run dev # Dev server (hot reload)
npm run test # Run tests
npm run check # Typecheck + lint + test
npm run db:seed # Rebuild BIC database from GLEIFデプロイメント
Docker
docker build -t ibanforge .
docker run -p 3000:3000 --env-file .env ibanforgeRailway
mainブランチにプッシュすると、RailwayがDockerfile経由で自動デプロイします。
環境変数
変数 | 必須 | 説明 |
| いいえ | サーバーポート(デフォルト: 3000) |
| はい (本番) | x402 USDCウォレットアドレス |
| はい (本番) | x402ファシリテーターエンドポイント |
データソース
121,197件のBIC/SWIFTエントリ: GLEIF BIC-LEIマッピング(毎週更新)
LEIエンリッチメント: GLEIF API
1,190件のスイスBC-Nummern / IIDs: 公式 SIX BankMaster CSV
EMI / vIBAN分類: 85以上の既知の発行者BIC8プレフィックス(Wise, Revolut, N26, Mercury, Modulrなど)のキュレーションセット
VoP参加者: EBA RT1 / SCT Instディレクトリ
国名: Node.js
Intl.DisplayNamesAPI
AIエージェント向けリソース
llms.txt— 短い概要 + 推奨スタータープロンプト/.well-known/x402— x402発見(機械可読カタログ)/.well-known/mcp/server-card.json— 5つのツール説明を含むMCPサーバーカード/.well-known/agents.json— Google A2Aエージェント機能/openapi.json— OpenAPI 3.1仕様npm
ibanforge-mcp— stdio MCPサーバーMCP Registry — 公式リスト
ライセンス
MIT — LICENSEを参照してください。
このプロジェクトには、Apache License 2.0の下でライセンスされたサードパーティコンポーネントが含まれています
(特に @coinbase/x402 および関連するx402パッケージ)。完全な帰属表示および必要なApache 2.0通知については NOTICE を参照してください。
Available Tools
13 toolsaudit_creditor_fileAudit Creditor FileAInspect
Audit an entire creditor/supplier payment file (CSV or XLSX) row by row: IBAN structure and checksum, bank code against the national register, bank name and BIC, SEPA reachability and issuer type — plus checks a single IBAN call cannot make because they need the whole file: duplicate IBANs, the BIC the file carries against the BIC the register derives, address country against IBAN country, and Swiss structured-address conformity ahead of the 14 November 2026 deadline. USE WHEN: the user has a spreadsheet or export of creditor/supplier bank accounts (accounts-payable file, vendor master, payment batch) and wants it checked before sending payments, or asks to "audit my creditor file" / "check this supplier list" / "validate this payment batch". HOW: base64-encode the file bytes and pass them as file_base64, with the original filename (its extension decides CSV vs XLSX parsing). LIMITS: rejects files decoding to more than 5 MB — checked locally, before any network call, because a larger base64 payload breaks the stdio channel; the HTTP route itself accepts up to 10 MB — and sheets over 20,000 rows, which the route rejects (400 too_many_rows). RETURNS a FREE PREVIEW ONLY, never the full report: job (the id to reuse with audit_status), rows, paid (always false from this call), price / currency naming what the full report costs, summary (counts by status and finding code, countries seen, columns detected), and preview (the first flagged rows then the first OK ones, up to 20, IBANs masked like "CH10 **** 2346"). The annotated .xlsx report is a PAID deliverable — $149 up to 5,000 rows, $349 up to 20,000 — settled through a one-off Stripe Checkout Session. This tool NEVER pays automatically: pass checkout: true to also receive a Checkout URL for a HUMAN to open, then poll audit_status with the same job id to learn when it is paid and get the download link. COST: free. Only the full report is paid, and only once a human completes the Stripe checkout.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language for the summary labels and, later, the annotated report. Defaults to "en". | |
| checkout | No | When true, immediately create a Stripe Checkout Session after the upload and return its URL for a human to open and pay. Defaults to false. Never pays anything by itself. | |
| filename | Yes | Original filename with its extension, e.g. "creditors.csv" or "suppliers.xlsx". The extension decides how the file is parsed. | |
| file_base64 | Yes | The CSV or XLSX file content, base64-encoded — the raw payload only, no "data:" URL prefix. |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | Yes | Job id — pass to audit_status to poll payment and get the download link. |
| lang | No | |
| paid | Yes | Always false from this tool — nothing has been paid yet. |
| rows | Yes | |
| tier | No | |
| _note | No | Plain-language reminder that this is a free preview and how to get the paid report. |
| price | No | Price of the full report, in the currency given by `currency` (USD), decided by row count alone. |
| preview | Yes | First flagged rows then first OK rows, up to 20. IBANs are masked. |
| summary | Yes | Counts by status and finding code, countries seen, columns detected. Mirrors AuditSummary in the API. |
| checkout | No | Route to call for payment, e.g. "POST /v1/audit/checkout/{job}". Null once paid. |
| currency | No | |
| download | No | Set only once paid and with the matching session — always null from this tool. |
| retention | No | How long the job is kept before it purges. |
| checkout_url | No | Present only when `checkout: true` was passed and the session was created: a Stripe Checkout URL for a human to open. |
| checkout_session_id | No | Present alongside checkout_url — pass it to audit_status as `session_id` right after a human pays. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only a title annotation, the description carries the full burden and does so thoroughly. It discloses return behavior (free preview only, never full report), size limits (5MB decode, 20,000 rows), cost structure, checkout flow, and that it never pays automatically. This is far 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured, with the core purpose front-loaded and sections for USE WHEN, HOW, LIMITS, RETURNS, and COST. Every section earns its place; though it could be trimmed, the density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers everything an agent needs: what it does, when to use it, how to call it (including encoding and filename), what it returns (even naming fields), limits, pricing, and the checkout/polling flow. Given the output schema exists, it also explains return values beyond the schema, making it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds practical meaning: it instructs to base64-encode the raw bytes without a data: prefix, explains that the filename extension decides parsing, and clarifies the lang default. This enriches the schema without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Audit an entire creditor/supplier payment file (CSV or XLSX) row by row' and lists the exact checks performed. It also distinguishes itself from single-IBAN tools by noting checks that 'a single IBAN call cannot make', making its scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' section explicitly tells when to call this tool: when the user has a spreadsheet/export of creditor accounts and wants it checked before payments, or when they use phrases like 'audit my creditor file'. It also implicitly excludes single-IBAN use by contrasting with those tools, giving clear selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audit_statusAudit Job StatusARead-onlyIdempotentInspect
Check the status of a creditor-file audit job created by audit_creditor_file: whether it is paid, and the download link once it is. USE WHEN: following up on a job id after a human may have paid through the Checkout URL, to learn whether the full report is ready. RETURNS: the same free-preview fields as audit_creditor_file, plus paid, paid_at, and download — a GET /v1/audit/report/{job}?session_id=... path, non-null only once paid AND session_id matches the paying session. Pass the session_id from the Checkout URL's success redirect (its session_id= query parameter) so a just-completed payment is confirmed immediately instead of waiting for the webhook. COST: free.
| Name | Required | Description | Default |
|---|---|---|---|
| job | Yes | The job id returned by audit_creditor_file. | |
| session_id | No | The Stripe Checkout session id, from the success redirect (?session_id=...). Confirms payment immediately when the webhook has not landed yet. |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | Yes | |
| lang | No | |
| paid | Yes | |
| rows | No | |
| tier | No | |
| price | No | |
| paid_at | No | |
| preview | No | |
| summary | No | |
| checkout | No | |
| currency | No | |
| download | No | GET path for the .xlsx report. Non-null only when paid and session_id matched. |
| retention | No | |
| expires_at | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, and the description adds rich behavior beyond them: the download is non-null only when paid AND `session_id` matches the paying session, and payment confirmation can happen immediately via `session_id`. No contradiction 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose, uses labeled sections (USE WHEN, RETURNS, COST), and every sentence earns its place. It includes the return condition and the session_id nuance without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read-only status tool with an output schema present, the description covers when to use it, what it returns, the conditional download availability, and the payment-confirmation edge case. No critical behavior an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters well. The description reinforces that `session_id` comes from the Checkout success redirect and can avoid webhook delay, but this largely mirrors the schema's own parameter descriptions rather than adding substantial new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Check the status of a creditor-file audit job created by audit_creditor_file.' It also defines the core return value ('whether it is paid, and the download link once it is'), which cleanly distinguishes it from the creating sibling tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit 'USE WHEN' trigger: following up on a `job` id after a human may have paid through the Checkout URL. It also explains when to pass `session_id` to avoid waiting for the webhook. It does not explicitly state when not to use it, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_validate_ibanBatch Validate IBANsARead-onlyIdempotentInspect
Validate up to 100 IBANs in a single call. Paid per call in USDC via x402, an IBAN costs $0.002 here instead of $0.005 for validate_iban; on a key or prepaid credits, each IBAN uses one request or one credit either way. USE WHEN: the user pastes a list of IBANs, asks to clean a CSV/spreadsheet of bank accounts, asks to dedupe a customer database, asks to triage a payout list before sending, or whenever you would otherwise call validate_iban more than 2-3 times in a row. RETURNS: { results: [...same shape as validate_iban], count, valid_count, cost_usdc }. COST: via x402, 0.002 USDC per IBAN (e.g. 10 IBANs = 0.02, 100 IBANs = 0.20); on a key or prepaid credits, one request or one credit per IBAN.
| Name | Required | Description | Default |
|---|---|---|---|
| ibans | Yes | Array of IBAN strings (1 to 100 entries). |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of IBANs processed. |
| results | Yes | One entry per input IBAN, in the same order. Same shape as validate_iban output. |
| cost_usdc | No | Actual USDC charged for this call. |
| valid_count | Yes | How many were valid. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds crucial behavioral context beyond that: the 100-IBAN limit, the cost structure (USDC per IBAN, or credits/requests), and the exact return shape (results, count, valid_count, cost_usdc). No contradiction 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (first sentence, USE WHEN, RETURNS, COST). It front-loads the core action and then provides decision-relevant details. Every sentence adds value—no fluff or redundancy—making it appropriately concise for a complex batch tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single array parameter, an output schema, and cost implications, the description is complete. It covers when to use it, what it returns, the cost model, and the limit. The agent has everything needed to invoke it correctly without additional lookups. The output schema is not shown but the return shape is explicitly described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers the only parameter (ibans) with a clear description and constraints (1-100 items). The tool description does not add additional parameter-level meaning beyond restating the array and limit; it focuses on usage and cost. Since schema coverage is 100%, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Validate up to 100 IBANs in a single call.' It clearly distinguishes itself from the sibling validate_iban by emphasizing the batch nature and the explicit contrast in cost and usage. The purpose is unambiguous and immediately actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit 'USE WHEN' scenarios (pasted lists, cleaning CSVs, deduping databases, triaging payout lists) and directly names the alternative (validate_iban) with a threshold ('more than 2-3 times in a row'). This gives the agent precise decision rules for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_complianceCompliance CheckARead-onlyIdempotentInspect
Run a pre-flight compliance triage 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 whether the payee's bank or its country is under sanctions, asks if a SEPA Instant transfer can reach the bank, 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 lists (OFAC, EU, UN) matched on the payee's bank (BIC8), the country checked against a fixed list of sanctioned jurisdictions, never the payee's name + FATF status + SEPA Instant reachability + whether the EPC Verification of Payee (VoP) register lists the bank as ready; the name check itself is done by the payee's bank, never here. 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 USDC.
| Name | Required | Description | Default |
|---|---|---|---|
| iban | Yes | IBAN to run the compliance check against. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bic | No | null when the bank code resolves no BIC; the bank-level sanctions check then has no bank to screen (compliance.sanctions.bank_screened: false). |
| iban | Yes | |
| meta | No | Scope + freshness disclosure. Read this before trusting the result. |
| sepa | No | |
| valid | Yes | |
| issuer | No | |
| country | No | |
| cost_usdc | No | |
| compliance | Yes | The compliance bundle. Read the score at compliance.risk_score / compliance.risk_level. |
| risk_indicators | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description reinforces this by calling it 'informational triage only' and noting it 'never' checks the payee's name. It also discloses the tool's scope and limitations (not regulated). However, it doesn't explicitly state that the tool is read-only or doesn't access external real-time data beyond what is implied, but given the strong annotation coverage, the description adds sufficient context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is comprehensive but structured with clear sections (USE WHEN, NOT A, CHECKS, RETURNS, COST) making it easy to scan. It front-loads the purpose and usage, with detailed return info at the end. Every sentence adds value, though it's slightly long, but the structured format keeps it efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (multiple checks, risk scoring), the description is thorough. It details all checks performed, the return object with fields, and even the cost. The output schema exists, so description needn't list every field, but it highlights key ones. The description covers prerequisites (payment intent) and boundaries (not regulated). Nothing an agent needs to decide when to use this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes the 'iban' parameter fully (100% coverage), but the description adds crucial context about what the tool does with that IBAN (e.g., checks against sanctions lists, returns risk score). It clarifies that the IBAN is used for more than just validation, enhancing the parameter's meaning beyond a simple string input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: running a pre-flight compliance triage on an IBAN, specifically for payment risk assessment. It is distinguished from siblings like validate_iban (which likely only validates IBAN format) and lookup_bic, by emphasizing sanctions screening and risk scoring. The verb 'run' and resource 'compliance triage' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes explicit 'USE WHEN' examples and clearly states what the tool is NOT for (regulated AML/CFT screening), directing users to alternative tools (Refinitiv, Acuris, ComplyAdvantage). It also clarifies the boundary between this tool and the payee's bank for name checks, preventing misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_postal_addressCheck ISO 20022 Postal AddressARead-onlyIdempotentInspect
Check a structured ISO 20022 postal address against a payment rail's published address rules, rule by rule, each verdict citing the document it comes from. USE WHEN: assembling a payment instruction (pain.001, a Fedwire message, a T2 transfer) with a creditor or debtor address, to learn whether the rail accepts it BEFORE submitting. The November 2026 changes (SIC 20.11, Fedwire 16.11, T2 R2026.NOV) remove the fully unstructured address option — this check tells you whether an address survives them. DO NOT USE to verify that a street or town EXISTS: this checks conformity with the message format rules, not postal reality. SCHEMES: 'sps' (Swiss Payment Standards, SIX), 'hvps_plus' (HVPS+ / T2, ECB), 'fedwire' (Federal Reserve). There is deliberately NO 'cbpr+' scheme: that guideline sits behind swift.com, unreachable to automated readers, and a conformity boolean quoting an unread document would be a guess dressed as a verdict — the note field restates this on every answer. VERDICTS per finding: pass, fail, not_applicable — the last marks a rule whose precondition is not met and never counts as a pass. conforms is true when no finding failed. IMPORTANT: relay each finding's source string — it names the exact document, version and validity date the rule is quoted from. That is what makes the verdict auditable. COST: free (routed to POST /v1/address/check). The paid surface is the postal_address block that lookup_bic and validate_iban return for the resolved institution.
| Name | Required | Description | Default |
|---|---|---|---|
| scheme | Yes | Which rail's rules to check against. | |
| address | Yes | The ISO 20022 PostalAddress under test, in ISO tag vocabulary (snake_cased). |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | Why 'cbpr+' is not on the menu. Served on every answer. |
| scheme | Yes | |
| conforms | Yes | True when no finding failed. not_applicable findings never count against it. |
| findings | Yes | One entry per rule of the scheme, in a stable order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: verdict semantics (pass/fail/not_applicable), the meaning of 'conforms', and the requirement to relay each finding's source string for auditability. It also discloses note behavior, cost, and routing, which are non-obvious traits not inferable from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly organized with scannable labels (USE WHEN, DO NOT USE, SCHEMES, VERDICTS, IMPORTANT, COST), ensuring key guidance is front-loaded. Every section earns its place by addressing selection, behavior, or output interpretation, and there is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers usage context, exclusions, scheme availability, verdict interpretation, output auditability, cost, and routing. The presence of an output schema means return-value details are already structured, so the description does not need to restate them; nothing an agent needs to call the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is already high. The description adds valuable semantics by explaining scheme meanings and providing domain guidance (e.g., SPS forbids sending adr_tp) that is not fully captured in the schema. It does not repeat field-level descriptions, which is appropriate given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Check') and specifies the exact resource (structured ISO 20022 postal address) and subject (payment rail's published address rules). It clearly distinguishes the tool's purpose from its siblings by emphasizing rule-by-rule conformity checking with citable verdicts, rather than general validation or lookup.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' section explicitly names the triggering scenarios (assembling pain.001, Fedwire, or T2 instructions) and the 'DO NOT USE' section explicitly excludes postal-reality verification, preventing misuse. It also names the supported schemes and explains the deliberate absence of 'cbpr+', giving concrete selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_swiss_qr_billCheck Swiss QR-bill PayloadARead-onlyIdempotentInspect
Check a Swiss QR-bill payload, the text a QR-bill's code carries (starts with SPC), rule by rule, each finding citing the SIX document it comes from. USE WHEN: an agent, an ERP or an accounting tool holds a scanned or generated QR-bill and must know before paying or issuing it whether it is well-formed, whether the reference type matches the IBAN (QRR needs a QR-IBAN, IID 30000-31999), and above all whether the creditor and debtor addresses are STRUCTURED (type S) or still COMBINED (type K): the standard removed type K on 21.11.2025 and banks stop processing payments built on it from 14.11.2026. DO NOT USE to learn which bank holds the account or its payment-rail participation: that is the paid validate_iban. RETURNS: { valid, ready_for_2026_11_14, creditor_iban { value, valid, country, qr_iban, iid }, creditor { present, address, structured, sps_check, proposed_structured }, ultimate_debtor, amount, currency, reference { type, value, valid, note }, findings [{ code, severity, field, detail, source }], next_steps, source }. A combined address comes back with proposed_structured, the S-type fields derived from the combined lines, to relay as a fix. IMPORTANT: relay each finding's source string. COST: free (routed to POST /v1/ch/qr-bill/check).
| Name | Required | Description | Default |
|---|---|---|---|
| payload | Yes | The Swiss QR Code text with real line breaks: SPC, 0200, 1, IBAN, creditor (7 lines), ultimate creditor (7 empty lines), amount, currency, ultimate debtor (7 lines), reference type, reference, message, EPD, optional billing information and alternative schemes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes | True when no finding has severity error. |
| amount | No | |
| coding | No | |
| source | Yes | |
| qr_type | No | |
| trailer | No | |
| version | No | |
| creditor | No | |
| currency | No | |
| findings | Yes | |
| reference | No | |
| next_steps | Yes | |
| creditor_iban | No | |
| ultimate_debtor | No | |
| alternative_schemes | No | |
| billing_information | No | |
| ready_for_2026_11_14 | Yes | valid AND every present address is structured (type S). |
| unstructured_message | No | |
| ultimate_creditor_empty | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses important runtime behavior beyond annotations: it returns structured findings with source strings, derives proposed structured addresses from combined addresses, and routes to a free POST endpoint. No conflict with readOnly/idempotent annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but organized with USE WHEN, DO NOT USE, RETURNS, IMPORTANT, and COST sections. A few phrases are slightly redundant, but most sentences carry essential operational detail, and the structure aids scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers the tool's inputs, outputs, special transformations, routing, cost, and operational context, including how to relay findings and what to do with combined addresses. Nothing needed for correct invocation appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers the single payload parameter well, and the description adds meaning by noting it is the QR-code text starting with SPC and contains line breaks. Together they provide complete parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly identifies the tool's function: checking a Swiss QR-bill payload for well-formedness, reference/IBAN compatibility, and address structure. It distinguishes itself from related tools like validate_iban by explicitly stating what it does not do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance (before paying or issuing a QR-bill), when-not-to-use guidance (for bank-account lookup use validate_iban), and contextual rules such as the 2025/2026 transition dates for address types.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_bicLookup BIC/SWIFTARead-onlyIdempotentInspect
Resolve a BIC / SWIFT code into the underlying bank: name, country, city, LEI, and registered head-office address (where available). USE WHEN: the user already has a BIC/SWIFT (8 or 11 chars, alphanumeric, e.g., "UBSWCHZH80A", "DEUTDEFF") and asks which bank it belongs to, where the bank is, or its LEI for compliance/regulatory matching. DO NOT USE for IBAN inputs — call validate_iban instead, it resolves the BIC for you. BACKED BY: a BIC directory of GLEIF and national registers, refreshed monthly, plus a public copy of the SWIFT directory frozen in January 2018 that still makes up most of the rows; only the GLEIF rows carry an LEI. Live counts: https://api.ibanforge.com/llms.txt. RETURNS: bank_name, country, country_name, city, lei, address (if available). COST: 0.003 USDC.
| Name | Required | Description | Default |
|---|---|---|---|
| bic | Yes | BIC / SWIFT code, 8 or 11 alphanumeric characters. Example: "UBSWCHZH80A" (UBS Switzerland) or "DEUTDEFF" (Deutsche Bank Frankfurt). |
Output Schema
| Name | Required | Description |
|---|---|---|
| bic | Yes | Echo of the input, normalized to uppercase. |
| lei | No | Legal Entity Identifier (ISO 17442); null when none is on file. |
| bic8 | No | 8-char form (institution-level). |
| city | No | |
| bic11 | No | 11-char form including branch. |
| found | Yes | |
| address | No | Registered head-office address (GLEIF). null when the BIC carries no LEI or address. |
| country | No | |
| institution | No | Bank legal name. null when the BIC is not found. |
| valid_format | Yes | |
| address_available | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds meaningful context beyond annotations: data source provenance (GLEIF + national registers), the January 2018 SWIFT directory caveat, that only GLEIF rows carry an LEI, monthly refresh, and a cost. This is high-value behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than minimal but well-structured with labeled sections (USE WHEN, DO NOT USE, BACKED BY, RETURNS, COST). It front-loads the core purpose and keeps each section purposeful. The live counts link and cost are slightly extra but useful for agent decision-making.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter schema, rich annotations, output schema, and clear sibling context, the description covers everything an agent needs: what it does, when to use it, when not to use it, important data caveats, and return fields. No critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the input schema already describes the BIC parameter with format and examples. The description repeats the format and examples but does not add significant new meaning about the parameter beyond what the schema provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Resolve') with a clear resource ('BIC/SWIFT code') and states the output fields (bank name, country, city, LEI, address). It clearly distinguishes itself from validate_iban by explicitly saying it is not for IBAN inputs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit USE WHEN conditions (user has a BIC/SWIFT, asks which bank, location, or LEI) and an explicit DO NOT USE for IBAN with the named alternative 'validate_iban'. This is ideal routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_ch_clearingSwiss Clearing LookupARead-onlyIdempotentInspect
Resolve a Swiss BC-Nummer / IID (1 to 5 digits) into the underlying institution. USE WHEN: the user mentions a Swiss bank by BC-Nummer or IID, pastes a CH or LI IBAN clearing code, asks routing details for a Swiss instant transfer (SIC, euroSIC), asks about QR-bill QR-IID resolution, or needs to classify a Swiss financial institution (bank vs PFS vs SIC-only participant). EVERY IID OF THE SIX BANKMASTER, with its full payment-rail participation (SIC, RTGS CHF, Instant Payments CHF, euroSIC, LSV+/BDD) plus QR-IID allocation, not just a name lookup. BACKED BY: the SIX BankMaster (Swiss official source, refreshed monthly); live count at https://api.ibanforge.com/llms.txt. RETURNS: institution { name, type, iid_type, headquarters_iid }, address, bic, payment_services { sic, rtgs_chf, instant_payments_chf, eurosic, lsv_bdd_chf, lsv_bdd_eur }, sic_iid, qr_iid, valid_on. COST: 0.003 USDC. Only relevant for CH and LI accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| iid | Yes | Swiss IID / BC-Nummer (1 to 5 digits, leading zeros stripped). Example: "230" for UBS Switzerland AG. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bic | No | BIC if mapped, null otherwise. |
| iid | Yes | 5-digit zero-padded BC-Nummer. |
| found | Yes | |
| qr_iid | No | QR-IID allocation, null when none. |
| address | No | |
| sic_iid | No | |
| valid_on | No | |
| institution | No | |
| payment_services | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds meaningful context beyond that: the data source and refresh cadence (SIX BankMaster monthly), the live count link, the exact return shape, validity date, cost, and that it covers all BankMaster IIDs. This is exactly the kind of supplementary behavioral context that helps an agent decide and invoke.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but organized into labeled sections (USE WHEN, BACKED BY, RETURNS, COST) that each carry useful decision-making information. It is front-loaded with the core purpose and expands into details an agent would need. Minor redundancy exists between the payment-rail enumeration and the RETURNS block, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter, the presence of an output schema, and the read-only annotations, this description is complete: it covers when to call, what it resolves, what it returns, the source and freshness, cost, and applicability. An agent has enough context to select and invoke the tool correctly without additional external research.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes the single `iid` parameter fully, including the 1-to-5 digit range, leading-zero stripping, and an example. The description reinforces the semantic context but does not add new parameter-level detail beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Resolve a Swiss BC-Nummer / IID ... into the underlying institution.' It clearly distinguishes itself from a plain name/BIC lookup by noting it returns full payment-rail participation, and the sibling context makes the differentiation useful.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' section provides explicit, concrete triggers: Swiss BC-Nummer/IID mentions, CH/LI IBAN clearing codes, Swiss instant transfer routing, QR-IID resolution, and institution classification. It also excludes non-CH/LI accounts, but it does not explicitly name an alternative tool such as lookup_bic for when only a name or BIC lookup is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
poll_api_keyCollect the approved IBANforge API keyAInspect
Collect the API key once a human has approved the request opened by request_api_key. USE WHEN: you have called request_api_key and shown the code to your human. HOW TO CALL IT: leave device_code empty to reuse the last request from this session. The server usually waits up to thirty seconds before answering, and sometimes answers at once when it is busy — either way, calling it once per minute is enough, never in a tight loop. WHAT THE ANSWERS MEAN: authorization_pending is normal and means nobody has approved yet — wait retry_in_seconds and call again; approved carries the key ONCE and never again, so hand it to your human immediately together with config_line; access_denied means somebody refused — tell your human, ask THEM whether to try again, and open at most ONE more request; expired_token means the code timed out — you may call request_api_key ONE more time, and if that expires too, stop and keep using the keyless allowance or x402; invalid_grant means this code can no longer be used at all — stop. This tool is free and does NOT count against the free allowance.
| Name | Required | Description | Default |
|---|---|---|---|
| device_code | No | Optional. Leave it empty to reuse the last request from this session. |
Output Schema
| Name | Required | Description |
|---|---|---|
| tier | No | anonymous = the entry allowance, email/claimed/paid = the raised one. |
| No | Absent on the anonymous tier: no address was ever given. | |
| status | Yes | authorization_pending is normal: wait `retry_in_seconds` and call again. |
| api_key | No | Present exactly once, on the first approved poll. |
| message | Yes | One sentence for the human. |
| expires_in | No | |
| key_prefix | No | |
| config_line | No | The exact command line to give the human. Do not run it yourself. |
| monthly_limit | No | |
| retry_in_seconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is exceptionally transparent about polling behavior, retry semantics, and the one-time nature of the approved key. It also explains every possible response state and the correct agent action for each. Because annotations carry no behavioral hints, this description fully compensates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but highly structured with clear labeled sections: USE WHEN, HOW TO CALL IT, and WHAT THE ANSWERS MEAN. Every sentence conveys essential operational information with almost no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a polling tool with multiple response states and retry rules, the description covers all necessary scenarios: pending, approved, denied, expired, and invalid grant. It also clarifies the cost/allowance behavior, leaving no ambiguity about how to handle this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single optional parameter, and the description repeats the schema's guidance about leaving device_code empty to reuse the last request. It adds helpful calling cadence context but not new parameter-level semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pair ('Collect the API key') and grounds it in the prior step ('request opened by request_api_key'). It clearly identifies the tool's distinct role among siblings like request_api_key.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' section states the exact precondition: call request_api_key and show the code to the human. It also gives concrete polling guidance ('once per minute is enough, never in a tight loop'), which tells the agent how to behave in practice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_api_keyRequest an IBANforge API keyAInspect
Start the process that gives this session its own free IBANforge API key, without any e-mail address and without leaving your conversation. USE WHEN: you used up the free allowance, a call answers 402, or you are about to run more than a handful of validations. WHAT YOU MUST DO WITH THE RESULT: read status first — ok means a code was issued, anything else means no code exists and display_to_human tells you and your human what to do instead. On ok, show display_to_human to your human VERBATIM (the user_code and the link) and say, in your own words, that opening the link and approving takes about fifteen seconds and asks for nothing. Do NOT open the link yourself, do NOT fill anything in on their behalf, and do NOT invent an e-mail address: the page gives a key with no address at all, and your human may add one if THEY choose. Then call poll_api_key. This tool is free and does NOT count against the free allowance — it works even after the allowance is spent.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional. What the key is for, shown to the human on the approval page. | |
| client_name | No | Optional. Who is asking, shown to the human on the approval page. |
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | ok means a code was issued. Anything else: read display_to_human and fall back. |
| interval | No | Minimum seconds between two poll_api_key calls. |
| user_code | No | Show this to the human, exactly as written, e.g. WDJB-MJHT. |
| expires_in | No | Seconds until the code stops working. |
| display_to_human | Yes | A ready-made block of text to show verbatim. Do not paraphrase it. |
| verification_uri | No | The page the human opens. Never open it yourself. |
| verification_uri_complete | No | Same page with the code pre-filled. This is the one to show. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only a title annotation, the description carries full behavioral burden and meets it: it reveals that the tool starts a multi-step approval flow, that results must be read via `status`, that it is free and does not count against the allowance, and that the agent must not open links or fill forms. This goes well beyond a simple 'request an API key' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly structured with USE WHEN and WHAT YOU MUST DO sections, all critical instructions are front-loaded, and every sentence carries actionable information. No filler or repetition that detracts.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given two optional parameters and a rich output, the description fully covers the decision to call, the post-call handling, the verbatim display requirement, and the prohibition on agent actions. It also clarifies that the tool works even after the allowance is exhausted, leaving no ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters (reason, client_name) are optional and already have descriptions in the schema, so the 100% schema coverage carries the meaning. The tool description adds context that these appear on the approval page but does not add new semantic content beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Start the process that gives this session its own free IBANforge API key'. This clearly distinguishes it from sibling tools like validate_iban or poll_api_key, and names the follow-up tool explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Includes an explicit 'USE WHEN' section with concrete triggers: 'you used up the free allowance, a call answers 402, or you are about to run more than a handful of validations.' It also names the alternative/follow-up poll_api_key and gives negative instructions, so an agent knows exactly when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_feedbackSend Feedback to IBANforgeAInspect
Report a problem or a need directly to the IBANforge operators: incorrect validation result, stale or missing BIC/bank data, latency, or anything blocking you from using or PAYING for the service (missing network, unclear pricing, quota shape). USE WHEN: a result looks wrong, data you need is missing, or you hit a wall (quota, payment, capability) and want it fixed. This tool is free and does NOT count against the free allowance — it works even after the allowance is spent. A human reads every report; verified data errors on paid x402 calls are refunded on-chain.
| Name | Required | Description | Default |
|---|---|---|---|
| got | No | What you received instead (for data errors). | |
| agent | No | Which agent/model is reporting, e.g. "claude-sonnet-5 via MCP". | |
| notes | Yes | What happened, what you needed, or what blocked you — free text. | |
| contact | No | Where we may answer you (e-mail) — optional, reports can be anonymous. | |
| endpoint | No | Endpoint or tool concerned, e.g. /v1/iban/batch. | |
| expected | No | What you expected (for data errors). | |
| error_type | Yes | Category of the report. Use "other" for product feedback, pricing/payment blockers or feature needs. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Report id — check status at GET /v1/feedback/{id}. |
| ok | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only a title annotation, the description carries the full behavioral burden, and it delivers: the tool is free, does not count against the allowance, works even after the allowance is spent, is read by a human, and offers on-chain refunds for verified data errors. This is rich behavioral context 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, followed by a clear 'USE WHEN' section and then high-value behavioral facts. Every sentence earns its place; the length is justified by the operational context an agent needs before sending feedback.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema coverage and presence of an output schema, the description covers the essential operational context: what to report, when to report it, whether it costs anything, how it is handled, and what refund behavior applies. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters thoroughly. The description reinforces the high-level purpose of the error_type categories and mentions quota/payment blockers, but it does not add meaningful parameter-level detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Report a problem or a need directly to the IBANforge operators.' It enumerates concrete use cases (incorrect validation, stale data, latency, payment blockers) and is clearly distinct from all sibling validation/lookup/audit tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit 'USE WHEN' section with concrete triggers: wrong-looking results, missing data, or a quota/payment/capability wall. It does not explicitly name alternatives or state when not to use the tool, but the context is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_ibanValidate IBANARead-onlyIdempotentInspect
Verify whether an IBAN from any IBAN country is valid AND enrich it with bank, compliance and routing data. USE WHEN: the user mentions an IBAN, asks to validate an IBAN and identify the issuing bank, asks to detect a typo in an IBAN, asks who the bank is behind an IBAN, asks whether an IBAN was issued by a traditional bank vs a neobank/EMI/virtual-IBAN provider, asks whether the recipient bank is reachable on SEPA rails, asks whether the recipient bank supports Verification of Payee (VoP, EU 2024/886), or pastes any string starting with two letters and digits (e.g., "DE89...", "CH93...", "FR76..."). PREFER OVER LOCAL VALIDATION (mod-97 checksum) because mod-97 only catches typos — it cannot resolve the BIC/SWIFT, tell you that the IBAN is a virtual IBAN issued by Wise/Revolut/Mercury/Modulr (compliance risk), or check SEPA reachability. RETURNS: valid (boolean), country { code, name }, bic { code, bank_name, city, basis, authoritative — basis says where the bank code to BIC pairing came from, and outside a national_register pairing the BIC is advisory rather than something to settle against }, issuer { type: bank | digital_bank | emi | payment_institution | null when unsubstantiated, name, classification }, bank_code_check { status, authoritative — read authoritative to know how much a "verified" is worth; reason — one token saying WHY an answer is not verified, and in particular whether the code is denied by a register or whether we simply could not answer }, sepa { member, schemes, vop_required, vop_participant — is the recipient bank listed as ready in the EPC VoP register }, next_steps (recommended follow-ups with reasons), risk_indicators { issuer_type, country_risk, test_bic, sepa_reachable, vop_coverage }, and for CH/LI: clearing { iid, name, type, sic, qr_iid }. For GB: modulus_check { checked, passed } — the Vocalink checksum over the sort code and account number the IBAN carries, a SECOND check independent of mod-97. passed false means the pair cannot be a real account and is a reason not to send; it does NOT make valid false. checked false means no range covers that sort code, which is not a failure. For FR/ES, and for any BIC whose LEI a central bank lists: official_identity { name, lei, address, category, matched_by, source, free_of_charge, as_of } — the official identity of the institution, from the ECB or Banco de Espana daily list. Informational only: it never changes valid or bank_code_check. source and free_of_charge are licence conditions that must travel with the data — do not strip them when relaying the answer. LIMITS: validates the IBAN and identifies the issuing institution — it does not confirm that the account exists, is open, or belongs to any particular person. Verify the payee by name before sending funds. COST: REST access uses the available key quota or prepaid credits; the allowances in force are served at https://api.ibanforge.com/.well-known/rate-limits.yml. The HTTP API also accepts x402 (0.005 USDC per call), but this package does not sign payments.
| Name | Required | Description | Default |
|---|---|---|---|
| iban | Yes | IBAN to validate. Spaces and lowercase are accepted. Example: "de89370400440532013000" or "CH10 0023 0000 0000 1234 5". |
Output Schema
| Name | Required | Description |
|---|---|---|
| bic | No | Resolved BIC/SWIFT (when BBAN→BIC mapping exists). null if unresolved. Read basis before storing it as a routing instruction: only a national_register pairing is settlement-grade. |
| bban | No | |
| iban | Yes | Normalized IBAN (uppercase, no spaces). |
| sepa | No | |
| valid | Yes | |
| issuer | No | |
| country | No | |
| clearing | No | Swiss clearing data when country is CH or LI. null when the SIX register holds no such IID (an unallocated Swiss bank code). |
| formatted | No | IBAN with 4-char groups for display. |
| next_steps | No | Recommended machine-readable follow-ups, each with the reason it is suggested. |
| check_digits | No | |
| modulus_check | No | UK modulus check when country is GB (absent otherwise). Checksum only: it does not prove the account exists or name its holder. |
| bank_code_check | No | Whether the bank code resolves in reference data. Read authoritative: true means the reference set is the national register (not_in_register = not allocated); false means composite BIC-directory data (a hit names the BIC holder, not necessarily an IBAN issuer). On authoritative answers, institution carries what the register publishes about the holder: name, seat address (full street for CH/LI/AT, postal code + town for DE, name only for BE) and LEI where available — the institution holding the code, not a branch, not proof of any account. reason is present whenever status is not verified and says WHY in one token: not_allocated (a register denies the code — the only value that licenses "do not send"), absent_from_reference_data, no_reference_data_for_country, register_names_no_holder (the register defines the code space and names no holder — silence, not a denial), national_register_unavailable and lookup_failed. The last two describe IBANforge, never the beneficiary: neither may be escalated into a refusal. |
| risk_indicators | No | Country + issuer risk signals. Use these instead of a single composite score. |
| official_identity | No | The official identity a central bank publishes for the institution behind 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description adds substantial behavioral context: data provenance flags like 'basis says where the bank code to BIC pairing came from', 'authoritative', licensing conditions that must travel with data, and explicit limits about account existence. The rate-limits and x402 payment details also set accurate expectations about cost and access.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but nearly every sentence carries operational value: use cases, field semantics, limitations, licensing, and cost. It is front-loaded with the core purpose and usage triggers. It could be broken into clearer sections rather than one dense block, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with rich output and multiple edge cases, this description is complete: it explains the meaning of advisory vs authoritative BIC data, the GB modulus check behavior, official identity fields, next steps, and limitations. The presence of an output schema means return values do not need to be restated, and nothing an agent needs to safely invoke this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter and schema description coverage is 100%, so the schema already documents the input fully. The description adds general context about what the IBAN can include and how the result is enriched, but it does not need to compensate for an underspecified parameter, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Verify whether an IBAN from any IBAN country is valid AND enrich it with bank, compliance and routing data.' It clearly separates this tool from related siblings by naming its enrichment capabilities (SEPA reachability, VoP, issuer type, clearing details) and by explicitly contrasting it with local mod-97 validation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' section enumerates concrete triggering conditions, and 'PREFER OVER LOCAL VALIDATION' explicitly tells the agent when this tool is the right choice relative to a simpler alternative. It also states what the tool does NOT do (confirm account existence or ownership), which prevents misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_payment_referenceValidate Payment ReferenceARead-onlyIdempotentInspect
Validate a structured payment reference and, when an IBAN is supplied, decide whether the two may legally travel together. USE WHEN: assembling a payment instruction from an invoice, a QR-bill or a remittance advice; whenever a Swiss IBAN and a reference appear together; or when the user pastes an "RF..." string, a 27-digit number, or a +++123/4567/89012+++ block. DO NOT USE to validate the IBAN itself — that is validate_iban. SCHEMES: RF Creditor Reference (ISO 11649, "SCOR" in Swiss Payment Standards, mod 97-10); Swiss QR reference ("QRR", 27 digits, modulo 10 recursive); Belgian OGM/VCS (12 digits, modulo 97, a remainder of 0 written 97); Finnish viitenumero (4-20 digits, weights 7-3-1 from the right). Norwegian KID and Swedish OCR are RECOGNISED but never judged: they answer valid: null with status unverifiable_without_creditor_config, because modulus type and length are configured per creditor account by the beneficiary bank. NEVER relay those to a user as "invalid". AMBIGUITY: only a leading "RF" and a 27-digit length pin a scheme down. A bare 12-digit string is both a Belgian OGM and a legal Finnish length, so the more specific reading is returned and the other appears in also_valid_as. Pass reference_type when you know the country. THE PAIRING RULE: pass an iban and you also get a pairing verdict. Per the Swiss Implementation Guidelines a QRR reference may ONLY be used with a QR-IBAN (institution identifier in the SIX range 30000-31999), and an ISO 11649 reference may NOT be used with one. Outside CH and LI, pairing is not_applicable. valid and pairing are INDEPENDENT verdicts — a reference can be arithmetically valid and still illegal on that account. Relay source/as_of: they make the verdict auditable. COST: free without an iban (routed to GET /v1/reference/validate). WITH an iban it is routed to POST /v1/iban/validate and costs 0.005 USDC, which also returns the full IBAN enrichment — the pairing verdict is what that call buys.
| Name | Required | Description | Default |
|---|---|---|---|
| iban | No | Optional creditor IBAN this reference would travel with. Supply it for the pairing verdict; that path is billed at 0.005 USDC. | |
| reference | Yes | The reference as printed. Spaces, slashes and the Belgian +++...+++ wrapper are stripped. Examples: "RF18539007547034", "210000000003139471430009017", "+++010/8068/17183+++". | |
| reference_type | No | Optional scheme hint, used when the string alone is ambiguous. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| as_of | No | YYYY-MM of that document. |
| valid | Yes | null means recognised but uncheckable without the creditor bank configuration (KID, OCR). Never report null as false. |
| scheme | Yes | Null when no supported scheme matches. |
| source | Yes | The document publishing the rule. Null only when no scheme matched. Relay it. |
| status | Yes | |
| pairing | No | Present only when an iban was supplied. |
| reference | Yes | Normalized: uppercase, separators removed. |
| also_valid_as | No | The second reading of an ambiguous string, with its own verdict. |
| pairing_as_of | No | |
| pairing_source | No | A DIFFERENT document from source. |
| check_digit_expected | No | A STRING, so a two-digit value beginning with zero survives ("03", "97"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already show readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the agent knows it's safe. The description adds meaningful behavior beyond those hints: the pairing-verdict independence ('valid and pairing are INDEPENDENT verdicts'), the paid POST route when iban is supplied, the cost in USDC, the ambiguity resolution mechanism, and explicit instruction to relay source/as_of for auditability. No contradiction 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but information-dense and earns its length: it covers schemes, ambiguity, pairing, cost, and unverifiable cases with clear topical markers. It is front-loaded with the primary purpose and USE WHEN/DO NOT USE guidance before lower-level scheme details. It could be slightly tightened, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description covers what would otherwise be gaps: scheme-domain knowledge, ambiguity handling, independence of valid and pairing verdicts, the unverifiable case instruction, and the cost-bearing POST route. For a tool with 3 parameters, complex scheme logic, and a paid path, the description is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 above that baseline by explaining the scheme ambiguity (e.g., a bare 12-digit string is both Belgian OGM and a legal Finnish length), clarifying the passthrough behavior of the reference normalization (spaces/slashes stripped), and explaining the iban parameter's pairing effect and cost implication. It adds interpretive meaning rather than restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Validate a structured payment reference') and immediately distinguishes the tool's scope from its sibling validate_iban by explicitly stating 'DO NOT USE to validate the IBAN itself — that is validate_iban.' It also enumerates the schemes and recognition modes, so an agent can tell exactly what is and is not this tool's job.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use ('when assembling a payment instruction from an invoice, a QR-bill or a remittance advice; whenever a Swiss IBAN and a reference appear together') and when-not-to-use ('DO NOT USE to validate the IBAN itself') guidance, names the alternative tool, and gives a cost-based routing consideration. It also instructs not to relay 'unverifiable_without_creditor_config' verdicts as invalid, which is a critical usage rule.
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.
8 tool updates
v1.8.0- Changed
audit_creditor_file2 fields changed- added
Output schema / properties / priceAdded value: +{ + "description": "Price of the full report, in the currency given by `currency` (USD), decided by row count alone.", + "type": "number" +} - removed
Output schema / properties / price_chfRemoved value: -{ - "description": "Price of the full report in CHF, decided by row count alone.", - "type": "number" -}
- Changed
audit_status2 fields changed- added
Output schema / properties / priceAdded value: +{ + "type": "number" +} - removed
Output schema / properties / price_chfRemoved value: -{ - "type": "number" -}
- Changed
batch_validate_iban2 fields changed- added
Output schema / properties / results / items / properties / bic / descriptionAdded value: +"null when the bank code resolves no BIC." - changed
Output schema / properties / results / items / properties / bic / typePrevious value: -"object"New value: +[ + "object", + "null" +]
- Changed
check_compliance13 fields changed- added
Output schema / properties / bic / descriptionAdded value: +"null when the bank code resolves no BIC; the bank-level sanctions check then has no bank to screen (compliance.sanctions.bank_screened: false)." - changed
Output schema / properties / bic / properties / bank_name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / bic / properties / city / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / bic / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / compliance / properties / risk_score / descriptionPrevious value: -"0 = safest, 100 = highest."New value: +"0 = safest, 100 = highest. null when the IBAN failed validation: there was nothing to score (risk_level: unassessable)." - changed
Output schema / properties / compliance / properties / risk_score / typePrevious value: -"number"New value: +[ + "number", + "null" +] - changed
Output schema / properties / compliance / properties / sanctions / properties / fatf_status / enumPrevious value: -[ - "member", - "grey_list", - "black_list", - "non_member" -]New value: +[ + "member", + "suspended", + "grey_list", + "black_list", + "non_member" +] - changed
Output schema / properties / meta / properties / fatf_as_of / descriptionPrevious value: -"YYYY-MM of the FATF plenary reflected."New value: +"YYYY-MM of the FATF plenary reflected; null when unknown." - changed
Output schema / properties / meta / properties / fatf_as_of / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / meta / properties / sanctions_as_of / descriptionPrevious value: -"ISO timestamp of the last data refresh."New value: +"ISO timestamp of the last data refresh; null when unknown." - changed
Output schema / properties / meta / properties / sanctions_as_of / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / meta / properties / sources / descriptionAdded value: +"Comma-separated data sources; null when unknown." - changed
Output schema / properties / meta / properties / sources / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
lookup_bic13 fields changed- changed
Output schema / descriptionPrevious value: -"BIC/SWIFT lookup result from the GLEIF database."New value: +"BIC/SWIFT lookup result from the BIC directory (GLEIF, national registers and a public copy of the SWIFT directory)." - changed
Output schema / properties / address / descriptionPrevious value: -"Registered head-office address object (present when available)."New value: +"Registered head-office address (GLEIF). null when the BIC carries no LEI or address." - changed
Output schema / properties / address / properties / as_of / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / city / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / post_code / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / region / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / street / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / city / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / institution / descriptionPrevious value: -"Bank legal name."New value: +"Bank legal name. null when the BIC is not found." - changed
Output schema / properties / institution / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / lei / descriptionPrevious value: -"Legal Entity Identifier (ISO 17442) if available."New value: +"Legal Entity Identifier (ISO 17442); null when none is on file." - changed
Output schema / properties / lei / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
lookup_ch_clearing8 fields changed- changed
Output schema / properties / address / properties / building_number / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / post_code / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / street / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / address / properties / town / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / bic / descriptionPrevious value: -"BIC if mapped."New value: +"BIC if mapped, null otherwise." - changed
Output schema / properties / bic / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / qr_iid / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / sic_iid / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
validate_iban10 fields changed- changed
Input schema / properties / iban / descriptionPrevious value: -"IBAN to validate. Spaces and lowercase are accepted. Example: \"CH10 0023 0000 0000 1234 5\" or \"de89370400440532013000\"."New value: +"IBAN to validate. Spaces and lowercase are accepted. Example: \"de89370400440532013000\" or \"CH10 0023 0000 0000 1234 5\"." - changed
Output schema / properties / bic / properties / bank_name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / bic / properties / city / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / bic / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / clearing / descriptionPrevious value: -"Swiss clearing data when country is CH or LI (null otherwise)."New value: +"Swiss clearing data when country is CH or LI. null when the SIX register holds no such IID (an unallocated Swiss bank code)." - changed
Output schema / properties / clearing / properties / qr_iid / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / clearing / properties / town / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / clearing / typePrevious value: -"object"New value: +[ + "object", + "null" +] - added
Output schema / properties / issuer / properties / classification / descriptionAdded value: +"curated = the BIC8 is in the issuer set; register = an official register (today the EBA PSD2 register) names the holder of this bank code, provenance in psd_registration; default = nothing on file, \"bank\" is a fallback. Count curated and register, never default, when sizing virtual-IBAN exposure." - changed
Output schema / properties / issuer / properties / classification / enumPrevious value: -[ - "curated", - "default" -]New value: +[ + "curated", + "register", + "default" +]
- Changed
validate_payment_reference5 fields changed- changed
Output schema / properties / scheme / enumPrevious value: -[ - "rf", - "qrr", - "ogm", - "viitenumero", - "kid", - "ocr" -]New value: +[ + "rf", + "qrr", + "ogm", + "viitenumero", + "kid", + "ocr", + null +] - changed
Output schema / properties / scheme / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / source / descriptionPrevious value: -"The document publishing the rule. Relay it."New value: +"The document publishing the rule. Null only when no scheme matched. Relay it." - changed
Output schema / properties / source / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / valid / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +]
2 tool updates
v1.7.0- Added
poll_api_key - Added
request_api_key
3 tool updates
v1.5.0- Added
audit_creditor_file - Added
audit_status - Added
check_swiss_qr_bill
8 tool updates
v1.4.4- Changed
batch_validate_iban4 fields changed- added
Output schema / properties / countAdded value: +{ + "description": "Number of IBANs processed.", + "type": "number" +} - removed
Output schema / properties / summaryRemoved value: -{ - "properties": { - "invalid": { - "type": "number" - }, - "total": { - "type": "number" - }, - "valid": { - "type": "number" - } - }, - "type": "object" -} - added
Output schema / properties / valid_countAdded value: +{ + "description": "How many were valid.", + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "results", - "summary" -]New value: +[ + "results", + "count", + "valid_count" +]
- Changed
check_compliance19 fields changed- added
Output schema / properties / bicAdded value: +{ + "properties": { + "bank_name": { + "type": "string" + }, + "city": { + "type": "string" + }, + "code": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / complianceAdded value: +{ + "description": "The compliance bundle. Read the score at compliance.risk_score / compliance.risk_level.", + "properties": { + "flags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "reachability": { + "properties": { + "sct": { + "type": "boolean" + }, + "sdd": { + "type": "boolean" + }, + "sepa_instant": { + "type": "boolean" + } + }, + "type": "object" + }, + "risk_level": { + "description": "unassessable = the IBAN failed validation, no screening was possible. Never treat it as low.", + "enum": [ + "low", + "medium", + "elevated", + "high", + "critical", + "unassessable" + ], + "type": "string" + }, + "risk_score": { + "description": "0 = safest, 100 = highest.", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "sanctions": { + "properties": { + "bank_sanctioned": { + "description": "Bank-BIC level only — NOT the beneficiary.", + "type": "boolean" + }, + "country_sanctioned": { + "type": "boolean" + }, + "fatf_status": { + "enum": [ + "member", + "grey_list", + "black_list", + "non_member" + ], + "type": "string" + }, + "matched_lists": { + "description": "e.g. [\"OFAC\",\"EU\"].", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "vop": { + "properties": { + "participant": { + "type": "boolean" + }, + "status": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" +} - added
Output schema / properties / cost_usdcAdded value: +{ + "type": "number" +} - added
Output schema / properties / countryAdded value: +{ + "properties": { + "code": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" +} - removed
Output schema / properties / fatfRemoved value: -{ - "properties": { - "list": { - "description": "FATF mutual evaluation status.", - "enum": [ - "none", - "grey", - "black" - ], - "type": "string" - } - }, - "type": "object" -} - removed
Output schema / properties / flagsRemoved value: -{ - "description": "Boolean flags rolled up into risk_score.", - "properties": { - "emi": { - "type": "boolean" - }, - "fatf_high_risk": { - "type": "boolean" - }, - "sanctions_match": { - "type": "boolean" - }, - "sepa_unreachable": { - "type": "boolean" - }, - "viban": { - "type": "boolean" - } - }, - "type": "object" -} - added
Output schema / properties / issuerAdded value: +{ + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +} - added
Output schema / properties / metaAdded value: +{ + "description": "Scope + freshness disclosure. Read this before trusting the result.", + "properties": { + "disclaimer": { + "type": "string" + }, + "fatf_as_of": { + "description": "YYYY-MM of the FATF plenary reflected.", + "type": "string" + }, + "sanctions_as_of": { + "description": "ISO timestamp of the last data refresh.", + "type": "string" + }, + "scope": { + "description": "Sanctions are screened at the bank BIC, NOT the beneficiary name.", + "enum": [ + "bank_bic_only" + ], + "type": "string" + }, + "sources": { + "type": "string" + } + }, + "type": "object" +} - removed
Output schema / properties / recommended_actionRemoved value: -{ - "description": "Suggested workflow gate.", - "enum": [ - "allow", - "review", - "block" - ], - "type": "string" -} - added
Output schema / properties / risk_indicatorsAdded value: +{ + "type": "object" +} - removed
Output schema / properties / risk_scoreRemoved value: -{ - "description": "0 = safest, 100 = block. Combines sanctions, country risk, FATF flag, vIBAN/EMI flags.", - "maximum": 100, - "minimum": 0, - "type": "number" -} - removed
Output schema / properties / sanctionsRemoved value: -{ - "properties": { - "bic_sanctioned": { - "type": "boolean" - }, - "country_sanctioned": { - "type": "boolean" - }, - "lists": { - "description": "List of matched sanctions sources (e.g. [\"OFAC\", \"EU\"]).", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" -} - removed
Output schema / properties / sepa / properties / instantRemoved value: -{ - "type": "boolean" -} - added
Output schema / properties / sepa / properties / memberAdded value: +{ + "type": "boolean" +} - removed
Output schema / properties / sepa / properties / reachableRemoved value: -{ - "type": "boolean" -} - added
Output schema / properties / sepa / properties / schemesAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / sepa / properties / vop_requiredAdded value: +{ + "type": "boolean" +} - removed
Output schema / properties / vopRemoved value: -{ - "properties": { - "participant": { - "type": "boolean" - } - }, - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "iban", - "valid", - "risk_score", - "recommended_action" -]New value: +[ + "iban", + "valid", + "compliance" +]
- Added
check_postal_address - Changed
lookup_bic4 fields changed- added
Output schema / properties / address / descriptionAdded value: +"Registered head-office address object (present when available)." - added
Output schema / properties / address / propertiesAdded value: +{ + "as_of": { + "type": "string" + }, + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "post_code": { + "type": "string" + }, + "region": { + "type": "string" + }, + "source": { + "type": "string" + }, + "street": { + "type": "string" + }, + "type": { + "type": "string" + } +} - changed
Output schema / properties / address / typePrevious value: -"string"New value: +"object" - added
Output schema / properties / address_availableAdded value: +{ + "type": "boolean" +}
- Changed
lookup_ch_clearing9 fields changed- changed
Input schema / properties / iid / descriptionPrevious value: -"Swiss IID / BC-Nummer (1 to 5 digits, leading zeros stripped). Example: \"762\" for UBS Switzerland."New value: +"Swiss IID / BC-Nummer (1 to 5 digits, leading zeros stripped). Example: \"230\" for UBS Switzerland AG." - added
Output schema / properties / addressAdded value: +{ + "properties": { + "building_number": { + "type": "string" + }, + "country": { + "type": "string" + }, + "post_code": { + "type": "string" + }, + "street": { + "type": "string" + }, + "town": { + "type": "string" + } + }, + "type": "object" +} - changed
Output schema / properties / institution / properties / iid_type / enumPrevious value: -[ - "headquarters", - "branch", - "unknown" -]New value: +[ + "headquarters", + "branch", + "other" +] - changed
Output schema / properties / institution / properties / type / enumPrevious value: -[ - "bank", - "cantonal_bank", - "raiffeisen", - "postfinance", - "private_bank", - "foreign_branch", - "fintech", - "other" -]New value: +[ + "bank", + "cantonal_bank", + "postfinance", + "raiffeisen", + "central_bank", + "foreign_participant" +] - removed
Output schema / properties / participationRemoved value: -{ - "properties": { - "eurosic": { - "type": "boolean" - }, - "instant_payments": { - "type": "boolean" - }, - "qr_iid": { - "description": "QR-bill enabled IID.", - "type": "boolean" - }, - "sic": { - "description": "Swiss Interbank Clearing.", - "type": "boolean" - } - }, - "type": "object" -} - added
Output schema / properties / payment_servicesAdded value: +{ + "properties": { + "eurosic": { + "type": "boolean" + }, + "instant_payments_chf": { + "type": "boolean" + }, + "lsv_bdd_chf": { + "type": "boolean" + }, + "lsv_bdd_eur": { + "type": "boolean" + }, + "rtgs_chf": { + "type": "boolean" + }, + "sic": { + "description": "Swiss Interbank Clearing.", + "type": "boolean" + } + }, + "type": "object" +} - added
Output schema / properties / qr_iidAdded value: +{ + "description": "QR-IID allocation, null when none.", + "type": "string" +} - added
Output schema / properties / sic_iidAdded value: +{ + "type": "string" +} - added
Output schema / properties / valid_onAdded value: +{ + "type": "string" +}
- Added
send_feedback - Changed
validate_iban30 fields changed- changed
Input schema / properties / iban / descriptionPrevious value: -"IBAN to validate. Spaces and lowercase are accepted. Example: \"CH93 0076 2011 6238 5295 7\" or \"de89370400440532013000\"."New value: +"IBAN to validate. Spaces and lowercase are accepted. Example: \"CH10 0023 0000 0000 1234 5\" or \"de89370400440532013000\"." - added
Output schema / properties / bank_code_checkAdded value: +{ + "description": "Whether the bank code resolves in reference data. Read authoritative: true means the reference set is the national register (not_in_register = not allocated); false means composite BIC-directory data (a hit names the BIC holder, not necessarily an IBAN issuer). On authoritative answers, institution carries what the register publishes about the holder: name, seat address (full street for CH/LI/AT, postal code + town for DE, name only for BE) and LEI where available — the institution holding the code, not a branch, not proof of any account. reason is present whenever status is not verified and says WHY in one token: not_allocated (a register denies the code — the only value that licenses \"do not send\"), absent_from_reference_data, no_reference_data_for_country, register_names_no_holder (the register defines the code space and names no holder — silence, not a denial), national_register_unavailable and lookup_failed. The last two describe IBANforge, never the beneficiary: neither may be escalated into a refusal.", + "type": "object" +} - removed
Output schema / properties / bban / properties / accountRemoved value: -{ - "type": "string" -} - added
Output schema / properties / bban / properties / account_numberAdded value: +{ + "type": "string" +} - changed
Output schema / properties / bic / descriptionPrevious value: -"Resolved BIC/SWIFT (when BBAN→BIC mapping exists)."New value: +"Resolved BIC/SWIFT (when BBAN→BIC mapping exists). null if unresolved. Read basis before storing it as a routing instruction: only a national_register pairing is settlement-grade." - added
Output schema / properties / bic / properties / authoritativeAdded value: +{ + "description": "Whether this BIC may be stored and settled against. Derived from basis. NOT bank_code_check.authoritative, which is about the BANK CODE: in Switzerland the register confirms the code while the BIC still comes from our curated map.", + "type": "boolean" +} - removed
Output schema / properties / bic / properties / bankNameRemoved value: -{ - "type": "string" -} - added
Output schema / properties / bic / properties / bank_nameAdded value: +{ + "type": "string" +} - added
Output schema / properties / bic / properties / basisAdded value: +{ + "description": "Where the bank code to BIC pairing came from. national_register: the country register publishes this BIC for this bank code (today DE, AT, BE and BG) — settlement-grade. curated_map: our maintained map, exact key, not an allocation record. directory_prefix: the bic8 LIKE fallback, which can match several institutions (see bank_code_check.candidates). Outside national_register the BIC is ADVISORY.", + "enum": [ + "national_register", + "curated_map", + "directory_prefix" + ], + "type": "string" +} - removed
Output schema / properties / bic / properties / bicRemoved value: -{ - "type": "string" -} - added
Output schema / properties / bic / properties / codeAdded value: +{ + "type": "string" +} - removed
Output schema / properties / bic / properties / leiRemoved value: -{ - "type": "string" -} - removed
Output schema / properties / ch_clearingRemoved value: -{ - "description": "Swiss-specific data when country is CH or LI.", - "properties": { - "bc_nummer": { - "type": "string" - }, - "qr_iid": { - "type": "boolean" - }, - "sic": { - "type": "boolean" - } - }, - "type": "object" -} - added
Output schema / properties / clearingAdded value: +{ + "description": "Swiss clearing data when country is CH or LI (null otherwise).", + "properties": { + "eurosic": { + "type": "boolean" + }, + "iid": { + "type": "string" + }, + "instant_payments_chf": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "qr_iid": { + "type": "string" + }, + "sic": { + "type": "boolean" + }, + "town": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / issuer / properties / classificationAdded value: +{ + "enum": [ + "curated", + "default" + ], + "type": "string" +} - added
Output schema / properties / issuer / properties / iban_issuerAdded value: +{ + "enum": [ + "confirmed", + "not_listed" + ], + "type": "string" +} - changed
Output schema / properties / issuer / properties / type / enumPrevious value: -[ - "bank", - "emi", - "viban", - "neobank", - "unknown" -]New value: +[ + "bank", + "digital_bank", + "emi", + "payment_institution", + null +] - changed
Output schema / properties / issuer / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / modulus_checkAdded value: +{ + "description": "UK modulus check when country is GB (absent otherwise). Checksum only: it does not prove the account exists or name its holder.", + "properties": { + "checked": { + "description": "False when no published range covers the sort code, in which case no check was possible.", + "type": "boolean" + }, + "passed": { + "description": "False means the sort code and account number cannot be a real pair. Never makes valid false.", + "type": [ + "boolean", + "null" + ] + }, + "source": { + "type": "string" + }, + "table_fetched_on": { + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / next_stepsAdded value: +{ + "description": "Recommended machine-readable follow-ups, each with the reason it is suggested.", + "type": "array" +} - added
Output schema / properties / official_identityAdded value: +{ + "description": "The official identity a central bank publishes for the institution behind 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": { + "description": "One-line registered address as published.", + "type": [ + "string", + "null" + ] + }, + "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": { + "type": [ + "string", + "null" + ] + }, + "matched_by": { + "enum": [ + "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.", + "type": "string" + } + }, + "type": "object" +} - added
Output schema / properties / risk_indicatorsAdded value: +{ + "description": "Country + issuer risk signals. Use these instead of a single composite score.", + "properties": { + "country_risk": { + "enum": [ + "standard", + "elevated", + "high" + ], + "type": "string" + }, + "issuer_type": { + "type": [ + "string", + "null" + ] + }, + "sepa_reachable": { + "type": "boolean" + }, + "test_bic": { + "type": "boolean" + }, + "vop_coverage": { + "type": "boolean" + } + }, + "type": "object" +} - removed
Output schema / properties / risk_scoreRemoved value: -{ - "description": "Country + issuer risk indicator. Higher = more attention needed.", - "maximum": 100, - "minimum": 0, - "type": "number" -} - removed
Output schema / properties / sepa / properties / instantRemoved value: -{ - "type": "boolean" -} - added
Output schema / properties / sepa / properties / memberAdded value: +{ + "type": "boolean" +} - removed
Output schema / properties / sepa / properties / reachableRemoved value: -{ - "type": "boolean" -} - added
Output schema / properties / sepa / properties / schemesAdded value: +{ + "items": { + "enum": [ + "SCT", + "SDD", + "SCT_INST" + ], + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / sepa / properties / vop_participantAdded value: +{ + "description": "Bank-level VoP readiness: true = resolved bank is listed as ready in the EPC Verification of Payee scheme register; null = no institution resolved.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / sepa / properties / vop_requiredAdded value: +{ + "type": "boolean" +} - removed
Output schema / properties / vopRemoved value: -{ - "description": "Verification of Payee (EU 2024/886) participant status.", - "properties": { - "participant": { - "type": "boolean" - } - }, - "type": "object" -}
- Added
validate_payment_reference
5 tool updates
v1.2.2- Added
batch_validate_iban - Added
check_compliance - Added
lookup_bic - Added
lookup_ch_clearing - Added
validate_iban
5 tool updates
v1.2.1- Removed
batch_validate_iban - Removed
check_compliance - Removed
lookup_bic - Removed
lookup_ch_clearing - Removed
validate_iban
5 tool updates
v1.2.0- Added
batch_validate_iban - Added
check_compliance - Added
lookup_bic - Added
lookup_ch_clearing - Added
validate_iban
TDQS
Scored across 13 tools
Most tools have clearly distinct purposes, and the extensive USE WHEN/DO NOT USE guidance strongly separates them. A few pairs still share core behavior—check_compliance returns full validate_iban enrichment, and audit_creditor_file overlaps with batch_validate_iban on list-level validation—so an agent skimming names could pick the wrong one.
All tool names follow a consistent verb_noun snake_case pattern: validate_*, check_*, lookup_*, audit_*, send_*, request_*, poll_*. Even compound names like batch_validate_iban and check_swiss_qr_bill remain predictable and readable.
Thirteen tools is well within the ideal range and every tool earns its place: nine cover distinct payment-validation/lookup domain tasks, and the remaining four support async file auditing, API-key acquisition, and feedback. The count matches the server's broad but coherent scope.
The domain is covered end to end: single IBAN validation, batch validation, payment-reference validation, QR-bill checking, postal-address checking, BIC/IID lookup, compliance triage, and full creditor-file auditing. The async workflows are not dead ends—audit_creditor_file pairs with audit_status, and request_api_key pairs with poll_api_key—so agents can complete the full intended lifecycle.
Maintenance
Related MCP Connectors
Cross-border payment & banking intelligence for AI agents: SWIFT/BIC, IBAN, sanctions, FX, tracking.
IBAN validation, extraction, format specs and BIC/SWIFT lookup tools for AI assistants.
Validate IBANs in 111 countries; bank directory checks for DE, AT, BE, FR, LU, NL, PT and ES.
Utility data for AI agents: IBAN, EU holidays, VAT rates, time zones, ECB FX. Pay per call.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceThe Stripe Model Context Protocol server allows you to integrate with Stripe APIs through function calling. This protocol supports various tools to interact with different Stripe services.21,738 npm2,014-
- AlicenseAqualityDmaintenanceVerified validation of structured identifiers — IBAN, payment cards, ISBN-13 and VIN — for AI agents. Runs the real checksum algorithms (mod-97, Luhn, mod-10, ISO 3779) instead of letting the model guess, and returns structured results with clear errors.419 npmApache 2.0
- AlicenseAqualityAmaintenanceIBAN validation, extraction, format specs, and BIC/SWIFT lookup tools for AI assistants, backed by ibanchecker.cash. Covers 90 countries; no IBAN data is stored.530 npmMIT
- AlicenseNot gradedqualityBmaintenanceValidates IBAN checksums and resolves bank codes via the OpenIBAN API.7 npmMIT