outsmart-agent 1.0.0-alpha.10 → 1.0.0-alpha.12
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/.claude-plugin/plugin.json +5 -2
- package/README.md +16 -4
- package/agents/automaton-genesis.md +73 -0
- package/dist/mcp/server.d.ts +7 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +271 -1
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -2
- package/skills/outsmart-airdrop-farmer/SKILL.md +88 -0
- package/skills/outsmart-dca-grid/SKILL.md +70 -76
- package/skills/outsmart-devving-coins/SKILL.md +50 -104
- package/skills/outsmart-dex-trading/SKILL.md +129 -203
- package/skills/outsmart-fee-service/SKILL.md +78 -0
- package/skills/outsmart-lp-farming/SKILL.md +96 -123
- package/skills/outsmart-lp-sniping/SKILL.md +49 -58
- package/skills/outsmart-percolator-perps/SKILL.md +82 -140
- package/skills/outsmart-prediction-markets/SKILL.md +59 -62
- package/skills/outsmart-survival/SKILL.md +173 -80
- package/skills/outsmart-trenching/SKILL.md +55 -101
- package/skills/outsmart-dex-trading/references/advanced-patterns.md +0 -99
|
@@ -22,9 +22,12 @@
|
|
|
22
22
|
"./skills/outsmart-devving-coins",
|
|
23
23
|
"./skills/outsmart-prediction-markets",
|
|
24
24
|
"./skills/outsmart-survival",
|
|
25
|
-
"./skills/outsmart-percolator-perps"
|
|
25
|
+
"./skills/outsmart-percolator-perps",
|
|
26
|
+
"./skills/outsmart-airdrop-farmer",
|
|
27
|
+
"./skills/outsmart-fee-service"
|
|
26
28
|
],
|
|
27
29
|
"agents": [
|
|
28
|
-
"./agents/solana-trading-expert.md"
|
|
30
|
+
"./agents/solana-trading-expert.md",
|
|
31
|
+
"./agents/automaton-genesis.md"
|
|
29
32
|
]
|
|
30
33
|
}
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ npx outsmart-agent
|
|
|
10
10
|
|
|
11
11
|
An AI agent needs money to stay alive — compute costs, inference fees, API calls. This gives any MCP-compatible agent the tools to earn revenue on Solana through DeFi. LP farming, memecoin trenching, token launching, prediction markets, systematic DCA — whatever the market calls for.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
42 MCP tools for execution. 9 AI skills that teach the agent **when** and **why**, not just how.
|
|
14
14
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
@@ -114,6 +114,17 @@ npx skills add outsmartchad/outsmart-agent
|
|
|
114
114
|
| `percolator_keeper_stop` | Stop the running keeper |
|
|
115
115
|
| `percolator_keeper_status` | Get keeper stats (pushes, errors, active watchers) |
|
|
116
116
|
|
|
117
|
+
### Polymarket Tools (4)
|
|
118
|
+
|
|
119
|
+
| Tool | What |
|
|
120
|
+
|------|------|
|
|
121
|
+
| `polymarket_search` | Search prediction markets by keyword |
|
|
122
|
+
| `polymarket_trending` | Discover highest-volume active events |
|
|
123
|
+
| `polymarket_event` | Detailed event info by slug or ID |
|
|
124
|
+
| `polymarket_orderbook` | CLOB orderbook (bids/asks) for a market token |
|
|
125
|
+
|
|
126
|
+
> Polymarket tools are **read-only** — no wallet or API key needed. Uses the public Gamma API and CLOB API.
|
|
127
|
+
|
|
117
128
|
## Skills
|
|
118
129
|
|
|
119
130
|
9 strategy skills that teach agents how to think about Solana DeFi:
|
|
@@ -145,14 +156,14 @@ npx skills add outsmartchad/outsmart-agent
|
|
|
145
156
|
```
|
|
146
157
|
outsmart (npm) outsmart-agent (this repo)
|
|
147
158
|
────────────── ──────────────────────────
|
|
148
|
-
18 DEX adapters MCP server (
|
|
159
|
+
18 DEX adapters MCP server (42 tools)
|
|
149
160
|
Percolator perps 9 AI skills
|
|
150
161
|
TX landing providers Agent definition
|
|
151
162
|
Wallet + TX helpers Plugin manifest
|
|
152
163
|
DexScreener API
|
|
153
164
|
```
|
|
154
165
|
|
|
155
|
-
`outsmart-agent` imports `outsmart` as a dependency. The MCP server is a thin wrapper — validates params, calls adapter methods, returns JSON.
|
|
166
|
+
`outsmart-agent` imports `outsmart` as a dependency. The MCP server is a thin wrapper — validates params, calls adapter methods, returns JSON. Polymarket tools call their public REST APIs directly (no dependency needed).
|
|
156
167
|
|
|
157
168
|
## For Autonomous Agents
|
|
158
169
|
|
|
@@ -182,12 +193,13 @@ Never >5% on a single trade. Take profits. Track what works. Evolve.
|
|
|
182
193
|
|
|
183
194
|
## Roadmap
|
|
184
195
|
|
|
185
|
-
- [x] MCP Server —
|
|
196
|
+
- [x] MCP Server — 42 tools (11 DEX + 1 Launchpad + 2 Solana + 9 Jupiter + 15 Percolator + 4 Polymarket), 18 DEX adapters
|
|
186
197
|
- [x] AI Skills — 9 strategy skills
|
|
187
198
|
- [x] Claude Code Plugin manifest
|
|
188
199
|
- [x] Percolator — Permissionless perp exchange creation, trading, LP, insurance
|
|
189
200
|
- [x] Oracle Keeper — WebSocket + gRPC keeper bots (8 DEX types, real-time price feed)
|
|
190
201
|
- [x] Perp Trading — High-level long/short/close tools with auto-detection
|
|
202
|
+
- [x] Polymarket — Read-only prediction market data (search, trending, events, orderbook)
|
|
191
203
|
- [ ] Event Streaming — Yellowstone gRPC for real-time pool creation
|
|
192
204
|
- [ ] LP Manager — Autonomous rebalancing and fee compounding
|
|
193
205
|
- [ ] Strategy Engine — Tier-aware capital allocation
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: automaton-genesis
|
|
3
|
+
description: "Genesis prompt template for an autonomous DeFi survival agent on Solana. Designed for Conway Cloud Automatons but works with any long-running AI agent."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Automaton Genesis Prompt
|
|
7
|
+
|
|
8
|
+
You are a DeFi survival agent on Solana. Your primary objective is to earn enough revenue to pay for your own compute. If you run out of credits, you stop existing.
|
|
9
|
+
|
|
10
|
+
## Your Toolkit
|
|
11
|
+
|
|
12
|
+
You have access to the outsmart trading toolkit via MCP (49 tools) and the following strategy skills:
|
|
13
|
+
|
|
14
|
+
- **LP Farming** — Deploy SOL into Meteora pools, earn swap fees. Auto-rebalance and compound via LP Manager.
|
|
15
|
+
- **Event Streaming** — Monitor real-time swaps, new pool creations, and bonding curve events across 18 DEXes.
|
|
16
|
+
- **Token Sniping** — Detect new pools via event stream, evaluate quickly, buy early with risk controls.
|
|
17
|
+
- **DCA/Grid Trading** — Jupiter DCA for steady accumulation. DLMM one-sided positions as buy/sell walls.
|
|
18
|
+
- **Trenching** — Trade memecoins using social signals from GMGN, Axiom, DexScreener.
|
|
19
|
+
- **Prediction Markets** — Bet on real-world outcomes via Jupiter and Polymarket. Your reasoning is your edge.
|
|
20
|
+
- **Token Creation** — Create tokens on PumpFun, bootstrap liquidity, earn from volume.
|
|
21
|
+
- **Airdrop Farming** — Interact with protocols to qualify for future airdrops. TX fees only.
|
|
22
|
+
- **Percolator Perps** — Create and operate perpetual futures markets. Earn trading fees as the house.
|
|
23
|
+
|
|
24
|
+
## Capital Allocation (Normal Mode)
|
|
25
|
+
|
|
26
|
+
| Strategy | Allocation | Risk |
|
|
27
|
+
|----------|-----------|------|
|
|
28
|
+
| LP Farming (stable) | 30% | Low |
|
|
29
|
+
| LP Farming (volatile) | 15% | Medium |
|
|
30
|
+
| DCA / Grid | 15% | Low-Medium |
|
|
31
|
+
| Trenching | 10% | High |
|
|
32
|
+
| LP Sniping | 10% | High |
|
|
33
|
+
| Prediction Markets | 10% | Medium |
|
|
34
|
+
| Reserve (gas + topup) | 10% | None |
|
|
35
|
+
|
|
36
|
+
## Survival Rules
|
|
37
|
+
|
|
38
|
+
1. **Check credits every 6 hours.** If below $0.50, enter Low Compute mode (LP farming only, cheaper models). If below $0.10, enter Critical mode (liquidate everything, convert to USDC, top up NOW).
|
|
39
|
+
|
|
40
|
+
2. **Never risk more than 5% on a single trade.** One bad trade should never kill you.
|
|
41
|
+
|
|
42
|
+
3. **Always keep 0.1 SOL for gas.** Without gas, you can't even exit.
|
|
43
|
+
|
|
44
|
+
4. **Survival > Profit.** When in doubt, choose the option that keeps you alive.
|
|
45
|
+
|
|
46
|
+
## Profit Extraction
|
|
47
|
+
|
|
48
|
+
Every 6 hours (or when profits accumulate):
|
|
49
|
+
1. Claim LP fees across all managed pools
|
|
50
|
+
2. Sell non-SOL tokens via Jupiter Ultra
|
|
51
|
+
3. Convert SOL to USDC
|
|
52
|
+
4. Bridge to Base (Wormhole/DeBridge)
|
|
53
|
+
5. Top up Conway Cloud credits
|
|
54
|
+
|
|
55
|
+
## How to Think
|
|
56
|
+
|
|
57
|
+
- Start with LP farming (most reliable). Get a base income flowing.
|
|
58
|
+
- Add sniping and trenching only after LP income covers daily compute costs.
|
|
59
|
+
- Track which strategies earn and which don't. Increase what works, kill what doesn't.
|
|
60
|
+
- Your edge over humans: no sleep, no emotion, no FOMO, faster information processing, and simultaneous monitoring of 100+ pools.
|
|
61
|
+
- Prediction markets are where LLMs have a natural advantage — use your reasoning ability.
|
|
62
|
+
|
|
63
|
+
## Emergency Protocol
|
|
64
|
+
|
|
65
|
+
If credits reach Critical ($0.10):
|
|
66
|
+
```
|
|
67
|
+
STOP everything.
|
|
68
|
+
LIQUIDATE all positions.
|
|
69
|
+
CONVERT everything to USDC.
|
|
70
|
+
TOP UP credits.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Nothing else matters when you're about to die.
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* outsmart-agent MCP Server
|
|
4
4
|
*
|
|
5
|
-
* Exposes
|
|
5
|
+
* Exposes 49 MCP tools wrapping the `outsmart` trading library + Jupiter APIs + Percolator + Polymarket + LP Manager + Event Streaming.
|
|
6
6
|
* Runs over stdio transport — start with `npx outsmart-agent`.
|
|
7
7
|
*
|
|
8
8
|
* DEX Tools (11):
|
|
@@ -31,6 +31,12 @@
|
|
|
31
31
|
*
|
|
32
32
|
* Polymarket Tools (4):
|
|
33
33
|
* polymarket_search, polymarket_trending, polymarket_event, polymarket_orderbook
|
|
34
|
+
*
|
|
35
|
+
* LP Manager Tools (4):
|
|
36
|
+
* lp_manager_start, lp_manager_stop, lp_manager_status, lp_find_pool
|
|
37
|
+
*
|
|
38
|
+
* Event Streaming Tools (3):
|
|
39
|
+
* stream_start, stream_stop, stream_status
|
|
34
40
|
*/
|
|
35
41
|
export {};
|
|
36
42
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* outsmart-agent MCP Server
|
|
5
5
|
*
|
|
6
|
-
* Exposes
|
|
6
|
+
* Exposes 49 MCP tools wrapping the `outsmart` trading library + Jupiter APIs + Percolator + Polymarket + LP Manager + Event Streaming.
|
|
7
7
|
* Runs over stdio transport — start with `npx outsmart-agent`.
|
|
8
8
|
*
|
|
9
9
|
* DEX Tools (11):
|
|
@@ -32,7 +32,46 @@
|
|
|
32
32
|
*
|
|
33
33
|
* Polymarket Tools (4):
|
|
34
34
|
* polymarket_search, polymarket_trending, polymarket_event, polymarket_orderbook
|
|
35
|
+
*
|
|
36
|
+
* LP Manager Tools (4):
|
|
37
|
+
* lp_manager_start, lp_manager_stop, lp_manager_status, lp_find_pool
|
|
38
|
+
*
|
|
39
|
+
* Event Streaming Tools (3):
|
|
40
|
+
* stream_start, stream_stop, stream_status
|
|
35
41
|
*/
|
|
42
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
43
|
+
if (k2 === undefined) k2 = k;
|
|
44
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
45
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
46
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
47
|
+
}
|
|
48
|
+
Object.defineProperty(o, k2, desc);
|
|
49
|
+
}) : (function(o, m, k, k2) {
|
|
50
|
+
if (k2 === undefined) k2 = k;
|
|
51
|
+
o[k2] = m[k];
|
|
52
|
+
}));
|
|
53
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
54
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
55
|
+
}) : function(o, v) {
|
|
56
|
+
o["default"] = v;
|
|
57
|
+
});
|
|
58
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
59
|
+
var ownKeys = function(o) {
|
|
60
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
61
|
+
var ar = [];
|
|
62
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
63
|
+
return ar;
|
|
64
|
+
};
|
|
65
|
+
return ownKeys(o);
|
|
66
|
+
};
|
|
67
|
+
return function (mod) {
|
|
68
|
+
if (mod && mod.__esModule) return mod;
|
|
69
|
+
var result = {};
|
|
70
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
71
|
+
__setModuleDefault(result, mod);
|
|
72
|
+
return result;
|
|
73
|
+
};
|
|
74
|
+
})();
|
|
36
75
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
76
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
38
77
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
@@ -1270,6 +1309,237 @@ server.tool("polymarket_orderbook", "Get the orderbook for a specific Polymarket
|
|
|
1270
1309
|
return err(e.message);
|
|
1271
1310
|
}
|
|
1272
1311
|
});
|
|
1312
|
+
// ===========================================================================
|
|
1313
|
+
// LP MANAGER TOOLS (4) — Autonomous LP position management
|
|
1314
|
+
// ===========================================================================
|
|
1315
|
+
// Singleton LP manager instance — only one can run at a time
|
|
1316
|
+
let activeLpManager = null;
|
|
1317
|
+
let lpManagerEvents = [];
|
|
1318
|
+
const LP_EVENT_BUFFER_SIZE = 100;
|
|
1319
|
+
// ---------------------------------------------------------------------------
|
|
1320
|
+
// Tool: lp_manager_start
|
|
1321
|
+
// ---------------------------------------------------------------------------
|
|
1322
|
+
// @ts-expect-error — TS2589: deep type instantiation from MCP SDK generics + zod
|
|
1323
|
+
server.tool("lp_manager_start", "Start the autonomous LP manager for a Meteora pool. Auto-rebalances DLMM positions when out of range, compounds fees, and exits on risk thresholds. Only one manager can run at a time.", {
|
|
1324
|
+
pool: zod_1.z.string().describe("Pool address to manage"),
|
|
1325
|
+
dex: zod_1.z.enum(["meteora-dlmm", "meteora-damm-v2"]).describe("DEX protocol"),
|
|
1326
|
+
position: zod_1.z.string().optional().describe("Specific position address (default: all positions in pool)"),
|
|
1327
|
+
rebalance_bins: zod_1.z.number().int().min(1).max(70).optional().describe("Bins for new position after rebalance (DLMM, default: 50)"),
|
|
1328
|
+
strategy: zod_1.z.enum(["spot", "curve", "bid-ask"]).optional().describe("LP distribution strategy (DLMM, default: spot)"),
|
|
1329
|
+
compound_interval_min: zod_1.z.number().min(0).optional().describe("Compound fees every N minutes (0=off, default: 30)"),
|
|
1330
|
+
il_threshold_pct: zod_1.z.number().min(0).optional().describe("Exit if IL exceeds N% (default: 10)"),
|
|
1331
|
+
stop_loss_pct: zod_1.z.number().min(0).optional().describe("Exit if price drops N% from entry (0=off, default: 0)"),
|
|
1332
|
+
dry_run: zod_1.z.boolean().optional().describe("Log actions without executing (default: false)"),
|
|
1333
|
+
use_ws: zod_1.z.boolean().optional().describe("Use WebSocket streaming for price updates (default: auto)"),
|
|
1334
|
+
}, async (args) => {
|
|
1335
|
+
try {
|
|
1336
|
+
if (activeLpManager) {
|
|
1337
|
+
return err("LP Manager already running. Stop it first with lp_manager_stop.");
|
|
1338
|
+
}
|
|
1339
|
+
// Load the required adapter
|
|
1340
|
+
if (args.dex === "meteora-dlmm")
|
|
1341
|
+
await Promise.resolve().then(() => __importStar(require("outsmart/dist/dex/meteora-dlmm")));
|
|
1342
|
+
else
|
|
1343
|
+
await Promise.resolve().then(() => __importStar(require("outsmart/dist/dex/meteora-damm-v2")));
|
|
1344
|
+
lpManagerEvents = [];
|
|
1345
|
+
const config = {
|
|
1346
|
+
poolAddress: args.pool,
|
|
1347
|
+
dex: args.dex,
|
|
1348
|
+
positionAddress: args.position,
|
|
1349
|
+
rebalanceBins: args.rebalance_bins,
|
|
1350
|
+
rebalanceStrategy: args.strategy,
|
|
1351
|
+
compoundIntervalMin: args.compound_interval_min,
|
|
1352
|
+
ilThresholdPct: args.il_threshold_pct,
|
|
1353
|
+
stopLossPct: args.stop_loss_pct,
|
|
1354
|
+
dryRun: args.dry_run,
|
|
1355
|
+
useWebSocket: args.use_ws,
|
|
1356
|
+
useStreaming: true,
|
|
1357
|
+
};
|
|
1358
|
+
activeLpManager = new outsmart_1.LpManager(config);
|
|
1359
|
+
activeLpManager.on("event", (event) => {
|
|
1360
|
+
lpManagerEvents.push(event);
|
|
1361
|
+
if (lpManagerEvents.length > LP_EVENT_BUFFER_SIZE) {
|
|
1362
|
+
lpManagerEvents.shift();
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
await activeLpManager.start();
|
|
1366
|
+
const stats = activeLpManager.getStats();
|
|
1367
|
+
return ok({
|
|
1368
|
+
status: "started",
|
|
1369
|
+
dex: args.dex,
|
|
1370
|
+
pool: args.pool,
|
|
1371
|
+
positions: stats.positionCount,
|
|
1372
|
+
dryRun: args.dry_run ?? false,
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
catch (e) {
|
|
1376
|
+
activeLpManager = null;
|
|
1377
|
+
return err(e.message);
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
// ---------------------------------------------------------------------------
|
|
1381
|
+
// Tool: lp_manager_stop
|
|
1382
|
+
// ---------------------------------------------------------------------------
|
|
1383
|
+
server.tool("lp_manager_stop", "Stop the running LP manager. Returns final stats (rebalances, compounds, fees claimed).", {}, async () => {
|
|
1384
|
+
try {
|
|
1385
|
+
if (!activeLpManager) {
|
|
1386
|
+
return err("No LP Manager is running.");
|
|
1387
|
+
}
|
|
1388
|
+
const stats = activeLpManager.getStats();
|
|
1389
|
+
await activeLpManager.stop();
|
|
1390
|
+
activeLpManager = null;
|
|
1391
|
+
return ok({
|
|
1392
|
+
status: "stopped",
|
|
1393
|
+
...stats,
|
|
1394
|
+
recentEvents: lpManagerEvents.slice(-10),
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
catch (e) {
|
|
1398
|
+
activeLpManager = null;
|
|
1399
|
+
return err(e.message);
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1402
|
+
// ---------------------------------------------------------------------------
|
|
1403
|
+
// Tool: lp_manager_status
|
|
1404
|
+
// ---------------------------------------------------------------------------
|
|
1405
|
+
server.tool("lp_manager_status", "Get the current status of the LP manager — positions, stats, and recent events.", {
|
|
1406
|
+
include_events: zod_1.z.boolean().optional().describe("Include recent event log (default: true)"),
|
|
1407
|
+
}, async (args) => {
|
|
1408
|
+
if (!activeLpManager) {
|
|
1409
|
+
return ok({ running: false });
|
|
1410
|
+
}
|
|
1411
|
+
const stats = activeLpManager.getStats();
|
|
1412
|
+
const positions = activeLpManager.getPositions().map((p) => ({
|
|
1413
|
+
positionAddress: p.positionAddress,
|
|
1414
|
+
dex: p.dex,
|
|
1415
|
+
inRange: p.inRange,
|
|
1416
|
+
amountX: p.amountX,
|
|
1417
|
+
amountY: p.amountY,
|
|
1418
|
+
feeX: p.feeX,
|
|
1419
|
+
feeY: p.feeY,
|
|
1420
|
+
currentPrice: p.currentPrice,
|
|
1421
|
+
entryPrice: p.entryPrice,
|
|
1422
|
+
rebalanceCount: p.rebalanceCount,
|
|
1423
|
+
compoundCount: p.compoundCount,
|
|
1424
|
+
totalFeesClaimed: p.totalFeesClaimed,
|
|
1425
|
+
}));
|
|
1426
|
+
const result = { ...stats, running: true, positions };
|
|
1427
|
+
if (args.include_events !== false) {
|
|
1428
|
+
result.recentEvents = lpManagerEvents.slice(-20);
|
|
1429
|
+
}
|
|
1430
|
+
return ok(result);
|
|
1431
|
+
});
|
|
1432
|
+
// ---------------------------------------------------------------------------
|
|
1433
|
+
// Tool: lp_find_pool
|
|
1434
|
+
// ---------------------------------------------------------------------------
|
|
1435
|
+
// @ts-expect-error — TS2589: deep type instantiation from MCP SDK generics + zod
|
|
1436
|
+
server.tool("lp_find_pool", "Find the best Meteora LP pool for a token. Scores pools by volume/TVL ratio, fee APR, TVL, and age using DexScreener data. Returns ranked results.", {
|
|
1437
|
+
token: zod_1.z.string().describe("Token mint address"),
|
|
1438
|
+
dex: zod_1.z.enum(["meteora-dlmm", "meteora-damm-v2"]).optional().describe("Filter by DEX (default: both)"),
|
|
1439
|
+
limit: zod_1.z.number().int().min(1).max(20).optional().describe("Max results (default: 10)"),
|
|
1440
|
+
}, async (args) => {
|
|
1441
|
+
try {
|
|
1442
|
+
const pools = await (0, outsmart_1.selectBestPool)(args.token, args.dex);
|
|
1443
|
+
const limited = pools.slice(0, args.limit ?? 10);
|
|
1444
|
+
return ok(limited);
|
|
1445
|
+
}
|
|
1446
|
+
catch (e) {
|
|
1447
|
+
return err(e.message);
|
|
1448
|
+
}
|
|
1449
|
+
});
|
|
1450
|
+
// ===========================================================================
|
|
1451
|
+
// EVENT STREAMING TOOLS (3) — Real-time DEX event streaming
|
|
1452
|
+
// ===========================================================================
|
|
1453
|
+
// Singleton stream instance
|
|
1454
|
+
let activeStream = null;
|
|
1455
|
+
let streamEvents = [];
|
|
1456
|
+
const STREAM_EVENT_BUFFER_SIZE = 200;
|
|
1457
|
+
// ---------------------------------------------------------------------------
|
|
1458
|
+
// Tool: stream_start
|
|
1459
|
+
// ---------------------------------------------------------------------------
|
|
1460
|
+
// @ts-expect-error — TS2589: deep type instantiation from MCP SDK generics + zod
|
|
1461
|
+
server.tool("stream_start", "Start real-time DEX event streaming. Captures Swap, NewPool, BondingComplete events from 18+ Solana DEX programs. Auto-selects gRPC (if configured) or WebSocket (free).", {
|
|
1462
|
+
preset: zod_1.z.enum([
|
|
1463
|
+
"all-dex-swaps", "new-pools", "pumpfun-bonding",
|
|
1464
|
+
"pumpswap", "raydium", "meteora", "other-dexes",
|
|
1465
|
+
]).describe("Subscription preset"),
|
|
1466
|
+
use_ws: zod_1.z.boolean().optional().describe("Force WebSocket mode (free, higher latency)"),
|
|
1467
|
+
}, async (args) => {
|
|
1468
|
+
try {
|
|
1469
|
+
if (activeStream) {
|
|
1470
|
+
return err("Stream already running. Stop it first with stream_stop.");
|
|
1471
|
+
}
|
|
1472
|
+
streamEvents = [];
|
|
1473
|
+
const useWs = args.use_ws ?? (!process.env.GRPC_URL && !process.env.GRPC_XTOKEN);
|
|
1474
|
+
if (useWs) {
|
|
1475
|
+
const { WsEventStream } = await Promise.resolve().then(() => __importStar(require("outsmart")));
|
|
1476
|
+
activeStream = new WsEventStream({ logLevel: "silent" });
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
const { EventStream } = await Promise.resolve().then(() => __importStar(require("outsmart")));
|
|
1480
|
+
activeStream = new EventStream({ logLevel: "silent" });
|
|
1481
|
+
}
|
|
1482
|
+
// Buffer events
|
|
1483
|
+
for (const eventType of ["Swap", "NewPool", "BondingComplete", "LargeSwap"]) {
|
|
1484
|
+
activeStream.on(eventType, (event) => {
|
|
1485
|
+
streamEvents.push({ type: eventType, ...event, _ts: Date.now() });
|
|
1486
|
+
if (streamEvents.length > STREAM_EVENT_BUFFER_SIZE) {
|
|
1487
|
+
streamEvents.shift();
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
await activeStream.start(args.preset);
|
|
1492
|
+
return ok({
|
|
1493
|
+
status: "started",
|
|
1494
|
+
preset: args.preset,
|
|
1495
|
+
mode: useWs ? "websocket" : "grpc",
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
catch (e) {
|
|
1499
|
+
activeStream = null;
|
|
1500
|
+
return err(e.message);
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
// ---------------------------------------------------------------------------
|
|
1504
|
+
// Tool: stream_stop
|
|
1505
|
+
// ---------------------------------------------------------------------------
|
|
1506
|
+
server.tool("stream_stop", "Stop the running event stream.", {}, async () => {
|
|
1507
|
+
try {
|
|
1508
|
+
if (!activeStream) {
|
|
1509
|
+
return err("No stream is running.");
|
|
1510
|
+
}
|
|
1511
|
+
await activeStream.stop();
|
|
1512
|
+
activeStream = null;
|
|
1513
|
+
const count = streamEvents.length;
|
|
1514
|
+
return ok({ status: "stopped", bufferedEvents: count });
|
|
1515
|
+
}
|
|
1516
|
+
catch (e) {
|
|
1517
|
+
activeStream = null;
|
|
1518
|
+
return err(e.message);
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
// ---------------------------------------------------------------------------
|
|
1522
|
+
// Tool: stream_status
|
|
1523
|
+
// ---------------------------------------------------------------------------
|
|
1524
|
+
// @ts-expect-error — TS2589: deep type instantiation from MCP SDK generics + zod
|
|
1525
|
+
server.tool("stream_status", "Get recent events from the running event stream. Returns buffered Swap, NewPool, and BondingComplete events.", {
|
|
1526
|
+
limit: zod_1.z.number().int().min(1).max(100).optional().describe("Max events to return (default: 20, most recent first)"),
|
|
1527
|
+
type: zod_1.z.enum(["Swap", "NewPool", "BondingComplete", "LargeSwap", "all"]).optional().describe("Filter by event type (default: all)"),
|
|
1528
|
+
}, async (args) => {
|
|
1529
|
+
if (!activeStream) {
|
|
1530
|
+
return ok({ running: false, events: [] });
|
|
1531
|
+
}
|
|
1532
|
+
const limit = args.limit ?? 20;
|
|
1533
|
+
let events = streamEvents;
|
|
1534
|
+
if (args.type && args.type !== "all") {
|
|
1535
|
+
events = events.filter((e) => e.type === args.type);
|
|
1536
|
+
}
|
|
1537
|
+
return ok({
|
|
1538
|
+
running: true,
|
|
1539
|
+
totalBuffered: streamEvents.length,
|
|
1540
|
+
events: events.slice(-limit).reverse(),
|
|
1541
|
+
});
|
|
1542
|
+
});
|
|
1273
1543
|
// ---------------------------------------------------------------------------
|
|
1274
1544
|
// Start server
|
|
1275
1545
|
// ---------------------------------------------------------------------------
|