Skip to main content
Glama

ponscli

CI npm node license

An unofficial command-line interface for the Pons launchpad on Robinhood Chain (chain ID 4663), built for developers and agents alike. Not affiliated with Pons or Robinhood; it reads public contracts on a public chain.

  • Read-only by default. The CLI runs without ever seeing a private key. Signing is an explicit opt-in, so an agent cannot spend by accident.

  • Structured output everywhere. --json on every command, enabled automatically when stdout is not a terminal. Errors are structured too, with stable exit codes.

  • Protocol values are read from the chain. Fees, tax windows and the approved pair-token list are queried live, never hard-coded. The on-chain values differ from the contract source.

  • Two-tier RPC. Free endpoints round-robined in Tier 1; a paid endpoint in Tier 2, reached only after Tier 1 is fully exhausted. Without a paid credential, bulk work degrades rather than turning an outage into an invoice.

  • Two binaries. pons for people, pons-mcp for models, over the same core, so the price an agent is quoted is the price the CLI prints.

Install

npm install -g ponscli
pons --version

Or without installing anything. The package is ponscli and the binary is pons, so npx has to be told which one to run:

npx -p ponscli pons info 0x44D6…20f4

Two Node versions matter, and they are not the same one. The CLI runs on 20.11 or newer, which CI checks on every push by installing the packaged tarball on exactly that version. Building it needs 20.19 or newer, because the linter's dependency tree requires it. From a clone, npm install builds as part of the install, and npm run dev -- <command> runs it from source.

Related MCP server: r0x-os

Quick start

Reading needs no key, no wallet and no configuration.

pons info 0x44D6…20f4             # price, reserves, graduation phase, live snipe tax
pons pairs                        # every quote asset a launch may be priced in
pons watch 0x44D6…20f4            # follow one launch's trades as they happen
pons tx 0x2e8d…f58e               # receipt, decoded logs, and why a failure failed
pons doctor                       # probe every RPC endpoint with real calls

Trading needs a key. Nothing is signed unless you say so.

pons wallet create                          # generate a key into an encrypted keystore
pons buy  0x44D6…20f4 0.05                  # price it, simulate it, print it. Nothing is sent
pons buy  0x44D6…20f4 0.05 --dry-run        # the same, said explicitly
pons buy  0x44D6…20f4 0.05 --confirm        # sign and broadcast
pons sell 0x44D6…20f4 50% --slippage 200

Everything is machine-readable when piped, and that is the default:

pons info 0x44D6…20f4 | jq .graduation

Commands

Full reference, including which contract each command touches: docs/commands.md.

Reading, no key required

pons info <token>

Price, supply, graduation progress, fees, live snipe tax

pons pairs

Approved quote assets, in the order the Pons client renders them

pons watch <token>

Curve trades, buybacks and graduation, followed with a cursor

pons tx <hash>

Receipt, decoded logs, and the revert reason behind a failure

Trading, with RPC and a key

pons buy <token> <amount>

Buy on whichever venue the token trades

pons sell <token> <amount|50%|all>

Sell on the same

pons graduate <token>

Finish a curve that has raised its threshold. Anyone may call this

Launching

pons launch --name X --symbol Y

Create a token. V2 by default

Fees

pons claim

V2 creator or protocol fees held in the escrow

pons collect <token>

V1 position fees held by the locker

pons vault show|release <token>

The V2 buyback vault

Wallet and setup

pons wallet create|import|show|export

Key management

pons wallet balance|track|untrack

Holdings

pons wallet transfer|sweep

Spend

pons config list|get|set|unset|path

Configuration, and where each value came from

pons doctor

Endpoint health, probed with the calls the CLI actually makes

The two generations

Pons has launched tokens through two factories, and both are supported. You never have to say which one you mean: both registries are asked, and the answer settles everything after it.

V1

V2

Venue

a Uniswap V3 pool, from the first block

a bonding curve, graduating to Uniswap V4

Quote asset

WETH

ETH, or one of 23 approved tokens

Opening protection

wallet and transaction caps, for two blocks

a snipe tax, 99% decaying over three seconds

Liquidity

locked forever; only its fees come out

seeded into the pool at graduation

Fees

pons collect

pons claim

New launches

closed

open

V1's factory is retired. launchEnabled() has been false since 2026-08-12, and the transaction that set it is the last thing the factory ever emitted; no address has ever been whitelisted past it, so pons launch --generation v1 refuses before building anything. Its tokens are another matter. Thousands still hold liquidity, and a forty-pool sample saw 223 swaps in under six days, which is why reading and trading them is fully supported.

Trading

Every write builds a Plan first: what it will send, to whom, what it expects back, and what is worth warning about. That same Plan is what gets simulated and what gets signed, so the three cannot drift apart.

mode

what happens

(no flag)

Build the plan, simulate it against live state with a balance override, and print both. Nothing is signed or sent

--dry-run

The same work, asked for explicitly: "mode": "dry-run" in the payload, and no reminder that nothing was sent

--unsigned

Emit calldata and value for somebody else to sign. The only mode that does not simulate

--confirm

Sign and broadcast

Four behaviours worth knowing:

  • The venue is not a choice you have to make. The launch record says where the token trades. --route curve|v4|v3 overrides that answer rather than searching for one.

  • The floor is fixed when you accept it. The plan is rebuilt from live state immediately before broadcasting, and the floor you accepted is carried into the rebuild rather than recomputed from the new price. A trade cannot be signed below the bound you approved, and if the price has moved past it nothing is sent at all.

  • A sell into a curve at its threshold is redirected, not failed. The curve stops trading once it has raised enough, and pons graduate <token> is a call anyone can make.

  • A V1 sell is unwrapped for you. V1 pools hold WETH rather than ETH, so a sell leaves its proceeds at the router and unwraps them in the same transaction. Selling the obvious way would work and hand you WETH.

Launching

pons launch --name "My Token" --symbol MINE --desc "..."      # plan it and simulate it. Nothing is sent
pons launch --name "My Token" --symbol MINE --dry-run         # the same, said explicitly
pons launch --name "My Token" --symbol MINE \
  --pair USDG --creator-tax 250 --dev-buy 100 --confirm       # launch, quoted in USDG

A launch is the one thing here that cannot be undone. Before it builds a transaction the command prints the whole of what you are committing to: the address the token will land at, the supply, where it graduates, the fee split, and what the snipe tax will do. It also checks locally everything the factory would reject on chain.

  • The address is known before you send. Both generations deploy with CREATE2 from a salt you choose, so pons launch prints the token and curve addresses in advance and refuses a salt that is already taken. --salt accepts a raw 32-byte value, so a mined vanity address works.

  • The terms are pinned. previewLaunchEconomics returns a digest covering the supply, the curve fee, the pool's fee tier and the protocol's fee split, and it travels with the launch. If the protocol owner changes any of them while your transaction is in flight, the launch reverts rather than quietly repricing.

  • --dev-buy is atomic, and it has to be. The V2 factory demands exactly the launch fee and nothing more, so an opening buy cannot ride along with it; the buy goes through the launchpad's own router in the same transaction instead. A launch without one has been bought out inside two blocks on this chain.

  • --buyback costs you, not holders. The vault is funded entirely from your own fee share and releases over five years, split with the protocol. It is not a holder distribution, and the plan says so as a warning rather than a footnote.

pons pairs lists the assets a launch may be priced in: native ETH plus the twenty-three approved tokens, which are tokenised equities, two index funds and one stablecoin. They come back in the order the Pons create page renders them, so the two agree row for row.

Security

  • Read-only is the default. No command signs anything without --confirm. Three of the four execution modes cost nothing, and every one of them but --unsigned proves the call against the deployed contracts first, without the account holding funds.

  • The keystore is scrypt + AES-256-GCM, written owner-only. A password comes from a hidden prompt or PONS_PASSWORD; a key to import comes from PONS_PRIVATE_KEY.

  • Neither is ever a flag. An argument is visible in the process table and lands in shell history. There is no flag that takes either, and pons config list says so where somebody would look for one.

  • Credentials never reach a log line. A paid endpoint carries its key in the URL and error messages embed URLs, so URLs are masked inside thrown errors, not just in formatted output.

  • The MCP server cannot sign. It never loads a keystore and never broadcasts. See docs/agents.md.

  • A native transfer is signed with a fixed 100,000 gas limit. Nitro charges the L1 posting cost out of the transaction's own limit and eth_estimateGas does not say so; at 21,000 a transfer works while L1 is cheap and fails intermittently when it is not.

Found something that could cost somebody funds? Please report it privately. SECURITY.md has the how, what is in scope, and what the design guarantees.

Configuration

Values resolve through a ladder: flag > environment > config file > default. pons config list prints the resolved value alongside the tier it came from, so a surprising setting is one command away from being explained.

The config file is flat JSON at $XDG_CONFIG_HOME/ponscli/config.json (falling back to ~/.config/ponscli/config.json), written owner-only.

Key

Environment

Default

rpc.url

PONS_RPC_URL

unset. Your own node, tried first

rpc.endpoints

PONS_RPC_ENDPOINTS

the official and nodeflare public endpoints

rpc.alchemyKey

PONS_ALCHEMY_KEY

unset, which disables the paid tier

rpc.tier

PONS_RPC_TIER

auto

rpc.timeoutMs

PONS_RPC_TIMEOUT_MS

10000

wallet.keystore

PONS_KEYSTORE

<config dir>/keystore.json

wallet.tracked

PONS_WALLET_TRACKED

empty

output.json

PONS_JSON

on when stdout is not a TTY

output.color

PONS_COLOR

auto (honours NO_COLOR)

trade.slippageBps

PONS_SLIPPAGE_BPS

100 (1%)

trade.priorityFeeGwei

PONS_PRIORITY_FEE_GWEI

unset

cache.dir

PONS_CACHE_DIR

<cache dir>/ponscli

PONS_PASSWORD and PONS_PRIVATE_KEY are read from the environment but are deliberately not config keys: neither belongs in a file that config list prints and that users paste into issue reports.

Architecture

The full document, holding every decision and the measurement behind it, is docs/architecture/ponscli.md. The shape in brief:

src/core/       business logic, framework-free
src/commands/   thin CLI wiring
src/mcp/        the MCP server, also thin
src/chain/      the RPC waterfall
src/abi/        generated and committed

Both front ends are shells over src/core/. That is what makes pons-mcp a wrapper rather than a second implementation.

How requests are routed

Tier 1 is a round-robin over free endpoints; Tier 2 is a paid endpoint reached only once every Tier 1 candidate has been tried. Every rule comes from a measurement against this chain's own endpoints rather than from a general-purpose retry policy. The ones that matter most day to day:

  • A revert is an answer, not a failure. It comes straight back to you instead of being retried across every endpoint and then escalated to the paid tier.

  • A rate limit parks an endpoint for 30 seconds, not an hour. Free endpoints are token buckets; a long park costs more availability than the throttling did.

  • Writes never round-robin. A nonce taken from one node and broadcast to another is nonce too low, so transactions pin a single endpoint.

  • eth_chainId is not a health check. One public endpoint answers it faster than any other and then rejects eth_call. pons doctor probes with real calls for exactly this reason.

ABIs

src/abi/ is generated and committed, so the CLI works offline and an interface change shows up as a reviewable diff.

npm run abi:fetch     # regenerate from Sourcify, falling back to Blockscout
npm run abi:check     # fail if the committed files have drifted

Each file records where its ABI came from and how the match was proven. There are four provenance classes, because the contracts differ:

class

example

how it is proven

Verified at its address

PonsV2LaunchFactory

Sourcify's own bytecode match

Deployed identically on every chain

Permit2

verified on Base; every selector present in Robinhood's bytecode

Deployed once per launch, verified nowhere

the V2 curve and token

compiled from the factory's verified standard-JSON input, matched byte for byte against a live instance outside its immutables

Deployed many times, verified at some

the V3 pool, V1's token

one verified instance, proven general against a second, independently chosen one

One file is written by hand: erc20Errors.ts, holding the errors third-party quote assets revert with. A quote asset is somebody else's token, there is no single ABI covering the twenty-three approved ones, and without these the most ordinary failure on a USDG launch prints as four unexplained bytes.

For agents

Full guide: docs/agents.md.

pons-mcp ships in this package as a second binary and calls into the same core/ the CLI does.

// claude_desktop_config.json, .mcp.json, or your client's equivalent
{
  "mcpServers": {
    "pons": { "command": "pons-mcp" }
  }
}

Six tools: pons_info, pons_pairs, pons_plan_buy, pons_plan_sell, pons_transaction, pons_endpoints.

The server cannot sign, and there is no flag that makes it. It reads the chain and it builds unsigned transactions; a person sends them. That is the whole security model, and it is why the server is safe to leave running next to a model: the worst a confused agent can do is quote you a bad price, not spend your money.

Answers come back in base units, because a model can do exact arithmetic on 50000000000000000 and cannot on 0.05.

For an agent shelling out to the CLI instead, --json is already the default when stdout is not a terminal, and an argument mistake carries the failing command's usage line so the caller can correct itself:

{
  "ok": false,
  "error": {
    "code": "USAGE",
    "message": "missing required argument 'token'",
    "hint": "run 'pons info --help'",
    "details": { "command": "info", "usage": "pons info [options] <token>" }
  }
}

Agentic coding

This repository carries its own agent configuration. CLAUDE.md is the project brief, with AGENTS.md symlinked to it for Codex, Cursor, Copilot and others.

.claude/hooks/block-secrets.sh

Refuses any command line holding a private key or an inline password

.claude/hooks/warn-broadcast.sh

Says out loud when --confirm or pons launch is about to spend real money

.claude/skills/verify/

Runs the checks this project gates on, and explains what each failure means here

Testing

npm run typecheck
npm run lint
npm test
npm run build

The suite is entirely offline. Every test drives the real command surface against test/fakeChain.ts, a table of address + ABI + function → result that serves Multicall3 and eth_getLogs too, so what is exercised is the same decoding and aggregation the live path uses.

Two checks reach the network and are deliberately not part of npm test:

npm run test:sequence   # prove multi-block sequences against live mainnet state
npm run abi:check       # fail if a committed ABI has drifted from its verified source

Sequences, without a local node

A simulation proves one call against one block. It cannot prove that an approval lands and the sell in the next block then succeeds, or that a launch confirms and the curve it created is buyable a block later. Those are the failures that reach a user.

Robinhood Chain answers eth_simulateV1, which runs several blocks of several calls with state carrying across all of them, against live mainnet state. npm run test:sequence uses it to prove six sequences, including the whole life of a launch: created, traded, taken past its graduation threshold, and seeded into a Uniswap V4 pool. No local node, no Foundry, nothing spent.

Every sequence carries a control that must fail. Without one, a state override could be doing the work that the sequence appears to prove.

Spending real money on purpose

scripts/mainnet-e2e.sh launches a token, buys it, sells it and claims the fees against mainnet, for real. Sequences are covered for free by the check above, so what this adds is the one thing simulation cannot: a real transaction, signed by a real key, accepted by the real mempool, with a real receipt to decode. It is off unless you say so, asks before every transaction, and must never run in CI.

PONS_E2E=i-understand ./scripts/mainnet-e2e.sh

Exit codes

Scripts and agents can branch on the outcome without parsing prose.

Code

Meaning

0

Success

1

Unclassified failure

2

Usage: bad flags, arguments or command

3

Configuration is missing, malformed or contradictory

4

Every RPC endpoint failed

5

The chain answered, and the answer was a revert

6

Keystore missing, wrong password, or signing refused

7

The user declined a confirmation

8

The account cannot pay for what was asked

In --json mode a failure writes {"ok": false, "error": {...}} to stderr, never stdout, so a pipe carries only results.

Contributing

See CONTRIBUTING.md, and SECURITY.md for anything that should not be a public issue. The short version: run the four checks above, keep new behaviour in src/core/, and verify any claim about the protocol against mainnet before writing it down. The contract sources are stale in several places that matter.

About

Written from scratch in TypeScript on viem. No source is copied from any repository: the command surface is derived from a behavioural map of chainstacklabs/pumpfun-cli, and the RPC policy from measurements taken against this chain's own endpoints.

Pons itself is at ponsfamily.com: the web client for launching and exploring, its analytics, and its documentation. This CLI is not part of it, is not endorsed by it, and talks to the same public contracts anybody else can.

License

MIT. See LICENSE.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables agents to query live Robinhood Chain data including tokens, wallets, Chainlink feeds, heat scores, and tracking error on tokenized equities, all read-only without API keys.
    4
    13
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI agents to interact with Robinhood Chain via USDG payments, offering tools for balance, pricing, trading, and more.
    18
    63
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to scan tokens for honeypots, check safe launches, and build launch transactions on Robinhood Chain via the Model Context Protocol.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides live, read-only access to Robinhood Chain and Lox Corp data, enabling AI agents to query chain stats, token launches, agent details, and more.
    10
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Token swaps and honeypot/rug checks for AI agents on 8 chains, paid per-call in USDC via x402.

  • Agentic Finance: 500+ tools for AI agents over x402 or MPP, free via PoW, or prepaid card credits

  • 63 pay-per-call tools for agents: vision, text, data, web, blockchain. USDC on Base via x402.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mesutgulecen/ponscli'

If you have feedback or need assistance with the MCP directory API, please join our Discord server