search_format_staples
Identify meta-relevant cards for Magic: The Gathering formats, filtered by role, tier, color, and price. Optimize deckbuilding with targeted card recommendations for competitive play.
Instructions
Find format staples, meta cards, and role-specific cards for competitive play
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| color_identity | No | Color identity filter (e.g., "wr", "grixis", "colorless") | |
| format | Yes | Magic format to analyze | |
| limit | No | Number of results to return | |
| max_price | No | Maximum price in USD | |
| role | No | Card role in deck archetypes | |
| tier | No | Meta tier level | competitive |
Implementation Reference
- The main handler method that validates input, builds Scryfall search query based on format staples parameters, executes the search, formats results as text, and handles errors.async execute(args: unknown) { try { // Validate parameters const params = this.validateParams(args); // Build search query const query = this.buildSearchQuery(params); // Execute search const results = await this.scryfallClient.searchCards({ query, limit: params.limit, order: this.getOrderForTier(params.tier) }); // Format results const responseText = formatSearchResultsAsText(results); return { content: [ { type: 'text', text: responseText } ] }; } catch (error) { // Handle validation errors if (error instanceof ValidationError) { return { content: [ { type: 'text', text: `Validation error: ${error.message}` } ], isError: true }; } // Generic error handling return { content: [ { type: 'text', text: `Unexpected error: ${error instanceof Error ? error.message : 'Unknown error occurred'}` } ], isError: true }; } }
- Input schema defining parameters for format, tier, role, color identity, max price, and limit. Requires 'format'.readonly inputSchema = { type: 'object' as const, properties: { format: { type: 'string', enum: ['standard', 'modern', 'legacy', 'vintage', 'commander', 'pioneer', 'brawl', 'standardbrawl'], description: 'Magic format to analyze' }, tier: { type: 'string', enum: ['top', 'competitive', 'budget', 'fringe'], default: 'competitive', description: 'Meta tier level' }, role: { type: 'string', enum: ['removal', 'threats', 'utility', 'lands', 'ramp', 'draw', 'counterspells'], description: 'Card role in deck archetypes' }, color_identity: { type: 'string', description: 'Color identity filter (e.g., "wr", "grixis", "colorless")' }, max_price: { type: 'number', minimum: 0, description: 'Maximum price in USD' }, limit: { type: 'number', default: 20, minimum: 1, maximum: 100, description: 'Number of results to return' } }, required: ['format'] };
- src/server.ts:72-72 (registration)Registration of the SearchFormatStaplesTool instance in the tools Map using the name 'search_format_staples'.this.tools.set("search_format_staples", new SearchFormatStaplesTool(this.scryfallClient));
- Helper method to construct the Scryfall search query string based on input parameters including format, role, colors, price, and tier filters.private buildSearchQuery(params: { format: string; tier: string; role?: string; color_identity?: string; max_price?: number; }): string { let query = `f:${params.format}`; // Add role-specific search terms if (params.role) { query += ` ${this.getRoleSearchTerms(params.role)}`; } // Add color identity filter if (params.color_identity) { query += ` ${this.getColorIdentityFilter(params.color_identity)}`; } // Add price filter if (params.max_price !== undefined) { query += ` usd<=${params.max_price}`; } // Add tier-specific filters query += ` ${this.getTierFilter(params.tier)}`; return query; }
- Helper method for input validation, checking types, required fields, enums for format/tier/role, and bounds for price/limit.private validateParams(args: unknown): { format: string; tier: string; role?: string; color_identity?: string; max_price?: number; limit: number; } { if (!args || typeof args !== 'object') { throw new ValidationError('Invalid parameters'); } const params = args as any; if (!params.format || typeof params.format !== 'string') { throw new ValidationError('Format is required and must be a string'); } const validFormats = ['standard', 'modern', 'legacy', 'vintage', 'commander', 'pioneer', 'brawl', 'standardbrawl']; if (!validFormats.includes(params.format)) { throw new ValidationError(`Format must be one of: ${validFormats.join(', ')}`); } const tier = params.tier || 'competitive'; const validTiers = ['top', 'competitive', 'budget', 'fringe']; if (!validTiers.includes(tier)) { throw new ValidationError(`Tier must be one of: ${validTiers.join(', ')}`); } if (params.role) { const validRoles = ['removal', 'threats', 'utility', 'lands', 'ramp', 'draw', 'counterspells']; if (!validRoles.includes(params.role)) { throw new ValidationError(`Role must be one of: ${validRoles.join(', ')}`); } } if (params.max_price !== undefined) { if (typeof params.max_price !== 'number' || params.max_price < 0) { throw new ValidationError('Max price must be a non-negative number'); } } const limit = params.limit || 20; if (typeof limit !== 'number' || limit < 1 || limit > 100) { throw new ValidationError('Limit must be a number between 1 and 100'); } return { format: params.format, tier, role: params.role, color_identity: params.color_identity, max_price: params.max_price, limit }; }