search_tokens
Search for SRC-20 tokens using filters like ticker, deployer, holders, and minted percentage. Sort and paginate results via the Stampchain MCP Server.
Instructions
Search for SRC-20 tokens with various filtering criteria
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| deployer | No | Filter by deployer address | |
| min_holders | No | Minimum number of holders | |
| min_percent_minted | No | Minimum percent minted | |
| page | No | Page number | |
| page_size | No | Items per page | |
| query | No | Search query for token ticker | |
| sort_by | No | Sort field (Note: only deploy_timestamp is supported by the API) | deploy_timestamp |
| sort_order | No | Sort order | DESC |
Implementation Reference
- src/tools/tokens.ts:230-353 (handler)The main handler function for the search_tokens tool. Validates input, constructs API query, calls stampchain API's searchTokens, applies client-side filtering if needed, formats results into table and detailed view, includes metadata.public async execute(params: SearchTokensParams, context?: ToolContext): Promise<ToolResponse> { try { context?.logger?.info('Executing search_tokens tool', { params }); // Validate parameters const validatedParams = this.validateParams(params); // Build query parameters const queryParams = { query: validatedParams.query, deployer: validatedParams.deployer, sort_by: validatedParams.sort_by, sort_order: validatedParams.sort_order, page: validatedParams.page, page_size: validatedParams.page_size, }; // Remove undefined values Object.keys(queryParams).forEach((key) => { if (queryParams[key as keyof typeof queryParams] === undefined) { delete queryParams[key as keyof typeof queryParams]; } }); // Search tokens const searchResponse = await this.apiClient.searchTokens(queryParams); if (!searchResponse || searchResponse.length === 0) { return textResponse('No tokens found matching the search criteria'); } // Note: searchTokens returns TokenResponse[] directly const tokens = searchResponse; // Note: Client-side filtering for unsupported API fields let filteredTokens = tokens; if ( validatedParams.min_holders !== undefined || validatedParams.min_percent_minted !== undefined ) { // These fields are not available in the current API response // Filtering will be skipped and a note will be added to the output filteredTokens = tokens; } // Create summary const lines = [`Found ${filteredTokens.length} tokens`]; lines.push('---'); // Create table view const tokenTable = createTable(filteredTokens, [ { key: 'tick', label: 'Ticker' }, { key: 'max', label: 'Max Supply' }, { key: 'lim', label: 'Mint Limit' }, { key: 'deci', label: 'Decimals' }, { key: 'creator', label: 'Creator', format: (v: unknown) => (typeof v === 'string' ? v.substring(0, 8) + '...' : String(v)), }, ]); lines.push(tokenTable); // Add detailed view for top tokens lines.push('\n\nDetailed View (Top 5):'); lines.push('---'); filteredTokens.slice(0, 5).forEach((token, index) => { lines.push(`\n${index + 1}. ${token.tick}`); lines.push(` Protocol: ${token.p} | Operation: ${token.op}`); lines.push(` Max Supply: ${token.max}`); if (token.lim) { lines.push(` Mint Limit: ${token.lim}`); } if (token.deci !== undefined) { lines.push(` Decimals: ${token.deci}`); } lines.push(` Creator: ${token.creator}`); lines.push(` Block Index: ${token.block_index}`); lines.push(` Block Time: ${new Date(token.block_time).toLocaleString()}`); if (token.creator_name) { lines.push(` Creator Name: ${token.creator_name}`); } if (token.destination_name) { lines.push(` Destination: ${token.destination_name}`); } }); // Include metadata const metadata = { results_count: filteredTokens.length, query_params: queryParams, note: 'Pagination and holder/minting statistics are not available in the current API response', additional_filters: { min_holders: validatedParams.min_holders, min_percent_minted: validatedParams.min_percent_minted, }, }; // Add note about unsupported filters if ( validatedParams.min_holders !== undefined || validatedParams.min_percent_minted !== undefined ) { lines.push( '\n⚠️ Note: Holder and minting percentage filters are not supported by the current API and have been ignored.' ); } return multiResponse( { type: 'text', text: lines.join('\n') }, { type: 'text', text: `\n\nSearch Metadata:\n${JSON.stringify(metadata, null, 2)}` } ); } catch (error) { context?.logger?.error('Error executing search_tokens tool', { error }); if (error instanceof ValidationError) { throw error; } throw new ToolExecutionError('Failed to search tokens', this.name, error); } }
- src/schemas/tokens.ts:122-135 (schema)Zod schema defining the input parameters and validation for the search_tokens tool.export const SearchTokensParamsSchema = z.object({ query: z.string().optional().describe('Search query for token ticker'), deployer: z.string().optional().describe('Filter by deployer address'), min_holders: z.number().int().nonnegative().optional().describe('Minimum number of holders'), min_percent_minted: z.number().min(0).max(100).optional().describe('Minimum percent minted'), sort_by: z .enum(['deploy_timestamp', 'holders', 'percent_minted']) .optional() .default('deploy_timestamp') .describe('Sort field'), sort_order: z.enum(['ASC', 'DESC']).optional().default('DESC').describe('Sort order'), page: z.number().int().positive().optional().default(1).describe('Page number'), page_size: z.number().int().positive().max(100).optional().default(20).describe('Items per page'), });
- src/tools/tokens.ts:367-372 (registration)Factory function that instantiates and registers the SearchTokensTool instance for use in tool registry.export function createTokenTools(apiClient?: StampchainClient) { return { get_token_info: new GetTokenInfoTool(apiClient), search_tokens: new SearchTokensTool(apiClient), }; }
- src/tools/index.ts:93-97 (registration)Tool metadata registration listing 'search_tokens' as part of the tokens category.tokens: { category: 'SRC-20 Tokens', description: 'Tools for SRC-20 token information', tools: ['get_token_info', 'search_tokens'], },
- src/tools/index.ts:47-70 (registration)Central list of all available tool names including 'search_tokens' for discovery and registration.export function getAvailableToolNames(): string[] { return [ // Stamp tools 'get_stamp', 'search_stamps', 'get_recent_stamps', 'get_recent_sales', 'get_market_data', 'get_stamp_market_data', // Collection tools 'get_collection', 'search_collections', // Token tools 'get_token_info', 'search_tokens', // Analysis tools 'analyze_stamp_code', 'get_stamp_dependencies', 'analyze_stamp_patterns', ]; }