Accept payments with your MCP tool
A drop-in commerce core for MCP servers built on Agentic Commerce Protocol (ACP). It allows tools to accept payments within conversations for assets, upgrades, licenses, credits, etc. Supports standalone, embedded, and library-only usage, with Stripe integration and a mock payment provider.
Notifications You must be signed in to change notification settings
Fork 0
Star 1
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
2 Commits
2 Commits
examples
examples
src
src
test
test
.env.example
.env.example
.gitignore
.gitignore
Dockerfile
Dockerfile
LICENSE
LICENSE
README.md
README.md
config.example.json
config.example.json
package-lock.json
package-lock.json
package.json
package.json
tsconfig.json
tsconfig.json
Repository files navigation
A drop-in commerce core for MCP servers, built on the Agentic Commerce Protocol (ACP). Point it at a simple products file and your tool can take money inside the conversation that was already happening: buy an asset, upgrade to Pro, renew a license, buy credits. The commerce logic is a clean library; the MCP server and the ACP REST endpoints are thin faces over it.
Full documentation lives at afcommerce.com.
It is built for companies that already run (or are building) an MCP tool and will eventually want to charge for something inside it. The commerce rides along with a real brand and a real product, so the trust problem of an unknown storefront does not apply.
What it is not
Not a standalone shopping destination for unknown sellers.
Not a CRM, order database, or customer history store. On a successful payment we hand the order to the merchant and forget it.
Not a frontend. There is no cart UI or chat widget, on purpose.
Three ways to use it
Standalone server. Run the whole stack (npm start or the Docker image, or the Lambda handler). Our code is the MCP server.
Embedded. Import the commerce core into your own MCP server and register the tools there. You never touch our transport.
Library only. Call the core from your REST API or bot, no MCP at all.
Quickstart (standalone, Docker)
cp config.example.json config.json # edit it for your store cp .env.example .env # add your Stripe key (or leave blank for the mock) docker build -t mcp-commerce . docker run --rm -p 3000:3000 \ -v "$PWD/config.json:/app/config.json" \ --env-file .env \ mcp-commerce
The server then exposes:
Path What it is
POST /mcp MCP endpoint (streamable HTTP, stateless JSON)
/checkout_sessions... ACP REST checkout endpoints
POST /webhooks/stripe Stripe webhook receiver
GET /feed?format=jsonl|csv ACP product feed
Without STRIPE_SECRET_KEY set, the server uses a mock payment provider (no real charges), which is handy for local runs and demos.
Quickstart (embedded / library)
import { createCommerce, createCheckoutService, BundledCatalogSource, SqliteCartStore, SqliteCheckoutSessionStore, MockPaymentProvider, NoTaxCalculator, NoopOrderSink, registerCommerceTools, } from "mcp-commerce";
const catalogSource = new BundledCatalogSource({ path: "./products.json" });
const commerce = createCommerce({ catalogSource, cartStore: new SqliteCartStore({ path: "./carts.sqlite" }), config: { currency: "usd", cartTtlSeconds: 3600 }, });
// Register the shopper-facing tools on your own MCP server: registerCommerceTools(yourMcpServer, commerce /*, checkoutService */);
The AWS-backed drivers (DynamoDB stores, S3 catalog source) live in a separate entry so the optional AWS SDK only loads when you use them:
import { DynamoCartStore, S3CatalogSource } from "mcp-commerce/aws";
Quickstart (AWS Lambda)
Front an API Gateway HTTP API (payload format v2) at the exported handler:
handler = dist/lambda.handler
Set COMMERCE_CONFIG (and the secret env vars) the same way the server uses them. On Lambda, use the DynamoDB stores for carts, sessions, and idempotency (set storage.type to dynamo); an in-memory SQLite store would not survive between invocations. The S3 catalog source fits the same stack. The handler routes the ACP endpoints, the Stripe webhook, the feed, and the MCP endpoint, all through the same core as the standalone server.
Products file
Catalog only, no orders or config mixed in. Prices are integer minor units (cents) to match Stripe and avoid floating point money bugs.
{ "currency": "usd", "products": [ { "id": "pro-license", "title": "Pro License", "description": "Full license with all features unlocked.", "url": "https://example.com/products/pro-license", "image_url": "https://example.com/img/pro-license.png", "price": 4999, "available": true, "variants": [ { "id": "pro-single", "title": "Single seat", "price": 4999 }, { "id": "pro-team", "title": "Team (5 seats)", "price": 19999 } ] } ] }
A product with variants is bought by variant id; a product without variants is bought by its own id. See examples/products.example.json for a full sample.
Configuration
Non-secret settings live in config.json (see config.example.json). Secrets only ever come from environment variables (see .env.example), never a committed file.
Config highlights:
currency, cartTtlSeconds
catalog: { "type": "bundled" | "remoteUrl" | "s3", ... }
storage: { "type": "sqlite" | "dynamo", ... }
tax: { "enabled": false } (see Tax below)
successUrl, cancelUrl, orderWebhookUrl, permalinkBase
acp: { "requireSignature": false }
links: terms, privacy, return policy links surfaced in the session
feed: merchant-level fields for the ACP product feed
Environment variables:
Variable Purpose
PORT Server port (default 3000)
COMMERCE_CONFIG Path to the config file (default ./config.json)
CART_DB, SESSION_DB, IDEMPOTENCY_DB SQLite file paths (default in-memory)
STRIPE_SECRET_KEY Stripe key; blank uses the mock provider
STRIPE_WEBHOOK_SECRET Verifies incoming Stripe webhooks
ACP_BEARER_TOKEN Bearer token agents present to the ACP endpoints
ACP_SIGNING_SECRET Optional HMAC request-signature verification
ORDER_WEBHOOK_SECRET Optional signature on the order we POST to the merchant
The ACP endpoints are closed by default: with no ACP_BEARER_TOKEN set, every request is rejected.
Storage and catalog drivers
Two data types, stored separately and swappable per deploy:
Catalog (read only): bundled file, remote URL, or S3 object.
Cart and checkout session (short lived, TTL'd, not customer data): SQLite for Docker/EC2, DynamoDB for Lambda (native per-item TTL).
Payments and tax
Direct Stripe (everywhere): a hosted Stripe Checkout URL the shopper opens. Used by the MCP checkout tool and any merchant-facing surface.
Delegated (SPT) (US, Stripe preview terms): a third-party agent grants a scoped Shared Payment Token, charged immediately by the ACP complete endpoint.
Tax is delegated to Stripe Tax rather than reimplemented. It is off by default; set tax.enabled and provide a Stripe key to turn it on. Tax is computed once the buyer's address is known (from fulfillment_details on update, or the billing address on complete) and folded into the line tax and the session total.
MCP tools
search_products, get_product, add_to_cart, view_cart, update_cart_item, remove_from_cart, and checkout (registered when a checkout service is provided). Because the transport is stateless, add_to_cart returns a cart_id that must be passed back on later calls; the tool descriptions tell the agent so.
Development
npm install npm run dev # tsx src/server.ts npm test # node --test npm run typecheck npm run build # tsc -> dist/ npm run feed # print the product feed to stdout
Documentation and related projects
Documentation, the docs page for this module
Auto Learning Agents, an AI agents OS and UI
Adaptive Recall, a learning MCP memory tool
Levity, a free AI image creation UI
AI Apps API, the company and developer site behind these projects
License
Elastic License 2.0. Free to use, modify, and embed in your own product, including proprietary and commercial ones. The one limitation is that you may not offer the software to third parties as a hosted or managed commerce service. See the LICENSE file for the full text.
Copyright (c) 2026 Paul Crinigan, aiappsapi.com
About
ACP Payment Module: drop-in Agentic Commerce Protocol checkout and Stripe payments for MCP servers. It has an optional starter MCP server template, but I figured it was more usable as a module you could add to your own.
www.afcommerce.com/free-acp-payments-module/
Topics
typescript
checkout
stripe
mcp
payments
acp
mcp-server
agentic-commerce
Resources
Readme
License
View license
Uh oh!
There was an error while loading. Please reload this page.
Activity
Stars
1 star
Watchers
0 watching
Forks
0 forks
Report repository
Releases
No releases published
Packages 0
Uh oh!
There was an error while loading. Please reload this page.
Contributors
Uh oh!
There was an error while loading. Please reload this page.
Languages
TypeScript 99.6%
Dockerfile 0.4%