# Check Digits

**Category:** 💰 Finance & Fintech  
**Repository:** https://github.com/toolstop/toolstop  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/check-digits

## Description
Catch a mistyped IBAN, card, barcode, VIN or routing number before it causes a failed payment.

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "check-digits": {
    "command": "npx",
    "args": ["-y","check-digits"]
  }
}
```

## Documentation & README

# toolstop

Small, stateless MCP servers. Each one does a single narrow job exactly, so an
assistant can call it instead of guessing.

Every server runs on Cloudflare Workers at `<name>.toolstop.dev`, holds no
state, and can also run locally over stdio.

## Servers

| Server | Does | Endpoint |
|---|---|---|
| [check-digits](packages/mcp-check-digits) | Validates check digits for IBAN, LEI, ISBN, GTIN/UPC/EAN, VIN, NPI, ISIN, ABA routing numbers and payment cards | `https://check-digits.toolstop.dev` |

## Connecting

Remote, over streamable HTTP. No install, no account:

```json
{
  "mcpServers": {
    "check-digits": {
      "type": "url",
      "url": "https://check-digits.toolstop.dev"
    }
  }
}
```

Local, over stdio:

```bash
npx @toolstop/check-digits
```

## Design

**Stateless.** No database, no vector index, no metered upstream API. A request
is answered from its arguments alone. Servers scale to zero and an idle one
costs nothing.

**Zero runtime dependencies.** No MCP SDK, no schema library. MCP over
streamable HTTP is request/response, which makes hand-rolled dispatch small
enough to be worth it: faster cold starts, and no supply chain.

**Telemetry records shape and outcome, never argument values.** A check-digit
server that logged its input would be storing real IBANs and card numbers. The
transport emits one row per request describing *what kind* of call happened and
whether it succeeded. `packages/_shared/transport.test.mjs` asserts that no raw
argument value can reach it.

The row also carries a session id, and it is derived from the **network** the
request came from, truncated to a /24 or /48 before hashing, never the full
address. Hashing the whole IP would not have anonymised it: the IPv4 space is 32
bits and the other inputs are public, so the id was walkable back to one address
until this was fixed on 2026-08-10. Each server's README states the complete
recorded row rather than only what is left out.

**Every tool declares `readOnlyHint`, a complete `inputSchema` and an
`outputSchema`**, so a client can tell what a call will do before making it and
what shape comes back. The transport refuses to start a server whose tools do
not state their annotations, rather than defaulting them to something reassuring.

## Repo layout

```
packages/_shared/     shared transport, dispatch and telemetry
packages/mcp-<name>/  one server
scripts/discover.mjs  derives the CI matrix from the filesystem
scripts/smoke.mjs     protocol check against a live endpoint
```

See [CLAUDE.md](CLAUDE.md) for the operating manual.

## Development

```bash
npm install
npm test                                # every server plus the shared transport
node scripts/smoke.mjs mcp-check-digits # protocol check against the live endpoint
```

## License

MIT

