Skip to main content
Glama
bmurdock

Scryfall MCP Server

by bmurdock

build_scryfall_query

Transform natural language into optimized Scryfall search queries for Magic: The Gathering cards. Specify formats, budget, and optimization strategies to get precise or broad results with explanations and alternatives.

Instructions

Convert natural language requests into optimized Scryfall search queries with explanations and alternatives

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
explain_mappingNoWhether to include detailed explanation of natural language to Scryfall mapping
formatNoMagic format to restrict search to (optional)
include_alternativesNoWhether to include alternative query suggestions
max_resultsNoTarget number of results for optimization
natural_queryYesNatural language description of what you want to find (e.g., "red creatures under $5 for aggressive decks", "blue counterspells in modern")
optimize_forNoSearch optimization strategy: precision (fewer, more relevant results), recall (broader search), discovery (interesting cards), budget (cost-effective)precision
price_budgetNoPrice constraints for the search
test_queryNoWhether to test the generated query and optimize based on results

Implementation Reference

  • The main execute method implementing the tool logic: validates input, parses natural language, builds and tests Scryfall query, formats response.
    async execute(args: unknown) {
      try {
        // Validate input parameters
        const params = validateBuildQueryParams(args);
        
        // Sanitize natural language input (using a more permissive approach for natural language)
        const sanitizedQuery = params.natural_query.trim()
          // eslint-disable-next-line no-control-regex
          .replace(/[\x00-\x1F\x7F-\x9F]/g, '') // Remove control characters
          .substring(0, 500); // Enforce max length
        
        if (!sanitizedQuery) {
          throw new ValidationError('Natural query cannot be empty after sanitization');
        }
        
        // Parse natural language
        const parsed = this.parser.parse(sanitizedQuery, {
          targetFormat: params.format,
          optimizationStrategy: params.optimize_for,
          maxResults: params.max_results
        });
        
        // Check parsing confidence
        if (parsed.confidence < 0.3) {
          return this.handleLowConfidenceParsing(parsed, params);
        }
        
        // Build Scryfall query
        const buildOptions = {
          optimize_for: params.optimize_for,
          format: params.format,
          max_results: params.max_results,
          price_budget: params.price_budget
        };
        
        const buildResult = await this.queryBuilder.build(parsed, buildOptions);
        
        // Test query if requested (sanitize the generated query before testing)
        let testResult;
        if (params.test_query) {
          const sanitizedTestQuery = sanitizeQuery(buildResult.query);
          testResult = await this.testQuery(sanitizedTestQuery);
        }
        
        // Format response
        const responseText = this.formatResponse(
          buildResult,
          testResult,
          params,
          parsed
        );
        
        return {
          content: [{
            type: 'text',
            text: responseText
          }]
        };
    
      } catch (error) {
        return this.handleError(error);
      }
    }
  • Input schema defining parameters for the build_scryfall_query tool, including natural_query, format, optimization options, etc.
    readonly inputSchema = {
      type: 'object' as const,
      properties: {
        natural_query: {
          type: 'string',
          description: 'Natural language description of what you want to find (e.g., "red creatures under $5 for aggressive decks", "blue counterspells in modern")',
          minLength: 1,
          maxLength: 500
        },
        format: {
          type: 'string',
          enum: ['standard', 'modern', 'legacy', 'vintage', 'commander', 'pioneer', 'brawl', 'pauper', 'penny', 'historic', 'alchemy'],
          description: 'Magic format to restrict search to (optional)'
        },
        optimize_for: {
          type: 'string',
          enum: ['precision', 'recall', 'discovery', 'budget'],
          default: 'precision',
          description: 'Search optimization strategy: precision (fewer, more relevant results), recall (broader search), discovery (interesting cards), budget (cost-effective)'
        },
        max_results: {
          type: 'number',
          minimum: 1,
          maximum: 175,
          default: 20,
          description: 'Target number of results for optimization'
        },
        price_budget: {
          type: 'object',
          properties: {
            max: {
              type: 'number',
              minimum: 0,
              description: 'Maximum price per card'
            },
            currency: {
              type: 'string',
              enum: ['usd', 'eur', 'tix'],
              default: 'usd',
              description: 'Currency for price constraints'
            }
          },
          description: 'Price constraints for the search'
        },
        include_alternatives: {
          type: 'boolean',
          default: true,
          description: 'Whether to include alternative query suggestions'
        },
        explain_mapping: {
          type: 'boolean',
          default: true,
          description: 'Whether to include detailed explanation of natural language to Scryfall mapping'
        },
        test_query: {
          type: 'boolean',
          default: true,
          description: 'Whether to test the generated query and optimize based on results'
        }
      },
      required: ['natural_query']
    };
  • src/server.ts:77-77 (registration)
    Registration of the BuildScryfallQueryTool instance in the server's tools map under the name 'build_scryfall_query'.
    this.tools.set("build_scryfall_query", new BuildScryfallQueryTool(this.scryfallClient));
  • Class definition with tool name and description.
    export class BuildScryfallQueryTool {
      readonly name = 'build_scryfall_query';
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. While it mentions the tool generates 'optimized Scryfall search queries with explanations and alternatives,' it doesn't describe what 'optimized' means operationally, whether it makes external API calls to Scryfall, what rate limits might apply, or what the output format looks like. For a complex 8-parameter tool with no annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that clearly states the tool's purpose and key features. Every word earns its place - 'convert,' 'natural language requests,' 'optimized Scryfall search queries,' 'explanations,' and 'alternatives' all contribute essential information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 8 parameters, no annotations, and no output schema, the description is inadequate. It doesn't explain what the tool actually returns (just that it generates queries 'with explanations and alternatives'), doesn't address behavioral aspects like whether it makes live API calls, and provides no guidance on error conditions or limitations. The 100% schema coverage helps with parameters but doesn't compensate for missing behavioral and output context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 8 parameters thoroughly. The description adds no specific parameter information beyond what's in the schema. The baseline score of 3 is appropriate when the schema does all the parameter documentation work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('convert natural language requests into optimized Scryfall search queries') and the resource involved (Scryfall queries). It distinguishes from siblings by focusing on query generation rather than direct card searching (like search_cards) or analysis (like analyze_deck_composition). The inclusion of 'with explanations and alternatives' adds valuable differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context (natural language to query conversion) but doesn't explicitly state when to use this tool versus alternatives like search_cards or search_alternatives. It suggests this is for users who want to translate human descriptions into formal queries, but lacks explicit guidance on when this approach is preferred over direct querying.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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