Skip to main content
Glama
bmurdock

Scryfall MCP Server

by bmurdock

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
NameRequiredDescriptionDefault
color_identityNoColor identity filter (e.g., "wr", "grixis", "colorless")
formatYesMagic format to analyze
limitNoNumber of results to return
max_priceNoMaximum price in USD
roleNoCard role in deck archetypes
tierNoMeta tier levelcompetitive

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
      };
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bmurdock/scryfall-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server