Install
$ agentstack add mcp-dragon486-agentpaybridge ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
agent-pay-bridge
One call. Any agent payment protocol.
[](https://www.npmjs.com/package/agent-pay-bridge) [](#status) [](#status) [](#status) [](LICENSE) [](tsconfig.json)
Agentic commerce has three competing payment protocols — Coinbase's x402, Google's AP2, and OpenAI/Stripe's ACP — and merchants are picking different ones. If your agent only speaks one, you're dead in the water two-thirds of the time.
agent-pay-bridge probes the merchant, figures out which protocol they speak, and routes the payment — all from a single call:
const receipt = await bridge.pay({
url: 'https://paid-api.example.com/generate',
maxAmount: '1000000', // 1 USDC in 6-decimal base units
currency: 'USDC',
});
// { protocol: 'x402', status: 'settled', amountPaid: '1000000', ... }
Your agent never needs to know or care which protocol ran.
Why this exists
| Without agent-pay-bridge | With agent-pay-bridge | |---|---| | Implement x402, AP2, and ACP separately per agent | One bridge.pay() call handles all three | | Update every agent when a new protocol version ships | Update one adapter, all agents benefit | | if (merchant.usesX402) { ... } else if (merchant.usesAP2) { ... } | await bridge.pay({ url, maxAmount, currency }) | | Hardcoded protocol choice per deployment | Auto-detects at runtime — no config changes |
The ecosystem has no dominant standard yet. This bridge lets you ship agents today without betting on the winner.
Status
| Protocol | Status | Notes | |---|---|---| | x402 | ✅ Fully implemented | Challenge → sign → settle, end-to-end tested against a real mock server | | AP2 | 🟡 Scaffolded | Builds valid Intent / Cart / Payment mandates; returns pending until wired to a live processor | | ACP | 🟡 Scaffolded | Models Shared Payment Token request shape; returns pending until wired to a live processor |
x402 is implemented first because it's the only one with a fully open, public-testable spec — no gatekeeper approval needed to build against it.
Quick start
npm install agent-pay-bridge
Or clone and run locally:
git clone https://github.com/dragon486/AgentPayBridge.git
cd AgentPayBridge/agent-pay-bridge
npm install
npm test # full end-to-end x402 flow against a mock server
npm run build
npm run example
Usage
x402 (fully working today)
import { PayBridge, X402Adapter, DemoSigner } from 'agent-pay-bridge';
// Swap DemoSigner for a real wallet signer before touching real funds.
const bridge = new PayBridge([new X402Adapter(new DemoSigner())]);
const receipt = await bridge.pay({
url: 'https://your-x402-merchant.example.com/resource',
maxAmount: '1000000', // 1 USDC
currency: 'USDC',
memo: 'Fetching a generated report',
});
console.log(receipt);
// {
// protocol: 'x402',
// status: 'settled',
// amountPaid: '1000000',
// currency: 'USDC',
// settlementRef: '0x...',
// raw: { ... }
// }
All three protocols registered (auto-detect)
import { PayBridge, X402Adapter, AP2Adapter, ACPAdapter, DemoSigner } from 'agent-pay-bridge';
const bridge = new PayBridge([
new X402Adapter(new DemoSigner()),
new AP2Adapter(),
new ACPAdapter(),
]);
// bridge.pay() probes the merchant and picks the right protocol automatically.
const receipt = await bridge.pay({
url: 'https://merchant.example.com/api',
maxAmount: '500000',
currency: 'USDC',
});
Protocol detection only (no payment)
const protocol = await bridge.detect('https://merchant.example.com/api');
console.log(protocol); // 'x402' | 'ap2' | 'acp' | undefined
> ⚠️ Real funds warning: DemoSigner produces a non-cryptographic fake signature for local testing only. Before going to mainnet, swap it for a real wallet signer (viem, ethers, or a KMS-backed signer).
How it works
Agent
│
│ bridge.pay({ url, maxAmount, currency })
▼
PayBridge
│
│ 1. probe(url) → GET the resource, capture status / headers / body
▼
Adapter selection
│
│ 2. each adapter: supports(probeResult)?
▼
Matched adapter (X402Adapter | AP2Adapter | ACPAdapter)
│
│ 3. adapter.pay(intent, probeResult) — protocol-specific flow
▼
Normalized PaymentReceipt
{ protocol, status, amountPaid, currency, settlementRef, raw }
Discovery is stateless and synchronous from the adapter's perspective — the bridge handles all the HTTP probing and routing.
Adding a new protocol
Every protocol is one class implementing a two-method interface:
interface ProtocolAdapter {
readonly name: ProtocolName;
supports(probe: ProbeResult): boolean;
pay(intent: PaymentIntent, probe: ProbeResult): Promise;
}
Write one adapter, register it with new PayBridge([..., yourAdapter]) — done. The core (PayBridge, discovery, types) never changes.
API reference
PayBridge
| Method | Signature | Description | |---|---|---| | pay | (intent: PaymentIntent) => Promise | Probes, detects, and executes payment | | detect | (url: string) => Promise | Probes and returns protocol name without paying |
PaymentIntent
| Field | Type | Required | Description | |---|---|---|---| | url | string | ✅ | Merchant or resource endpoint | | maxAmount | string | ✅ | Max spend in base units (e.g. "1000000" = 1 USDC) | | currency | string | ✅ | ISO code or token symbol ("USDC", "USD") | | memo | string | — | Human-readable note for audit trails | | metadata | Record | — | Adapter-specific options |
PaymentReceipt
| Field | Type | Description | |---|---|---| | protocol | 'x402' \| 'ap2' \| 'acp' | Protocol that handled the payment | | status | 'settled' \| 'pending' \| 'failed' | Outcome | | amountPaid | string | Actual amount charged (base units) | | currency | string | Currency / token | | settlementRef | string | Tx hash, mandate ID, or SPT token | | raw | unknown | Full protocol response payload |
Roadmap
- [ ] Real viem-based signer — production-ready EVM wallet integration
- [ ] Discovery cache — skip re-probing the same merchant within a session
- [ ] Wire AP2Adapter to a live processor once one is publicly testable
- [ ] Wire ACPAdapter to Stripe's ACP endpoint once available
- [ ] MCP tool wrapper — expose
bridge.payas a Model Context Protocol tool so any MCP-compatible agent framework can use it with zero glue code - [ ] Retry + fallback logic — try next adapter if the first one fails
Contributing
Issues and PRs are very welcome, especially:
- Real settlement paths for the AP2 and ACP adapters
- A viem / ethers signer implementation (the
PaymentSignerinterface is two methods — it's a small lift) - Additional x402 payment schemes beyond
exact - Tests for edge cases in adapter selection
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines (coming soon — open an issue in the meantime).
License
MIT © dragon486
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: dragon486
- Source: dragon486/AgentPayBridge
- License: MIT
- Homepage: https://www.npmjs.com/package/agent-pay-bridge
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.