getNFTInfo
Retrieve detailed information about NFTs from a specified ERC721 contract using an Ethereum provider. Query metadata, ownership, and other key attributes to manage and analyze NFT collections.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chainId | No | Optional. The chain ID to use. | |
| contractAddress | Yes | The address of the ERC721 contract | |
| provider | No | Optional. The provider to use. If not provided, the default provider is used. |
Implementation Reference
- src/tools/erc721.ts:106-140 (registration)Registers the 'getNFTInfo' MCP tool with the server, including description, input schema, and inline handler function that calls EthersService to get collection info and formats the response."getNFTInfo", "Get information about an ERC721 NFT collection including its name, symbol, and total supply. Provides basic details about the NFT contract.", { contractAddress: contractAddressSchema.describe("The address of the ERC721 contract"), provider: providerSchema.describe("Optional. The provider to use. If not provided, the default provider is used."), chainId: chainIdSchema.describe("Optional. The chain ID to use.") }, async (params) => { try { const info = await ethersService.getERC721CollectionInfo( params.contractAddress, params.provider, params.chainId ); return { content: [{ type: "text", text: `NFT Information: Name: ${info.name} Symbol: ${info.symbol} Total Supply: ${info.totalSupply}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `Error getting NFT information: ${error instanceof Error ? error.message : String(error)}` }] }; } } );
- src/tools/erc721.ts:41-45 (schema)TypeScript type definition for GetNFTInfoParams used in the tool.type GetNFTInfoParams = { contractAddress: string; provider?: string; chainId?: number; };
- src/services/erc/erc721.ts:35-125 (handler)Helper function getNFTInfo that implements the core logic for retrieving ERC721 collection information (name, symbol, totalSupply) with caching, rate limiting, metrics, and comprehensive error handling. Likely used by EthersService.getERC721CollectionInfo.export async function getNFTInfo( ethersService: EthersService, contractAddress: string, provider?: string, chainId?: number ): Promise<ERC721Info> { metrics.incrementCounter('erc721.getNFTInfo'); return timeAsync('erc721.getNFTInfo', async () => { try { // Check rate limiting const identity = `${contractAddress}:${provider || 'default'}`; if (!rateLimiter.consume('token', identity)) { throw new ERC721Error('Rate limit exceeded for NFT operations'); } // Create cache key const cacheKey = createTokenCacheKey( CACHE_KEYS.ERC721_INFO, contractAddress, chainId ); // Check cache first const cachedInfo = contractCache.get(cacheKey); if (cachedInfo) { return cachedInfo as ERC721Info; } // Get provider from ethers service const ethersProvider = ethersService['getProvider'](provider, chainId); // Check if address is contract const code = await ethersProvider.getCode(contractAddress); if (code === '0x' || code === '0x0') { throw new TokenNotFoundError(contractAddress); } // Create contract instance const contract = new ethers.Contract(contractAddress, ERC721_ABI, ethersProvider); // Fetch NFT information - some contracts might not implement all methods let name = ''; let symbol = ''; let totalSupply: string | undefined = undefined; try { name = await contract.name(); } catch (error) { logger.debug('Error getting NFT name', { contractAddress, error }); name = 'Unknown Collection'; } try { symbol = await contract.symbol(); } catch (error) { logger.debug('Error getting NFT symbol', { contractAddress, error }); symbol = 'NFT'; } try { // totalSupply is optional in ERC721 const supplyBigInt = await contract.totalSupply(); totalSupply = supplyBigInt.toString(); } catch (error) { // totalSupply function is not required in ERC721, so ignore errors logger.debug('NFT contract does not implement totalSupply', { contractAddress }); } // Format data const nftInfo: ERC721Info = { name, symbol, totalSupply }; // Cache result for future use (1 hour TTL) contractCache.set(cacheKey, nftInfo, { ttl: 3600000 }); return nftInfo; } catch (error) { logger.debug('Error getting ERC721 NFT info', { contractAddress, error }); if (error instanceof TokenNotFoundError) { throw error; } throw handleTokenError(error, 'Failed to get NFT collection information'); } }); }
- src/tools/erc721.ts:26-140 (helper)Zod schemas used to validate input parameters for the getNFTInfo tool (contractAddress, provider, chainId).const contractAddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/); const providerSchema = z.string().optional(); const chainIdSchema = z.number().optional(); const tokenIdSchema = z.union([z.string(), z.number()]); const addressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/); const gasOptionsSchema = z.object({ gasLimit: z.number().optional(), gasPrice: z.number().optional(), maxFeePerGas: z.number().optional(), maxPriorityFeePerGas: z.number().optional(), nonce: z.number().optional(), value: z.string().optional() }).optional(); // Parameter types type GetNFTInfoParams = { contractAddress: string; provider?: string; chainId?: number; }; type GetNFTOwnerParams = { contractAddress: string; tokenId: string | number; provider?: string; chainId?: number; }; type GetNFTTokenURIParams = { contractAddress: string; tokenId: string | number; provider?: string; chainId?: number; }; type GetNFTMetadataParams = { contractAddress: string; tokenId: string | number; provider?: string; chainId?: number; }; type TransferNFTParams = { contractAddress: string; tokenId: string | number; from: string; to: string; provider?: string; chainId?: number; gasOptions?: TokenOperationOptions; }; type ApproveNFTParams = { contractAddress: string; tokenId: string | number; owner: string; approved: string; provider?: string; chainId?: number; gasOptions?: TokenOperationOptions; }; type SetNFTApprovalForAllParams = { contractAddress: string; owner: string; operator: string; approved: boolean; provider?: string; chainId?: number; gasOptions?: TokenOperationOptions; }; /** * Register ERC721 tools with the MCP server */ export function registerERC721Tools(server: McpServer, ethersService: EthersService) { silentLogger.debug('Registering ERC721 tools'); // Get NFT Info server.tool( "getNFTInfo", "Get information about an ERC721 NFT collection including its name, symbol, and total supply. Provides basic details about the NFT contract.", { contractAddress: contractAddressSchema.describe("The address of the ERC721 contract"), provider: providerSchema.describe("Optional. The provider to use. If not provided, the default provider is used."), chainId: chainIdSchema.describe("Optional. The chain ID to use.") }, async (params) => { try { const info = await ethersService.getERC721CollectionInfo( params.contractAddress, params.provider, params.chainId ); return { content: [{ type: "text", text: `NFT Information: Name: ${info.name} Symbol: ${info.symbol} Total Supply: ${info.totalSupply}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `Error getting NFT information: ${error instanceof Error ? error.message : String(error)}` }] }; } } );