LLMs accept malformed IBANs, mistype card check digits, and invent ISBN and VIN check digits — confidently and silently. veridigit gives an agent the real checksum algorithms instead, returning a structured result with the parsed parts and clear reasons when something is wrong. It ships as both an MCP server and a typed TypeScript library.
| Identifier | LLM-alone error | veridigit | |
|---|---|---|---|
| IBAN (mod-97 check digits) | 100% | 0% | |
| VIN (ISO 3779 check digit) | 100% | 0% | |
| ISBN-13 (mod-10 check digit) | 88% | 0% | |
| Payment card (Luhn check digit) | 75% | 0% |
Method: 32 check-digit questions on randomly generated, non-memorised
identifiers, asked of a frontier model with no tools, scored against the algorithmic
answer. veridigit is deterministic, so it is correct by construction. The baseline is
one frontier model, tool-free, at temperature 0 — reproduce it on any model with the
harness in the repo (bench/).
As an MCP server, in your client config:
{
"mcpServers": {
"veridigit": { "command": "npx", "args": ["-y", "veridigit"] }
}
}
As a TypeScript library:
npm install veridigit
import { validateIban, validateCard } from "veridigit";
validateIban("GB82 WEST 1234 5698 7654 32");
// { valid: true, country: "United Kingdom", checkDigits: "82", ... }
validateCard("4111 1111 1111 1111");
// { valid: true, luhnValid: true, brand: "Visa", ... }
validate_ibanISO 7064 mod-97 checksum and country-specific length, 75+ countries.
validate_cardLuhn checksum, brand from BIN (Visa, Mastercard, Amex, Discover, Diners, JCB, UnionPay), length rules.
validate_isbnISBN-13: 978/979 prefix and the mod-10 weighted check digit.
validate_vinISO 3779 alphabet (no I/O/Q) and the position-9 transliteration check digit.
veridigit validates the structure of an identifier — its format and checksum. It does not confirm that a bank account, card, book or vehicle actually exists, is active, or belongs to anyone, and it makes no network calls.