Skip to main content
Glama

nft-farm-mcp

Find free-mint NFT collections that went up, and the wallets farming them, ranked by secondary-market PnL read directly from chain state.

Ships as an MCP server (stdio) and a CLI. Works on any EVM chain with a Seaport deployment; Robinhood Chain by default.

  • Reads only eth_getLogs / eth_call / eth_getTransaction. No API key, no account, no wallet. Every tool is read-only and never sends a transaction.

  • Data comes from Seaport OrderFulfilled events (sales) and Transfer from 0x0 (mints). No third-party indexer.

  • Requires Node ≥ 20.

Tiếng Việt: README.vi.md


Install

claude mcp add nft-farm -- npx -y nft-farm-mcp@latest
{
  "mcpServers": {
    "nft-farm": {
      "command": "npx",
      "args": ["-y", "nft-farm-mcp@latest"],
      // optional — public RPCs are rate-limited; a private endpoint helps a lot
      // on busy chains like Ethereum and Base
      "env": {
        "NFT_FARM_CHAIN": "robinhood",
        "NFT_FARM_RPC_BASE": "https://your-base-endpoint"
      }
    }
  }
}

The package has no runtime dependencies — viem and the MCP SDK are bundled, so npx fetches one 305 kB tarball instead of installing a dependency tree.

Two binaries ship: nft-farm-mcp is the MCP server, nft-farm is the CLI.


Related MCP server: SOL Claimer MCP Server

Tools

Tool

Purpose

list_chains

List built-in chains, or resolve one chain spec and get its measured block time, detected Seaport address and scan-cost estimate

scan_collections

Rank free-mint collections by secondary PnL in a block window

scan_wallets

Rank the wallets that minted those collections; flag wallets minting several (overlap = farming signal)

job_status

Poll / cancel a background scan and read its result

// 1. confirm the chain is supported and see what a scan will cost
list_chains { "chain": "base", "days": 1 }

// 2. rank collections — start narrow, async is the safe default
scan_collections { "chain": "base", "days": 1, "top": 10, "probe": 20, "async": true }

// 3. poll until status leaves "running"
job_status { "jobId": "<id from step 2>" }

// 4. take the interesting collections further: who minted them?
scan_wallets { "chain": "base", "days": 1, "topCollections": 10, "minOverlap": 2, "async": true }

Pass async: true unless the window is genuinely small. A scan that exceeds the inline budget is started as a background job automatically, but the estimate is approximate — an explicit async: true can never time out, and costs one extra job_status round-trip when the scan turns out to be fast.


Arguments

Shared by scan_collections and scan_wallets

Chain

Arg

Type

Default

Meaning

chain

string

robinhood

Built-in key, numeric chain id ("8453"), or an RPC URL

rpcUrls

string[]

chain defaults

First is primary, the rest are failover

seaport

string

detected

Marketplace address override

blockTimeMs

number

measured

Skip block-time measurement

Window — omit all four and you get the last 7 days.

Arg

Type

Default

Meaning

days

number, ≤ 90

7

Rolling window ending at chain tip

fromBlock / toBlock

string (decimal)

tip

Explicit blocks. Strings, not numbers

from / to

string

ISO date or unix seconds

Cost / tuning

Arg

Type

Default

Meaning

async

boolean

auto

true → return a jobId immediately

concurrency

number, 1–16

2

Max in-flight getLogs

maxLogSpan

number

per chain

Max block span per getLogs; see list_chains

mintProbeCalls

number, 1–500

20

Max getLogs spent finding one collection's mints

mintLookbackDays

number, ≤ 90

90

How far before the window to look for mints

cache

boolean

true

Disk cache of immutable history

scan_collections only

Arg

Type

Default

Meaning

top

number, 1–200

20

Rows returned

probe

number, 1–400

80

Top-by-volume collections to mint-probe. Dominates runtime

minSales

number

1

Minimum secondary sales to qualify

sortBy

enum

pnlAth

pnlAth | pnlAvg | ath | volume | sales | floor

freeOnly

boolean

true

false includes paid mints

scan_wallets only

Arg

Type

Default

Meaning

top

number, 1–200

20

Wallet rows per table

topCollections

number, 1–100

15

Profitable collections used as seeds

minOverlap

number

2

Distinct seeded collections a wallet must have minted

maxMints

number

400

Mint events to fetch per collection

minSales

number

2

Minimum sales to seed (note: scan_collections defaults to 1)

probe

number, 1–400

max(50, topCollections × 4)

Candidates before the free-mint filter

walletSort

enum

totalEst

totalEst | realized | overlap | mints

list_chains / job_status

list_chains takes chain, rpcUrls, days — all optional. With no chain it just lists the built-ins.

job_status takes jobId (omit to list recent jobs) and cancel (abort instead of read).

Ranges are rejected, not clamped: days: 120 is a validation error.


Reading the output

Every tool returns a markdown table in content and typed data in structuredContent. All *Eth fields are decimal strings, not numbers — parse before comparing, or "9" sorts above "10". Amounts are in the chain's native token (chain.nativeSymbol: POL on Polygon, APE on ApeChain, BNB, AVAX), despite the Eth suffix.

collections[]

Field

Meaning

volumeEth, athEth, floorEth, avgEth

Computed only from sales inside the requested window. athEth is the top sale in that window, not an all-time high; floorEth is the lowest sale, not a live listing floor

freeMint

true / false / null. null means the probe budget ran out — unknown, not paid

mintCostEth

Median of the sampled mint transaction values; 0 when free, null when unknown

pnlAthEth

athEth − mintCostEth. Best-case single sale in the window, gas excluded

pnlAvgEth

avgEth − mintCostEth. The more honest figure

roiAth

number, or the string "inf" when the mint was free, or null

mintSamples / mintsObserved

Transactions actually sampled / mint logs seen. Low mintSamples means a thin verdict

topWallets[], overlapWallets[]

Field

Meaning

realizedPnlEth

Gross Seaport proceeds. The only figure backed by real sales. No gas, royalty or marketplace fee deducted

realizedSales

Number of those sales

estUnrealizedAvgEth

Mints the wallet still holds × the collection's window average sale. Mark-to-market, not money received

totalEstPnlAvgEth

realizedPnlEth + estUnrealizedAvgEth

collectionsMinted

True count of seeded collections this wallet minted

hits

Capped at the top 5 collections by mint count — use collectionsMinted for the real number. Each hit has mintCount and soldCount

What "realized" counts. A sale is credited to a wallet only when all three hold: it is a listing-side fill (Seaport bid fills have no resolvable seller), the collection is one of the seeded ones, and that wallet appears in the sampled minter set for it. It is therefore a floor on actual proceeds, not a full P&L.

How freeMint is decided. At most 8 mint transactions are sampled; freeMint is true when ≥ 80 % of them carry value == 0. It reads native tx.value only, so mints priced in ERC-20, routed through an aggregator, or batched (one transaction minting many tokens) are mis-priced.

Sampling. maxMints bounds how many mint events are fetched per collection, so minter sets are a sample of the largest minters, not the full holder list.

None of this is financial advice — verify on-chain before acting on a wallet.


When something goes wrong

Symptom

What it means / what to do

getLogs failed at … via <url>

That endpoint refuses log queries. Several widely-listed public RPCs answer eth_chainId but reject eth_getLogs. Pass different rpcUrls, or lower maxLogSpan

Chain … has no Seaport deployment at any known address

No Seaport 1.6/1.5/1.4 on that chain. Pass seaport: "0x…" if it uses another marketplace

Unknown chain id N. Pass an RPC for it

Supply rpcUrls alongside the numeric chain

Tool call times out

Re-issue with async: true, then poll job_status

Empty collections

Widen days, lower minSales, or set freeOnly: false. Many rows with freeMint: null means the probe budget ran out — raise mintProbeCalls

scan_wallets returns three empty arrays

No collection passed the free + profitable seed filter. Run scan_collections first to see what is there

job_status.status is one of running, done, error, cancelled. Stop polling on any of the last three, and read error when it is non-null. Poll every 5–15 s. Jobs live in the server process only: the last 32 are retained and all are lost if the server restarts.


Chain support

Built-in keys: robinhood, ethereum, base, optimism, arbitrum, polygon, zora, blast, apechain, abstract, bnb, avalanche.

chain also accepts a numeric id or a bare RPC URL. For an unknown chain the server detects and caches what it needs: chain id from eth_chainId, block time measured from two block timestamps, and the marketplace by probing Seaport's deterministic address (1.6 → 1.5 → 1.4) with getCode.

maxLogSpan defaults differ per chain — Ethereum 2 000, Base/OP/Polygon/Zora/ Blast/BNB/Avalanche 10 000, ApeChain/Abstract 20 000, Arbitrum 50 000, Robinhood 100 000, auto-detected chains 10 000 — then auto-tune to what the endpoint actually accepts. list_chains reports the current value.

Environment variables

Variable

Purpose

RPC_URL

Default RPC; comma-separated for failover

NFT_FARM_RPC_<CHAIN>

Per-chain override, e.g. NFT_FARM_RPC_BASE

NFT_FARM_CHAIN

Default chain (default robinhood)

NFT_FARM_CACHE_DIR

Cache location (default ~/.nft-farm/cache)

NFT_FARM_SYNC_CALL_BUDGET

Estimated calls allowed inline before switching to a job (default 40)


Performance and caching

Block history is immutable, so decoded Seaport sales are cached in aligned block buckets under ~/.nft-farm/cache and reused; only the tip is re-fetched. Collection names, token standards, mint-cost probes and minter sets are cached too. Buckets within ~10 minutes of head are never cached, so a reorg cannot poison the store. Delete the directory to reset; cache: false bypasses it.

Robinhood (1 day, 73k sale legs, probe: 10)

Base (0.15 day, probe: 3)

Cold — Seaport phase

34.3 s

0.4 s

Cold — mint probe

59.6 s

30 s

Cold total

1 m 36 s

39 s

Warm — Seaport phase

0.9 s

0.8 s

Those numbers are at probe 3–10. The default is probe: 80 over 7 days, which is minutes of work — another reason to start narrow and use async.

Cache size scales with sales volume: one day of Robinhood Seaport (73 k sale legs) is ~2.3 MB gzipped.


CLI

Same engine, no MCP client needed:

npx -y -p nft-farm-mcp nft-farm scan --days 7 --top 20
npx -y -p nft-farm-mcp nft-farm chains

# or from source
npm install && npm run build
npm run scan -- --chain base --days 1 --top 10
npm run wallets -- --days 1 --top 20 --min-overlap 2

nft-farm --help lists every flag. Flags mirror the MCP arguments (--chain, --rpc repeatable/comma-separated, --days, --top, --probe, --sort, --all for paid mints, --json, --concurrency, --max-span, --mint-probe-calls, --mint-lookback, --no-cache, --cache-dir).

Two CLI-only differences worth knowing: --min-sales defaults to 1 for both commands (the MCP scan_wallets uses 2), and --sort pnlFloor is an alias that sorts by floor price, not by floor PnL.


Development

npm run typecheck
npm test          # typecheck + bundle + MCP stdio smoke test

MCP_PLAN.md records the RPC measurements behind the design and the places the first design was wrong — useful if you port this to another chain or RPC provider.

MIT.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (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
    A
    maintenance
    An MCP server that enables AI assistants to analyze Solana wallets for empty or low-value token accounts. It allows users to identify opportunities to recover SOL rent by closing or burning these accounts through the SOL Claimer API.
    4
    8
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Cross-chain DeFi intelligence MCP server for AI agents. 7 tools for yield discovery, pool analysis, profit simulation, risk scoring, whale tracking, impermanent loss calculation, and DeFi overview across 86 chains and 6,500+ liquidity pools.
    7
    1
    AGPL 3.0
  • A
    license
    -
    quality
    C
    maintenance
    MCP server that provides AI agents with crypto token safety checks (honeypot, liquidity, rug risk) and alpha signals (smart money buys, fresh rug radar) across PulseChain, Monad, Base, and BSC.
    47
    MIT

View all related MCP servers

Related MCP Connectors

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/0xsyncroot/nft-farm-mcp'

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