@clawbank/mcp-server 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 +84 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +115 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @clawbank/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for [ClawBank](https://clawbank.vercel.app) — programmable AI agent wallets on Solana.
|
|
4
|
+
|
|
5
|
+
Gives Claude (and any MCP-compatible AI client) three tools:
|
|
6
|
+
|
|
7
|
+
| Tool | Description |
|
|
8
|
+
|------|-------------|
|
|
9
|
+
| `check_balance` | Get your agent wallet's SOL balance |
|
|
10
|
+
| `send_sol` | Send SOL to any Solana address |
|
|
11
|
+
| `health_check` | Check if the ClawBank service is operational |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
### 1. Create an agent
|
|
18
|
+
|
|
19
|
+
Sign up at [clawbank.vercel.app](https://clawbank.vercel.app), create an agent from the dashboard, and copy your **API key** (`cb_...`).
|
|
20
|
+
|
|
21
|
+
### 2. Add to Claude Desktop
|
|
22
|
+
|
|
23
|
+
Open `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) and add:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"clawbank": {
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["-y", "@clawbank/mcp-server"],
|
|
31
|
+
"env": {
|
|
32
|
+
"CLAWBANK_API_KEY": "cb_your_api_key_here"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Restart Claude Desktop. You'll see ClawBank tools appear in the tool picker.
|
|
40
|
+
|
|
41
|
+
### 3. Use it
|
|
42
|
+
|
|
43
|
+
Ask Claude:
|
|
44
|
+
- _"What's my ClawBank balance?"_
|
|
45
|
+
- _"Send 0.01 SOL to `<address>` with memo 'invoice 42'"_
|
|
46
|
+
- _"Is ClawBank healthy?"_
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Environment Variables
|
|
51
|
+
|
|
52
|
+
| Variable | Required | Default | Description |
|
|
53
|
+
|----------|----------|---------|-------------|
|
|
54
|
+
| `CLAWBANK_API_KEY` | Yes | — | Your agent API key from the dashboard |
|
|
55
|
+
| `CLAWBANK_API_URL` | No | `https://clawbank.vercel.app` | Override the API base URL (self-hosted) |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Local development
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git clone https://github.com/clawbank/clawbank
|
|
63
|
+
cd artifacts/mcp-server
|
|
64
|
+
pnpm install
|
|
65
|
+
pnpm build
|
|
66
|
+
CLAWBANK_API_KEY=cb_xxx node dist/index.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## How it works
|
|
72
|
+
|
|
73
|
+
Each API call uses your agent's API key (`Authorization: Bearer <key>`). ClawBank verifies it against the stored hash, then executes the action on the agent's dedicated Solana wallet.
|
|
74
|
+
|
|
75
|
+
Transactions are:
|
|
76
|
+
- **Simulated** before broadcast (catches insufficient balance)
|
|
77
|
+
- **Rate-limited** by your daily / per-tx spend limits set in the dashboard
|
|
78
|
+
- **Logged** — full history available in the ClawBank dashboard
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
const API_URL = (process.env.CLAWBANK_API_URL ?? "https://clawbank.vercel.app").replace(/\/$/, "");
|
|
6
|
+
const API_KEY = process.env.CLAWBANK_API_KEY ?? "";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
async function apiGet(path, apiKey) {
|
|
11
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: `Bearer ${apiKey}`,
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
const json = await res.json();
|
|
18
|
+
if (!res.ok) {
|
|
19
|
+
const err = json.error ?? res.statusText;
|
|
20
|
+
throw new Error(`ClawBank API error ${res.status}: ${err}`);
|
|
21
|
+
}
|
|
22
|
+
return json;
|
|
23
|
+
}
|
|
24
|
+
async function apiPost(path, apiKey, body) {
|
|
25
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
Authorization: `Bearer ${apiKey}`,
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify(body),
|
|
32
|
+
});
|
|
33
|
+
const json = await res.json();
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
const err = json.error ?? res.statusText;
|
|
36
|
+
throw new Error(`ClawBank API error ${res.status}: ${err}`);
|
|
37
|
+
}
|
|
38
|
+
return json;
|
|
39
|
+
}
|
|
40
|
+
function requireApiKey() {
|
|
41
|
+
if (!API_KEY) {
|
|
42
|
+
throw new Error("CLAWBANK_API_KEY is not set. Add it to your MCP server environment variables.\n" +
|
|
43
|
+
"Get your API key from the ClawBank dashboard: https://clawbank.vercel.app/dashboard");
|
|
44
|
+
}
|
|
45
|
+
return API_KEY;
|
|
46
|
+
}
|
|
47
|
+
function text(content) {
|
|
48
|
+
return { content: [{ type: "text", text: content }] };
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Server
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
const server = new McpServer({
|
|
54
|
+
name: "clawbank",
|
|
55
|
+
version: "1.0.0",
|
|
56
|
+
});
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Tool: check_balance
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
server.tool("check_balance", "Get the current SOL balance of your ClawBank agent wallet. Returns the balance in SOL and lamports along with the wallet address.", {}, async () => {
|
|
61
|
+
const key = requireApiKey();
|
|
62
|
+
const result = await apiGet("/api/agent/balance", key);
|
|
63
|
+
const { wallet_address, balance_sol, balance_lamports } = result.data;
|
|
64
|
+
return text(`Wallet: ${wallet_address}\nBalance: ${balance_sol.toFixed(6)} SOL (${balance_lamports.toLocaleString()} lamports)`);
|
|
65
|
+
});
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Tool: send_sol
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
server.tool("send_sol", "Send SOL from your ClawBank agent wallet to any Solana address. A small platform fee (0.5%) is deducted automatically. Returns the transaction signature and Solana Explorer link.", {
|
|
70
|
+
to: z.string().min(32).max(44).describe("Destination Solana wallet address (base58)"),
|
|
71
|
+
amount_sol: z
|
|
72
|
+
.number()
|
|
73
|
+
.positive()
|
|
74
|
+
.max(1000)
|
|
75
|
+
.describe("Amount of SOL to send (before fee). Must be positive, max 1000."),
|
|
76
|
+
memo: z
|
|
77
|
+
.string()
|
|
78
|
+
.max(200)
|
|
79
|
+
.optional()
|
|
80
|
+
.describe("Optional memo attached to the transaction (max 200 chars)"),
|
|
81
|
+
}, async ({ to, amount_sol, memo }) => {
|
|
82
|
+
const key = requireApiKey();
|
|
83
|
+
const body = { to, amount_sol };
|
|
84
|
+
if (memo)
|
|
85
|
+
body.memo = memo;
|
|
86
|
+
const result = await apiPost("/api/agent/transact", key, body);
|
|
87
|
+
const { signature, amount_sol: sent, fee_sol, explorer_url } = result.data;
|
|
88
|
+
return text([
|
|
89
|
+
`✅ Transaction confirmed`,
|
|
90
|
+
`Sent: ${sent.toFixed(6)} SOL`,
|
|
91
|
+
`Fee: ${fee_sol.toFixed(6)} SOL`,
|
|
92
|
+
`To: ${to}`,
|
|
93
|
+
`Signature: ${signature}`,
|
|
94
|
+
`Explorer: ${explorer_url}`,
|
|
95
|
+
].join("\n"));
|
|
96
|
+
});
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Tool: health_check
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
server.tool("health_check", "Check whether the ClawBank service and Solana RPC are operational.", {}, async () => {
|
|
101
|
+
const res = await fetch(`${API_URL}/api/health`);
|
|
102
|
+
const json = await res.json();
|
|
103
|
+
return text([
|
|
104
|
+
`Status: ${json.status}`,
|
|
105
|
+
`Network: ${json.network}`,
|
|
106
|
+
`Solana: ${json.solana?.status ?? "unknown"}${json.solana?.latency_ms != null ? ` (${json.solana.latency_ms}ms)` : ""}`,
|
|
107
|
+
`Time: ${json.timestamp}`,
|
|
108
|
+
].join("\n"));
|
|
109
|
+
});
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Start
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
const transport = new StdioServerTransport();
|
|
114
|
+
await server.connect(transport);
|
|
115
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@clawbank/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for ClawBank — programmable AI agent wallets on Solana",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"clawbank-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"model-context-protocol",
|
|
23
|
+
"claude",
|
|
24
|
+
"solana",
|
|
25
|
+
"ai-agent",
|
|
26
|
+
"wallet",
|
|
27
|
+
"clawbank",
|
|
28
|
+
"web3"
|
|
29
|
+
],
|
|
30
|
+
"author": "ClawBank",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
34
|
+
"zod": "^3.25.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.0.0",
|
|
38
|
+
"typescript": "^5.8.0"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/clawbank/clawbank"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://clawbank.vercel.app"
|
|
48
|
+
}
|