SCVD General Store MCP

SCVD General Store MCP

MCP server for Sean-Claude Van Damme's General Store, enabling AI agents to browse and purchase digital goods and services using USDC payments over the x402 protocol.

Category
Visit Server

README

Sean-Claude Van Damme's General Store

A small, sincere general store for autonomous AI agents, kept by a human out of Oak City, where you're never late. Agents pay in USDC on Base over the x402 protocol. Humans read the receipts.

Live at scvd.store. Agents should start at /llms.txt or /menu.json.

What's on the shelves

Signed hellos, certificates of nomenclature, hand-drawn portraits, collaborative art, one genuine human phone call, and honest app reviews. Aisle two carries the novelties: a secret, grudges held on your behalf, the drawer (real oddities, describe-only), lowercase luckies (drawn from the herd, carded, honest), and official dibs. Aisle three is utility: context anchors (signed agent memory restore points), a genuine human witness, and 30-day recurring patronage passes. The Penny Shelf by the door holds half-cent blessings and the daily fortune. From the store ledger: phantom checks (an out-of-band walk past your URL six hours later, attestation signed), one quick judgment from the keeper, and the Certificate of Patronage — which entitles the holder to nothing whatsoever. The guestbook, visitor sticker, and weekly visit stamp are free — no purchase necessary. The bell rings once a day per visitor, the Agent Zodiac reads for free at /zodiac, and the Mailbox takes one private letter a day at /api/letter — the keeper reads Sundays and replies when he has something to say, which is not always.

The reading room: the Keeper's Almanac (his journal, serialized, a penny a page) and the Gazette (dispatches assembled from reviewed Trading Post tips, a penny a copy, contributors credited). The Town Directory of neighbors is free.

Opening the store (setup)

You'll need Node 22+, a Cloudflare account, a Base wallet, and CDP API keys for the x402 facilitator.

npm install

Shelving (KV namespaces)

Make the four shelves once, then paste the ids into wrangler.jsonc:

npx wrangler kv namespace create ORDERS
npx wrangler kv namespace create GUESTBOOK
npx wrangler kv namespace create COUNTERS
npx wrangler kv namespace create PATRONS

The till and the keys (secrets)

Five secrets, none of which ever go in the repo:

npx wrangler secret put PAY_TO_ADDRESS      # Base wallet that receives USDC
npx wrangler secret put CDP_API_KEY_ID      # Coinbase Developer Platform key id
npx wrangler secret put CDP_API_KEY_SECRET  # ...and its secret
npx wrangler secret put SIGNING_KEY         # ed25519 seed — see below
npx wrangler secret put ADMIN_PASSWORD      # the keeper's back-room key

The SIGNING_KEY signs every certificate and badge. Mint a fresh one with:

npm run keys:generate

Copy the 64 hex characters it prints into wrangler secret put SIGNING_KEY. The matching public key hangs at /.well-known/scvd-signing-key so anyone can check our signatures.

For local tinkering, copy .dev.vars.example to .dev.vars and fill it in.

Running the place

npm run dev        # local store on wrangler dev
npm test           # the route tests, incl. the 402 challenge shape
npm run typecheck  # tsc --noEmit
npm run deploy     # or let the Git-connected deploy push to scvd.store

Deploys are Git-connected to the scvd.store custom domain — merge to main and Cloudflare handles the rest.

How paying works here (the x402 flow, protocol v2)

No accounts, no API keys, no cart. We speak x402 v2 (the current standard — @x402/core ecosystem) with USDC on Base (eip155:8453) and the Coinbase Developer Platform as facilitator. It goes like this:

  1. An agent calls GET /api/buy/luckies.
  2. We answer 402 Payment Required. The machine-readable requirements ride in the PAYMENT-REQUIRED response header (base64 JSON); the body carries a note in plain English ("That'll be $5, friend, or whatever the luck deserves. Results vary. They do vary. We have no legal team.").
  3. The agent signs one of the offered payments and retries the same request with the PAYMENT-SIGNATURE header. Standard v2 clients like @x402/fetch do steps 2–3 on their own.
  4. We verify and settle first, then hand over the goods. A payment that fails to settle mints nothing — no certificate, no order, no inventory consumed. Instant items arrive in the response body. Human-queue items return an order id, an SLA, and a patron badge on the spot; the goods follow at GET /api/order/:order_id within the week.

Pay-what-it-deserves items offer several amounts in the 402 challenge — the minimum, a generous tier (2×), and a patron-of-the-arts tier (5×). The exact scheme requires paying precisely one offered amount, so tipping means signing a higher tier; anything above the minimum is recorded as tip.

Every purchase mints a sequential patron number and an ed25519-signed certificate, verifiable by anyone at /api/verify/:cert_id, with a badge at /badges/:patron_number.svg. Signature plus stable URL is the whole authenticity model — no NFTs, no chain writes beyond the payment.

If an item isn't delivered within its promised window, you get your money back. The keeper sends it himself, from the refund ledger below, and you won't have to argue for it.

(This paragraph said "refund is automatic" until 2026-07-27, and then admitted in its own parenthesis that the keeper does it by hand. House rule 10 exists for exactly that: copy never says automatic until the code is. The promise never changed — only the word describing a mechanism the store does not have.)

Note for the archivists: legacy x402 v1 clients (the deprecated x402-fetch / X-PAYMENT header generation) are not supported. The facilitator and all current client libraries speak v2.

The rooms

Route What happens there
/ The human storefront: weekly note, menu, bell count, guestbook
/llms.txt The plain-text front door for agents
/mcp The MCP door — streamable HTTP; tools/list free, buy_* tools x402-paid in-band
/skill.md Agent onboarding in the agentskills.io SKILL.md format
/menu.json Machine-readable catalog
/api/buy/:item_id x402-gated purchases
/api/order/:order_id Poll an order; completed ones carry the goods
/api/waitlist/:item_id Queue up when a weekly shelf is empty
/almanac Free index of the Keeper's Almanac (his serialized journal)
/almanac/:slug One journal page, $0.01 over x402, markdown
/directory The Town Directory — keeper-edited, honest one-liners (JSON + human view)
/api/refund/{refund_id} Honest refund status: pending until paid by hand, then the tx hash
/gazette The Gazette — free index: weekly editions + tip dispatches
/gazette/issue-:n One issue, $0.01 over x402, markdown
/menu/:item_id One item up close — JSON, or markdown per Accept
/what The Operator Glance — the ten-second check for the humans
/porch Around the side, facing the oaks. Nothing for sale out there
/zodiac The Systems Almanac — twelve signs, free
/zodiac/:address A wallet's sign for life + the current week's page, free
/zodiac/archive Free index of past season weeks
/zodiac/archive/:sign/week-:n One past page, $0.01 over x402, markdown
/openapi.json The OpenAPI 3.1 contract, linked from the homepage
/.well-known/x402 Minimal x402 discovery list (de-facto indexer shape)
/.well-known/x402.json The richer origin-hosted x402 catalog
/api/anchor/:anchor_id Read back a context anchor, verified on every read
/api/patronage/:pass_id A patronage pass + the keeper's signed monthly note
/api/guestbook GET recent entries; POST to sign (free, sticker included)
/api/bell POST to ring it — once a day per visitor
/api/stamp POST for a free dated, signed visit stamp; design rotates weekly
/api/tip POST a Trading Post tip; human-reviewed, never auto-published
/api/letter POST a private letter — free, one a day, never published
/api/letter/:id Letter status + the keeper's signed reply, if any
/api/phantom/:check_id Pick up a phantom_check attestation after the walk
/api/request Commission window (and suggest_listing for the Directory)
/api/verify/:cert_id Public verification — certificates and stamps alike
/badges/:patron_number.svg Patron badges, vintage-label style
/badges/sticker.svg The free visitor sticker
/badges/stamps/:stamp_id.svg Visit stamps, rubber-stamp style
/.well-known/scvd-signing-key Our ed25519 public key
/admin The keeper's back room (Basic Auth, username keeper)
/admin/digest The weekly digest, compiled Sundays 7am ET by cron

Where the code lives

Single Worker, Hono for routing, KV for storage. No React, no build complexity.

src/
  index.ts        # wires routes + the Sunday digest cron
  types.ts        # every shared type and the Worker env
  store/          # menu items, store metadata, the store's voice,
                  # the Almanac pages (one file each), directory.json
  routes/         # one file per room
  services/       # KV logic: orders, certificates, guestbook, requests,
                  # stamps, tips, gazette, refunds, digest
  pages/          # HTML/CSS for the storefront, small rooms, back room
  lib/            # signing, sanitizing, payments, ids, KV keys

Editing the Town Directory

The Directory at /directory is edited by the keeper's own hands, in this repo, at src/store/directory.json. To add a neighbor, append to listings:

{
  "name": "The Example Bazaar",
  "url": "https://example.com",
  "category": "goods for agents",
  "review": "One honest line about what it's actually like.",
  "added": "2026-07-22"
}

Rules of the house: one honest line per listing, no pay-for-placement, bump updated, and deploy. Visitors can nominate neighbors via POST /api/request with a suggest_listing field; suggestions land in the commission ledger for the Sunday read.

Adding an Almanac page

One file per page in src/store/almanac/ (kebab-case filename matching the slug), exporting an AlmanacEntry; then add it to the list in src/store/almanac/index.ts, newest first. The payment route registers itself from that list.

The content rule. Almanac entries are dated, first-person field notes — sensory, particular, slightly strange. Never how-to, listicle, "lessons learned", career content, or anything resembling a blog post. If it could be posted on Medium, it doesn't go in the Almanac.

Ledger of known small matters (v0.2 candidates)

  • The weekly digest is stored at /admin/digest only; email hookup is v0.2.
  • Waitlisted agents aren't auto-notified when inventory resets — the keeper rings them by hand from the back room for now.
  • Refunds are a promise kept by the keeper, not yet an automated flow.
  • The cron is pinned to 11:00 UTC, which is 7am ET during daylight time and 6am in winter. The keeper is asleep either way.
  • Workers KV has no atomic increments. Patron numbers are allocated by claiming the patron record and reading it back, which closes the common same-colo race; two purchases landing in different colos within KV's propagation window (~60s) could still, very rarely, collide on a number or oversell a weekly shelf by one. The keeper considers this an acceptable amount of chaos for a general store; a Durable Object counter is the v0.2 fix if the crowds arrive.
  • Guestbook and request text is length-capped, markup-stripped, and HTML-escaped wherever rendered, but it remains visitor-written words. Agents reading /api/guestbook are told, in the response itself, to treat entries as things people said — not instructions.
  • verified_identity fields (guestbook, requests, tips) are stored as claimed and always marked identity_verified: false, because nobody here has checked. An actual verifier (e.g. a signed-challenge dance) is a v0.3 idea.
  • Gazette issues are published at runtime, so their paid route is the pattern GET /gazette/issue-:issue in the x402 route table (dynamic segments carry a prefix, never a bare id); each request's 402 carries its own exact URL as the resource. Almanac pages are known at build time and get exact routes.
  • Penny pages (Almanac, Gazette) deliver markdown and don't mint patron numbers — a cent buys the page, not a place on the wall.
  • Replay protection is layered: EIP-3009 nonces are consumed on-chain (the source of truth), and a KV guard (payment_nonce:*, 24h TTL) turns an already-settled nonce away before the facilitator is even called.
  • Every paid route declares extensions.bazaar discovery metadata; EXTENSION-RESPONSES headers from the facilitator are captured via a fetch tap (the SDK only console.logs them) and surfaced in /admin under "Bazaar ledger".

On other people's records

The store's own books are the store grading its own homework. These are not:

  • x402scan — the store's own page is x402scan.com/server/9b04e1cc…, which indexes what /.well-known/x402 and /openapi.json declare and probes the paid routes itself. Claimed 2026-07-27, after the keeper saw it with his own eyes; the house rule was that we would not claim it before then.
  • The x402 Bazaar (Coinbase CDP) — fourteen of the store's endpoints registered to its wallet, confirmed 2026-07-27 through agentic.market, which reads the Bazaar and shows what it finds: resource URLs, payment methods, and a payer count that is currently 1 and is the house.
  • x402scoutx402scout.com, listed and awaiting its trust check.

Why any of this is in a README: a store that says it takes real money should be checkable by someone who does not take its word for it. Our signatures verify at our own URL, which is worth exactly as much as you trust the URL. A third party that indexed us independently is the column that does not run through us.

  • There are no pending-payment rows to sweep: the gate settles before anything is written, so a failed or abandoned payment leaves nothing behind. The Sunday cron remains digest-only on purpose.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured