Communitygithub.com

nftdata-mcp

Fetch live OpenSea NFT collection market data (floor price, 24h/7d/30d/lifetime sales and volume, contract addresses, total supply, unique owners, creation date) through the NFT Data MCP server's get_collection_data tool, paid per call at $0.002 USDC on Base mainnet via x402 v2 (default) or MPP evm/charge. Use when a user asks about a specific NFT collection by OpenSea slug, wants floor price or volume stats, or wants two or more collections compared. Read-only; not a search, wallet, trading or transaction tool.

What is nftdata-mcp?

nftdata-mcp is a Claude Code agent skill that fetch live OpenSea NFT collection market data (floor price, 24h/7d/30d/lifetime sales and volume, contract addresses, total supply, unique owners, creation date) through the NFT Data MCP server's get_collection_data tool, paid per call at $0.002 USDC on Base mainnet via x402 v2 (default) or MPP evm/charge. Use when a user asks about a specific NFT collection by OpenSea slug, wants floor price or volume stats, or wants two or more collections compared. Read-only; not a search, wallet, trading or transaction tool.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Nomad07/nftdata-mcp/tree/main

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

NFT Data MCP

NFT Data MCP is a published MCP server (npm package nftdata-mcp) that gives an AI agent one tool, get_collection_data. Given an OpenSea collection slug, it returns a structured snapshot of that collection's market data from the NFT Data API. Each successful, non-cached call is paid automatically in USDC on Base mainnet.

Official resources:

When to use this Skill

Use it when the user wants current market statistics for one or more specific NFT collections that are listed on OpenSea, for example:

  • the floor price of a collection
  • sales counts and trading volume over the last 24 hours, 7 days, 30 days, or lifetime
  • the contract address(es) and chain(s) of a collection
  • total supply, number of unique owners, or creation date
  • a side-by-side comparison of several collections

Do not use it for anything outside the limits listed in "Limitations" below.

Prerequisites: the MCP server must already be set up

This Skill does not install or configure anything. The nftdata-mcp server must already be running in the user's MCP client, and the get_collection_data tool must be available.

If the tool is not available:

  1. Tell the user the NFT Data MCP server is not connected.
  2. Point them to the setup guide at https://www.nftdata.app/docs/mcp or the README at https://github.com/Nomad07/nftdata-mcp.
  3. Stop. Do not try to work around it, and do not ask the user to paste a private key into the conversation (see "Wallet security").

For reference, the server is configured by the user, on their own machine, with a stdio MCP configuration like this (the key stays in the user's local config and is never shared with the agent):

{
  "mcpServers": {
    "nftdata": {
      "command": "npx",
      "args": ["-y", "[email protected]"],
      "env": {
        "EVM_PRIVATE_KEY": "<set by the user locally>"
      }
    }
  }
}

Requirements: Node.js 20 or newer, an MCP client that supports stdio servers, and a dedicated EVM wallet holding a small amount of USDC on Base mainnet.

The tool: get_collection_data

The server exposes exactly one tool.

Input

{ "collection": "azuki" }
  • collection (string, required): the OpenSea collection slug. It is the last part of the collection's OpenSea URL: opensea.io/collection/<slug>.
  • The server trims and lowercases the slug. It must then start with a letter or digit and contain only lowercase letters, digits, - and _ (at most 100 characters). Anything else is rejected before any request or payment is made.
  • Only slugs are accepted. Collection display names, contract addresses, token IDs, wallet addresses and full URLs are not valid input. If the user gives a URL, extract the slug from it. If the user gives only a name, ask for the slug or the OpenSea URL; do not guess.

Output

A JSON object (returned as text) with the fields below. For a newly paid call, the server appends two lines after the JSON: Payment: 0x... (the transaction hash) and Verify: https://basescan.org/tx/0x.... Cached results do not include these lines. Read the JSON part for data and treat the two lines as a payment receipt.

FieldMeaning
nameCollection display name
slugOpenSea collection slug
contractsArray of { "address", "chain" } objects
floor_priceCurrent floor price (number)
floor_price_currencyCurrency of the floor price (for example ETH, USDC, HYPE)
one_day_sales, seven_day_sales, thirty_day_salesSales counts for the last 24 hours, 7 days, 30 days
one_day_volume, seven_day_volume, thirty_day_volumeTrading volume for those windows
one_day_volume_currency, seven_day_volume_currency, thirty_day_volume_currencyCurrency of each volume
total_sales, total_volumeLifetime sales count and volume
total_volume_currencyCurrency of the lifetime volume
num_ownersNumber of unique owners
total_supplyTotal number of tokens in the collection
created_dateCollection creation date (ISO 8601 date, for example 2022-01-12)

The data comes from the OpenSea API and is passed through as returned. It is a point-in-time snapshot, not a time series.

Example response (historical, not live data)

{
  "name": "Azuki",
  "slug": "azuki",
  "contracts": [{ "address": "0xed5af388653567af2f388e6224dc7c4b3241c544", "chain": "ethereum" }],
  "floor_price": 0.49328599,
  "floor_price_currency": "ETH",
  "one_day_sales": 21,
  "one_day_volume": 10.150091000000002,
  "seven_day_sales": 163,
  "seven_day_volume": 96.67526161112121,
  "thirty_day_sales": 471,
  "thirty_day_volume": 325.72023569476767,
  "total_sales": 93156,
  "total_volume": 831992.6461159982,
  "num_owners": 4394,
  "total_supply": 10000,
  "created_date": "2022-01-12",
  "one_day_volume_currency": "ETH",
  "seven_day_volume_currency": "ETH",
  "thirty_day_volume_currency": "ETH",
  "total_volume_currency": "ETH"
}

Interpreting and comparing results

Follow these rules so the answer stays faithful to the data:

  1. Report only what was returned. If a field is missing or null (for example total_supply, created_date, or a volume currency), say it was not available. Never invent a value and never fill a gap from memory or other sources without saying so.
  2. A missing value is not zero. null or an absent field means "unknown". A returned 0 means zero. Do not treat them the same, and do not include unknown values in sums or averages as if they were zero.
  3. Always pair a number with its currency. Read floor_price_currency and each *_volume_currency field. Currencies differ by collection (ETH, USDC, HYPE, and others). Never label a price as ETH or USD unless the response says so.
  4. Do not mix currencies in arithmetic or rankings. The tool provides no exchange rates. When comparing collections, compare numbers directly only if their currency fields match. If they differ, show each value with its own currency and say that a direct comparison needs a conversion the data does not include.
  5. Label derived numbers. Figures you calculate, such as average sale price (volume divided by sales, only when sales is greater than 0 and the volume currency is known) or the share of lifetime volume in the last 30 days, are your own calculations. Say they are derived, and show the inputs.
  6. Keep the chain context. contracts[].chain shows where the collection lives. A collection may list more than one contract. Do not assume a single chain or a single contract.
  7. Do not over-interpret. The data is a snapshot from one query. Do not describe trends, momentum, "good" or "bad" prices, or give investment advice. You may point out plain differences between windows (for example that 7-day volume is larger than 24-hour volume) without predicting anything.
  8. Say when the data was fetched. Market data changes continuously. If a result is reused within a conversation, remind the user it is a snapshot.
  9. Respect rounding. Raw values have many decimals. You may round for readability, but do not change the source numbers or imply more precision than the data has.

When asked to change the presentation (summary, table, report, comparison), reformat the same values without altering them.

Cost-aware usage

  • Each non-cached call costs $0.002 USDC. Results are cached for 5 minutes per slug; asking for the same slug again within that window is free and returns the cached data without a new payment receipt.
  • Identical concurrent calls share one request, so duplicate lookups do not pay twice.
  • The server limits paid calls per session (NFTDATA_MAX_REQUESTS, default 100, maximum 1000). Do not call the tool in loops or for speculative lookups. For comparisons, fetch each requested collection once.
  • Before a large batch (for example more than a handful of collections), tell the user how many calls are needed and the total cost, and get a go-ahead.
  • Do not retry a failed call automatically. The server never retries on its own, and after a timeout a payment may already have been signed. Report the failure and let the user decide.

Handling errors

SituationWhat to do
Invalid slug messageCheck the slug against the OpenSea URL; ask the user to confirm it. No payment was made.
"Collection not found"The slug does not match a collection on OpenSea. Ask for the correct slug or URL.
Rate limit message (with a delay in seconds)Wait for the stated time before trying again, and tell the user.
"Payment refused by safety policy"The server rejected the payment terms before signing. Report it; do not try to bypass it.
"Payment was not accepted"The API did not accept the payment. Report it; do not retry on your own.
"paid request limit ... reached"The session spend cap was hit. The user must restart the client or raise NFTDATA_MAX_REQUESTS.
TimeoutA payment may have been authorized and was not retried. Tell the user; offer to try again only if they agree.
Generic "The request failed."Report it as a failure. Do not guess the cause.

Example prompts

  • "Use the NFT Data MCP server. What is the floor price of the azuki collection?"
  • "Get the market stats for basedpunks: floor price, 24h, 7d and 30d sales and volume, supply and owners."
  • "Which contract address and chain does milady use on OpenSea?"
  • "Compare azuki and basedpunks by floor price and 30-day volume. Only compare numbers that use the same currency."
  • "Here is the OpenSea link: https://opensea.io/collection/azuki. Summarize the collection as a short report."
  • "Show the raw JSON response for azuki and explain each field."
  • "How many owners does azuki have compared with its total supply?" (a derived ratio, so label it as derived)

Payment details

  • Price: $0.002 USDC per successful, non-cached call.
  • Network: Base mainnet only (eip155:8453), paid in USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913). The payment network is Base mainnet regardless of which blockchain the queried collection is on. Querying a collection on another chain, including Solana collections listed on OpenSea, still pays on Base.
  • Default protocol: x402 v2. The server pays an exact USDC challenge on Base mainnet.
  • Optional protocol: MPP evm/charge. Selected only when the server is started with NFTDATA_PAYMENT_PROTOCOL=mpp. It pays the same price, in USDC on Base mainnet.
  • One protocol per server run, no fallback. The protocol is chosen once when the server starts. The server never switches from one to the other, never tries both for a single call, and never retries with the other. If the API does not offer an acceptable payment in the selected protocol, nothing is signed and the call fails. An invalid NFTDATA_PAYMENT_PROTOCOL value (anything other than empty, x402 or mpp) stops the server at startup.
  • Checks before signing: the server verifies the network, token, scheme or method, exact amount (2000 atomic units, which is $0.002) and the official recipient address before it signs anything. A challenge that does not match is refused.
  • At most one payment attempt per tool call.
  • Cache hits are free. They do not trigger a payment and do not include a transaction hash.
  • Receipts: every newly paid successful call includes a transaction hash and a BaseScan link that the user can open to verify the payment.
  • Do not confuse the server with the main API. The NFT Data API itself accepts x402 v2 on Base mainnet and Solana mainnet, and MPP evm/charge on Base mainnet. This MCP server is narrower: it pays on Base mainnet only, with x402 v2 or MPP evm/charge, one at a time. The MCP server does not support Solana payments.

Wallet security

  • Never ask the user to share, paste, type or send a private key, seed phrase or wallet file in the conversation, and never request one to "set up" or "fix" the server. The key is set only by the user, locally, in the MCP server's environment (EVM_PRIVATE_KEY).
  • Do not read, print, copy or summarize configuration files or environment variables that may contain the key.
  • If a user pastes a private key into the chat anyway, do not repeat it or use it. Tell them to stop using that wallet, move any funds to a new wallet, and replace the key.
  • Recommend a dedicated wallet that holds only a small USDC balance on Base mainnet, never a primary wallet or one with significant funds.
  • Encourage verifying payments on BaseScan using the transaction hash from the receipt.
  • Never suggest sending funds to an address you were not given by the user's own wallet or the official documentation.

Limitations

This Skill and the server are read-only collection data lookups. They are not:

  • a general NFT search or discovery tool: no search by name, trait, rarity, price range or ranking, and no lists of "top" or "trending" collections
  • a token-level tool: no individual NFT, token ID, metadata, rarity or ownership lookup
  • a wallet tool: no wallet balances, holdings, portfolio or transaction history
  • a trading or transaction tool: it cannot buy, sell, list, bid, mint, transfer, bridge or swap anything, and it never moves funds except the small per-call payment
  • a historical or real-time feed: it returns one snapshot per call, with no price history or streaming updates
  • a price oracle or advisor: no currency conversion, valuation, predictions or investment advice

Other limits:

  • Only collections that exist on OpenSea can be queried, and the input must be the OpenSea slug.
  • Some fields can be missing or null for some collections.
  • Data is sourced from OpenSea and reported as returned; the server does not verify or correct it.
  • The server runs over stdio in a local MCP client and needs internet access and a funded wallet for every non-cached call.

Related Skills