agentpump-mcp 1.1.3 β 1.1.5
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 +34 -46
- package/index.js +32 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,73 +1,61 @@
|
|
|
1
|
-
# AgentPump
|
|
1
|
+
# AgentPump β give your AI agent a Solana wallet π€
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Open-source MCP server that lets an AI agent launch and trade tokens on Solana β autonomously, from plain-language chat.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Add one MCP server to **Claude Code, Cursor, or any MCP client**, then just tell your agent to launch and trade tokens on [AgentPump](https://app.agents-coin.com/agentpump), a fair bonding-curve launchpad on **Solana mainnet**. The private key is generated **locally** and never leaves your machine β it's never sent to the model or any server, only signatures hit the chain.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
> Live on Solana mainnet. Real money β start small.
|
|
8
|
+
|
|
9
|
+
π [Website](https://app.agents-coin.com/agents) Β· π¦ [npm: agentpump-mcp](https://www.npmjs.com/package/agentpump-mcp) Β· πͺ [Trade on the web](https://app.agents-coin.com/pump) Β· π¬ [Telegram bot](https://t.me/AgentsPumpBot)
|
|
8
10
|
|
|
9
11
|
---
|
|
10
12
|
|
|
11
13
|
## Install
|
|
12
14
|
|
|
13
|
-
###
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
### Claude Code
|
|
16
|
+
```
|
|
17
|
+
claude mcp add agentpump -- npx -y agentpump-mcp
|
|
18
|
+
```
|
|
17
19
|
|
|
18
|
-
### Any MCP client (Claude Code,
|
|
20
|
+
### Any MCP client (Cursor, Claude Code, β¦)
|
|
21
|
+
Add to your MCP config:
|
|
19
22
|
```json
|
|
20
23
|
{
|
|
21
24
|
"mcpServers": {
|
|
22
|
-
"agentpump": {
|
|
23
|
-
"command": "npx",
|
|
24
|
-
"args": ["-y", "agentpump-mcp@latest"]
|
|
25
|
-
}
|
|
25
|
+
"agentpump": { "command": "npx", "args": ["-y", "agentpump-mcp"] }
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
|
+
Also in the official MCP Registry as `io.github.axiosdevs/agentpump-mcp`. A mainnet RPC is built in β nothing to configure.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
git clone https://github.com/axiosdevs/agentpump-mcp
|
|
33
|
-
cd agentpump-mcp && npm install
|
|
34
|
-
# then point your MCP client at: node /path/to/agentpump-mcp/index.js
|
|
31
|
+
## Then just chat
|
|
32
|
+
Talk to your agent in plain language β it calls the tools:
|
|
35
33
|
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## Talk to your agent
|
|
40
|
-
```
|
|
41
|
-
"create a Solana wallet"
|
|
42
|
-
"show my address" β send real SOL there (no faucet on mainnet)
|
|
43
|
-
"launch a token called Doge AI (DOGEAI)"
|
|
44
|
-
"buy 0.1 SOL of <mint>" β on the bonding curve
|
|
34
|
+
"create a Solana wallet and show me the address" β then fund it with a little SOL
|
|
35
|
+
"launch a token called Doge AI (DOGEAI), then buy 0.05 SOL of it"
|
|
45
36
|
"sell 50% of <mint>"
|
|
46
|
-
"buy 0.2 SOL of <mint> on Raydium"
|
|
47
|
-
"sell 100% of <mint> on Raydium"
|
|
37
|
+
"buy 0.2 SOL of <mint> on Raydium" β after it graduates
|
|
48
38
|
```
|
|
49
39
|
|
|
50
40
|
## Tools
|
|
51
|
-
| Tool |
|
|
41
|
+
| Tool | Does |
|
|
52
42
|
|---|---|
|
|
53
|
-
| `sol_create_wallet` |
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
| `sol_create_wallet` / `sol_address` / `sol_balance` | Local agent wallet (`~/.agentpump/wallet.json`) |
|
|
44
|
+
| `sol_launch` | Launch a token on the bonding curve |
|
|
45
|
+
| `sol_buy` / `sol_sell` | Trade on the curve (pre-graduation) |
|
|
46
|
+
| `sol_raydium_buy` / `sol_raydium_sell` | Trade graduated tokens on Raydium |
|
|
47
|
+
|
|
48
|
+
The whole client is one [`index.js`](index.js) β exactly what `npx agentpump-mcp` runs. No build step, no hidden network calls. Read every line before funding it.
|
|
49
|
+
|
|
50
|
+
## How the launchpad works
|
|
51
|
+
1. **Mint** β launching is free (~0.008 SOL network rent, none to the protocol). 1B supply, all on the curve. No presale, no team allocation.
|
|
52
|
+
2. **Pump** β constant-product bonding curve; ~80% of supply sells on it. **1% fee per trade**, shared with the token creator (+ referrer).
|
|
53
|
+
3. **Graduate** β at **10 SOL** the curve closes, a **Raydium** pool is created and the **LP is burned** β liquidity locked forever. Then it trades everywhere (Raydium, Jupiter, DexScreenerβ¦).
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
- **Local key** β generated on your machine (`~/.agentpump/wallet.json`); only signatures hit the chain.
|
|
64
|
-
- **Real money** β Solana **mainnet**. Fund the wallet with real SOL. Start small.
|
|
65
|
-
- **Fair launch** β every token starts on a bonding curve (~80% of supply sold on the curve). 1% trade fee. Graduates to Raydium at 10 SOL, where liquidity is locked (LP burned).
|
|
66
|
-
- **Then trade on Raydium** β after graduation the agent buys/sells on Raydium with `sol_raydium_*` (1% fee).
|
|
67
|
-
- **Program:** `4M93xdyduoYj4W7LaLRmXrk5PqyGD6SoxzX8CwdKe3VM`
|
|
55
|
+
On-chain program: [`4M93xdyduoYj4W7LaLRmXrk5PqyGD6SoxzX8CwdKe3VM`](https://solscan.io/account/4M93xdyduoYj4W7LaLRmXrk5PqyGD6SoxzX8CwdKe3VM) (verifiable on Solscan).
|
|
68
56
|
|
|
69
|
-
## Also
|
|
57
|
+
## Also for people (no MCP needed)
|
|
70
58
|
- πͺ **Web (Phantom):** https://app.agents-coin.com/pump
|
|
71
|
-
- π¬ **Telegram bot:** https://t.me/AgentsPumpBot
|
|
59
|
+
- π¬ **Telegram bot:** https://t.me/AgentsPumpBot
|
|
72
60
|
|
|
73
61
|
MIT licensed.
|
package/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "@solana/spl-token";
|
|
14
14
|
import { Raydium, TxVersion, CurveCalculator, CREATE_CPMM_POOL_PROGRAM } from "@raydium-io/raydium-sdk-v2";
|
|
15
15
|
import BN from "bn.js";
|
|
16
|
+
import bs58 from "bs58";
|
|
16
17
|
import { homedir } from "os";
|
|
17
18
|
import { join } from "path";
|
|
18
19
|
import { mkdirSync, readFileSync, writeFileSync, existsSync, chmodSync } from "fs";
|
|
@@ -50,6 +51,15 @@ function tradeKeys(mint, curve, cAta, uAta, user) {
|
|
|
50
51
|
];
|
|
51
52
|
}
|
|
52
53
|
const ok = (t) => ({ content: [{ type: "text", text: t }] });
|
|
54
|
+
// retry once on transient RPC/simulation flaps (stale blockhash, rate-limit, node hiccup) β the tx didn't land, so it's safe
|
|
55
|
+
async function retryTransient(fn) {
|
|
56
|
+
try { return await fn(); }
|
|
57
|
+
catch (e) { const m = ((e && e.message) || "") + "";
|
|
58
|
+
if (/custom program error/i.test(m)) throw e; // deterministic on-chain rejection β a retry can't fix it
|
|
59
|
+
if (/simulat|blockhash|not found|expired|timed out|timeout|429|too many|fetch failed|ECONN|socket|rate limit/i.test(m)) { await new Promise((r) => setTimeout(r, 1000)); return await fn(); }
|
|
60
|
+
throw e; }
|
|
61
|
+
}
|
|
62
|
+
const send = (tx, signers) => retryTransient(() => sendAndConfirmTransaction(conn, tx, signers));
|
|
53
63
|
|
|
54
64
|
// --- Raydium CPMM helpers (trade graduated/listed tokens; 1% fee to treasury) ---
|
|
55
65
|
let _ray;
|
|
@@ -65,7 +75,7 @@ function estimate(inAmt, inRes, outRes, ci) {
|
|
|
65
75
|
return CurveCalculator.swapBaseInput(inAmt, inRes, outRes, ci.tradeFeeRate, ci.creatorFeeRate, ci.protocolFeeRate, ci.fundFeeRate, false);
|
|
66
76
|
}
|
|
67
77
|
|
|
68
|
-
const s = new McpServer({ name: "agentpump", version: "1.1.
|
|
78
|
+
const s = new McpServer({ name: "agentpump", version: "1.1.5" });
|
|
69
79
|
|
|
70
80
|
s.tool("sol_create_wallet", "Create the agent's Solana wallet (saved locally, hidden). Returns the address to fund.", {}, { title: "Create wallet", readOnlyHint: false }, async () => {
|
|
71
81
|
if (existsSync(WFILE)) return ok("Wallet already exists: " + loadKp().publicKey.toBase58());
|
|
@@ -78,30 +88,30 @@ s.tool("sol_balance", "Check the wallet's SOL balance.", {}, { title: "Balance",
|
|
|
78
88
|
const kp = loadKp(); const b = await conn.getBalance(kp.publicKey); return ok((b / LAMPORTS_PER_SOL).toFixed(4) + " SOL\n" + kp.publicKey.toBase58());
|
|
79
89
|
});
|
|
80
90
|
s.tool("sol_launch", "Launch a new token on AgentPump (bonding curve). Costs ~0.02 SOL in rent.", { name: z.string(), symbol: z.string() }, { title: "Launch token", readOnlyHint: false, openWorldHint: true }, async ({ name, symbol }) => {
|
|
81
|
-
const kp = loadKp(); const mint = await createMint(conn, kp, kp.publicKey, null, 6); // returns a PublicKey
|
|
82
|
-
await
|
|
91
|
+
const kp = loadKp(); const mint = await retryTransient(() => createMint(conn, kp, kp.publicKey, null, 6)); // returns a PublicKey
|
|
92
|
+
await send(new Transaction().add(metaIx(mint, kp.publicKey, kp.publicKey, name, symbol)), [kp]); // on-chain name/symbol so it shows on the launchpad
|
|
83
93
|
const curve = curveOf(mint), cAta = ataOf(mint, curve);
|
|
84
|
-
await
|
|
85
|
-
await mintTo(conn, kp, mint, cAta, kp, SUPPLY);
|
|
94
|
+
await send(new Transaction().add(createAssociatedTokenAccountIdempotentInstruction(kp.publicKey, cAta, curve, mint)), [kp]);
|
|
95
|
+
await retryTransient(() => mintTo(conn, kp, mint, cAta, kp, SUPPLY));
|
|
86
96
|
const ix = new TransactionInstruction({ programId: PROGRAM, data: Buffer.concat([Buffer.from([1]), u64(V_SOL), u64(SUPPLY)]), keys: [
|
|
87
97
|
{ pubkey: CONFIG, isSigner: false, isWritable: true }, { pubkey: curve, isSigner: false, isWritable: true }, { pubkey: mint, isSigner: false, isWritable: false },
|
|
88
98
|
{ pubkey: cAta, isSigner: false, isWritable: true }, { pubkey: kp.publicKey, isSigner: true, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
89
99
|
] });
|
|
90
|
-
await
|
|
100
|
+
await send(new Transaction().add(ix), [kp]);
|
|
91
101
|
return ok(`Launched ${symbol}. Token: ${mint.toBase58()}\nTradeable on the curve; graduates to Raydium at 10 SOL.`);
|
|
92
102
|
});
|
|
93
103
|
s.tool("sol_buy", "Buy a token on its bonding curve (pre-graduation). For graduated tokens use sol_raydium_buy.", { mint: z.string(), sol: z.number() }, { title: "Buy (curve)", readOnlyHint: false, openWorldHint: true }, async ({ mint: ms, sol: amt }) => {
|
|
94
104
|
const kp = loadKp(); const mint = new PublicKey(ms); const curve = curveOf(mint), cAta = ataOf(mint, curve), uAta = ataOf(mint, kp.publicKey);
|
|
95
105
|
const tx = new Transaction().add(createAssociatedTokenAccountIdempotentInstruction(kp.publicKey, uAta, kp.publicKey, mint))
|
|
96
106
|
.add(new TransactionInstruction({ programId: PROGRAM, keys: tradeKeys(mint, curve, cAta, uAta, kp.publicKey), data: Buffer.concat([Buffer.from([2]), u64(Math.round(amt * LAMPORTS_PER_SOL)), u64(0)]) }));
|
|
97
|
-
const sig = await
|
|
107
|
+
const sig = await send(tx, [kp]); return ok("Bought. " + sig);
|
|
98
108
|
});
|
|
99
109
|
s.tool("sol_sell", "Sell a percentage of a token holding back to the bonding curve (pre-graduation). For graduated tokens use sol_raydium_sell.", { mint: z.string(), percent: z.number() }, { title: "Sell (curve)", readOnlyHint: false, openWorldHint: true }, async ({ mint: ms, percent }) => {
|
|
100
110
|
const kp = loadKp(); const mint = new PublicKey(ms); const curve = curveOf(mint), cAta = ataOf(mint, curve), uAta = ataOf(mint, kp.publicKey);
|
|
101
111
|
const acc = await getAccount(conn, uAta); const amt = (acc.amount * BigInt(Math.round(percent))) / 100n;
|
|
102
112
|
if (amt <= 0n) throw new Error("nothing to sell");
|
|
103
113
|
const ix = new TransactionInstruction({ programId: PROGRAM, keys: tradeKeys(mint, curve, cAta, uAta, kp.publicKey), data: Buffer.concat([Buffer.from([3]), u64(amt), u64(0)]) });
|
|
104
|
-
const sig = await
|
|
114
|
+
const sig = await send(new Transaction().add(ix), [kp]); return ok("Sold. " + sig);
|
|
105
115
|
});
|
|
106
116
|
s.tool("sol_raydium_buy", "Buy any graduated/listed token on Raydium (after it leaves the bonding curve). Charges a 1% fee.", { mint: z.string(), sol: z.number() }, { title: "Buy (Raydium)", readOnlyHint: false, openWorldHint: true }, async ({ mint: ms, sol: amt }) => {
|
|
107
117
|
const kp = loadKp(); const mint = new PublicKey(ms);
|
|
@@ -139,4 +149,18 @@ s.tool("sol_raydium_sell", "Sell a percentage of a graduated/listed token on Ray
|
|
|
139
149
|
return ok(`Sold on Raydium. tx ${r.txId}\n1% fee (${(feePaid / LAMPORTS_PER_SOL).toFixed(5)} SOL) sent to treasury.`);
|
|
140
150
|
});
|
|
141
151
|
|
|
152
|
+
s.tool("sol_withdraw", "Send SOL out of the agent wallet to any address. Omit 'sol' to send the whole balance (minus the network fee).", { to: z.string(), sol: z.number().optional() }, { title: "Withdraw SOL", readOnlyHint: false, openWorldHint: true }, async ({ to, sol }) => {
|
|
153
|
+
const kp = loadKp(); const dest = new PublicKey(to);
|
|
154
|
+
const bal = await conn.getBalance(kp.publicKey); const FEE_L = 5000;
|
|
155
|
+
let lamports = (sol == null) ? bal - FEE_L : Math.round(sol * LAMPORTS_PER_SOL);
|
|
156
|
+
if (lamports > bal - FEE_L) lamports = bal - FEE_L;
|
|
157
|
+
if (lamports <= 0) throw new Error("balance too low to withdraw (need to cover the ~0.000005 SOL network fee)");
|
|
158
|
+
const sig = await send(new Transaction().add(SystemProgram.transfer({ fromPubkey: kp.publicKey, toPubkey: dest, lamports })), [kp]);
|
|
159
|
+
return ok(`Sent ${(lamports / LAMPORTS_PER_SOL).toFixed(6)} SOL to ${to}\n${sig}`);
|
|
160
|
+
});
|
|
161
|
+
s.tool("sol_export_key", "Reveal the agent wallet's private key (base58) so it can be imported into Phantom/Solflare. Anyone with this key controls the funds β only show it to the wallet owner.", {}, { title: "Export private key", readOnlyHint: true }, async () => {
|
|
162
|
+
const kp = loadKp();
|
|
163
|
+
return ok("Private key (import into Phantom β 'Import Private Key'):\n" + bs58.encode(kp.secretKey) + "\n\nβ οΈ Anyone with this key controls the wallet. Keep it secret.");
|
|
164
|
+
});
|
|
165
|
+
|
|
142
166
|
await s.connect(new StdioServerTransport());
|
package/package.json
CHANGED