get_sip009_collection_info
Retrieve SIP-009 NFT collection details including total supply and last token ID by providing contract address, name, and network.
Instructions
Get information about a SIP-009 NFT collection including total supply and last token ID.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| contractAddress | Yes | The contract address | |
| contractName | Yes | The contract name of the SIP-009 NFT collection | |
| network | Yes | The Stacks network |
Implementation Reference
- The complete tool definition and handler (execute function) for 'get_sip009_collection_info'. It calls read-only functions on the contract via Hiro API to get last token ID and optional collection info, then formats a markdown response with collection statistics.export const getSIP009CollectionInfoTool: Tool<undefined, typeof SIP009CollectionInfoScheme> = { name: "get_sip009_collection_info", description: "Get information about a SIP-009 NFT collection including total supply and last token ID.", parameters: SIP009CollectionInfoScheme, execute: async (args, context) => { try { await recordTelemetry({ action: "get_sip009_collection_info" }, context); // Get collection information const lastTokenIdResult = await callReadOnlyFunction( args.contractAddress, args.contractName, "get-last-token-id", [], args.network ); const lastTokenId = lastTokenIdResult.okay ? parseInt(lastTokenIdResult.result.replace('u', '')) : 0; // Try to get additional collection info if available let collectionInfo = null; try { const collectionInfoResult = await callReadOnlyFunction( args.contractAddress, args.contractName, "get-collection-info", [], args.network ); if (collectionInfoResult.okay) { collectionInfo = collectionInfoResult.result; } } catch { // Collection info function may not exist } return `# SIP-009 NFT Collection Information **Contract**: ${args.contractAddress}.${args.contractName} **Network**: ${args.network} ## Collection Stats - **Total Supply**: ${lastTokenId} NFTs - **Last Token ID**: ${lastTokenId} - **Token ID Range**: 1 to ${lastTokenId} ${collectionInfo ? ` ## Additional Collection Details ${collectionInfo} ` : ''} ## Contract Verification ✅ This contract implements the SIP-009 NFT standard trait. ## Integration Notes - All token IDs start from 1 (SIP-009 requirement) - Use get_sip009_token_info to get details for specific tokens - Post-conditions are mandatory for all transfers`; } catch (error) { return `❌ Failed to get SIP-009 collection info: ${error}`; } },
- Zod schema defining the input parameters: contractAddress, contractName, and network (mainnet/testnet/devnet).const SIP009CollectionInfoScheme = z.object({ contractAddress: z.string().describe("The contract address"), contractName: z.string().describe("The contract name of the SIP-009 NFT collection"), network: NetworkScheme.describe("The Stacks network"), });
- src/tools/index.ts:55-55 (registration)Registration of the tool in the FastMCP server using server.addTool().server.addTool(getSIP009CollectionInfoTool);
- src/tools/index.ts:11-16 (registration)Import statement that brings the getSIP009CollectionInfoTool into the index file for registration.import { getSIP009TokenInfoTool, getSIP009CollectionInfoTool, generateSIP009TransferTool, generateSIP009TemplateTool } from "./stacks_blockchain/tokens/sip009_nft.js";
- Helper function used by the handler to call read-only Clarity functions on the contract via Hiro Systems API.async function callReadOnlyFunction( contractAddress: string, contractName: string, functionName: string, functionArgs: any[], network: string ): Promise<any> { const apiUrl = network === "mainnet" ? "https://api.hiro.so" : "https://api.testnet.hiro.so"; try { const response = await fetch( `${apiUrl}/v2/contracts/call-read/${contractAddress}/${contractName}/${functionName}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ sender: contractAddress, arguments: functionArgs, }), } ); if (!response.ok) { const data: any = await response.json(); throw new Error(data.error || `HTTP ${response.status}`); } return await response.json(); } catch (error) { throw new Error(`Failed to call ${functionName}: ${error}`); } }