payments-toolkit-mcp
Payments Toolkit MCP is a local validation assistant for card numbers and IBANs, exposed as MCP tools, resources, prompts, and widget apps.
Validate card numbers: run a Luhn checksum check on 8–19 digit card numbers (
validate_card_numumber).Detect card network: identify Visa, Mastercard, American Express, Discover, Diners Club, or JCB from the card number's prefix (
detect_card_type).Validate IBANs: check country-specific length and ISO 13616 mod-97 checksum; results include country name and flag SVG (
validate_iban).Use the static resource: fetch the supported card networks and their prefix ranges via
payments-toolkit://card-networks.Render widget apps:
detect_card_typeandvalidate_ibanare bound to MCP App widgets (card-preview,iban-preview) for richer UIs.Prompt-assisted checks: use the
check_payment_detailsprompt to guide the model to run relevant tools and summarize results.Run in multiple modes: connect over stdio (Claude Code) or Streamable HTTP, and inspect tools via a local web UI.
Provides card number validation and network identification for American Express cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Provides card number validation and network identification for Diners Club cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Provides card number validation and network identification for Discover cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Provides card number validation and network identification for JCB cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Provides card number validation and network identification for Mastercard cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Provides card number validation and network identification for Visa cards, including Luhn checksum verification and IIN/BIN prefix recognition.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@payments-toolkit-mcpCheck if this card number is valid: 4111 1111 1111 1111"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
payments-toolkit-mcp
Payments Toolkit is a validation assistant for card numbers and IBANs. Ask in plain English — it checks card numbers (Luhn checksum and card network) and IBANs (format, country length, checksum) by running real validators.
Learn more: A validation assistant built on MCP, AG-UI, and MCP Apps
This is the MCP server: it exposes payments-related validation utilities as MCP tools, a static resource, two MCP Apps (widgets that render the card and IBAN tools' results), and a prompt template — all local logic, no network calls, no API keys required.
Table of Contents generated with DocToc
Tools
validate_card_number— Luhn checksum validation for a card number (digits only, 8-19 length).detect_card_type— identifies the card network (Visa, Mastercard, American Express, Discover, Diners Club, JCB) from the IIN/BIN prefix. Bound to thecard-previewMCP App widget.validate_iban— format, country-specific length, and ISO 13616 mod-97 checksum validation for an IBAN. Bound to theiban-previewMCP App widget; its result also carries the country name and flag SVG.
Related MCP server: stripe-mcp-server
Resources
card_networks(payments-toolkit://card-networks) — static JSON listing of supported card networks and their prefix ranges.card-preview(ui://payments-toolkit/card-preview) — MCP App widget HTML rendered bydetect_card_type.iban-preview(ui://payments-toolkit/iban-preview) — MCP App widget HTML rendered byvalidate_iban; shows the grouped IBAN, its country and flag, and whether the checksum passed. Flags are vendored from flag-icons (MIT) bypnpm run vendor:flags.
Prompts
check_payment_details— takes an optionalcardNumberand/oribanargument and returns a message instructing the model to run the relevant tools and summarize the results. Unlike tools, prompts are invoked explicitly by the user (e.g. as a/mcp__payments-toolkit-mcp__check_payment_detailsslash command in Claude Code), not chosen autonomously by the model.
Prerequisites
Node.js 18+ (project developed against v24)
Setup
pnpm install
pnpm run buildUsage
The server supports two transports, chosen at startup.
Stdio (default — one client per process, e.g. Claude Code/Desktop):
pnpm run startStreamable HTTP (a single long-running server multiple clients can connect to
over POST/GET/DELETE /mcp, with sessions keyed by the Mcp-Session-Id
header):
cp .env.example .env # first time only — fill in MCP_AUTH_TOKEN
pnpm run start:http # listens on PORT (default 3000).env is loaded automatically (via dotenv) and is gitignored. Stdio mode
doesn't use it — MCP_AUTH_TOKEN only matters for HTTP.
Inspect and call the tools/resource directly via a local web UI, without wiring up a client:
pnpm run inspectType-checking, linting, formatting, building
pnpm run typecheck # tsc --noEmit (server + tests + both widget tsconfigs)
pnpm run lint # eslint .
pnpm run lint:fix # eslint . --fix
pnpm run format # prettier --write .
pnpm run format:check # prettier --check .
pnpm run build # builds the widgets, compiles the server, copies flags into dist/
pnpm run toc # regenerates this README's table of contentsTesting
pnpm test # run the full suite once
pnpm run test:watch # re-run on file changes
pnpm run test:coverage # run once and print a coverage reportOnly pnpm test builds the widgets first (via its pretest hook). Run pnpm run build:widget beforehand if you use test:watch or test:coverage on a
fresh checkout — otherwise the widget-resource tests fail with ENOENT on
dist/ui/*/mcp-app.html.
Tests are split into two kinds, mirroring src/:
tests/unit/— pure logic (src/lib/*), no MCP or HTTP involved.tests/integration/—server.test.tswires the realMcpServerto a realClientover an in-memory transport and drives it throughtools/resources/prompts;http.test.tsdrives the Streamable HTTP transport's Express app directly with supertest to cover session creation/reuse/teardown.
Connect to Claude Code
Over stdio:
claude mcp add payments-toolkit-mcp -- node /path/to/payments-toolkit-mcp/dist/index.js
claude mcp listOver HTTP (start the server with pnpm run start:http first):
claude mcp add --transport http payments-toolkit-mcp http://localhost:3000/mcpInside a Claude Code session, run /mcp to confirm the connection and see the
discovered tools/resources/prompts. If you add or change a prompt after the
session already connected, reconnect via /mcp (or restart the session) — the
prompt list is enumerated at connection time.
Deployment
Running start:http as a standalone service (e.g. one Railway service talking
to another, rather than a local stdio child) needs:
MCP_AUTH_TOKEN— a shared-secret bearer token; every request must present it asAuthorization: Bearer <token>, checked with a constant-time comparison.runHttpthrows at boot if it's unset. See.env.example.No public domain. This token is defense-in-depth, not the primary boundary — the intended deployment puts this service on a private network (e.g. Railway's internal
*.railway.internalnetworking) reachable only by the caller that needs it, not the public internet. Full OAuth (the MCP Authorization spec) is overkill here: that model exists for third-party clients acting on behalf of many distinct end users, not a single caller you control.A
Dockerfileis included, mirroring the deployment conventions ofpayments-toolkit-agent(its consumer).DOTENV_CONFIG_QUIET=true— optional, but recommended on a platform (like Railway) that classifies logs by stream:dotenv@18+logs its own "injected env (N) from .env" line viaconsole.errorregardless of whether a.envfile was even found, which such a platform then flags as an error even though nothing failed. This variable silences that message; it's read directly bydotenv, not by this app's own code.
Notes
Over stdio, stdout is reserved for the JSON-RPC protocol stream, so that transport's logs go to stderr — never
console.logthere, useconsole.errorfor debug output. The HTTP transport has no such constraint, so its logs go to stdout instead (seesrc/lib/logger.ts);index.tssetsMCP_TRANSPORT(not meant to be set manually) so the logger picks the right one.Each MCP server instance can only be
connect()-ed to one transport, so the HTTP transport creates a freshMcpServerper session (keyed byMcp-Session-Id) rather than sharing one across clients.
Available Tools
3 toolsdetect_card_typeDetect Card TypeA
Identifies the card network (Visa, Mastercard, American Express, Discover, Diners Club, JCB) from the card number's IIN/BIN prefix. Accepts digits only (spaces/dashes should be stripped by the caller).
| Name | Required | Description | Default |
|---|---|---|---|
| cardNumber | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| network | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the core behavior (uses the IIN/BIN prefix) and the input requirement (digits only, caller must strip spaces/dashes). However, it does not describe what happens for invalid inputs (e.g., unknown prefix, out-of-specified length) or clarify that it performs no validation (suggested by sibling). There is no mention of side effects, but none are expected. It provides some transparency but leaves gaps.
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 two concise sentences that pack essential information: purpose, network list, and input preprocessing instruction. There is no extraneous text. It front-loads the core action and follows with important input guidance. Every word earns its place.
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 tool is simple with one parameter and an output schema, so description need not explain return values. It covers purpose, input format, and the IIN/BIN mechanism. It lacks explicit caveats (e.g., handling of unknown networks, validation not performed) but given complexity and annotations, it is reasonably complete. The lack of usage guidance vs. siblings is a minor gap, but overall adequate.
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 description adds value beyond the schema: it clarifies the parameter is the full card number and explicitly states that spaces/dashes should be removed, which complements the pattern '^\d{8,19}$'. It also explains the number's use (IIN/BIN prefix) that the schema doesn't convey. However, it does not mention the parameter name by name or provide additional format details (e.g., maximum length, examples). Given the schema has strong constraints, the description provides marginal extra semantics but not complete coverage.
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 function: 'Identifies the card network (Visa, Mastercard, American Express, Discover, Diners Club, JCB) from the card number's IIN/BIN prefix.' It specifies the resource (card number) and the action (detect card type), and lists the distinct networks. This distinguishes it from siblings like 'validate_card_number' (validation) and 'validate_iban' (IBAN), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description notes an input precondition: 'Accepts digits only (spaces/dashes should be stripped by the caller).' This is a clear usage instruction on formatting, but it does not provide guidance on when to choose this tool versus the sibling tools (validate_card_number, validate_iban). The usage is implied by the tool's name and purpose, but no explicit alternatives or exclusions are given. As such, it is adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_card_numberValidate Card NumberA
Checks whether a card number passes the Luhn checksum algorithm. Accepts digits only (spaces/dashes should be stripped by the caller).
| Name | Required | Description | Default |
|---|---|---|---|
| cardNumber | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It states the algorithm (Luhn) and input requirements (digits only, spaces/dashes stripped by caller), which is useful. However, it does not disclose what happens on invalid input (e.g., return value or error behavior) or any other side effects, leaving some gaps.
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 two sentences, front-loaded with the core purpose, and every sentence adds value. No wasted words.
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 simplicity (one parameter, clear algorithm) and the presence of an output schema, the description is fairly complete. It covers the algorithm, input constraints, and caller responsibility. It could mention the return format (boolean) but the output schema likely covers that, so this is adequate.
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 has 0% description coverage, so the description must compensate. It explains that the cardNumber should be digits only and that spaces/dashes should be stripped, which adds meaning beyond the schema's pattern. However, it does not explain the expected format beyond digits (e.g., length range) or the meaning of the return value, so it only partially compensates.
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: 'Checks whether a card number passes the Luhn checksum algorithm.' It uses a specific verb ('checks') and resource ('card number'), and the mention of the Luhn algorithm distinguishes it from sibling tools like detect_card_type and validate_iban.
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 clear context on when to use the tool (to validate a card number via Luhn) and includes a usage note about stripping spaces/dashes. However, it does not explicitly state when not to use it or mention alternatives like validate_iban for other validation needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_ibanValidate IBANA
Validates an International Bank Account Number (IBAN): checks the country-specific length and the ISO 13616 mod-97 checksum. Spaces are stripped and letters are case-insensitive.
| Name | Required | Description | Default |
|---|---|---|---|
| iban | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes | |
| country | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With zero annotations, the description carries full burden and does add useful non-obvious behaviors: spaces are stripped and letters are case-insensitive. However, it omits other behavioral traits like side-effect-free execution, error behavior on invalid input, or whether validation is local. Adds genuine context but doesn't fully cover the space.
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?
Two efficient sentences: the first states purpose and validation depth; the second covers input normalization edge cases. Zero wasted words, information density is excellent, and the most important information is front-loaded.
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 single-parameter validation tool with an output schema, this description is nearly complete: it explains the validation logic (length + checksum) and accepted input forms. Annotations are absent, so a note on read-only/side-effect-free semantics would push it to 5, but the scope is fully appropriate for its complexity.
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 0%, so the description must compensate—and it does by explaining that the iban string tolerates spaces (stripped) and case variations. This meaningfully enriches the bare schema definition (string, 4-50 chars). Could go further by noting whether other whitespace (tabs) is stripped, but for one parameter it's well-handled.
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?
Uses a specific verb ('Validates') with a well-defined resource ('International Bank Account Number (IBAN)') and names the exact validation standard (ISO 13616) and checksum algorithm (mod-97). The IBAN domain is self-evidently distinct from sibling card tools, and the technical specificity makes the tool's 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 description clarifies what 'validates' means by specifying both length checks and checksum verification, giving agents a clear sense of this tool's validation depth. However, it provides no explicit when-to-use vs. alternatives (e.g., no contrast with validate_card_number or note that this is local-only validation).
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.
3 tool updates
v1.0.0- First observed
detect_card_type - First observed
validate_card_number - First observed
validate_iban
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: validate_card_number checks Luhn, detect_card_type identifies network via prefix, and validate_iban validates IBAN. No overlap between card validation and IBAN validation, and card type detection is a separate concern.
All tools follow the verb_noun pattern (validate_*, detect_*), but there's a slight inconsistency: 'validate_card_number' uses 'card_number' while 'detect_card_type' uses 'card_type', but both are clear and consistent in style. Minor deviation from uniform noun usage.
With only 3 tools, the server is focused but feels slightly thin for a 'payments-toolkit'. The scope is narrow (validation/detection), but it could benefit from additional related tools like card expiry validation or payment amount validation. However, it's not egregiously under-scoped.
The server covers card number validation and type detection and IBAN validation, which are core payment validation tasks. However, it omits other common validations (e.g., CVV, expiry date, bank account routing numbers) and any operations beyond validation (e.g., formatting, masking). The gaps are notable but the main validation lifecycle is present.
Maintenance
Related MCP Connectors
Finans/kimlik doğrulama MCP sunucusu: IBAN, BIC/SWIFT, ABD ABA/ACH yönlendirme no, kart (Luhn/BIN…
MCP server for Modern Treasury — payment orders, transactions, counterparties and ledgers.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceAn MCP server for validating JSON against schemas, checking email deliverability, verifying URLs, assessing data quality, and validating API responses using RFC-compliant checks and heuristic analysis.4 npmMIT
- AlicenseAqualityDmaintenanceA local MCP server for Stripe payment operations with 52 tools across 8 domains, featuring built-in PII redaction and strict input validation for safe AI-assisted development workflows.5222 npm1MIT
- AlicenseAqualityCmaintenanceAn MCP server that provides AI agents with tools to validate SWIFT MT and ISO 20022 MX payment messages, check BIC/IBAN correctness, and convert between MT and MX formats.710 npmMIT
- FlicenseAqualityAmaintenanceA fully local, closed-world MCP server that manages, validates, and serves bank-specific ISO 20022 clearing profiles and rule packs, enabling AI agents to discover profiles, fetch them, lint payloads against them, and validate rule-pack definitions.442 PyPI1-