Skip to main content
Glama

analyze_deck

Analyze Hearthstone deck codes to identify archetypes, explain gameplans, assess strengths and weaknesses, and predict matchup outcomes for strategic coaching.

Instructions

Analyze a Hearthstone deck code to classify its archetype, explain its gameplan, identify strengths and weaknesses, and predict matchup dynamics. Use this for strategic deck coaching — it combines card data with strategy knowledge.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
deck_codeYesHearthstone deck code (base64 deckstring)

Implementation Reference

  • The `analyzeDeck` function is the handler for the 'analyze_deck' tool. It decodes the provided deck code, queries the database for card details and archetype strategies, and returns a structured analysis of the deck.
    export function analyzeDeck(
      db: Database.Database,
      input: AnalyzeDeckInputType,
    ): AnalyzeDeckResult {
      // 1. Decode the deck
      let decoded: { cards: Array<[number, number]>; heroes: number[]; format: number };
    
      try {
        decoded = decode(input.deck_code);
      } catch (err) {
        return {
          success: false,
          message: `Invalid deck code: ${err instanceof Error ? err.message : String(err)}`,
        };
      }
    
      // 2. Format
      const format = decoded.format === 1 ? 'Wild' : 'Standard';
    
      // 3. Hero class
      let heroClass = 'UNKNOWN';
      if (decoded.heroes.length > 0) {
        const heroDbfId = decoded.heroes[0];
        const heroRow = db
          .prepare('SELECT player_class FROM cards WHERE id = ?')
          .get(String(heroDbfId)) as { player_class: string | null } | undefined;
    
        if (heroRow?.player_class) {
          heroClass = heroRow.player_class;
        } else if (HERO_CLASS_MAP[heroDbfId]) {
          heroClass = HERO_CLASS_MAP[heroDbfId];
        }
      }
    
      // 4. Build card list and profile data
      const deckCards: Array<{ name: string; mana_cost: number | null; count: number }> = [];
      const profileCards: DeckProfile['cards'] = [];
      const manaCurve: Record<string, number> = {};
      const typeDistribution: Record<string, number> = {};
      let totalCards = 0;
      let totalCost = 0;
      let cardsWithCost = 0;
    
      for (const [dbfId, count] of decoded.cards) {
        const row = db
          .prepare('SELECT * FROM cards WHERE id = ?')
          .get(String(dbfId)) as CardRow | undefined;
    
        const name = row ? row.name : `Unknown Card (${dbfId})`;
        const manaCost = row?.mana_cost ?? null;
        const type = row?.type ?? null;
        const text = row?.text ?? null;
        const keywords = row?.keywords ?? null;
    
        deckCards.push({ name, mana_cost: manaCost, count });
    
        // Add profile cards (expand by count for classification)
        for (let i = 0; i < count; i++) {
          profileCards.push({ mana_cost: manaCost, type, text, keywords });
        }
    
        totalCards += count;
    
        // Mana curve
        const bucket = manaCurveBucket(manaCost);
        manaCurve[bucket] = (manaCurve[bucket] ?? 0) + count;
    
        // Type distribution
        const cardType = type ?? 'UNKNOWN';
        typeDistribution[cardType] = (typeDistribution[cardType] ?? 0) + count;
    
        // Average cost tracking
        if (manaCost != null) {
          totalCost += manaCost * count;
          cardsWithCost += count;
        }
      }
    
      const avgCost = cardsWithCost > 0 ? totalCost / cardsWithCost : 0;
    
      // 5. Build DeckProfile and classify
      const profile: DeckProfile = {
        avg_cost: avgCost,
        cards: profileCards,
        total_cards: totalCards,
        mana_curve: manaCurve,
        type_distribution: typeDistribution,
      };
    
      const classification = classifyArchetype(profile);
    
      // 6. Look up archetype info from strategy tables
      let archetypeInfo: AnalyzeDeckSuccess['archetype_info'] | undefined;
      const archetypeRow = db
        .prepare('SELECT * FROM archetypes WHERE LOWER(name) = LOWER(?)')
        .get(classification.archetype) as ArchetypeRow | undefined;
    
      if (archetypeRow) {
        archetypeInfo = {
          description: archetypeRow.description,
          gameplan: archetypeRow.gameplan,
          strengths: parseJson(archetypeRow.strengths),
          weaknesses: parseJson(archetypeRow.weaknesses),
        };
      }
    
      // 7. Look up matchup expectations
      let matchups: AnalyzeDeckSuccess['matchups'] | undefined;
      const matchupRows = db
        .prepare(
          `SELECT archetype_a, archetype_b, favoured, key_tension FROM matchup_framework
           WHERE LOWER(archetype_a) = LOWER(?) OR LOWER(archetype_b) = LOWER(?)`,
        )
        .all(classification.archetype, classification.archetype) as MatchupRow[];
    
      if (matchupRows.length > 0) {
        matchups = matchupRows
          .filter((m) => m.archetype_a.toLowerCase() !== m.archetype_b.toLowerCase() ||
            m.archetype_a.toLowerCase() !== classification.archetype.toLowerCase())
          .map((m) => {
            const isA = m.archetype_a.toLowerCase() === classification.archetype.toLowerCase();
            return {
              vs_archetype: isA ? m.archetype_b : m.archetype_a,
              favoured: m.favoured,
              key_tension: m.key_tension,
            };
          });
      }
    
      return {
        success: true,
        deck: {
          format,
          hero_class: heroClass,
          cards: deckCards,
          total_cards: totalCards,
          mana_curve: manaCurve,
          type_distribution: typeDistribution,
        },
        classification,
        archetype_info: archetypeInfo,
        matchups: matchups && matchups.length > 0 ? matchups : undefined,
      };
    }
  • The Zod schema `AnalyzeDeckInput` defines the required input for the `analyze_deck` tool.
    export const AnalyzeDeckInput = z.object({
      deck_code: z.string().describe('Hearthstone deck code (base64 deckstring)'),
    });
  • src/server.ts:164-174 (registration)
    The 'analyze_deck' tool is registered in `src/server.ts`, where it uses `AnalyzeDeckInput` for parameter validation and calls `analyzeDeck` to process the request.
    // 5. analyze_deck
    server.tool(
      'analyze_deck',
      'Analyze a Hearthstone deck code to classify its archetype, explain its gameplan, identify strengths and weaknesses, and predict matchup dynamics. Use this for strategic deck coaching — it combines card data with strategy knowledge.',
      AnalyzeDeckInput.shape,
      async (params) => {
        try {
          const result = analyzeDeck(db, params);
          return {
            content: [
              { type: 'text' as const, text: formatAnalyzeDeck(result) },

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/hearthstone-oracle'

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