
Validates IBANs with full BIC/SWIFT lookup, SEPA Instant reachability, and Swiss BC-Nummer resolution in under 50ms. Exposes five MCP tools covering single and batch validation, BIC lookup across 121,000 entries with LEI enrichment from GLEIF, Swiss clearing number lookups from SIX BankMaster, and compliance scoring that checks sanctions lists, FATF status, and Verification of Payee support. Works over stdio or streamable HTTP. Runs without an API key using x402 micropayments on Base, or grab a free tier key for 200 requests per month. Reach for this when your agent needs to triage payment lists, classify EMI/vIBAN issuers like Wise or Revolut, or run pre-flight compliance checks before SEPA transfers.
Public tool metadata for what this MCP can expose to an agent.
validate_ibanVerify whether a European IBAN is valid AND enrich it with bank, compliance and routing data. USE WHEN: the user mentions an IBAN, asks to verify a bank account number, asks to detect a typo in an IBAN, asks who the bank is behind an IBAN, asks if a recipient is a real bank vs...1 paramsVerify whether a European IBAN is valid AND enrich it with bank, compliance and routing data. USE WHEN: the user mentions an IBAN, asks to verify a bank account number, asks to detect a typo in an IBAN, asks who the bank is behind an IBAN, asks if a recipient is a real bank vs...
ibanstringbatch_validate_ibanValidate up to 100 IBANs in a single call (10x cheaper per IBAN than calling validate_iban repeatedly). 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,...1 paramsValidate up to 100 IBANs in a single call (10x cheaper per IBAN than calling validate_iban repeatedly). 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,...
ibansarraylookup_bicResolve a BIC / SWIFT code into the underlying bank: name, country, city, LEI, address. 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/reg...1 paramsResolve a BIC / SWIFT code into the underlying bank: name, country, city, LEI, address. 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/reg...
bicstringcheck_complianceRun a full pre-flight compliance check on an IBAN before sending a SEPA / cross-border payment. USE WHEN: the user is about to send a payment / payout / refund and wants to triage risk first, asks "is this IBAN safe to pay?", asks for sanctions screening, asks if a SEPA Instan...1 paramsRun a full pre-flight compliance check on an IBAN before sending a SEPA / cross-border payment. USE WHEN: the user is about to send a payment / payout / refund and wants to triage risk first, asks "is this IBAN safe to pay?", asks for sanctions screening, asks if a SEPA Instan...
ibanstringlookup_ch_clearingResolve 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 reso...1 paramsResolve 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 reso...
iidstringIBANforge checks the bank behind an IBAN before you pay. It validates IBANs from all 89 IBAN countries and, in all but 8 of them, names the bank and its BIC, with the source of that answer. Where it reads the national register (Germany, Austria, Belgium, Slovakia, Czech Republic, Bulgaria, Switzerland and Liechtenstein), it also tells you whether the bank code is allocated at all; elsewhere it names the bank from a partial register or a composite map, and says that such an answer cannot rule a code out. For a SEPA bank it resolves, it gives the SEPA schemes that reach it (Credit Transfer, Instant, Direct Debit), from the EPC scheme registers when they list the bank and from the country otherwise (the answer says which), and says whether the EPC Verification of Payee (VoP) register lists the bank as ready to answer VoP requests. It does not check who holds the account: that name check belongs to the payee's bank, through VoP.
Not a name check (VoP, BAV, CoP), not proof that an account exists or is open, not a sanctions screening of the payee (bank and country only), not a licensed copy of the SWIFT BIC directory. The national check digits inside the BBAN are checked for France and Monaco (RIB key), Belgium, Italy and San Marino (CIN), Spain (DC), Germany (the account-number check digit, by the Bundesbank method of each bank code) and the United Kingdom (modulus check): a wrong key shows in checks.national_check_digits and never turns valid to false. The Polish settlement-number check digit is checked with the bank code. The national keys of the other countries are not checked yet.
For business software and AI agents alike: a REST API, a native MCP server, prepaid packs by card, and x402 micropayments with no signup.
89 IBAN countries · bank codes checked against the national registers of DE, AT, BE, SK, CZ, BG, CH, LI · 121k+ BIC entries (39k+ LEI via GLEIF; about two thirds a public copy of the SWIFT directory frozen in January 2018) · 1,100+ Swiss BC-Nummern (SIX)
Add to your MCP config (~/Library/Application Support/Claude/claude_desktop_config.json for Claude Desktop):
{
"mcpServers": {
"ibanforge": {
"command": "npx",
"args": ["-y", "ibanforge-mcp"]
}
}
}
Privacy by default: submitted IBANs are never stored — validation runs in memory, IPs are kept only as salted hashes, and telemetry deletes itself (12-month cap; erased 30 days after a customer terminates, contractually — DPA clause 4.7).
Optional: set IBANFORGE_API_KEY=ifk_... in env (a key that needs no e-mail: 25 requests a month, raised to 200 a month once claimed). Without it the server uses the public/demo surface; combine with x402 micropayments for unlimited pay-per-call access without signup.
claude mcp add ibanforge npx -- -y ibanforge-mcp
POST https://api.ibanforge.com/mcp
Content-Type: application/json
Accept: application/json, text/event-stream
Authorization: Bearer ifk_your_key # optional
Standard JSON-RPC initialize + tools/list + tools/call flow. Use this when stdio is not an option (CI/CD, serverless, Vercel agents, etc.). Without a key it answers a keyless allowance per source address; with a key (Authorization: Bearer or X-API-Key), the tool calls count against that key exactly as on the REST API.
| Tool | When to use it | Cost |
|---|---|---|
validate_iban | User mentions an IBAN, a bank account, or a SEPA payment | $0.005 |
batch_validate_iban | List of IBANs, CSV cleanup, customer DB dedup, payout list triage | $0.002/each in USDC via x402; 1 credit each on a key |
lookup_bic | User already has a BIC/SWIFT — backed by 121k+ BIC entries (39k+ LEI-enriched via GLEIF) | $0.003 |
lookup_ch_clearing | Swiss BC-Nummer / IID: every IID of the SIX BankMaster with its rail participation (SIC, euroSIC, CHF instant) and its QR-IID where SIX allocates one | $0.003 |
check_compliance | Pre-flight risk triage before a SEPA / cross-border payment (OFAC, EU, UN lists on the payee's bank, the country against a fixed sanctions list, FATF, VoP readiness) | $0.02 |
validate_payment_reference | RF/ISO 11649, Swiss QRR, Belgian OGM/VCS or Finnish viitenumero checksum, plus the QRR ↔ QR-IBAN pairing verdict | free |
check_postal_address | An ISO 20022 address against one rail's published rules (sps, hvps_plus, fedwire), each finding citing its source | free |
check_swiss_qr_bill | A Swiss QR-bill payload — header, QR-IBAN and reference pairing, structured (S) versus combined (K) addresses (type K not permitted since 21.11.2025; banks guarantee its payment only until the end of September 2026) | free |
send_feedback | Report incorrect data or claim an x402 refund | free |
request_api_key | You used up the free allowance, or need a durable key — a human approves in a browser, no e-mail | free |
poll_api_key | Collect that key once it is approved, handed over exactly once | free |
The free tools need no key, no wallet and no signup: they are the ones to try first. The last two are the way out of the free allowance without anyone typing an address — they keep answering after the allowance is spent.
Full descriptions of the read-only data tools, with WHEN-to-use triggers, are served live at /.well-known/mcp/server-card.json.
If you can open a web address but cannot send a POST (no code execution, no MCP connector), these pages hold real answers of the API, each with its date, and all of them open with a plain GET.
Do not simulate answers from the API: quote these real ones, with the date each carries (served_at, as_of, or the date of the page). To get answers on the IBANs of your user, ask them to add https://api.ibanforge.com/mcp as a custom connector in their assistant; where to click, assistant by assistant: https://ibanforge.com/docs/mcp. A connector with no key draws on the same keyless allowance as any other caller, counted per source address. In Claude its calls leave from Anthropic's cloud, not from the user's device (Anthropic's documentation), so that allowance is shared with other users and may already be spent; other assistants were not checked by us. With a key, the hosted endpoint counts the calls against that key, as the REST API does: in Claude, the user adds the request header Authorization: Bearer followed by the key when creating the connector; ChatGPT sends no key to a connector (OpenAI's documentation). A POST to https://api.ibanforge.com/v1/keys/generate with no body returns a key, no e-mail; the npm package ibanforge-mcp reads it from IBANFORGE_API_KEY.
IBANforge is x402-native. Any agent with a wallet on Base L2 can discover, pay, and call:
GET https://api.ibanforge.com/.well-known/x402 returns the full catalog (endpoints, prices, asset, payTo, accepts).POST /v1/iban/validate without auth → API replies 402 Payment Required with x402 v1 challenge.No human in the loop, no sales call, no card. See the x402 spec.
Pick your language:
| Language | Package | Install | Source |
|---|---|---|---|
| TypeScript / JavaScript | @ibanforge/sdk | npm install @ibanforge/sdk | sdks/typescript/ |
| Python | ibanforge | pip install ibanforge | sdks/python/ |
| Java (17+) | com.ibanforge:ibanforge-sdk | Maven dependency, see README | sdks/java/ |
| .NET (net8.0) | IBANforge.Sdk | dotnet add package IBANforge.Sdk | sdks/dotnet/ |
| MCP server | ibanforge-mcp | npx -y ibanforge-mcp | mcp/ |
| Curl / any HTTP client | — | — | OpenAPI spec |
The Python SDK ships with sync + async clients, typed exception classes, and a free-tier quota fallback to x402 baked in:
from ibanforge import IBANforge
# 1-line key, no e-mail: 25 requests a month, 200 once claimed
key = IBANforge.generate_api_key() # shown ONCE: store key["api_key"] now
with IBANforge(api_key=key["api_key"]) as client:
out = client.validate_iban("DE89370400440532013000")
print(out["country"]["code"]) # DE
print(out["bic"]["bank_name"]) # Commerzbank
print(out["bank_code_check"]["authoritative"]) # True (checked against the Bundesbank register)
# Or the free format-only check (mod-97 + structure, no DB hit)
out = IBANforge().format_iban("DE89370400440532013000")
# Validate IBAN — no key needed for the first 25 calls a week per source address
# (ISO week in UTC, reset on Monday 00:00 UTC). The answer carries a `trial` block
# with the count left this week, the reset instant and how to get a key.
curl -X POST https://api.ibanforge.com/v1/iban/validate \
-H "Content-Type: application/json" \
-d '{"iban":"DE89 3704 0044 0532 0130 00"}'
# The Swiss example of the SWIFT IBAN registry passes mod-97 too, and comes back
# bank_code_check.reason = "not_allocated": the SIX register allocates its bank code to nobody.
curl -X POST https://api.ibanforge.com/v1/iban/validate \
-H "Content-Type: application/json" \
-d '{"iban":"CH93 0076 2011 6238 5295 7"}'
# Beyond the keyless trial, send a key: an empty POST to /v1/keys/generate returns one
# (no e-mail, no card), for every endpoint, 200 requests a month once claimed.
curl -X POST https://api.ibanforge.com/v1/iban/validate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ifk_..." \
-d '{"iban":"DE89 3704 0044 0532 0130 00"}'
# Lookup BIC
curl https://api.ibanforge.com/v1/bic/UBSWCHZH80A
# Free format pre-flight (no auth, mod-97 only)
curl 'https://api.ibanforge.com/v1/iban/format?iban=DE89370400440532013000'
# Free demo (no auth)
curl https://api.ibanforge.com/v1/demo
| Method | Path | Cost | Description |
|---|---|---|---|
POST | /v1/iban/validate | $0.005 | Single IBAN: bank-code verdict + BIC with its source + SEPA + issuer + risk + Swiss bc_nummer. A weekly keyless trial per source address (see above) |
POST | /v1/iban/batch | $0.002/IBAN (USDC, x402) | Up to 100 IBANs in one call; on a key or a credit pack, one credit per IBAN |
GET | /v1/bic/{code} | $0.003 | BIC/SWIFT lookup with LEI |
GET | /v1/ch/clearing/{iid} | $0.003 | Swiss BC-Nummer / IID — SIC, euroSIC, QR-IID |
POST | /v1/iban/compliance | $0.02 | Bank-level sanctions (OFAC, EU, UN) + FATF + SEPA Instant + VoP readiness + risk score 0-100 |
GET | /v1/iban/format | free | Pure mod-97 + structure check, no DB hit |
GET | /v1/iban/structure[/{country}] | free | IBAN templates per country, no auth |
GET|POST | /v1/reference/validate | free | RF/ISO 11649, Swiss QRR, Belgian OGM/VCS, Finnish viitenumero |
POST | /v1/address/check | free | ISO 20022 address vs sps / hvps_plus / fedwire rules |
GET | /v1/demo | free | Example validations, no auth |
GET | /v1/credits/bundles | free | Prepaid credit bundles and their prices |
GET | /health | free | Health + DB status |
POST | /v1/keys/generate | free | Generate an ifk_* API key: no body for a key that needs no e-mail (25 req/month, 200 once claimed at /v1/keys/claim), or {email} for 200 req/month from the start |
GET | /v1/keys/usage | free | Your key's usage this month (key in the Authorization header) |
Full OpenAPI 3.1: api.ibanforge.com/openapi.json.
POST /v1/iban/validate answers 200 with valid: false, an error code and an error_detail sentence. The codes: invalid_format, unsupported_country, wrong_length, invalid_check_digits, checksum_failed, invalid_bban_structure.{"error": "<token>", "message": "<sentence>"}: 400 for malformed JSON, a missing iban or a batch over 100; 402 when a payment is needed or an allowance is used up (cause.reason says which); 413 for a body over 256 KB; 429 past the rate limit.429 carries Retry-After, and every counted response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (rate-limits.yml).GET /v1/keys/usage, and X-Quota-Used, X-Quota-Limit, X-Quota-Remaining on every answer served on a monthly key; X-Credits-Remaining, X-Credits-Total on a prepaid credit key (GET /v1/credits/balance).key_prefix, never the key) or GitHub Issues.Local mod-97 catches typos. It does not tell you whether the bank code is allocated, resolve BIC/SWIFT, classify EMIs (Wise / Revolut / Mercury / Modulr, a real compliance signal), check SEPA reachability and VoP readiness, return Swiss BC-Nummer/QR-IID, or screen the payee's bank against sanctions lists. IBANforge does, in a single call.
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 build -t ibanforge .
docker run -p 3000:3000 --env-file .env ibanforge
Push to main — Railway auto-deploys via Dockerfile.
| Variable | Required | Description |
|---|---|---|
PORT | No | Server port (default: 3000) |
WALLET_ADDRESS | Yes (prod) | x402 USDC wallet address |
FACILITATOR_URL | Yes (prod) | x402 facilitator endpoint |
/llms.txt and /health. Breakdown as of the 2026-07 refresh (121,610 total):
/llms.txtnot_allocated; partial lists for Finland (Finance Finland), Italy (Banca d'Italia, with the codes it has struck off and their legal successor), San Marino (BCSM) and Luxembourg (ABBL), where a miss is not a refusalvop.csv), refreshed weekly with the other compliance listsIntl.DisplayNames APISome of these sources may be served but not redistributed: the EBA STEP2 and NBP directory rows, the OeNB, NBB and BCSM registers, the Bank of England PRA list, the UN list and the EPC registers. So are the Polish, Finnish and Luxembourg keys of the composite bank-code map and the Finance Finland list. They are not in this repository: the hosted API loads them from a private repository, and a deployment without them answers "not consulted" where they would have spoken, never "no". See NOTICE.
The keys of the composite map that came from sources granting no right to reuse them were removed on 29 September 2026, from this repository and from the service: all of them for the United Arab Emirates, Bosnia and Herzegovina, Estonia, Georgia, Kazakhstan, Moldova, Serbia and Türkiye, whose bank codes now answer "not consulted" with no BIC, part of them for Spain and Italy, and those of Romania. Where open data names one BIC, the Italian and Romanian ones were rebuilt from it (the Banca d'Italia's LEI and GLEIF, scripts/derive-map-keys.ts); the other Italian keys, taken from national files or added by hand, are unchanged. The Slovenian, Lithuanian, Hungarian and Croatian keys come from those countries' central banks, and every answer built from them carries the credit each asks for in bic.source.
llms.txt — short summary + recommended starter prompt/.well-known/x402 — x402 discovery (machine-readable catalog)/.well-known/mcp/server-card.json — MCP server card: full descriptions of the read-only data tools, every tool listed by name/.well-known/agents.json — Google A2A agent capabilities/openapi.json — OpenAPI 3.1 specibanforge-mcp — stdio MCP serverUse of the hosted API (api.ibanforge.com) is governed by the
Terms of Service. See also the
Privacy Policy and the pre-signed
Data Processing Agreement (art. 28 GDPR)
for customers whose calls involve personal data. Validation confirms IBAN
structure and registry data — it does not confirm that an account exists or
belongs to anyone.
MIT — see LICENSE.
The MIT License covers the code and its documentation, not the data files: the third-party records they contain remain subject to their publishers' terms, described in NOTICE. Records that may not be redistributed are no longer in this repository since 25 September 2026; earlier commits keep copies, still subject to those terms.
This project includes third-party components licensed under the Apache License 2.0
(notably @coinbase/x402 and related x402 packages). See NOTICE for
full attributions and required Apache 2.0 notices.
IBANFORGE_API_KEYsecretOptional Bearer ifk_* API key (free tier 200 req/month).
IBANFORGE_API_BASEOverride the API base URL (default https://api.ibanforge.com).