Skip to main content
Glama
payments-toolkit-mcp

payments-toolkit-mcp

by ramigs

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 the card-preview MCP App widget.

  • validate_iban — format, country-specific length, and ISO 13616 mod-97 checksum validation for an IBAN. Bound to the iban-preview MCP 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 by detect_card_type.

  • iban-preview (ui://payments-toolkit/iban-preview) — MCP App widget HTML rendered by validate_iban; shows the grouped IBAN, its country and flag, and whether the checksum passed. Flags are vendored from flag-icons (MIT) by pnpm run vendor:flags.

Prompts

  • check_payment_details — takes an optional cardNumber and/or iban argument 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_details slash command in Claude Code), not chosen autonomously by the model.

Prerequisites

  • Node.js 18+ (project developed against v24)

  • pnpm

Setup

pnpm install
pnpm run build

Usage

The server supports two transports, chosen at startup.

Stdio (default — one client per process, e.g. Claude Code/Desktop):

pnpm run start

Streamable 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 inspect

Type-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 contents

Testing

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 report

Only 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.ts wires the real McpServer to a real Client over an in-memory transport and drives it through tools/resources/prompts; http.test.ts drives 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 list

Over HTTP (start the server with pnpm run start:http first):

claude mcp add --transport http payments-toolkit-mcp http://localhost:3000/mcp

Inside 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 as Authorization: Bearer <token>, checked with a constant-time comparison. runHttp throws 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.internal networking) 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 Dockerfile is included, mirroring the deployment conventions of payments-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 via console.error regardless of whether a .env file 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 by dotenv, 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.log there, use console.error for debug output. The HTTP transport has no such constraint, so its logs go to stdout instead (see src/lib/logger.ts); index.ts sets MCP_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 fresh McpServer per session (keyed by Mcp-Session-Id) rather than sharing one across clients.

Available Tools

3 tools
detect_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).

Inputs: cardNumber (required). Returns: network

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).

Inputs: cardNumber (required). Returns: valid

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.

Inputs: iban (required). Returns: valid, country

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 3 tools

    Disambiguation5/5

    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.

    Naming Consistency4/5

    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.

    Tool Count3/5

    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.

    Completeness3/5

    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

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      An 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.
      8 npm
      19 PyPI
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      A 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.
      52
      49 npm
      1
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      An 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.
      7
      6 npm
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      A 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.
      4
      30 PyPI
      1
      Apache 2.0