Skip to main content
Glama
bmurdock

Scryfall MCP Server

by bmurdock

validate_brawl_commander

Check if a Magic: The Gathering card is valid as a commander in Brawl or Standard Brawl formats using Scryfall MCP Server integration.

Instructions

Validate if a card can be a legal commander in Brawl or Standard Brawl formats

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
card_identifierYesCard name, set code+collector number, or Scryfall ID to validate
formatYesBrawl format to validate for (brawl = Historic Brawl, standardbrawl = Standard Brawl)

Implementation Reference

  • The main execute method that handles tool invocation: validates inputs, fetches card data from Scryfall, performs commander validation, formats detailed response with eligibility checks and deck constraints, handles various errors.
    async execute(args: unknown) {
      try {
        // Validate parameters
        const params = this.validateParams(args);
    
        // Validate card identifier format
        validateCardIdentifier(params.card_identifier);
    
        // Fetch card data
        const card = await this.scryfallClient.getCard({ identifier: params.card_identifier });
        const formattedCard = formatCard(card);
    
        // Validate commander eligibility
        const validation = this.validateCommander(formattedCard, params.format);
    
        // Format response
        let responseText = `**Brawl Commander Validation: ${formattedCard.name}**\n\n`;
        responseText += `**Format:** ${params.format === 'brawl' ? 'Historic Brawl (100 cards)' : 'Standard Brawl (60 cards)'}\n`;
        responseText += `**Card Type:** ${formattedCard.type_line}\n`;
        responseText += `**Color Identity:** ${formattedCard.color_identity?.join('') || 'Colorless'}\n`;
        responseText += `**Arena Availability:** ${validation.arenaAvailable ? '✅ Available' : '❌ Not Available'}\n`;
        responseText += `**Format Legality:** ${validation.formatLegal ? '✅ Legal' : '❌ Not Legal'}\n`;
        responseText += `**Commander Eligible:** ${validation.commanderEligible ? '✅ Yes' : '❌ No'}\n\n`;
    
        if (validation.isValid) {
          responseText += `✅ **VALID COMMANDER**\n\n`;
          responseText += `${formattedCard.name} can be used as a commander in ${params.format === 'brawl' ? 'Historic Brawl' : 'Standard Brawl'}.\n\n`;
          responseText += `**Deck Building Constraints:**\n`;
          responseText += `- Deck size: ${params.format === 'brawl' ? '100' : '60'} cards (including commander)\n`;
          responseText += `- Color identity: ${formattedCard.color_identity?.join('') || 'Colorless'} only\n`;
          responseText += `- Card pool: ${params.format === 'brawl' ? 'Historic-legal' : 'Standard-legal'} cards\n`;
          responseText += `- Platform: Arena only\n`;
          responseText += `- Singleton: No duplicates except basic lands\n`;
        } else {
          responseText += `❌ **INVALID COMMANDER**\n\n`;
          responseText += `**Issues Found:**\n`;
          validation.issues.forEach(issue => {
            responseText += `- ${issue}\n`;
          });
        }
    
        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
          };
        }
    
        // Handle API errors
        if (error instanceof ScryfallAPIError) {
          let errorMessage = `Scryfall API error: ${error.message}`;
          
          if (error.status === 404) {
            errorMessage = `Card not found: "${(args as any)?.card_identifier || 'unknown'}". Please check the card name or identifier.`;
          }
    
          return {
            content: [
              {
                type: 'text',
                text: errorMessage
              }
            ],
            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 required parameters: card_identifier (string) and format (enum ['brawl', 'standardbrawl']).
    readonly inputSchema = {
      type: 'object' as const,
      properties: {
        card_identifier: {
          type: 'string',
          description: 'Card name, set code+collector number, or Scryfall ID to validate'
        },
        format: {
          type: 'string',
          enum: ['brawl', 'standardbrawl'],
          description: 'Brawl format to validate for (brawl = Historic Brawl, standardbrawl = Standard Brawl)'
        }
      },
      required: ['card_identifier', 'format']
    };
  • src/server.ts:76-76 (registration)
    Tool registration in the MCP server's tools Map, instantiating ValidateBrawlCommanderTool with ScryfallClient.
    this.tools.set("validate_brawl_commander", new ValidateBrawlCommanderTool(this.scryfallClient));
  • Core validation helper: checks if card is legendary creature/planeswalker, format-legal, Arena-available; returns validation result with issues list.
    private validateCommander(card: any, format: 'brawl' | 'standardbrawl'): {
      isValid: boolean;
      commanderEligible: boolean;
      formatLegal: boolean;
      arenaAvailable: boolean;
      issues: string[];
    } {
      const issues: string[] = [];
      let commanderEligible = false;
      let formatLegal = false;
      let arenaAvailable = false;
    
      // Check if card is legendary
      const isLegendary = card.type_line?.toLowerCase().includes('legendary') || false;
      
      // Check if card is a creature or planeswalker
      const isCreature = card.type_line?.toLowerCase().includes('creature') || false;
      const isPlaneswalker = card.type_line?.toLowerCase().includes('planeswalker') || false;
      
      commanderEligible = isLegendary && (isCreature || isPlaneswalker);
      
      if (!isLegendary) {
        issues.push('Card must be legendary');
      }
      if (!isCreature && !isPlaneswalker) {
        issues.push('Card must be a creature or planeswalker');
      }
    
      // Check format legality
      const legalities = card.legalities || {};
      formatLegal = legalities[format] === 'legal';
      
      if (!formatLegal) {
        issues.push(`Card is not legal in ${format} (status: ${legalities[format] || 'unknown'})`);
      }
    
      // Check Arena availability
      const games = card.games || [];
      arenaAvailable = games.includes('arena');
      
      if (!arenaAvailable) {
        issues.push('Card is not available in Arena');
      }
    
      const isValid = commanderEligible && formatLegal && arenaAvailable;
    
      return {
        isValid,
        commanderEligible,
        formatLegal,
        arenaAvailable,
        issues
      };
    }
  • Input parameter validation helper: checks types, required fields, valid format enum, trims card_identifier.
    private validateParams(args: unknown): {
      card_identifier: string;
      format: 'brawl' | 'standardbrawl';
    } {
      if (!args || typeof args !== 'object') {
        throw new ValidationError('Invalid parameters');
      }
    
      const params = args as any;
    
      if (!params.card_identifier || typeof params.card_identifier !== 'string') {
        throw new ValidationError('Card identifier is required and must be a string');
      }
    
      if (!params.format || typeof params.format !== 'string') {
        throw new ValidationError('Format is required and must be a string');
      }
    
      const validFormats = ['brawl', 'standardbrawl'];
      if (!validFormats.includes(params.format)) {
        throw new ValidationError(`Format must be one of: ${validFormats.join(', ')}`);
      }
    
      return {
        card_identifier: params.card_identifier.trim(),
        format: params.format as 'brawl' | 'standardbrawl'
      };
    }

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