@codespar/mcp-circle 0.1.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 +112 -0
- package/dist/index.js +219 -0
- package/package.json +30 -0
- package/src/index.ts +227 -0
- package/tsconfig.json +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# @codespar/mcp-circle
|
|
2
|
+
|
|
3
|
+
> MCP server for **Circle** — USDC stablecoin payments, payouts, transfers, and wallets
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@codespar/mcp-circle)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
### Claude Desktop
|
|
11
|
+
|
|
12
|
+
Add to `~/.config/claude/claude_desktop_config.json`:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"mcpServers": {
|
|
17
|
+
"circle": {
|
|
18
|
+
"command": "npx",
|
|
19
|
+
"args": ["-y", "@codespar/mcp-circle"],
|
|
20
|
+
"env": {
|
|
21
|
+
"CIRCLE_API_KEY": "your-key"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Claude Code
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
claude mcp add circle -- npx @codespar/mcp-circle
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Cursor / VS Code
|
|
35
|
+
|
|
36
|
+
Add to `.cursor/mcp.json` or `.vscode/mcp.json`:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"servers": {
|
|
41
|
+
"circle": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["-y", "@codespar/mcp-circle"],
|
|
44
|
+
"env": {
|
|
45
|
+
"CIRCLE_API_KEY": "your-key"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Tools
|
|
53
|
+
|
|
54
|
+
| Tool | Description |
|
|
55
|
+
|------|-------------|
|
|
56
|
+
| `create_wallet` | Create a new Circle wallet |
|
|
57
|
+
| `get_wallet` | Get wallet details by ID |
|
|
58
|
+
| `create_payment` | Accept a USDC payment via Circle |
|
|
59
|
+
| `get_payment` | Get payment details by ID |
|
|
60
|
+
| `create_payout` | Create a payout from Circle (USDC to fiat) |
|
|
61
|
+
| `get_payout` | Get payout details by ID |
|
|
62
|
+
| `create_transfer` | Create a USDC transfer between Circle wallets |
|
|
63
|
+
| `get_transfer` | Get transfer details by ID |
|
|
64
|
+
| `get_balance` | Get account balance |
|
|
65
|
+
| `list_transactions` | List transactions with optional filters |
|
|
66
|
+
|
|
67
|
+
## Authentication
|
|
68
|
+
|
|
69
|
+
Circle uses a Bearer API key for authentication.
|
|
70
|
+
|
|
71
|
+
## Sandbox / Testing
|
|
72
|
+
|
|
73
|
+
Circle provides a sandbox at `api-sandbox.circle.com`. Use a sandbox API key for testing.
|
|
74
|
+
|
|
75
|
+
### Get your credentials
|
|
76
|
+
|
|
77
|
+
1. Go to [Circle Developer Portal](https://developers.circle.com)
|
|
78
|
+
2. Create a developer account
|
|
79
|
+
3. Generate a sandbox API key
|
|
80
|
+
4. Set the `CIRCLE_API_KEY` environment variable
|
|
81
|
+
|
|
82
|
+
## Environment Variables
|
|
83
|
+
|
|
84
|
+
| Variable | Required | Description |
|
|
85
|
+
|----------|----------|-------------|
|
|
86
|
+
| `CIRCLE_API_KEY` | Yes | API key from Circle |
|
|
87
|
+
|
|
88
|
+
## Roadmap
|
|
89
|
+
|
|
90
|
+
### v0.2 (planned)
|
|
91
|
+
- `create_card_payment` — Create a card payment
|
|
92
|
+
- `create_wire_payment` — Create a wire transfer payment
|
|
93
|
+
- `create_ach_payment` — Create an ACH payment
|
|
94
|
+
- `get_settlement` — Get settlement details
|
|
95
|
+
- `list_settlements` — List settlements with filters
|
|
96
|
+
|
|
97
|
+
### v0.3 (planned)
|
|
98
|
+
- `smart_contract_calls` — Execute smart contract calls
|
|
99
|
+
- `cross_chain_transfers` — Transfer assets across blockchains
|
|
100
|
+
|
|
101
|
+
Want to contribute? [Open a PR](https://github.com/codespar/mcp-dev-brasil) or [request a tool](https://github.com/codespar/mcp-dev-brasil/issues).
|
|
102
|
+
|
|
103
|
+
## Links
|
|
104
|
+
|
|
105
|
+
- [Circle Website](https://circle.com)
|
|
106
|
+
- [Circle API Documentation](https://developers.circle.com)
|
|
107
|
+
- [MCP Dev Brasil](https://github.com/codespar/mcp-dev-brasil)
|
|
108
|
+
- [Landing Page](https://codespar.dev/mcp)
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for Circle — USDC stablecoin infrastructure.
|
|
4
|
+
*
|
|
5
|
+
* Tools:
|
|
6
|
+
* - create_wallet: Create a new Circle wallet
|
|
7
|
+
* - get_wallet: Get wallet details by ID
|
|
8
|
+
* - create_payment: Accept a USDC payment
|
|
9
|
+
* - get_payment: Get payment details by ID
|
|
10
|
+
* - create_payout: Create a payout (USDC to fiat)
|
|
11
|
+
* - get_payout: Get payout details by ID
|
|
12
|
+
* - create_transfer: Create a USDC transfer between wallets
|
|
13
|
+
* - get_transfer: Get transfer details by ID
|
|
14
|
+
* - get_balance: Get wallet balance
|
|
15
|
+
* - list_transactions: List transactions with filters
|
|
16
|
+
*
|
|
17
|
+
* Environment:
|
|
18
|
+
* CIRCLE_API_KEY — API key from https://www.circle.com/
|
|
19
|
+
*/
|
|
20
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
21
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
22
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
23
|
+
const API_KEY = process.env.CIRCLE_API_KEY || "";
|
|
24
|
+
const BASE_URL = "https://api.circle.com/v1";
|
|
25
|
+
async function circleRequest(method, path, body) {
|
|
26
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
27
|
+
method,
|
|
28
|
+
headers: {
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
"Authorization": `Bearer ${API_KEY}`,
|
|
31
|
+
},
|
|
32
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
33
|
+
});
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
const err = await res.text();
|
|
36
|
+
throw new Error(`Circle API ${res.status}: ${err}`);
|
|
37
|
+
}
|
|
38
|
+
return res.json();
|
|
39
|
+
}
|
|
40
|
+
const server = new Server({ name: "mcp-circle", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
41
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
42
|
+
tools: [
|
|
43
|
+
{
|
|
44
|
+
name: "create_wallet",
|
|
45
|
+
description: "Create a new Circle wallet",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
50
|
+
description: { type: "string", description: "Wallet description" },
|
|
51
|
+
},
|
|
52
|
+
required: ["idempotencyKey"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "get_wallet",
|
|
57
|
+
description: "Get wallet details by ID",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {
|
|
61
|
+
id: { type: "string", description: "Wallet ID" },
|
|
62
|
+
},
|
|
63
|
+
required: ["id"],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "create_payment",
|
|
68
|
+
description: "Accept a USDC payment via Circle",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
73
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount (e.g. '10.00')" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Payment amount" },
|
|
74
|
+
source: { type: "object", properties: { id: { type: "string", description: "Source ID" }, type: { type: "string", description: "Source type (e.g. card, ach)" } }, required: ["id", "type"], description: "Payment source" },
|
|
75
|
+
description: { type: "string", description: "Payment description" },
|
|
76
|
+
},
|
|
77
|
+
required: ["idempotencyKey", "amount", "source"],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "get_payment",
|
|
82
|
+
description: "Get payment details by ID",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
id: { type: "string", description: "Payment ID" },
|
|
87
|
+
},
|
|
88
|
+
required: ["id"],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "create_payout",
|
|
93
|
+
description: "Create a payout from Circle (USDC to fiat)",
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
98
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Payout amount" },
|
|
99
|
+
destination: { type: "object", properties: { id: { type: "string", description: "Destination ID (bank account)" }, type: { type: "string", description: "Destination type (e.g. wire)" } }, required: ["id", "type"], description: "Payout destination" },
|
|
100
|
+
},
|
|
101
|
+
required: ["idempotencyKey", "amount", "destination"],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "get_payout",
|
|
106
|
+
description: "Get payout details by ID",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: "object",
|
|
109
|
+
properties: {
|
|
110
|
+
id: { type: "string", description: "Payout ID" },
|
|
111
|
+
},
|
|
112
|
+
required: ["id"],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "create_transfer",
|
|
117
|
+
description: "Create a USDC transfer between Circle wallets",
|
|
118
|
+
inputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {
|
|
121
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
122
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Transfer amount" },
|
|
123
|
+
source: { type: "object", properties: { id: { type: "string", description: "Source wallet ID" }, type: { type: "string", description: "Source type (wallet)" } }, required: ["id", "type"], description: "Transfer source" },
|
|
124
|
+
destination: { type: "object", properties: { id: { type: "string", description: "Destination wallet ID" }, type: { type: "string", description: "Destination type (wallet, blockchain)" } }, required: ["id", "type"], description: "Transfer destination" },
|
|
125
|
+
},
|
|
126
|
+
required: ["idempotencyKey", "amount", "source", "destination"],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "get_transfer",
|
|
131
|
+
description: "Get transfer details by ID",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: {
|
|
135
|
+
id: { type: "string", description: "Transfer ID" },
|
|
136
|
+
},
|
|
137
|
+
required: ["id"],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "get_balance",
|
|
142
|
+
description: "Get account balance",
|
|
143
|
+
inputSchema: { type: "object", properties: {} },
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "list_transactions",
|
|
147
|
+
description: "List transactions with optional filters",
|
|
148
|
+
inputSchema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
type: { type: "string", enum: ["payment", "payout", "transfer"], description: "Filter by transaction type" },
|
|
152
|
+
status: { type: "string", enum: ["pending", "confirmed", "complete", "failed"], description: "Filter by status" },
|
|
153
|
+
from: { type: "string", description: "Start date (ISO 8601)" },
|
|
154
|
+
to: { type: "string", description: "End date (ISO 8601)" },
|
|
155
|
+
pageSize: { type: "number", description: "Number of results per page" },
|
|
156
|
+
pageBefore: { type: "string", description: "Cursor for previous page" },
|
|
157
|
+
pageAfter: { type: "string", description: "Cursor for next page" },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
}));
|
|
163
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
164
|
+
const { name, arguments: args } = request.params;
|
|
165
|
+
try {
|
|
166
|
+
switch (name) {
|
|
167
|
+
case "create_wallet":
|
|
168
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/wallets", args), null, 2) }] };
|
|
169
|
+
case "get_wallet":
|
|
170
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/wallets/${args?.id}`), null, 2) }] };
|
|
171
|
+
case "create_payment":
|
|
172
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/payments", args), null, 2) }] };
|
|
173
|
+
case "get_payment":
|
|
174
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/payments/${args?.id}`), null, 2) }] };
|
|
175
|
+
case "create_payout":
|
|
176
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/payouts", args), null, 2) }] };
|
|
177
|
+
case "get_payout":
|
|
178
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/payouts/${args?.id}`), null, 2) }] };
|
|
179
|
+
case "create_transfer":
|
|
180
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/transfers", args), null, 2) }] };
|
|
181
|
+
case "get_transfer":
|
|
182
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/transfers/${args?.id}`), null, 2) }] };
|
|
183
|
+
case "get_balance":
|
|
184
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", "/balances"), null, 2) }] };
|
|
185
|
+
case "list_transactions": {
|
|
186
|
+
const params = new URLSearchParams();
|
|
187
|
+
if (args?.type)
|
|
188
|
+
params.set("type", String(args.type));
|
|
189
|
+
if (args?.status)
|
|
190
|
+
params.set("status", String(args.status));
|
|
191
|
+
if (args?.from)
|
|
192
|
+
params.set("from", String(args.from));
|
|
193
|
+
if (args?.to)
|
|
194
|
+
params.set("to", String(args.to));
|
|
195
|
+
if (args?.pageSize)
|
|
196
|
+
params.set("pageSize", String(args.pageSize));
|
|
197
|
+
if (args?.pageBefore)
|
|
198
|
+
params.set("pageBefore", String(args.pageBefore));
|
|
199
|
+
if (args?.pageAfter)
|
|
200
|
+
params.set("pageAfter", String(args.pageAfter));
|
|
201
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/transactions?${params}`), null, 2) }] };
|
|
202
|
+
}
|
|
203
|
+
default:
|
|
204
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
async function main() {
|
|
212
|
+
if (!API_KEY) {
|
|
213
|
+
console.error("CIRCLE_API_KEY environment variable is required");
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
const transport = new StdioServerTransport();
|
|
217
|
+
await server.connect(transport);
|
|
218
|
+
}
|
|
219
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codespar/mcp-circle",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Circle — USDC payments, wallets, payouts, transfers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-circle": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^22.0.0",
|
|
19
|
+
"typescript": "^5.8.0"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"circle",
|
|
25
|
+
"usdc",
|
|
26
|
+
"crypto",
|
|
27
|
+
"stablecoin",
|
|
28
|
+
"payments"
|
|
29
|
+
]
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP Server for Circle — USDC stablecoin infrastructure.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* - create_wallet: Create a new Circle wallet
|
|
8
|
+
* - get_wallet: Get wallet details by ID
|
|
9
|
+
* - create_payment: Accept a USDC payment
|
|
10
|
+
* - get_payment: Get payment details by ID
|
|
11
|
+
* - create_payout: Create a payout (USDC to fiat)
|
|
12
|
+
* - get_payout: Get payout details by ID
|
|
13
|
+
* - create_transfer: Create a USDC transfer between wallets
|
|
14
|
+
* - get_transfer: Get transfer details by ID
|
|
15
|
+
* - get_balance: Get wallet balance
|
|
16
|
+
* - list_transactions: List transactions with filters
|
|
17
|
+
*
|
|
18
|
+
* Environment:
|
|
19
|
+
* CIRCLE_API_KEY — API key from https://www.circle.com/
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
23
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
24
|
+
import {
|
|
25
|
+
CallToolRequestSchema,
|
|
26
|
+
ListToolsRequestSchema,
|
|
27
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
28
|
+
|
|
29
|
+
const API_KEY = process.env.CIRCLE_API_KEY || "";
|
|
30
|
+
const BASE_URL = "https://api.circle.com/v1";
|
|
31
|
+
|
|
32
|
+
async function circleRequest(method: string, path: string, body?: unknown): Promise<unknown> {
|
|
33
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
34
|
+
method,
|
|
35
|
+
headers: {
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
"Authorization": `Bearer ${API_KEY}`,
|
|
38
|
+
},
|
|
39
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
const err = await res.text();
|
|
43
|
+
throw new Error(`Circle API ${res.status}: ${err}`);
|
|
44
|
+
}
|
|
45
|
+
return res.json();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const server = new Server(
|
|
49
|
+
{ name: "mcp-circle", version: "0.1.0" },
|
|
50
|
+
{ capabilities: { tools: {} } }
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
54
|
+
tools: [
|
|
55
|
+
{
|
|
56
|
+
name: "create_wallet",
|
|
57
|
+
description: "Create a new Circle wallet",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {
|
|
61
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
62
|
+
description: { type: "string", description: "Wallet description" },
|
|
63
|
+
},
|
|
64
|
+
required: ["idempotencyKey"],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "get_wallet",
|
|
69
|
+
description: "Get wallet details by ID",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
id: { type: "string", description: "Wallet ID" },
|
|
74
|
+
},
|
|
75
|
+
required: ["id"],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "create_payment",
|
|
80
|
+
description: "Accept a USDC payment via Circle",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
85
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount (e.g. '10.00')" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Payment amount" },
|
|
86
|
+
source: { type: "object", properties: { id: { type: "string", description: "Source ID" }, type: { type: "string", description: "Source type (e.g. card, ach)" } }, required: ["id", "type"], description: "Payment source" },
|
|
87
|
+
description: { type: "string", description: "Payment description" },
|
|
88
|
+
},
|
|
89
|
+
required: ["idempotencyKey", "amount", "source"],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "get_payment",
|
|
94
|
+
description: "Get payment details by ID",
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {
|
|
98
|
+
id: { type: "string", description: "Payment ID" },
|
|
99
|
+
},
|
|
100
|
+
required: ["id"],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "create_payout",
|
|
105
|
+
description: "Create a payout from Circle (USDC to fiat)",
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
110
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Payout amount" },
|
|
111
|
+
destination: { type: "object", properties: { id: { type: "string", description: "Destination ID (bank account)" }, type: { type: "string", description: "Destination type (e.g. wire)" } }, required: ["id", "type"], description: "Payout destination" },
|
|
112
|
+
},
|
|
113
|
+
required: ["idempotencyKey", "amount", "destination"],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: "get_payout",
|
|
118
|
+
description: "Get payout details by ID",
|
|
119
|
+
inputSchema: {
|
|
120
|
+
type: "object",
|
|
121
|
+
properties: {
|
|
122
|
+
id: { type: "string", description: "Payout ID" },
|
|
123
|
+
},
|
|
124
|
+
required: ["id"],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "create_transfer",
|
|
129
|
+
description: "Create a USDC transfer between Circle wallets",
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: "object",
|
|
132
|
+
properties: {
|
|
133
|
+
idempotencyKey: { type: "string", description: "Unique idempotency key (UUID)" },
|
|
134
|
+
amount: { type: "object", properties: { amount: { type: "string", description: "Amount" }, currency: { type: "string", description: "Currency (USD)" } }, required: ["amount", "currency"], description: "Transfer amount" },
|
|
135
|
+
source: { type: "object", properties: { id: { type: "string", description: "Source wallet ID" }, type: { type: "string", description: "Source type (wallet)" } }, required: ["id", "type"], description: "Transfer source" },
|
|
136
|
+
destination: { type: "object", properties: { id: { type: "string", description: "Destination wallet ID" }, type: { type: "string", description: "Destination type (wallet, blockchain)" } }, required: ["id", "type"], description: "Transfer destination" },
|
|
137
|
+
},
|
|
138
|
+
required: ["idempotencyKey", "amount", "source", "destination"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "get_transfer",
|
|
143
|
+
description: "Get transfer details by ID",
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: {
|
|
147
|
+
id: { type: "string", description: "Transfer ID" },
|
|
148
|
+
},
|
|
149
|
+
required: ["id"],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "get_balance",
|
|
154
|
+
description: "Get account balance",
|
|
155
|
+
inputSchema: { type: "object", properties: {} },
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "list_transactions",
|
|
159
|
+
description: "List transactions with optional filters",
|
|
160
|
+
inputSchema: {
|
|
161
|
+
type: "object",
|
|
162
|
+
properties: {
|
|
163
|
+
type: { type: "string", enum: ["payment", "payout", "transfer"], description: "Filter by transaction type" },
|
|
164
|
+
status: { type: "string", enum: ["pending", "confirmed", "complete", "failed"], description: "Filter by status" },
|
|
165
|
+
from: { type: "string", description: "Start date (ISO 8601)" },
|
|
166
|
+
to: { type: "string", description: "End date (ISO 8601)" },
|
|
167
|
+
pageSize: { type: "number", description: "Number of results per page" },
|
|
168
|
+
pageBefore: { type: "string", description: "Cursor for previous page" },
|
|
169
|
+
pageAfter: { type: "string", description: "Cursor for next page" },
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
}));
|
|
175
|
+
|
|
176
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
177
|
+
const { name, arguments: args } = request.params;
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
switch (name) {
|
|
181
|
+
case "create_wallet":
|
|
182
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/wallets", args), null, 2) }] };
|
|
183
|
+
case "get_wallet":
|
|
184
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/wallets/${args?.id}`), null, 2) }] };
|
|
185
|
+
case "create_payment":
|
|
186
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/payments", args), null, 2) }] };
|
|
187
|
+
case "get_payment":
|
|
188
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/payments/${args?.id}`), null, 2) }] };
|
|
189
|
+
case "create_payout":
|
|
190
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/payouts", args), null, 2) }] };
|
|
191
|
+
case "get_payout":
|
|
192
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/payouts/${args?.id}`), null, 2) }] };
|
|
193
|
+
case "create_transfer":
|
|
194
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("POST", "/transfers", args), null, 2) }] };
|
|
195
|
+
case "get_transfer":
|
|
196
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/transfers/${args?.id}`), null, 2) }] };
|
|
197
|
+
case "get_balance":
|
|
198
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", "/balances"), null, 2) }] };
|
|
199
|
+
case "list_transactions": {
|
|
200
|
+
const params = new URLSearchParams();
|
|
201
|
+
if (args?.type) params.set("type", String(args.type));
|
|
202
|
+
if (args?.status) params.set("status", String(args.status));
|
|
203
|
+
if (args?.from) params.set("from", String(args.from));
|
|
204
|
+
if (args?.to) params.set("to", String(args.to));
|
|
205
|
+
if (args?.pageSize) params.set("pageSize", String(args.pageSize));
|
|
206
|
+
if (args?.pageBefore) params.set("pageBefore", String(args.pageBefore));
|
|
207
|
+
if (args?.pageAfter) params.set("pageAfter", String(args.pageAfter));
|
|
208
|
+
return { content: [{ type: "text", text: JSON.stringify(await circleRequest("GET", `/transactions?${params}`), null, 2) }] };
|
|
209
|
+
}
|
|
210
|
+
default:
|
|
211
|
+
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {
|
|
214
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
async function main() {
|
|
219
|
+
if (!API_KEY) {
|
|
220
|
+
console.error("CIRCLE_API_KEY environment variable is required");
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
const transport = new StdioServerTransport();
|
|
224
|
+
await server.connect(transport);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
main().catch(console.error);
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|