@t402/mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +228 -0
- package/bin/t402-mcp.js +53 -0
- package/dist/cjs/index.d.ts +69 -0
- package/dist/cjs/index.js +1692 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/server/index.d.ts +59 -0
- package/dist/cjs/server/index.js +1613 -0
- package/dist/cjs/server/index.js.map +1 -0
- package/dist/cjs/tools/index.d.ts +424 -0
- package/dist/cjs/tools/index.js +1404 -0
- package/dist/cjs/tools/index.js.map +1 -0
- package/dist/cjs/types-BINGE6ja.d.ts +147 -0
- package/dist/esm/chunk-AN6P2M7N.mjs +272 -0
- package/dist/esm/chunk-AN6P2M7N.mjs.map +1 -0
- package/dist/esm/chunk-SB4O25HA.mjs +1399 -0
- package/dist/esm/chunk-SB4O25HA.mjs.map +1 -0
- package/dist/esm/index.d.mts +69 -0
- package/dist/esm/index.mjs +81 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/server/index.d.mts +59 -0
- package/dist/esm/server/index.mjs +12 -0
- package/dist/esm/server/index.mjs.map +1 -0
- package/dist/esm/tools/index.d.mts +424 -0
- package/dist/esm/tools/index.mjs +45 -0
- package/dist/esm/tools/index.mjs.map +1 -0
- package/dist/esm/types-BINGE6ja.d.mts +147 -0
- package/package.json +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# @t402/mcp
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) Server for AI Agent Payments using the t402 Payment Protocol.
|
|
4
|
+
|
|
5
|
+
Enable AI agents like Claude to make stablecoin payments across multiple blockchain networks.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Multi-Chain Balance Checking** - Check balances on Ethereum, Base, Arbitrum, Optimism, Polygon, Avalanche, and more
|
|
10
|
+
- **Stablecoin Payments** - Send USDC, USDT, and USDT0 payments
|
|
11
|
+
- **Gasless Transactions** - Execute payments without ETH using ERC-4337
|
|
12
|
+
- **Cross-Chain Bridging** - Bridge USDT0 between chains using LayerZero
|
|
13
|
+
|
|
14
|
+
## Available Tools
|
|
15
|
+
|
|
16
|
+
| Tool | Description |
|
|
17
|
+
|------|-------------|
|
|
18
|
+
| `t402/getBalance` | Get token balances for a wallet on a specific network |
|
|
19
|
+
| `t402/getAllBalances` | Get balances across all supported networks |
|
|
20
|
+
| `t402/pay` | Execute a stablecoin payment |
|
|
21
|
+
| `t402/payGasless` | Execute a gasless payment using ERC-4337 |
|
|
22
|
+
| `t402/getBridgeFee` | Get fee quote for bridging USDT0 |
|
|
23
|
+
| `t402/bridge` | Bridge USDT0 between chains |
|
|
24
|
+
|
|
25
|
+
## Claude Desktop Integration
|
|
26
|
+
|
|
27
|
+
### Quick Start
|
|
28
|
+
|
|
29
|
+
1. Install the package globally:
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g @t402/mcp
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. Configure Claude Desktop by editing `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"t402": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["@t402/mcp"],
|
|
42
|
+
"env": {
|
|
43
|
+
"T402_DEMO_MODE": "true"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
3. Restart Claude Desktop
|
|
51
|
+
|
|
52
|
+
### Demo Mode
|
|
53
|
+
|
|
54
|
+
For testing without real transactions, enable demo mode:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"t402": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["@t402/mcp"],
|
|
62
|
+
"env": {
|
|
63
|
+
"T402_DEMO_MODE": "true"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Demo mode simulates transactions and returns mock results without executing on-chain.
|
|
71
|
+
|
|
72
|
+
### Production Configuration
|
|
73
|
+
|
|
74
|
+
For real payments, configure with a private key:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"t402": {
|
|
80
|
+
"command": "npx",
|
|
81
|
+
"args": ["@t402/mcp"],
|
|
82
|
+
"env": {
|
|
83
|
+
"T402_PRIVATE_KEY": "0x..."
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Warning:** Keep your private key secure. Consider using a dedicated wallet with limited funds for AI agent payments.
|
|
91
|
+
|
|
92
|
+
### ERC-4337 Gasless Transactions
|
|
93
|
+
|
|
94
|
+
For gasless payments, configure bundler and paymaster:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"t402": {
|
|
100
|
+
"command": "npx",
|
|
101
|
+
"args": ["@t402/mcp"],
|
|
102
|
+
"env": {
|
|
103
|
+
"T402_PRIVATE_KEY": "0x...",
|
|
104
|
+
"T402_BUNDLER_URL": "https://api.pimlico.io/v1/...",
|
|
105
|
+
"T402_PAYMASTER_URL": "https://api.pimlico.io/v2/..."
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Custom RPC URLs
|
|
113
|
+
|
|
114
|
+
Configure custom RPC endpoints for better reliability:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"t402": {
|
|
120
|
+
"command": "npx",
|
|
121
|
+
"args": ["@t402/mcp"],
|
|
122
|
+
"env": {
|
|
123
|
+
"T402_PRIVATE_KEY": "0x...",
|
|
124
|
+
"T402_RPC_ETHEREUM": "https://eth-mainnet.g.alchemy.com/v2/...",
|
|
125
|
+
"T402_RPC_BASE": "https://base-mainnet.g.alchemy.com/v2/...",
|
|
126
|
+
"T402_RPC_ARBITRUM": "https://arb-mainnet.g.alchemy.com/v2/..."
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Environment Variables
|
|
134
|
+
|
|
135
|
+
| Variable | Description |
|
|
136
|
+
|----------|-------------|
|
|
137
|
+
| `T402_PRIVATE_KEY` | Wallet private key (hex with 0x prefix) |
|
|
138
|
+
| `T402_DEMO_MODE` | Set to "true" for simulated transactions |
|
|
139
|
+
| `T402_BUNDLER_URL` | ERC-4337 bundler URL for gasless transactions |
|
|
140
|
+
| `T402_PAYMASTER_URL` | Paymaster URL for sponsored gas |
|
|
141
|
+
| `T402_RPC_ETHEREUM` | Custom RPC URL for Ethereum |
|
|
142
|
+
| `T402_RPC_BASE` | Custom RPC URL for Base |
|
|
143
|
+
| `T402_RPC_ARBITRUM` | Custom RPC URL for Arbitrum |
|
|
144
|
+
| `T402_RPC_OPTIMISM` | Custom RPC URL for Optimism |
|
|
145
|
+
| `T402_RPC_POLYGON` | Custom RPC URL for Polygon |
|
|
146
|
+
| `T402_RPC_AVALANCHE` | Custom RPC URL for Avalanche |
|
|
147
|
+
| `T402_RPC_INK` | Custom RPC URL for Ink |
|
|
148
|
+
| `T402_RPC_BERACHAIN` | Custom RPC URL for Berachain |
|
|
149
|
+
| `T402_RPC_UNICHAIN` | Custom RPC URL for Unichain |
|
|
150
|
+
|
|
151
|
+
## Supported Networks
|
|
152
|
+
|
|
153
|
+
| Network | Chain ID | Tokens |
|
|
154
|
+
|---------|----------|--------|
|
|
155
|
+
| Ethereum | 1 | USDC, USDT, USDT0 |
|
|
156
|
+
| Base | 8453 | USDC |
|
|
157
|
+
| Arbitrum | 42161 | USDC, USDT, USDT0 |
|
|
158
|
+
| Optimism | 10 | USDC, USDT |
|
|
159
|
+
| Polygon | 137 | USDC, USDT |
|
|
160
|
+
| Avalanche | 43114 | USDC, USDT |
|
|
161
|
+
| Ink | 57073 | USDT0 |
|
|
162
|
+
| Berachain | 80094 | USDT0 |
|
|
163
|
+
| Unichain | 130 | USDT0 |
|
|
164
|
+
|
|
165
|
+
## Cross-Chain Bridging
|
|
166
|
+
|
|
167
|
+
USDT0 can be bridged between these chains using LayerZero:
|
|
168
|
+
- Ethereum
|
|
169
|
+
- Arbitrum
|
|
170
|
+
- Ink
|
|
171
|
+
- Berachain
|
|
172
|
+
- Unichain
|
|
173
|
+
|
|
174
|
+
## Example Prompts
|
|
175
|
+
|
|
176
|
+
Once configured, you can ask Claude to:
|
|
177
|
+
|
|
178
|
+
- "Check my USDC balance on Base"
|
|
179
|
+
- "Show my balances across all chains"
|
|
180
|
+
- "Send 10 USDC to 0x... on Arbitrum"
|
|
181
|
+
- "How much does it cost to bridge 100 USDT0 from Arbitrum to Ethereum?"
|
|
182
|
+
- "Bridge 50 USDT0 from Arbitrum to Ink"
|
|
183
|
+
|
|
184
|
+
## Programmatic Usage
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import { createT402McpServer, loadConfigFromEnv } from '@t402/mcp';
|
|
188
|
+
|
|
189
|
+
const config = loadConfigFromEnv();
|
|
190
|
+
const server = createT402McpServer(config);
|
|
191
|
+
await server.run();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Using Individual Tools
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { executeGetBalance, executePay } from '@t402/mcp/tools';
|
|
198
|
+
|
|
199
|
+
// Check balance
|
|
200
|
+
const balance = await executeGetBalance({
|
|
201
|
+
network: 'base',
|
|
202
|
+
address: '0x...',
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Execute payment
|
|
206
|
+
const result = await executePay(
|
|
207
|
+
{
|
|
208
|
+
to: '0x...',
|
|
209
|
+
amount: '10.00',
|
|
210
|
+
token: 'USDC',
|
|
211
|
+
network: 'base',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
privateKey: '0x...',
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Security Considerations
|
|
220
|
+
|
|
221
|
+
1. **Use a dedicated wallet** - Create a new wallet specifically for AI agent payments
|
|
222
|
+
2. **Set spending limits** - Only fund the wallet with amounts you're comfortable with the AI spending
|
|
223
|
+
3. **Monitor transactions** - Regularly check transaction history
|
|
224
|
+
4. **Start with demo mode** - Test with demo mode before enabling real transactions
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
Apache-2.0
|
package/bin/t402-mcp.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* t402 MCP Server CLI
|
|
5
|
+
*
|
|
6
|
+
* Run the t402 MCP server for Claude Desktop and other AI agents.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx @t402/mcp
|
|
10
|
+
* t402-mcp
|
|
11
|
+
*
|
|
12
|
+
* Environment Variables:
|
|
13
|
+
* T402_PRIVATE_KEY - Wallet private key (hex with 0x prefix)
|
|
14
|
+
* T402_DEMO_MODE - Set to "true" to simulate transactions
|
|
15
|
+
* T402_BUNDLER_URL - ERC-4337 bundler URL for gasless transactions
|
|
16
|
+
* T402_PAYMASTER_URL - Paymaster URL for gasless transactions
|
|
17
|
+
* T402_RPC_ETHEREUM - Custom RPC URL for Ethereum
|
|
18
|
+
* T402_RPC_BASE - Custom RPC URL for Base
|
|
19
|
+
* T402_RPC_ARBITRUM - Custom RPC URL for Arbitrum
|
|
20
|
+
* ... (other networks follow same pattern)
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { createT402McpServer, loadConfigFromEnv } from "../dist/esm/index.mjs";
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
const config = loadConfigFromEnv();
|
|
27
|
+
|
|
28
|
+
// Log configuration status (to stderr so it doesn't interfere with stdio)
|
|
29
|
+
console.error("t402 MCP Server Configuration:");
|
|
30
|
+
console.error(` Private Key: ${config.privateKey ? "configured" : "not set"}`);
|
|
31
|
+
console.error(` Demo Mode: ${config.demoMode ? "enabled" : "disabled"}`);
|
|
32
|
+
console.error(` Bundler URL: ${config.bundlerUrl ? "configured" : "not set"}`);
|
|
33
|
+
console.error(` Paymaster URL: ${config.paymasterUrl ? "configured" : "not set"}`);
|
|
34
|
+
|
|
35
|
+
if (config.rpcUrls) {
|
|
36
|
+
console.error(` Custom RPC URLs: ${Object.keys(config.rpcUrls).join(", ")}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!config.privateKey && !config.demoMode) {
|
|
40
|
+
console.error("");
|
|
41
|
+
console.error("Warning: No private key configured.");
|
|
42
|
+
console.error("Set T402_PRIVATE_KEY env var or enable T402_DEMO_MODE=true");
|
|
43
|
+
console.error("");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const server = createT402McpServer(config);
|
|
47
|
+
await server.run();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
main().catch((error) => {
|
|
51
|
+
console.error("Fatal error:", error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export { T402McpServer, createT402McpServer, loadConfigFromEnv } from './server/index.js';
|
|
2
|
+
export { AllBalancesResult, BridgeInput, BridgeOptions, GASLESS_SUPPORTED_NETWORKS, GetAllBalancesInput, GetBalanceInput, GetBridgeFeeInput, PayGaslessInput, PayGaslessOptions, PayInput, PayOptions, TOOL_DEFINITIONS, bridgeInputSchema, executeBridge, executeGetAllBalances, executeGetBalance, executeGetBridgeFee, executePay, executePayGasless, formatAllBalancesResult, formatBalanceResult, formatBridgeFeeResult, formatBridgeResult, formatGaslessPaymentResult, formatPaymentResult, getAllBalancesInputSchema, getBalanceInputSchema, getBridgeFeeInputSchema, payGaslessInputSchema, payInputSchema } from './tools/index.js';
|
|
3
|
+
import { S as SupportedNetwork } from './types-BINGE6ja.js';
|
|
4
|
+
export { B as BridgeFeeQuote, b as BridgeResult, C as ChainBalance, G as GaslessPaymentResult, M as McpServerConfig, P as PaymentParams, a as PaymentResult, T as TokenBalance, c as ToolContext } from './types-BINGE6ja.js';
|
|
5
|
+
import { Address } from 'viem';
|
|
6
|
+
import 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Constants and network configurations for t402 MCP Server
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Chain IDs by network
|
|
14
|
+
*/
|
|
15
|
+
declare const CHAIN_IDS: Record<SupportedNetwork, number>;
|
|
16
|
+
/**
|
|
17
|
+
* Native token symbols by network
|
|
18
|
+
*/
|
|
19
|
+
declare const NATIVE_SYMBOLS: Record<SupportedNetwork, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Block explorer URLs by network
|
|
22
|
+
*/
|
|
23
|
+
declare const EXPLORER_URLS: Record<SupportedNetwork, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Default RPC URLs by network (public endpoints)
|
|
26
|
+
*/
|
|
27
|
+
declare const DEFAULT_RPC_URLS: Record<SupportedNetwork, string>;
|
|
28
|
+
/**
|
|
29
|
+
* USDC contract addresses by network
|
|
30
|
+
*/
|
|
31
|
+
declare const USDC_ADDRESSES: Partial<Record<SupportedNetwork, Address>>;
|
|
32
|
+
/**
|
|
33
|
+
* USDT contract addresses by network
|
|
34
|
+
*/
|
|
35
|
+
declare const USDT_ADDRESSES: Partial<Record<SupportedNetwork, Address>>;
|
|
36
|
+
/**
|
|
37
|
+
* USDT0 (LayerZero OFT) contract addresses by network
|
|
38
|
+
*/
|
|
39
|
+
declare const USDT0_ADDRESSES: Partial<Record<SupportedNetwork, Address>>;
|
|
40
|
+
/**
|
|
41
|
+
* Chains that support USDT0 bridging
|
|
42
|
+
*/
|
|
43
|
+
declare const BRIDGEABLE_CHAINS: SupportedNetwork[];
|
|
44
|
+
/**
|
|
45
|
+
* Get explorer URL for a transaction
|
|
46
|
+
*/
|
|
47
|
+
declare function getExplorerTxUrl(network: SupportedNetwork, txHash: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get LayerZero Scan URL for a message
|
|
50
|
+
*/
|
|
51
|
+
declare function getLayerZeroScanUrl(messageGuid: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a network supports a specific token
|
|
54
|
+
*/
|
|
55
|
+
declare function supportsToken(network: SupportedNetwork, token: "USDC" | "USDT" | "USDT0"): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Get token address for a network
|
|
58
|
+
*/
|
|
59
|
+
declare function getTokenAddress(network: SupportedNetwork, token: "USDC" | "USDT" | "USDT0"): Address | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Format token amount for display
|
|
62
|
+
*/
|
|
63
|
+
declare function formatTokenAmount(amount: bigint, decimals: number, symbol: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Parse token amount from string to bigint
|
|
66
|
+
*/
|
|
67
|
+
declare function parseTokenAmount(amount: string, decimals: number): bigint;
|
|
68
|
+
|
|
69
|
+
export { BRIDGEABLE_CHAINS, CHAIN_IDS, DEFAULT_RPC_URLS, EXPLORER_URLS, NATIVE_SYMBOLS, SupportedNetwork, USDC_ADDRESSES, USDT0_ADDRESSES, USDT_ADDRESSES, formatTokenAmount, getExplorerTxUrl, getLayerZeroScanUrl, getTokenAddress, parseTokenAmount, supportsToken };
|