Install
$ agentstack add mcp-nirholas-pumpfun-claims-bot ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
PumpFun Claims Bot
Read-only Telegram channel feed that broadcasts PumpFun on-chain activity — GitHub social fee claims, token graduations, and more. Posts rich, intelligence-enriched cards to a Telegram channel in real time.
Website · Live Channel · MCP Server · Deploy Guide · Contributing
> Looking for interactive monitoring? The [telegram-bot](../telegram-bot/) supports watch management, group chats, REST API, SSE streaming, and webhooks. Use this channel-bot for simple broadcast-only channels.
Features
Feed Types
| Feed | Description | Toggle | |------|-------------|--------| | GitHub Social Fee Claims | GitHub devs claiming PumpFun social fee PDA rewards | FEED_CLAIMS | | Token Graduations | Tokens graduating from bonding curve to PumpAMM | FEED_GRADUATIONS |
Claim Intelligence
Every GitHub social fee claim card includes:
| Feature | Description | |---------|-------------| | 🚨 First-Time Alert | 🚨🚨🚨 FIRST TIME CLAIM banner when a GitHub user claims for the first time ever | | ⚠️ Fake Claim Detection | Detects when claim_social_fee_pda instruction is called but no fees are actually paid out | | 📊 Claim Counter | Sequential claim number tracked persistently across restarts | | 💹 Lifetime SOL | Total SOL claimed from the PDA over all time | | 👤 GitHub Profile | Username, bio, repos, followers, account age, location, blog | | 𝕏 Social Links | Twitter/X profile with follower counts (from GitHub profile) | | 🏅 Influencer Badge | Tier-based badge for high-follower GitHub/X accounts | | 📈 Token Intel | Graduated/bonding curve status, curve progress %, created age, reply count | | 🔗 Token Socials | Twitter, Telegram, website links from token metadata | | 🏷️ Token Flags | NSFW, banned, cashback status indicators | | ⚠️ Trust Signals | Warnings for new GitHub accounts ( "Real GitHub project, dev claimed fast" · "Fork of popular repo, proceed with caution"
Architecture
Solana RPC (WebSocket + HTTP polling)
│
▼
┌───────────────────┐
│ SocialFeeIndex │──▶ Bootstraps ~148K SharingConfig → mint mappings
└────────┬──────────┘
│
┌────────▼──────────┐
│ ClaimMonitor │──▶ Decodes PumpFees program claim transactions
│ EventMonitor │──▶ Decodes Pump program logs (graduations)
└────────┬──────────┘
│ FeeClaimEvent / GraduationEvent
┌────────▼──────────┐
│ Enrichment Layer │
│ ├─ GitHub API │──▶ User profile, repos, followers
│ ├─ X/Twitter API │──▶ Follower counts, influencer tier
│ ├─ PumpFun API │──▶ Token info, creator profile, holders, trades
│ ├─ ClaimTracker │──▶ First-claim detection, persistent counts
│ └─ Fake Detect │──▶ Instruction called but no payout (amountLamports=0)
└────────┬──────────┘
│ ClaimFeedContext
┌────────▼──────────┐
│ Formatters │──▶ Rich HTML cards with sections & emoji layout
└────────┬──────────┘
│
┌────────▼──────────┐
│ grammY Bot │──▶ Posts photo + caption to Telegram channel
│ (retry + rate │ Falls back to text-only if photo fails
│ limiting) │
└───────────────────┘
Multi-RPC Failover
The RpcFallback class manages multiple Solana RPC endpoints with automatic rotation:
- Round-robin rotation after 3 consecutive failures on any endpoint
- 60-second cooldown per failed endpoint before retrying
- Earliest-expiry fallback — if all endpoints are in cooldown, picks the one expiring soonest
- Success resets — a single successful call resets the failure counter
- Configure via
SOLANA_RPC_URLS(comma-separated)
Programs Monitored
| Program | ID | Purpose | |---------|-----|---------| | PumpFees | pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ | Fee sharing, social fee PDA claims | | Pump | 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P | Bonding curve (graduations) | | PumpAMM | pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA | AMM (graduated pool events) |
Install
npm (MCP server — recommended for AI assistants)
Run the MCP server instantly with npx — no clone needed:
npx pumpfun-claims-bot
Or install globally:
npm install -g pumpfun-claims-bot
pumpfun-claims-bot
Add to your MCP client config (Claude Desktop, Cursor, VS Code Copilot):
{
"mcpServers": {
"pumpfun": {
"command": "npx",
"args": ["pumpfun-claims-bot"]
}
}
}
> npm package: pumpfun-claims-bot on npm
From source (full bot + Telegram feed)
git clone https://github.com/nirholas/pumpfun-claims-bot.git
cd pumpfun-claims-bot && npm install
Quick Start
1. Create a Telegram Bot
- Message @BotFather on Telegram
/newbot→ follow prompts → copy the bot token- Create a public channel (e.g.,
@pumpfunclaims) - Add the bot as an admin to the channel (must have "Post Messages" permission)
2. Configure Environment
cp .env.example .env
# ── Required ──────────────────────────────────────────────
TELEGRAM_BOT_TOKEN=your-bot-token-from-botfather
CHANNEL_ID=@your_channel_name # or numeric chat ID like -100xxx
# ── Solana RPC ────────────────────────────────────────────
SOLANA_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your-key
SOLANA_WS_URL=wss://mainnet.helius-rpc.com/?api-key=your-key
# Comma-separated fallback RPCs (rotates on 429/5xx/timeout)
SOLANA_RPC_URLS=https://mainnet.helius-rpc.com/?api-key=key1,https://your-other-rpc.com
# ── Feed Toggles (all default false except FEED_CLAIMS) ───
FEED_CLAIMS=true # GitHub social fee claims (default: true)
FEED_GRADUATIONS=false # Token graduations to PumpAMM (default: false)
FEED_LAUNCHES=false # New token launches (default: false)
FEED_WHALES=false # Large buy/sell whale alerts (default: false)
FEED_FEE_DISTRIBUTIONS=false # Creator fee distribution events (default: false)
# ── Claim Filter ──────────────────────────────────────────
REQUIRE_GITHUB=true # Only post claims with GitHub social fee PDA (default: true)
# ── Enrichment APIs ───────────────────────────────────────
GITHUB_TOKEN=ghp_your_token # Raises GitHub rate limit: 60 → 5000 req/hr
GROQ_API_KEY=gsk_your_key # Groq API for AI one-liner summaries
# X/Twitter follower counts & influencer detection
# Get cookies from x.com DevTools → Application → Cookies
# X_AUTH_TOKEN=your_auth_token_cookie
# X_CT0_TOKEN=your_ct0_cookie
# ── Affiliate Ref Codes ───────────────────────────────────
# Appended to Axiom / GMGN / Padre trading links in cards
# AXIOM_REF=your_ref
# GMGN_REF=your_ref
# PADRE_REF=your_ref
# ── Tuning ────────────────────────────────────────────────
POLL_INTERVAL_SECONDS=30 # HTTP polling fallback interval (default: 30)
WHALE_THRESHOLD_SOL=10 # Minimum SOL for whale alerts (default: 10)
LOG_LEVEL=info # debug | info | warn | error (default: info)
# ── Health Check ──────────────────────────────────────────
# PORT=3000 # Set automatically by Railway
Environment Variables Reference
| Variable | Required | Default | Description | |---|---|---|---| | TELEGRAM_BOT_TOKEN | ✅ | — | Bot token — message @BotFather → /newbot | | CHANNEL_ID | ✅ | — | Channel to post to (@channelname or -100xxx) — get the numeric ID via @userinfobot | | SOLANA_RPC_URL | ✅ | https://api.mainnet-beta.solana.com | Primary Solana HTTP RPC — free tier at Helius, QuickNode, or Alchemy | | SOLANA_WS_URL | — | Derived from SOLANA_RPC_URL | Solana WebSocket URL — same provider as SOLANA_RPC_URL, replace https:// with wss:// | | SOLANA_RPC_URLS | — | — | Comma-separated fallback RPC URLs — auto-rotates on 429 / 5xx / timeout | | FEED_CLAIMS | — | true | Post GitHub social fee claim cards | | FEED_GRADUATIONS | — | false | Post token graduation cards | | FEED_LAUNCHES | — | false | Post new token launch cards | | FEED_WHALES | — | false | Post whale buy/sell alerts | | FEED_FEE_DISTRIBUTIONS | — | false | Post creator fee distribution events | | REQUIRE_GITHUB | — | true | Skip claims that have no GitHub social fee PDA | | GITHUB_TOKEN | — | — | GitHub PAT — create one here (no scopes needed) — raises rate limit from 60 → 5000 req/hr | | GROQ_API_KEY | — | — | Groq API key for AI one-liner summaries — get a free key at console.groq.com | | X_AUTH_TOKEN | — | — | X/Twitter auth_token cookie — open x.com, DevTools → Application → Cookies → copy auth_token | | X_CT0_TOKEN | — | — | X/Twitter ct0 cookie (CSRF token) — same place as above, copy ct0 | | AXIOM_REF | — | — | Affiliate ref code for Axiom trading links | | GMGN_REF | — | — | Affiliate ref code for GMGN trading links | | PADRE_REF | — | — | Affiliate ref code for Padre trading links | | POLL_INTERVAL_SECONDS | — | 30 | HTTP polling interval when WebSocket is unavailable | | WHALE_THRESHOLD_SOL | — | 10 | Minimum SOL trade size to trigger a whale alert | | LOG_LEVEL | — | info | Log verbosity: debug \| info \| warn \| error | | PORT | — | 3000 | Health check HTTP server port — set automatically by Railway | | MCP_ENABLED | — | false | Enable the MCP (Model Context Protocol) server for AI assistant integrations | | MCP_PORT | — | 3001 | MCP server HTTP port (Streamable HTTP transport) |
3. Run
# Install dependencies
npm install
# Development (hot reload via tsx)
npm run dev
# Production
npm run build
npm start
4. Deploy with Docker
docker build -t pumpfun-channel-bot .
docker run -d --env-file .env pumpfun-channel-bot
5. Deploy to Railway
[](https://railway.com/deploy/Qab59T?referralCode=tqNsEB)
Railway auto-deploys from GitHub and provides persistent volumes for claim tracking data.
# Install Railway CLI
npm install -g @railway/cli
railway login
# Create & link project
railway init
railway link
# Set environment variables
railway variables set TELEGRAM_BOT_TOKEN=your-token
railway variables set CHANNEL_ID=@your_channel_name
railway variables set SOLANA_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your-key
railway variables set SOLANA_WS_URL=wss://mainnet.helius-rpc.com/?api-key=your-key
railway variables set FEED_CLAIMS=true
railway variables set REQUIRE_GITHUB=true
# Create persistent volume for claim tracker data
railway volume create --mount /app/data
# Deploy
railway up
See [railway.json](railway.json) for the deployment config:
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "Dockerfile"
},
"deploy": {
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}
Project Structure
channel-bot/
├── src/
│ ├── index.ts # Entry point — wires monitors, enrichment, & Telegram posting
│ ├── config.ts # Environment variable loading & validation
│ ├── mcp-server.ts # MCP server — exposes tools via Streamable HTTP or stdio
│ ├── mcp-stdio.ts # Standalone MCP entry point (stdio transport)
│ ├── claim-monitor.ts # PumpFees program monitor (WebSocket + HTTP polling)
│ ├── claim-tracker.ts # First-claim detection + claim counter (persisted to disk)
│ ├── event-monitor.ts # Pump program log decoder (graduations, launches)
│ ├── social-fee-index.ts # SocialFeeIndex — maps SharingConfig PDAs → mints (~148K)
│ ├── formatters.ts # Rich HTML card builders for Telegram
│ ├── pump-client.ts # PumpFun HTTP API client (token info, creator profiles)
│ ├── github-client.ts # GitHub API client (user profiles, rate-limited cache)
│ ├── x-client.ts # X/Twitter profile fetcher + influencer tier logic
│ ├── groq-client.ts # Groq AI one-liner summaries
│ ├── rpc-fallback.ts # Multi-RPC failover with round-robin
│ ├── health.ts # HTTP health check server
│ ├── types.ts # Program IDs, discriminators, event types
│ └── logger.ts # Leveled console logger
├── data/ # Persisted state (gitignored, Railway volume mount)
│ └── github-first-claims.json
├── Dockerfile # Multi-stage Docker build
├── railway.json # Railway deployment config
├── package.json
└── tsconfig.json
How It Works
Claim Detection Pipeline
Transaction detected on PumpFees program
│
▼
Identify instruction: claim_social_fee_pda?
│
├─ YES ──▶ Parse platform (2 = GitHub) + user_id from Anchor args
│ │
│ ▼
│ Check amountLamports from SocialFeePdaClaimed event
│ │
│ ├─ amountLamports > 0 ──▶ Real claim
│ │ ├─ Check ClaimTracker: first time for this GitHub user?
│ │ │ ├─ YES ──▶ 🚨 FIRST TIME CLAIM banner
│ │ │ └─ NO ──▶ Standard claim card
│ │ └─ Enrich: GitHub API + PumpFun API + X profile
│ │
│ └─ amountLamports = 0 ──▶ ⚠️ FAKE CLAIM (instruction called, no payout)
│
└─ NO ───▶ Other claim type (creator fee, cashback, etc.)
SocialFeeIndex Bootstrap
On startup, the bot fetches all SharingConfig accounts from the PumpFees program to build a reverse mapping from social fee PDA addresses to token mints. This enables resolving which token a social fee claim belongs to without additional RPC calls.
- ~148K mappings loaded at startup
- Incremental updates via WebSocket subscription on
CreateFeeSharingConfigandUpdateFeeSharesevents - Lookup:
socialFeeIndex.getMintForPda(pdaAddress)→ token mint - One PDA → many mints — handles scammers who reuse PDAs across multiple tokens
Fake Claim Detection
Some users call the claim_social_fee_pda instruction targeting random token PDAs where they have no fees to collect. The bot detects these by checking:
- The instruction discriminator matches
claim_social_fee_pda - The transaction logs contain no
SocialFeePdaClaimedevent — OR the event showsamountLamports = 0 - The GitHub user ID and platform are still parsed from the instruction args (Anchor Borsh format)
Fake claims are posted with a ⚠️ FAKE CLAIM warning and a 🚩 Fake claim — no fees paid out trust signal.
First-Claim Tracking
The ClaimTracker maintains a persistent set of GitHub user IDs that have successfully claimed:
- In-memory set for fast lookup during processing
- Debounced disk persistence (5-second delay) to
data/github-first-claims.json - Split check/mark pattern:
hasGithubUserClaimed()checks without side effects,markGithubUserClaimed()only called after successful Telegram post - Claim counter:
incrementGithubClaimCount()returns sequential claim number per user - First-claim status is NOT set for fake claims
Three-Layer First-Claim Verification
- Local dedup — Skip if already posted (survives restarts via persisted JSON)
- On-chain verification —
lifetimeClaimedLamports == amountLamportsconfirms it's truly the first claim on-chain - Graceful fallback — Skips first-claim banner if verification fails (prevents false positives after redeployment)
Example Claim Card
🚨🚨🚨 FIRST TIME CLAIM 🚨🚨🚨
🐙 $PUMP — PumpCoin 💹 $45K
↳ GitHub dev claimed PumpFun social fees
📊 Claim #1 · 0.1043 SOL lifetime ($15.65)
🏦 0.1043 SOL ($15.65)
↳ 8mNp...4rWz
👤 nirholas (Nicholas)
↳ 📦
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [nirholas](https://github.com/nirholas)
- **Source:** [nirholas/pumpfun-claims-bot](https://github.com/nirholas/pumpfun-claims-bot)
- **License:** MIT
- **Homepage:** https://pumpfun-claims-bot.vercel.app
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.