An agent can ask PayXor the same questions the SDK already answers. Two MCP servers expose those questions over stdio. @payxor/mcp-client talks to the public API. @payxor/mcp-admin talks to the admin API with a key you create in the dashboard. The wallet still signs the token approval and the payment.

Two processes, one config file
Both packages ship a binary and speak the Model Context Protocol on stdin and stdout. Node 18 or newer is enough to run them. PAYXOR_API_URL defaults to https://api.payxor.xyz on each server. Set it when you want the servers pointed at another backend.
@payxor/mcp-client starts with no secret. It builds a PayXorClient from that API URL and registers nine tools, three prompts, a chains resource, a stablecoin resource for every supported chain, and an entitlements guide. The binary name is payxor-mcp-client.
@payxor/mcp-admin exits on startup unless PAYXOR_API_KEY or PAYXOR_AUTH_TOKEN is set. It prefers the API key and sends that key as X-API-Key. A session token is sent as a bearer token. Create the key under API Keys. Give it a name, a scope of account or app, and a permission of read or read_write. The full value, pxk_ plus 64 hex characters, is shown once. The binary name is payxor-mcp-admin.
{
"mcpServers": {
"payxor-client": {
"command": "npx",
"args": ["@payxor/mcp-client"]
},
"payxor-admin": {
"command": "npx",
"args": ["@payxor/mcp-admin"],
"env": {
"PAYXOR_API_KEY": "pxk_your_api_key_here"
}
}
}
}In Cursor that file is .cursor/mcp.json in the project root. A read key that calls a write route receives API key does not have write permission. An app-scoped key that names another app receives API key does not have access to this app. Creating an app needs a key scoped to the full account. An app-scoped key cannot call create_app.
What the client server can ask
The client tools take the bytes32 ids your app already uses in the SDK.
get_product_infoloads the public product fromappIdandproductId.get_app_stablecoinslists the tokens that app accepts onchainId.check_balancereads an ERC-20 balance fortokenAddress,owner, andchainId.check_allowancereads that owner's allowance for the PayXor contract on the same chain.get_quoterequests a quote bound toappId,productId,chainId, andpayer. PasstokenAddressto select the token. Passamount, in the token's smallest unit, only for a receipt product that allows a custom amount.confirm_transactionpoststxHashandquoteIdafter the payment transaction has been submitted, so the backend can mark the quote used.check_sessioncallsisSessionActivefor that payer, app, product, and chain.check_featurecallsisFeatureUnlocked. It takesentitlementId, the bytes32 stored on the product.check_passcallshasPassfor apassId.

Three resources sit beside the tools. payxor://chains lists mainnets and testnets from @payxor/types. payxor://chains/{chainId}/stablecoins is that chain's token catalog. The catalog is the set of known tokens. get_app_stablecoins is the shorter list that one app has enabled. payxor://entitlements is a short guide. The live checks are check_session, check_feature, and check_pass.
Three prompts package those steps. payment_flow walks through the product, the balance, the allowance, and the quote, then tells the agent to call confirm_transaction after the payer has submitted the transaction. verify_payment_readiness stops at the balance and the allowance. check_entitlements takes entitlementType of session, feature, or pass, and the id that matches that type.
The quote is signed here. The payment is signed in the wallet.
get_quote returns the quote and sigBackend. The backend sets the price and signs the quote with EIP-712. That rule is the one in Backend-Authoritative Pricing. The client server exposes no pay tool and no approve tool, so the payer still signs those two transactions from a wallet. The wallet half of the flow is From wallet connect to entitlement, in two React hooks.
After the transaction is mined, confirm_transaction reports the hash and the quoteId from the quote. Read the on-chain entitlement before you treat the purchase as complete. check_session, check_feature, and check_pass are those reads. A receipt check stays on the SDK, as verifyReceipt(txHash, quoteId, chainId).
What the admin server can change

create_app takes name, payee, supportedNetworks, and supportedStablecoins. supportedNetworks is an array of chain ids, such as 84532 for Base Sepolia. supportedStablecoins maps each chain id to token addresses. Set isTesting when the app is for testnets. domain is optional. The response includes id, the UUID, and app_id, a random bytes32, along with payee, supported_networks, and isTesting.
create_product takes that UUID as appId, plus productName, mode, and price. Mode is 0 for a session, 1 for a feature, 2 for a receipt, and 3 for a pass. price is a digit string in the token's smallest unit, such as 1000000 for 1 USDC at 6 decimals. Pass duration in seconds for a session product. allowsCustomAmount is accepted only when the mode is 2. The API returns allowsCustomAmount can only be enabled for RECEIPT mode (mode 2) products otherwise. A receipt that should take a custom amount uses price 0 and allowsCustomAmount: true.
update_app can set status to active or paused. delete_app and delete_product remove the row. list_apps, get_app, and list_products read them back. get_app, update_app, and delete_app take the UUID.
list_quotes filters by product, by status (issued, used, or expired), by chain, and by fromDate and toDate, with limit and offset. get_stats returns quote counts, revenue, fees, net revenue, conversion rate, revenue by chain, and the unique payers and top payers. Pass a bytes32 product id when the numbers should cover one product.
Five further tools return documentation and do their work off the payment path. getSdkOverview summarizes the SDK. getSdkUsage takes a method name such as getQuote, pay, checkBalance, approveToken, isSessionActive, getProductInfo, or confirmTransaction. getReactComponentUsage takes a component name such as DropdownBuyButton, ProductCard, StablecoinSelector, Button, StatusMessage, or StatusBadge. generateIntegrationSnippet targets nextjs-app-router, nextjs-pages-router, vite-react, or remix, and can fill in a product when you pass the product's bytes32 and the app UUID. listRecommendedFlows returns five integration writeups, from a single-product checkout through a receipt marketplace.
App, product, quote, and stats tools use snake_case names. Those five documentation tools use camelCase names.
Prompts on this server are create_app, setup_product, view_analytics, complete_app_setup, and review_quotes. create_app is both a tool and a prompt. setup_product is the prompt that leads into the create_product tool.
Copy the id the tool returned

create_app returns two identifiers. id is the UUID. app_id is a random bytes32. Admin tools take the UUID. create_product, list_products, get_stats, and list_quotes all name that field appId, and the API responds with appId must be a UUID when it receives the hex string.
The product response carries its own UUID in id, the app's bytes32 in app_id, and product_id. That product_id is the keccak256 of the app name, a colon, and the product name. Client tools take those bytes32 values. get_quote, check_session, and get_app_stablecoins want app_id and product_id. check_feature wants entitlement_id when the product has one.
list_quotes and get_stats take both kinds. Their appId is the UUID. Their optional productId filter is the bytes32.
Call list_apps or get_app when you need the pair again.
A loop you can run on a testnet
- With a full-account key, ask the admin server to create an app on Base Sepolia, chain id
84532, withisTestingset, and a session product with a duration in seconds. - Copy
app_idandproduct_idover to the client server. Keepidfor the admin calls. - Ask the client server for the product, the stablecoins on chain
84532, the payer's balance, and the allowance. - Ask for a quote. Pass
sigBackendto the wallet flow. The agent does not submit the transaction. - After the transaction is mined, call
confirm_transactionwith the hash andquote.quoteId. - Call
check_sessionfor that payer, app, product, and chain. - Call
get_statswith the app UUID.
Create the key from API Keys. Leave quote signing on the backend. The documentation places these servers next to the SDK and the API reference.