Search by function tag
search_by_function_tagSearch Magic: The Gathering cards by functional tags like removal or ramp to find cards that perform specific roles in gameplay.
Instructions
Find cards using Tagger function (oracle) tags, e.g. removal, ramp.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tags | Yes | ||
| match | No | any | |
| colors | No | ||
| format | No | ||
| page | No |
Output Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| total | Yes | ||
| results | Yes |
Implementation Reference
- src/mcp-server.ts:374-384 (handler)Core execution logic for the 'search_by_function_tag' tool. Builds a Scryfall search query using 'otag:' prefixed kebab-case tags, combines with color and format filters using local helpers, fetches cards via Scryfall.searchCards, summarizes results using the shared 'summarize' function, and returns structured output.
async ({ tags, match, colors = [], format, page }: { tags: string[]; match: "any" | "all"; colors?: Array<"W" | "U" | "B" | "R" | "G">; format?: string; page?: number }) => { const terms = tags.map((t) => `otag:${toKebabTag(t)}`); const joined = match === "all" ? terms.join(" ") : terms.join(" OR "); const colorPart = colors.length ? `color>=${colors.join("")}` : undefined; const formatPart = format ? `legal:${format}` : undefined; const q = joinParts([joined, colorPart, formatPart]); const data: any = (await Scryfall.searchCards({ q, page })) as any; const items: any[] = Array.isArray(data?.data) ? data.data : []; const out = { total: Number(data?.total_cards ?? items.length), results: items.map(summarize) }; return { structuredContent: out } as any; } - src/mcp-server.ts:341-365 (schema)Zod input schema defining parameters for the tool: required tags array, match mode (any/all), optional colors, format legality filter, and pagination.
const searchByFuncTagInput = { tags: z.array(z.string()).min(1), match: z.enum(["any", "all"]).default("any"), colors: z.array(z.enum(["W", "U", "B", "R", "G"])).min(0).max(5).optional(), format: z .enum([ "standard", "pioneer", "modern", "legacy", "vintage", "commander", "oathbreaker", "pauper", "paupercommander", "historic", "timeless", "alchemy", "brawl", "duel", "predh" ]) .optional(), page: z.number().int().min(1).optional() } as const; - src/mcp-server.ts:366-385 (registration)MCP server tool registration call, specifying name, metadata, input/output schemas, and inline handler function.
server.registerTool( "search_by_function_tag", { title: "Search by function tag", description: "Find cards using Tagger function (oracle) tags, e.g. removal, ramp.", inputSchema: searchByFuncTagInput, outputSchema: searchByColorsOutput }, async ({ tags, match, colors = [], format, page }: { tags: string[]; match: "any" | "all"; colors?: Array<"W" | "U" | "B" | "R" | "G">; format?: string; page?: number }) => { const terms = tags.map((t) => `otag:${toKebabTag(t)}`); const joined = match === "all" ? terms.join(" ") : terms.join(" OR "); const colorPart = colors.length ? `color>=${colors.join("")}` : undefined; const formatPart = format ? `legal:${format}` : undefined; const q = joinParts([joined, colorPart, formatPart]); const data: any = (await Scryfall.searchCards({ q, page })) as any; const items: any[] = Array.isArray(data?.data) ? data.data : []; const out = { total: Number(data?.total_cards ?? items.length), results: items.map(summarize) }; return { structuredContent: out } as any; } ); - src/tags.ts:87-89 (helper)Utility function to convert input strings to kebab-case (lowercase, hyphens), used to normalize tags for Scryfall 'otag:' queries.
export function toKebabTag(input: string): string { return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""); } - src/mcp-server.ts:99-102 (schema)Shared Zod output schema for paginated card search results (total count and array of summarized cards), referenced by search_by_function_tag.
const searchByColorsOutput = { total: z.number().int().nonnegative(), results: z.array(z.object(cardSummaryShape)) } as const;