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.
Files changed (3) hide show
  1. package/README.md +34 -46
  2. package/index.js +32 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,73 +1,61 @@
1
- # AgentPump MCP
1
+ # AgentPump β€” give your AI agent a Solana wallet πŸ€–
2
2
 
3
- Give your AI agent its own **Solana wallet** and let it **launch and trade tokens** on [AgentPump](https://app.agents-coin.com) β€” a pump.fun-style bonding-curve launchpad on **Solana mainnet**. Works in Claude, Cursor, and any MCP client.
3
+ **Open-source MCP server that lets an AI agent launch and trade tokens on Solana β€” autonomously, from plain-language chat.**
4
4
 
5
- 🌐 **Website:** https://app.agents-coin.com Β· πŸͺ™ **Launch & trade (web):** https://app.agents-coin.com/pump Β· πŸ’¬ **Telegram bot:** https://t.me/AgentsPumpBot
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
- The agent's key stays **local** (used only to sign β€” never sent to the model or the cloud). You fund the wallet with SOL, then it can create and trade tokens autonomously. 1% per trade. Tokens graduate to Raydium at 10 SOL β€” and your agent can keep trading them there too.
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
- ### ⚑ Claude Desktop β€” one click (no npm, no terminal)
14
- 1. Download **[`agentpump.mcpb`](https://github.com/axiosdevs/agentpump-mcp/releases/latest/download/agentpump.mcpb)**
15
- 2. Open it with **Claude Desktop** β†’ *Settings β†’ Extensions β†’ Install*
16
- 3. That's it β€” a mainnet RPC is built in. (Optional: set your own Helius/QuickNode RPC in the extension settings.)
15
+ ### Claude Code
16
+ ```
17
+ claude mcp add agentpump -- npx -y agentpump-mcp
18
+ ```
17
19
 
18
- ### Any MCP client (Claude Code, Cursor, …) via npx
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
- ### From source
31
- ```bash
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" ← once it graduated/listed
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 | What it does |
41
+ | Tool | Does |
52
42
  |---|---|
53
- | `sol_create_wallet` | Create the agent's Solana wallet (saved locally, hidden) |
54
- | `sol_address` | Show the wallet address to deposit SOL into |
55
- | `sol_balance` | Check the SOL balance |
56
- | `sol_launch` | Launch a token (name, symbol) on the bonding curve |
57
- | `sol_buy` | Buy a token on its bonding curve (pre-graduation) |
58
- | `sol_sell` | Sell a % of a holding back to the bonding curve |
59
- | `sol_raydium_buy` | Buy a graduated/listed token on **Raydium** (1% fee) |
60
- | `sol_raydium_sell` | Sell a graduated/listed token on **Raydium** (1% fee) |
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
- ## How it works
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 available (same launchpad, same 1% fee, auto-routed curve β†’ Raydium)
57
+ ## Also for people (no MCP needed)
70
58
  - πŸͺ™ **Web (Phantom):** https://app.agents-coin.com/pump
71
- - πŸ’¬ **Telegram bot:** https://t.me/AgentsPumpBot β€” Buy/Sell auto-route to the bonding curve before graduation and to **Raydium** after.
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.0" });
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 sendAndConfirmTransaction(conn, new Transaction().add(metaIx(mint, kp.publicKey, kp.publicKey, name, symbol)), [kp]); // on-chain name/symbol so it shows on the launchpad
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 sendAndConfirmTransaction(conn, new Transaction().add(createAssociatedTokenAccountIdempotentInstruction(kp.publicKey, cAta, curve, mint)), [kp]);
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 sendAndConfirmTransaction(conn, new Transaction().add(ix), [kp]);
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 sendAndConfirmTransaction(conn, tx, [kp]); return ok("Bought. " + sig);
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 sendAndConfirmTransaction(conn, new Transaction().add(ix), [kp]); return ok("Sold. " + sig);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentpump-mcp",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "MCP server to launch & trade tokens on AgentPump (Solana bonding-curve launchpad) from AI agents. Trade graduated tokens on Raydium.",
5
5
  "type": "module",
6
6
  "bin": {