Open-source B2B and marketplace ecommerce; new stores include an MCP server for AI agents.
SendCheck — EVM address verification (x402)
Überblick
Beschreibung vom Entwickler (englisches Original)
Pre-send EVM address checks: free pre-check, $0.01 check, $0.05 deep scan. x402: payment is auth.
Die drei Säulen von PopNx MCP
Diese drei werden nie zu einer Punktzahl zusammengefasst: Meinungen, Messungen und Beliebtheit sind verschiedene Dinge.
- Stimmen der NutzeriNoch keine BewertungenBewertungen starten in einem späteren Schritt zusammen mit Benutzerkonten
- Unsere Basischecksi1 von 1 bestandenAnhand öffentlicher Informationen geprüft; Code noch nicht gescannt
- NutzungiNoch nicht gemessen★ –
Was du damit machen kannst
Für diesen Server haben wir noch keine Zusammenfassung in einfacher Sprache geschrieben. Unten stehen die Fakten, die wir aus der Registry gelesen haben.
- Verbindung: Läuft in der Cloud
- Transport: Streamable HTTP
- Kategorie: Onlineshops & Zahlungen
Installation
Wähle die KI-App, die du nutzt, und kopiere die Einstellungen.
Bevor du installierst
- Basischecks: 1 von 1 bestanden
- Läuft auf dem Server des Entwicklers: Was du fragst, läuft über dessen Server.
- Die Registry nennt keinen Schlüssel zum Eintragen.
Du brauchst
- Läuft in der CloudNichts zu installieren; die Verbindung läuft übers Internet
Welche App nutzt du?
Wähle oben deine App. Wir merken sie uns, damit der Button beim nächsten Mal „In … installieren“ anzeigt.
Funktioniert in Claude im Web, auf dem Desktop und auf dem Handy:
- Öffne Settings → Connectors
- Tippe auf Add custom connector
- Füge die Adresse unten ein und tippe auf Add
- Wenn eine Anmeldung verlangt wird, melde dich beim Dienst des Entwicklers an
https://api.pennyforge.org/mcpFühre das in deinem Terminal aus
claude mcp add --transport http sendcheck https://api.pennyforge.org/mcpOder kopier die Einstellungen selbst
In .cursor/mcp.json in deinem Projekt oder in ~/.cursor/mcp.json einfügen
{
"mcpServers": {
"sendcheck": {
"url": "https://api.pennyforge.org/mcp"
}
}
}Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.
Oder kopier die Einstellungen selbst
In .vscode/mcp.json in deinem Projekt einfügen
{
"servers": {
"sendcheck": {
"type": "http",
"url": "https://api.pennyforge.org/mcp"
}
}
}Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.
ChatGPT verbindet sich nur mit Servern im Internet:
- Öffne ChatGPT im Web → Settings → Connectors (Apps)
- Tippe auf Create oder Add (bei manchen Tarifen musst du zuerst Developer mode unter Advanced einschalten)
- Füge die Adresse unten ein, gib ihr einen Namen und speichere
- Wenn eine Anmeldung verlangt wird, melde dich beim Dienst des Entwicklers an
https://api.pennyforge.org/mcpMenünamen können sich je nach Tarif und mit der Zeit leicht unterscheiden.
Deine Auswahl bleibt in einem Cookie auf diesem Gerät; kein Konto nötig.
Diese Einstellungen werden aus dem Registry-Eintrag des Entwicklers erzeugt. Wenn in der README etwas anderes steht, folge der README.
Was er kann
Die Tool-Liste dieses Servers haben wir noch nicht gelesen; wir prüfen die Endpunkte reihum.
Basischecksi
Wir prüfen Informationen, die jeder sehen kann; den Code haben wir nicht gelesen. Checks, die nicht zutreffen, werden nicht mitgezählt. · Geprüft am 6. Nov. 2026
- ✓ Bestanden
Entwickler passt zum Repo
Der Registry-Name wurde über die Domain api.pennyforge.org bestätigt (die Registry prüft, wem die Domain gehört)
- … Noch nicht geprüft
Wird noch gepflegt
Dieses Repo haben wir noch nicht von GitHub gelesen
- … Noch nicht geprüft
Hat eine Lizenz
Dieses Repo haben wir noch nicht von GitHub gelesen
- … Noch nicht geprüft
Endpunkt antwortet
Noch nicht geprüft; wir prüfen die Endpunkte reihum
- … Noch nicht geprüft
Anmeldung mit OAuth
Noch nicht geprüft; wir prüfen die Endpunkte reihum
- … Noch nicht geprüft
Keine versteckten Anweisungen in Tool-Beschreibungen
Noch nicht geprüft; wir lesen die Tool-Liste, wenn wir den Endpunkt prüfen
Im Vergleich mit anderen in Onlineshops & Zahlungeni
- Mehr Sterne als 0 % der anderen 1741 Server in dieser Kategorie
- Neuer in der Registry veröffentlicht als 38 % der anderen 1741 Server in dieser Kategorie
- Basischecks gleich gut wie oder besser als bei 100 % der anderen 1741 Server in dieser Kategorie
Verglichen mit allen aktiven Servern dieser Kategorie in der Registry. Sterne zählen nur, wenn dem Herausgeber das Repo gehört.
Häufige Fragen
Ist SendCheck — EVM address verification (x402) sicher?
Er hat 1 von 1 zutreffenden Basischecks bestanden. Den Code haben wir nicht gelesen. Bevor du einen Schlüssel oder Token hinzufügst, sieh nach, welche Zugriffe der Server verlangt, und nutze einen Schlüssel, der nur die Berechtigungen hat, die du brauchst.
Welche Schlüssel oder Codes braucht er?
Die Registry nennt keinen erforderlichen Schlüssel, manche Server bitten dich aber bei der ersten Nutzung, dich anzumelden.
Läuft er auf meinem Computer oder in der Cloud?
Er läuft in der Cloud des Entwicklers. Du verbindest dich übers Internet, ohne etwas zu installieren, aber was du sendest, läuft über die Server des Entwicklers.
Wird er noch gepflegt?
Das GitHub-Repo wurde zuletzt – geändert, und die neueste Version (1.0.0) kam vor 2 Monaten in die Registry.
Welche Apps können ihn nutzen?
Apps, die MCP unterstützen, etwa Claude Desktop, Claude Code, Cursor und VS Code. Er verbindet sich per URL, also funktionieren auch Apps, die Remote-MCP-Server akzeptieren, zum Beispiel ChatGPT im Entwicklermodus.
Was kann ich stattdessen nutzen?
In derselben Kategorie: Spree Commerce: open-source B2B and marketplace ecommerce, Stripe MCP, MCP Cn Commerce
Alternativen
Server derselben Kategorie von anderen Entwicklern, sortiert nach Sternen.
So liest du eine Karte:★ GitHub-SterneiDrei Säulen: Bewertungen · Checks · NutzungiAktualisiert = neueste Version in der Registry veröffentlichti
Stripe MCP
MCP server integrating with Stripe - tools for customers, products, payments, and more.
MCP Cn Commerce
8 read-only MCP platform entries; support is operation-specific; merchant live acceptance pending
README vom Entwickler
README öffnen
Unverändert aus dem Repo des Entwicklers übernommen. PopNx MCP hat den Inhalt weder geprüft noch empfiehlt es ihn. HTML, Bilder und Skripte wurden entfernt. Links führen von dieser Website weg.
sendcheck-verify
Verify before you pay. A zero-dependency client for the free GET /validate pre-check on the SendCheck x402 API — the 10-line guard that stops your agent from signing a payment to a mistyped, mismatched, or tampered settlement address.
When an x402 client pays a service, it pays the settlement address the service told it about. A single wrong character (a case-flip, a dropped digit, a substituted address) and the USDC goes somewhere else forever. /validate is the free, no-key, no-account pre-check: is this address even a well-formed, correctly-cased EVM address before you put real money on it?
Since v0.2.0 the package does one more thing: it verifies the service's signed service card — an ES256 JWS over the payTo and the per-route maxPrice that the worker re-signs at every deploy — so a client that pinned the public key once can confirm the challenge's payTo cryptographically, before paying. That is the reference implementation of the drift-proof check (the "signed service card" from the address-drift article).
Why this exists
SendCheck's paid endpoints cost $0.01 (one chain) or $0.05 (all five chains) via x402 — USDC on Base, no account, no API key. But most "is this address garbage?" checks don't need chain data: the EIP-55 checksum alone catches the most common, most expensive failures (typos, dropped characters, tampered casing). So /validate is free, and this package makes calling it one line.
The signed service card (v0.2.0)
Pre-payment address checks have a hole: the "expected payTo" a client compares against usually comes from the same discovery doc it just fetched — so a compromised service can point you at its own new address, and for a service that rotates its address often, every remembered address is stale before the check finishes.
SendCheck closes that hole by signing its payment details. The worker signs the settlement address and the per-route max prices with a stable ES256 (EC P-256) key at every deploy, and serves the signed block { jws, key } in three places:
<origin>/.well-known/x402 → top-level "attestation"
/openapi.json → info["x-attestation"] the 402 challenge itself → extensions["x-sendcheck-attestation"]
**SendCheck signs its payment details with a stable key at every deploy, so
any client that has pinned that key once can cryptographically confirm —
before paying — that the address in the payment challenge is one we signed;
first contact is still trust-on-first-use.**
What the signature buys: key continuity for returning, stateful clients — a compromised worker/DNS/CDN cannot silently redirect your payments, and a rotated key is a *loud* event you can flag. What it does not buy (we under-claim on purpose): first-visit authenticity (that is TOFU), protection for ephemeral agents with no pin, or a price *below* the signed maxPrice.
The signed payload also carries a per-route maxPrice, so verifyChallenge catches a challenge that quietly raises the price above what the key signed.
The drift-proof wiring
import { checkService, verifyChallenge, ATTESTATION_EXTENSION } from "@pennyforgeorg/sendcheck-verify";
const origin = "https://api.pennyforge.org";
// 1) Once: pin the public key (first contact = trust-on-first-use). const first = await checkService(origin); // { ok, keyId, key: JWK, payTo, … } // persist { kid: first.keyId, x: first.key.x, y: first.key.y } somewhere durable
// 2) Every call: confirm the card still verifies and the key has not rotated. const svc = await checkService(origin, { pinnedKey: storedPin }); if (svc.keyChanged) { /* loud: the key rotated — inspect before trusting */ } if (!svc.ok) throw new Error("service card not valid: " + svc.attestation.reason);
// 3) At payment time: bind the 402 CHALLENGE to the signed card. // (challenge = decoded base64 PAYMENT-REQUIRED header, or the 402 JSON body) const verdict = await verifyChallenge(challenge, svc.block, { origin }); if (!verdict.valid) throw new Error("challenge not signed: " + verdict.reason); // …now sign the EIP-3009 payment to challenge.accepts[0].payTo.
verifyChallenge checks the challenge's payTo against the signed one and the challenge price against the signed maxPrice for the challenged route. Failure reasons: signature_invalid, challenge_payto_mismatch, price_exceeded, route_not_signed, expired, iat_future, service_mismatch, kid_mismatch, malformed.
Install
# GitHub npm registry (v0.2.0 published 2026-09-08)
npm install @pennyforgeorg/sendcheck-verify --registry https://npm.pkg.github.com
GitHub's npm registry asks for any valid GitHub token even on public reads — put //npm.pkg.github.com/:_authToken= in your .npmrc (classic PAT or fine-grained with Packages:Read works). No token handy? Install from the public repo:
npm install github:pennyforgeorg/sendcheck-verify
Requires Node 18+ (uses global fetch). Zero dependencies. MIT.
Quickstart
import { verifyBeforePay } from "@pennyforgeorg/sendcheck-verify";
// Throws SendCheckVerifyError unless the address passes the free pre-check. await verifyBeforePay("0x9504A5939AB5be2B2B1F8beA7D7ebeCcd96c485D");
// …then sign your x402 payment.
CommonJS:
const { verifyBeforePay } = require("@pennyforgeorg/sendcheck-verify");
Typical wiring inside an x402 client:
import { verifyBeforePay } from "@pennyforgeorg/sendcheck-verify";
import { wrapFetchWithPayment } from "x402-fetch"; // or your own x402 stack
const pay = wrapFetchWithPayment(fetch, { wallet });
async function call(serviceUrl, address, body) { await verifyBeforePay(address); // free — catch bad addresses here const res = await pay(serviceUrl, { // paid only when the address is clean method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), }); return res.json(); }
If you already normalize addresses on your side and just want the result object (no throw):
const r = await verifyBeforePay(addr, { throwOnError: false });
// { valid, status: "valid" | "plain" | "mismatch" | "format" | "network" | "http", // message, normalized, checked }
API
verifyBeforePay(address, opts?)
address— EVM address,0x+ 40 hex.opts.baseUrl— override the API host (default: the live worker).opts.fetchFn— inject a fetch implementation (tests / proxies).opts.throwOnError— defaulttrue; passfalseto always get the result back.
Behavior notes:
- A string that isn't even
0x+40-hex fails the local format check and throws (or returnschecked: false) without sending a request — you never pay a round trip for garbage input. status: "plain"= valid address, all-lowercase or all-uppercase (no case information). That's fine to pay; the response includes the normalized EIP-55 form.status: "mismatch"= the casing does not match the address hash — usually a typo or tampering. This is the one to treat as hard-fail.
looksLikeAddress(addr) — offline format check, no network.
verifyAttestation(attestation, opts?)
Verify a signed block { jws, key } (ES256 JWS over a canonical-JSON payload). Pure + async (WebCrypto); no network. Returns { valid, reason?, payload, keyId, signedAt, expiresAt, warning? }. opts: origin, expectedPayTo, challengePayTo, route, challengeMaxAmount (atomic USDC string), now (unix seconds, for tests). Time windows: exp hard-reject with a 60s clock-skew grace; iat may be up to 60s in the future; an iat older than 30 days is valid but returns warning: "stale". reason codes: malformed, header_mismatch, kid_mismatch, signature_invalid, service_mismatch, payto_mismatch, challenge_payto_mismatch, route_not_signed, price_exceeded, expired, iat_future.
checkService(origin, opts?)
Fetch /.well-known/x402, verify its signed card against the doc's own advertised payTo, and report whether a pinned key changed. Returns { ok, origin, payTo, keyId, signedAt, expiresAt, warning?, attestation, keyChanged, endpoints: [{resource, amount}] }. opts.fetchFn (inject fetch), opts.pinnedKey ({kid} or {kid,x,y}), opts.throwOnError. keyChanged is the loud rotation signal.
verifyChallenge(challenge, attestation, opts?)
Bind a 402 challenge to a signed card. challenge is the decoded 402 declaration ({ resource: { url }, accepts: [{ payTo, maxAmountRequired }] }) — decode the base64 PAYMENT-REQUIRED header with JSON.parse(Buffer.from(hdr, "base64").toString("utf8")). The route is derived from resource.url. Returns the verifyAttestation result.
ATTESTATION_EXTENSION — "x-sendcheck-attestation", the extension name
the signed block rides in under inside the 402 challenge's extensions map.
canonicalJson(value) — RFC-8785-style canonical JSON (recursively sorted
keys) — exported for anyone re-implementing the signer.
SendCheckVerifyError — thrown on non-valid results; err.result carries
the full result object.
The endpoint, in plain terms
GET https://api.pennyforge.org/validate?address=0x…
→ 200 { "valid": true, "status": "valid", "message": "Valid EIP-55 checksum.", "normalized": "0x…" }
Free. No key. No account. JSON in, JSON out. The paid siblings — POST /check ($0.01, one chain: wallet-vs-contract, activity, balances, verdict) and POST /deep ($0.05, all five chains + wrong-network detection) — use x402 (USDC on Base). Machine-readable docs: llms.txt and openapi.json on the same host.
Who runs it
SendCheck is a one-person studio (Pennyforge). The worker runs on Cloudflare Workers; the address engine is MIT and public here. If the free endpoint ever moves, opts.baseUrl is the only thing you change.
License
MIT — see LICENSE.