Skip to main content
Glama

find_combos

Discover infinite combos and synergistic card combinations for Magic: The Gathering Commander decks. Search by specific cards or color identities to find win conditions with detailed steps and prerequisites.

Instructions

Find known infinite combos and synergistic card combinations from Commander Spellbook. Use this when a user asks about combos involving specific cards, combos in specific colors, or wants to find win conditions. Returns combo steps, prerequisites, and results.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
card_nameNoSingle card name to search combos for
card_namesNoMultiple card names to search combos for
color_identityNoFilter combos within this color identity (e.g. ["W","U","B"])
limitNoMax results (default 20, max 50)

Implementation Reference

  • The main handler function that executes the logic to search for combos in the database, including filtering by card names and color identity.
    export function handler(db: Database.Database, params: FindCombosParams): FindCombosResult {
      const limit = params.limit ?? 20;
    
      // Collect all card names to search for
      const searchNames: string[] = [];
      if (params.card_name) searchNames.push(params.card_name);
      if (params.card_names) searchNames.push(...params.card_names);
    
      if (searchNames.length === 0 && !params.color_identity) {
        return { combos: [], total: 0 };
      }
    
      // Build query
      let sql = 'SELECT * FROM combos';
      const conditions: string[] = [];
      const bindings: unknown[] = [];
    
      // Card name filter: search in the JSON cards array
      if (searchNames.length > 0) {
        const nameConditions = searchNames.map(() => 'LOWER(cards) LIKE LOWER(?)');
        conditions.push(`(${nameConditions.join(' AND ')})`);
        for (const name of searchNames) {
          bindings.push(`%${name}%`);
        }
      }
    
      if (conditions.length > 0) {
        sql += ' WHERE ' + conditions.join(' AND ');
      }
    
      sql += ' ORDER BY popularity DESC LIMIT ?';
      // Fetch more than limit if we need to post-filter by color identity
      const fetchLimit = params.color_identity ? limit * 5 : limit;
      bindings.push(fetchLimit);
    
      const rows = db.prepare(sql).all(...bindings) as ComboRow[];
    
      // Post-filter by color identity constraint
      let filtered = rows;
      if (params.color_identity) {
        filtered = rows.filter(row => {
          const comboColors: string[] = row.color_identity
            ? JSON.parse(row.color_identity) as string[]
            : [];
          return fitsWithinIdentity(comboColors, params.color_identity!);
        });
      }
    
      // Apply limit after filtering
      const limited = filtered.slice(0, limit);
    
      const combos: ComboResult[] = limited.map(row => ({
        id: row.id,
        cards: JSON.parse(row.cards) as string[],
        color_identity: row.color_identity ? JSON.parse(row.color_identity) as string[] : [],
        prerequisites: row.prerequisites,
        steps: row.steps,
        results: row.results,
        popularity: row.popularity,
      }));
    
      return { combos, total: combos.length };
    }
  • Zod schema definition for input validation of the find_combos tool.
    export const FindCombosInput = z.object({
      card_name: z.string().optional().describe('Single card name to search combos for'),
      card_names: z.array(z.string()).optional().describe('Multiple card names to search combos for'),
      color_identity: z.array(z.string()).optional().describe('Filter combos within this color identity (e.g. ["W","U","B"])'),
      limit: z.number().min(1).max(50).optional().describe('Max results (default 20, max 50)'),
    });
  • src/server.ts:220-230 (registration)
    Registration of the 'find_combos' MCP tool in the server implementation.
    server.tool(
      'find_combos',
      'Find known infinite combos and synergistic card combinations from Commander Spellbook. Use this when a user asks about combos involving specific cards, combos in specific colors, or wants to find win conditions. Returns combo steps, prerequisites, and results.',
      FindCombosInput.shape,
      async (params) => {
        try {
          const result = findCombosHandler(db, params);
          return { content: [{ type: 'text' as const, text: formatFindCombos(result) }] };
        } catch (err) {
          return { content: [{ type: 'text' as const, text: `Error finding combos: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
        }
  • Helper function to filter combo color identity against user-provided constraints.
    function fitsWithinIdentity(comboColors: string[], constraintColors: string[]): boolean {
      return comboColors.every(c => constraintColors.includes(c));
    }

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/gregario/mtg-oracle'

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