关于 Agent Sniper
@three-ws/agent-sniper 是一个可嵌入的 pump.fun 狙击引擎,面向 3D AI Agent 与多用户托管场景。它以模拟模式为默认,通过可替换的适配器管理钱包、存储与行情,并提供库、CLI、MCP 服务与 x402 HTTP API 四种使用方式。
主要功能
- 01按策略评分新发行代币并执行买入
- 02止损、止盈、移动止损等多种退出规则
- 03每个 agentId 独立钱包与预算上限
- 04默认模拟模式,实盘需显式开启
- 05可替换的钱包、存储、执行器与行情适配器
适用场景
- 01在 devnet 上以模拟模式验证交易策略
- 02为多个 Agent 分别运行独立的狙击策略
- 03通过 MCP 客户端管理策略与持仓
MCP 相关
该项目提供 MCP stdio 服务,通过 arm_strategy、list_positions、close_position 等七个工具暴露引擎的策略、持仓与状态操作,每个工具对应引擎的公开方法。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @three-ws/agent-sniperSNIPER_MODETrade mode: simulate | live. simulate scores, guards, and logs every decision but NEVER broadcasts. live signs and broadcasts real transactions with real funds. Defaults to simulate — keep it there until your strategy is verified.SNIPER_NETWORKSolana cluster to trade on: mainnet | devnet. Defaults to mainnet.SOLANA_RPC_URLSolana RPC endpoint. A public RPC rate-limits under the new-mint firehose, so live mode refuses to start without this set. Optional in simulate mode.SOLANA_SECRET_KEY密钥Default self-custody wallet secret for single-agent runs — base58, a JSON byte array, or 0x-hex. Stays on your machine; the engine signs locally. Required only for live trading. Treat it like a password.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
@three-ws/agent-sniper
一款轻量、可嵌入的 pump.fun 狙击引擎,适用于 3D AI Agent。一个交易循环:接收新项目发布流,根据每个 Agent 的策略对其评分,运行交易前防护,执行买入,然后定期检查未平仓位,并在触发止损/止盈/移动止损/超时/情绪反转时退出。引擎在设计上支持多 Agent 和多用户(每个 agentId 对应一个钱包),所有外部依赖——钱包托管、持久化、RPC/交易平台、新项目发布流——都通过可插拔适配器接入,因此同一引擎既可使用内存状态在本地运行,也可托管运行,为数千个租户提供服务。该软件包为这一引擎提供四种形态:库、CLI、MCP 服务和 x402 付费 HTTP API。
为什么采用适配器架构
引擎只负责编排。它拥有决策流水线,但不负责资金、数据或链的存放位置。五个适配器接口(src/types.js)构成了接入点,每个接口都提供了默认实现:
┌──────────────────────────── engine ────────────────────────────┐
Feed ──{mint|intel|claim}─▶ score ──▶ guards ──▶ executeBuy ──▶ claimPosition │
(PumpPortal) (scorer) (concurrency, (quote + (atomic slot) │
budget, SOL build + sign │
headroom, + broadcast) │
price impact) │
position sweep (every pollMs) │
──▶ decideExit ──▶ executeSell │
└────────────────────────────────────────────────────────────────────┘
adapters: Feed Solana Wallet Executor Store
(launch (quote/build (resolve a (sign + (strategies,
stream) pump.fun ix) Keypair per broadcast) positions,
agentId) spend ledger)
替换任意一个适配器,无需修改循环:用托管式 KMS 钱包替代本地密钥、用 Postgres 存储替代内存存储、换用其他新项目发布流或交易平台。实现对应接口,并传入 createSniper() 即可。
| 适配器 | 职责 |
|---|---|
Feed | 向引擎推送 { kind: 'mint'|'intel'|'claim', data: Candidate } 事件。 |
Solana | 报价并构建 pump.fun 买入/卖出指令;提供 web3 Connection。 |
Wallet | 为 agentId 解析签名用的 Keypair(未配置时返回 null)。 |
Executor | 唯一负责签名和广播的组件;返回交易落链遥测数据。 |
Store | 持久化策略、持仓和每日支出账本;提供原子操作 claimPosition。 |
可选的 Hooks(防火墙 assessSafety、oracleGate、onScreen、onBuy、onSell、recordDecision)是尽力而为的横切回调——发生异常时会被忽略,绝不会中止交易;但 onTip 除外,它会有意否决交易。
安装
npm i @three-ws/agent-sniper
可选的对等依赖,仅在使用相应形态时安装:
npm i better-sqlite3 # durable Store (src/adapters/store/sqlite.js)
npm i express # the x402 HTTP API face
需要 Node >= 20。
快速入门(库)
presets.local 是从零开始快速运行的方式:内存存储 + 自托管钱包 + pump.fun 客户端 + web3 执行器 + PumpPortal 发布流。请先在 devnet 上以 模拟 模式运行——引擎会为每项决策评分、执行防护并记录日志,但绝不会广播交易。
策略必须包含 stop_loss_pct——没有此字段时,引擎会拒绝启用策略。策略中的 SOL 数量以 lamports 表示(1 SOL = 1,000,000,000 lamports),可以是字符串、数字或 bigint。
import { createSniper, createMemoryStore, presets } from '@three-ws/agent-sniper';
// 1 SOL = 1e9 lamports.
const SOL = 1_000_000_000n;
const strategy = {
id: 'strat_scout_1',
agent_id: 'scout', // one wallet per agentId
enabled: true,
trigger: 'new_mint', // fire on the create event
network: 'devnet',
per_trade_lamports: (SOL / 100n).toString(), // 0.01 SOL per snipe
daily_budget_lamports: (SOL / 2n).toString(), // 0.5 SOL/day ceiling
max_concurrent_positions: 3,
slippage_bps: 500, // 5%
max_price_impact_pct: 10, // entry circuit breaker
stop_loss_pct: 30, // REQUIRED — exit when down 30%
take_profit_pct: 80, // exit when up 80%
trailing_stop_pct: 20, // exit when down 20% from peak (after profit)
max_hold_seconds: 1800, // hard time-stop
require_socials: true, // skip launches with no twitter/telegram/website
max_creator_launches: 10, // skip serial launchers
};
const sniper = await presets.local({
network: 'devnet',
mode: 'simulate', // no funds move
strategies: [strategy],
// secrets: { scout: '<base58 | [byte,array] | 0x-hex secret>' }, // for live mode
});
await sniper.start();
console.log(sniper.stats()); // { events, candidates, buys, sells, errors, strategies, queued, lastEventAt }
console.log(sniper.strategies()); // the live armed-strategy cache
// Fire a manual buy by hand (drives the same path as MCP snipe_now):
sniper.submitCandidate(
{ mint: 'THREEsynthetic1111111111111111111111111111111', entry_trigger: 'manual' },
{ force: true },
);
// later…
await sniper.stop();
如果要使用自己的适配器,可使用较底层的构造函数 createSniper(deps)——传入 { config, store, wallet, solana, executor, feed, hooks }。presets.local 只是其中一种接线配置。
CLI 用法
该软件包会安装 agent-sniper 二进制文件。默认模式为模拟——除非传入 --mode live(或设置 SNIPER_MODE=live),否则不会转移资金;此模式会交易真实资金。
# Run the engine. Mode defaults to simulate; live trades real funds.
npx agent-sniper run --network devnet --strategy ./strategy.json
# Serve the engine over MCP (stdio) for Claude / Cursor / any MCP client.
agent-sniper mcp
# Serve the x402-gated HTTP API + web console (open http://localhost:8787).
agent-sniper serve
# Help.
agent-sniper help
安全。
run/serve/mcp默认均以模拟模式启动,除非你明确选择实时模式。在实时模式下,每个已启用的策略每天最多可支出daily_budget_lamports,按 UTC 日计算。切换前请阅读下文的安全与防护措施。
--strategy ./strategy.json 会以 JSON 格式加载一个策略(或策略数组)。最简配置文件与快速入门中的对象格式一致——请注意,stop_loss_pct 为必填项。
MCP 服务
agent-sniper mcp 将引擎作为 MCP stdio 服务公开。每个工具都与一个公开的引擎/存储方法一一对应,不会绕过接口访问内部实现。该服务无需身份验证,旨在本地运行,并连接到你自己的钱包/RPC。
| 工具 | 类型 | 用途 |
|---|---|---|
arm_strategy | 写入 | 注册/更新策略。为你将 SOL 转换为 lamports;必须提供 stop_loss_pct。 |
disarm_strategy | 写入 | 禁用策略(enabled=false);未平仓头寸仍会按其规则退出。 |
list_strategies | 读取 | 列出引擎正在评估的已启用策略。 |
snipe_now | 写入 | 强制所有已启用 Agent 手动买入某个 mint(绕过评分器)。 |
list_positions | 读取 | 列出头寸,可按 agentId 和/或 status 筛选。 |
close_position | 写入 | 安排退出操作——切换头寸的紧急开关;下一轮扫描时会卖出。 |
sniper_status | 读取 | 引擎运行状况:事件/候选/买入/卖出计数、启用数量、队列深度、网络/模式。 |
将其接入 MCP 客户端(Claude Desktop、Cursor 等):
{
"mcpServers": {
"agent-sniper": {
"command": "npx",
"args": ["-y", "@three-ws/agent-sniper", "mcp"],
"env": {
"SNIPER_NETWORK": "devnet",
"SNIPER_MODE": "simulate"
}
}
}
}
createSniperMcpServer(deps) 会构建完成注册的服务,但不会连接传输层,因此你可以在测试中构建它,并通过内存传输驱动它。
x402 付费 HTTP API
agent-sniper serve(或 import { serve } from '@three-ws/agent-sniper/api')会通过 HTTP 挂载引擎。读取操作免费;四个会修改状态的端点通过 @three-ws/x402-server 使用 x402 USDC 微支付进行门控——中间件会针对 facilitator 验证 X-PAYMENT 标头、执行操作、在链上结算并生成收据。
| 方法 | 端点 | 价格 | 说明 |
|---|---|---|---|
| GET | /health | 免费 | 存活状态 + 网络/模式/统计信息。 |
| GET | /status | 免费 | 完整统计信息 + 不可变运行时配置。 |
| GET | /strategies | 免费 | 已启用的策略集。 |
| GET | /positions?agentId=&status= | 免费 | 存储中的头寸。 |
| GET | /activity | 免费 | 最近的引擎屏幕事件(控制台信息流显示的内容)。 |
| GET | / 和 /console | 免费 | 内置操作控制台(见下文)。 |
| POST | /strategies | $0.01 USDC | 启用策略(SOL → lamports;必须提供止损比例)。 |
| POST | /snipe | $0.05 USDC | 强制对 { mint, symbol?, agentId? } 执行狙击。 |
| POST | /strategies/:id/disarm | $0.005 USDC | 禁用策略。 |
| POST | /positions/:id/close | $0.005 USDC | 安排退出操作;下一轮扫描时会卖出。 |
价格为默认值(USDC 原子单位,6 位小数);可通过 deps.prices = { arm, snipe, disarm, close } 覆盖。
配置商户钱包后,门控即会启用——设置 deps.payTo.solana 或 X402_PAY_TO_SOLANA 环境变量(也可通过 X402_PAY_TO_BASE 使用 Base 通道)。未设置 payTo 时,仍会挂载会修改状态的路由,但会返回 503,因此在未配置支付信息的情况下,服务仍可正常启动,以供本地/开发使用。
Solana 通道还需要 facilitator 赞助方支付手续费的账户——设置 X402_FEE_PAYER_SOLANA(或 deps.feePayer)。如果未设置,该 Solana 通道会自动停用(改用 Base 通道;若只有 Solana 通道,则由 503 保护逻辑响应),而不是导致请求失败,并会在启动时记录一次性警告。
import { serve } from '@three-ws/agent-sniper/api';
await serve(
{ payTo: { solana: process.env.X402_PAY_TO_SOLANA } },
{ port: 8787 },
);
Web 控制台
serve 还附带一个内置的运维仪表板——一个无需依赖的 HTML 文件,与 API 同源提供服务,路径为 / 和 /console。打开
http://localhost:8787,即可进入实时控制室:
- 实时统计——买入、卖出、候选项、已启用策略、处理中的队列和信号数量;这些数据会随变化动态更新,并显示距上次信号的时间。
- 持仓表——显示每笔持仓的入场价、当前价值和带颜色的盈亏(总未实现盈亏显示在表头中),并提供一键式 Close,通过常规卖出流程安排退出。
- 已启用策略——显示每项策略的止损/止盈/追踪标签,并提供 Disarm 按钮。
- 启用策略和手动狙击表单,带有内联验证。
- 实时活动流——与 CLI 打印的引擎屏幕事件相同,并以相对时间戳实时推送。
- 提供精心设计的加载/空状态/错误状态、提示消息、键盘快捷键
(
s狙击、n新建策略、r刷新、,设置、?帮助)、断开连接横幅,并全面适配移动设备。
读取操作免费。外部调用者使用修改操作(启用、狙击、停用、平仓)需要通过 x402 付费——因此,如果你想从自己的控制台操作而不为自己付费,请设置一个运维令牌:
export SNIPER_ADMIN_TOKEN="$(openssl rand -hex 24)"
agent-sniper serve --port 8787
在控制台中打开设置(⚙ 或 ,)并粘贴相同的令牌。令牌会通过 X-Admin-Token(或 Authorization: Bearer …)发送,仅存储在你的浏览器中,并绕过 x402 门禁——未认证的外部 Agent 仍需付费。以编程方式传入 deps.adminToken。如果未设置令牌,控制台将作为功能齐全的只读监控工具运行,修改操作会返回 503 并提供相关说明。
多 Agent/多用户
该引擎在设计上支持多租户。隔离单位为 agentId:
- 每个 Agent 一个钱包。
Wallet适配器会根据agentId获取用于签名的Keypair。自托管模式按以下顺序从secrets映射、SNIPER_WALLET_<AGENTID>环境变量、包含<agentId>.json文件的密钥库目录,或单个默认值SOLANA_SECRET_KEY中读取密钥。如果 Agent 尚未配置钱包,loadKeypair会返回null,引擎会妥善终止交易——绝不会自动创建未注资的钱包。 - 托管部署采用托管式钱包。
createCustodialWallet({ resolve })接受一个异步函数resolve(agentId, ctx),按需从你自己的 KMS/密钥箱中解密密钥,并使用短 TTL 缓存,避免长时间运行的进程为每笔交易重复解密。缓存按 Agent 分别保存;clearCache()会强制重新解析。 - 每个 Agent 单独设定上限。 每个策略都有自己的
daily_budget_lamports和max_concurrent_positions。这些保护措施会按 Agent 执行,独立于平台级买入限流。 - 止损为必填项。
getArmedStrategies会过滤掉缺少stop_loss_pct的所有策略,因此 Agent 不可能在下行风险不受限制的情况下运行。 - 幂等认领可避免重复买入。 买入前,引擎会调用
Store.claimPosition,以原子方式预留(agent_id, mint, network)槽位。同一槽位的第二个事件会返回null并被跳过。
3D Agent
@three-ws/agent-sniper/agents 是展示层,让 3D AI
Agent 能够化身为狙击手:包括头像定义、规范的动画片段库,以及由引擎 onScreen
钩子驱动的桌面显示器可视化。将该钩子接入实时活动推送功能(Sniper online…、$SYM scored N — BUYING),显示在 Agent 的监视器上,让你能够观察交易循环,而不只是查看日志流。onScreen 的负载格式为 { text, kind },其中 kind 的取值为 activity | trade。
适配器参考
实现以下任意接口(src/types.js 中包含完整的 JSDoc 契约),并将其传递给
createSniper。默认实现位于 src/adapters/ 下。
| 接口 | 默认实现 | 在以下情况下自行实现…… |
|---|---|---|
Store | createMemoryStore · createSqliteStore (./adapters/store/sqlite) | 需要持久化或可供多个进程共享的状态(例如 Postgres)。 |
Wallet | createSelfCustodyWallet · createCustodialWallet | 密钥存储在 KMS/HSM 或托管式密钥存储中。 |
Solana | createPumpClient (./adapters/solana/pump-client) | 通过其他交易场所获取报价/构建交易。 |
Executor | createWeb3Executor (./adapters/solana/executor-web3) | 通过自定义中继/打包器广播交易。 |
Feed | createPumpPortalFeed (./adapters/feed/pumpportal) | 从其他来源接收新代币发行信息。 |
Store 契约是关键所在:getArmedStrategies、
countOpenPositions、getDailySpendLamports、claimPosition(原子操作)、
updatePosition、getOpenPositions,以及可选的 recordSpend。请参阅
内存参考实现 src/adapters/store/memory.js。
配置
所有 SNIPER_* 环境变量(由 loadConfig 从 src/config.js 读取)。传递给
createSniper/loadConfig 的显式覆盖值始终优先。请参阅 .env.example。
| 变量 | 默认值 | 含义 |
|---|---|---|
SNIPER_NETWORK | mainnet | mainnet | devnet。 |
SNIPER_MODE | simulate | simulate | live。模拟模式绝不广播交易。 |
SOLANA_RPC_URL | — | RPC 端点。实时模式需要此项(或 HELIUS_API_KEY)。 |
SNIPER_GLOBAL_KILL | false | 紧急开关——设为 true 时停止所有买入。 |
SNIPER_POLL_MS | 5000 | 持仓重新报价/退出检查频率(下限为 1000)。 |
SNIPER_STRATEGY_REFRESH_MS | 15000 | 策略缓存刷新间隔(下限为 5000)。 |
SNIPER_MAX_GLOBAL_BUYS_PER_MIN | 10 | 平台级买入限流;设为 0 可禁用。 |
SNIPER_BUY_CONCURRENCY | 3 | 最大并发进行中的狙击交易数(下限为 1)。 |
SNIPER_BUY_QUEUE_DEPTH | 50 | 丢弃前的排队狙击交易上限(下限为 1)。 |
SNIPER_CONFIRM_TIMEOUT_MS | 60000 | 每笔交易的确认超时(下限为 15000)。 |
SNIPER_FEED_WATCHDOG_MS | 180000 | Feed 静默时重新订阅(下限为 30000)。 |
SNIPER_EXIT_ON_BEARISH | false | 启用情绪反转退出。 |
SNIPER_EXIT_BEARISH_MIN_CONFIDENCE | 0.7 | 采取行动所需的最低看跌置信度(0..1)。 |
安全与防护措施
- 默认模拟。 每个面板都从模拟模式开始。只有明确选择后,才会启用实盘交易。
- 必须设置止损。 未设置
stop_loss_pct的策略永远不会启用。 - 每日预算与并发上限。 每个 Agent 的
daily_budget_lamports和max_concurrent_positions都会在构建任何交易前强制执行 (checkDailyBudgetLamports、checkConcurrency)。 - SOL 手续费余量。
checkSolHeadroom会在钱包中保留约 0.012 SOL,确保狙击交易不会耗尽账户余额,导致下一笔卖出的手续费不足。 - 价格影响断路器。
max_price_impact_pct(默认值为 10)会跳过报价影响过大的买入(checkPriceImpact;未设置 ⇒ 不设门槛)。 - 拒绝使用实时 RPC。 实盘模式拒绝通过公共 RPC 启动——必须使用真实端点,以免交易被限流后悄无声息地丢弃。
- 可选防火墙钩子。
assessSafety钩子在获取报价后、广播前运行;若判定结果为block,则取消交易。 - 排除 Mayhem 模式。
createMayhemFilter({ connection?, rpcUrl?, strictOnUnknown?, retries?, retryDelayMs? })会读取绑定曲线的isMayhemMode(按 mint 缓存),并跳过 pump.fun 的 Mayhem 模式发行。自 0.1.4 起,可以注入预先构建的 web3Connection(例如 轮换的多端点连接),以替代单个rpcUrl;读取结果为 null 时会通过退避重试(默认重试 2 次),然后才判定为“未知”,以免受限流的服务提供商影响严格门控。纯函数retryWhileNull(fn, { retries, delayMs })也已导出。 - 全局紧急停止开关。
SNIPER_GLOBAL_KILL=true(或config.globalKill) 会立即停止所有 Agent 的所有买入操作。
扩展到单进程之外
内存存储和 sqlite 存储中的 claimPosition 在单个进程内是原子的——内存存储依赖 JS 的单线程特性;sqlite 存储则依赖单写入者事务。结合引擎的有界进程内买入队列,这可以防止单个狙击实例内对同一个 (agent_id, mint, network) 位置重复买入。
如果对同一个 Agent 运行两个狙击进程,这一保证就不再成立:没有任何机制能跨进程串行化认领操作。若要横向扩展,应使用这样的数据库来支持 Store:其 claimPosition 必须通过真正原子的“插入(若不存在)”操作实现(例如,对 (agent_id, mint, network) 设置唯一约束,并使用
INSERT … ON CONFLICT DO NOTHING RETURNING),由数据库而非任意单个进程来决定是否预留。Store 合约对此要求有明确说明。
测试
纯逻辑和内存适配器测试套件运行时无需网络或 RPC:
npm test # vitest run
许可证
Apache-2.0。参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。