Skip to main content
Glama

search_sets

Find Magic: The Gathering sets by name, type, or release date using partial matches and optional filters for precise results.

Instructions

Search for Magic: The Gathering sets with optional filtering by name, type, and release dates

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSet name or code to search for (partial matches supported)
released_afterNoISO date string - only show sets released after this date (YYYY-MM-DD)
released_beforeNoISO date string - only show sets released before this date (YYYY-MM-DD)
typeNoFilter by set type. Common types: core (yearly core sets), expansion (rotational sets), masters (reprint sets), commander (preconstructed Commander decks), promo (promotional cards), token (tokens and emblems)

Implementation Reference

  • SearchSetsTool class: defines the tool name, description, inputSchema, and the execute method that handles parameter validation, date validation, Scryfall API call via scryfallClient.getSets, result formatting with formatSetsAsText, and error handling.
    export class SearchSetsTool { readonly name = 'search_sets'; readonly description = 'Search for Magic: The Gathering sets with optional filtering by name, type, and release dates'; readonly inputSchema = { type: 'object' as const, properties: { query: { type: 'string', description: 'Set name or code to search for (partial matches supported)' }, type: { type: 'string', enum: SET_TYPES, description: 'Filter by set type. Common types: core (yearly core sets), expansion (rotational sets), masters (reprint sets), commander (preconstructed Commander decks), promo (promotional cards), token (tokens and emblems)' }, released_after: { type: 'string', description: 'ISO date string - only show sets released after this date (YYYY-MM-DD)', pattern: '^\\d{4}-\\d{2}-\\d{2}$' }, released_before: { type: 'string', description: 'ISO date string - only show sets released before this date (YYYY-MM-DD)', pattern: '^\\d{4}-\\d{2}-\\d{2}$' } }, required: [] }; constructor(private readonly scryfallClient: ScryfallClient) {} async execute(args: unknown) { try { // Validate parameters const params = validateSearchSetsParams(args); // Validate date strings if provided if (params.released_after) { validateDateString(params.released_after); } if (params.released_before) { validateDateString(params.released_before); } // Validate date range logic if (params.released_after && params.released_before) { const afterDate = new Date(params.released_after); const beforeDate = new Date(params.released_before); if (afterDate >= beforeDate) { throw new ValidationError('released_after date must be before released_before date'); } } // Execute sets search const sets = await this.scryfallClient.getSets({ query: params.query, type: params.type, released_after: params.released_after, released_before: params.released_before }); // Handle no results if (sets.length === 0) { let message = 'No sets found'; const filters = []; if (params.query) filters.push(`name/code: "${params.query}"`); if (params.type) filters.push(`type: ${params.type}`); if (params.released_after) filters.push(`released after: ${params.released_after}`); if (params.released_before) filters.push(`released before: ${params.released_before}`); if (filters.length > 0) { message += ` matching criteria (${filters.join(', ')})`; } message += '. Try broadening your search criteria.'; return { content: [ { type: 'text', text: message } ] }; } // Format sets for display const responseText = formatSetsAsText(sets); // Add search context let contextNote = ''; const appliedFilters = []; if (params.query) appliedFilters.push(`name/code: "${params.query}"`); if (params.type) appliedFilters.push(`type: ${params.type}`); if (params.released_after) appliedFilters.push(`released after: ${params.released_after}`); if (params.released_before) appliedFilters.push(`released before: ${params.released_before}`); if (appliedFilters.length > 0) { contextNote = `\n\n*Filtered by: ${appliedFilters.join(', ')}*`; } return { content: [ { type: 'text', text: responseText + contextNote } ] }; } catch (error) { // Handle different error types if (error instanceof ValidationError) { return { content: [ { type: 'text', text: `Validation error: ${error.message}` } ], isError: true }; } if (error instanceof RateLimitError) { const retry = error.retryAfter ? ` Retry after ${error.retryAfter}s.` : ''; return { content: [{ type: 'text', text: `Rate limit exceeded.${retry} Please wait and try again.` }], isError: true }; } if (error instanceof ScryfallAPIError) { let errorMessage = `Scryfall API error: ${error.message}`; if (error.status === 404) { errorMessage = 'No sets found. The Scryfall sets database may be temporarily unavailable.'; } else if (error.status === 429) { errorMessage = 'Rate limit exceeded. Please wait a moment and try again.'; } 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 }; } } }
  • src/server.ts:70-70 (registration)
    Registration of the search_sets tool in the MCP server's tools Map during constructor initialization.
    this.tools.set("search_sets", new SearchSetsTool(this.scryfallClient));
  • Zod schema definition for SearchSetsParams used in input validation by the validator function.
    export const SearchSetsParamsSchema = z.object({ query: z.string().optional(), type: z .enum(["core", "expansion", "masters", "commander", "draft_innovation", "funny"]) .optional(), released_after: z.string().datetime().optional(), released_before: z.string().datetime().optional(), });
  • Helper function to validate tool input parameters using the SearchSetsParamsSchema, throwing ValidationError on failure.
    export function validateSearchSetsParams(params: unknown) { try { return SearchSetsParamsSchema.parse(params); } catch (error) { if (error instanceof z.ZodError) { const firstError = error.errors[0]; throw new ValidationError( `Invalid parameter '${firstError.path.join(".")}': ${firstError.message}`, firstError.path.join(".") ); } throw error; }

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