Commit d916d2b
authored
feat: x402 payment protocol support (#11)
* feat: add x402 wallet management and payment signing CLI
Adds mcpc x402 subcommands: init, import, list, remove, sign.
Wallets stored in ~/.mcpc/wallets.json. Signing parses PAYMENT-REQUIRED
headers and produces PAYMENT-SIGNATURE for x402 payment protocol.
* feat: add x402 commands to mcpc --help output
* feat: add x402 auto-payment middleware for direct and bridge connections
Implement automatic x402 payment signing when calling paid MCP tools.
The --x402 global flag enables auto-payment using the default wallet.
Architecture:
- Shared signer module (src/lib/x402/signer.ts) for EIP-3009 typed data signing
- Fetch middleware (src/lib/x402/fetch-middleware.ts) wraps SDK's fetch with:
- Proactive signing: reads _meta.x402 from cached tools list, signs before request
- 402 fallback: if server returns HTTP 402, parses PAYMENT-REQUIRED header, signs, retries once
- Bridge receives wallet credentials via IPC (set-x402-wallet message type)
- Bridge maintains its own tools cache for proactive signing (populated on connect,
updated via listChanged notifications)
- Direct connections (withMcpClient) only support 402 fallback (no persistent tools cache)
- customFetch option threaded through transports.ts -> factory.ts -> SDK transport
Known issues and TODOs:
- --x402 is currently a boolean flag (always uses 'default' wallet). Supporting
--x402 [wallet-name] with optional value is blocked by Commander.js not being
able to disambiguate optional option values from subcommands. Options considered:
(a) pre-process args to convert '--x402 name' to '--x402=name' before Commander,
(b) use separate --x402-wallet <name> option, (c) strip --x402 from Commander
args and re-inject via closure. All approaches were prototyped but add significant
complexity. For now --x402 uses the default wallet; named wallets can wait.
- No unit tests yet for signer.ts and fetch-middleware.ts
- No E2E test with the demo x402 server
- Interactive shell does not support --x402 (only direct commands and sessions)
- Direct connections don't have proactive signing (no tools cache), only 402 fallback
- Pre-existing flaky test: sessions/bridge-resilience occasionally fails (unrelated)
* refactor: simplify x402 to single wallet
Drop multi-wallet support (named wallets, --name options, defaultWallet)
in favor of a single wallet stored in ~/.mcpc/wallets.json with a
versioned format { version: 1, wallet?: WalletData }.
- Remove wallet names from WalletData, X402WalletCredentials, SessionData
- Replace SessionData.walletName with x402 boolean flag
- Simplify wallets.ts CRUD to operate on single wallet
- Rename 'list' command to 'info', remove --name from all x402 commands
- Update bridge IPC: --wallet <name> arg becomes --x402 boolean flag
- Update all callsites (bridge-manager, sessions, helpers, parser, CLI)
This avoids Commander.js optional-arg parsing complexity for --x402
[wallet-name] and matches the actual use case (one wallet per user).
Multi-wallet can be added later with --x402-wallet <name> if needed.
* docs: add x402 agentic payments section to README
* docs: add Base link and warning emoji in x402 section1 parent 8de17a2 commit d916d2b
File tree
21 files changed
+1574
-54
lines changed- src
- bridge
- cli
- commands
- core
- lib
- auth
- x402
21 files changed
+1574
-54
lines changedLarge diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
| 65 | + | |
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
| |||
0 commit comments