Skip to main content
Glama

get_matchup

Analyze matchup dynamics between two Hearthstone archetypes. Learn who is favored, key strategic tensions, and priority actions for each side.

Instructions

Get the theoretical matchup dynamics between two Hearthstone archetypes. Explains who is favoured, why, the key strategic tension, and what each side should prioritise.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
archetype_aYesFirst archetype name (e.g. "aggro", "control")
archetype_bYesSecond archetype name (e.g. "combo", "midrange")

Implementation Reference

  • The main handler function `getMatchup` that queries the SQLite database for a matchup between two archetypes. Checks both orderings (a vs b and b vs a) for case-insensitive matches. Returns matchup data if found, otherwise suggests available archetypes.
    export function getMatchup(
      db: Database.Database,
      input: GetMatchupInputType,
    ): GetMatchupResult {
      // Check both orderings since the table stores one direction
      const row = db
        .prepare(
          `SELECT * FROM matchup_framework WHERE
            (LOWER(archetype_a) = LOWER(?) AND LOWER(archetype_b) = LOWER(?))
            OR
            (LOWER(archetype_a) = LOWER(?) AND LOWER(archetype_b) = LOWER(?))`,
        )
        .get(input.archetype_a, input.archetype_b, input.archetype_b, input.archetype_a) as MatchupInfo | undefined;
    
      if (row) {
        return {
          found: true,
          matchup: {
            archetype_a: row.archetype_a,
            archetype_b: row.archetype_b,
            favoured: row.favoured,
            reasoning: row.reasoning,
            key_tension: row.key_tension,
            archetype_a_priority: row.archetype_a_priority,
            archetype_b_priority: row.archetype_b_priority,
          },
        };
      }
    
      // Not found — suggest available archetypes
      const archetypes = db
        .prepare('SELECT DISTINCT archetype_a FROM matchup_framework UNION SELECT DISTINCT archetype_b FROM matchup_framework')
        .all() as Array<{ archetype_a: string }>;
    
      const availableNames = archetypes.map((a) => a.archetype_a);
    
      return {
        found: false,
        message: `No matchup found for "${input.archetype_a}" vs "${input.archetype_b}".`,
        suggestions: availableNames.length > 0 ? availableNames : undefined,
      };
    }
  • Zod input schema `GetMatchupInput` defining two required string fields: archetype_a and archetype_b.
    export const GetMatchupInput = z.object({
      archetype_a: z.string().describe('First archetype name (e.g. "aggro", "control")'),
      archetype_b: z.string().describe('Second archetype name (e.g. "combo", "midrange")'),
    });
    
    export type GetMatchupInputType = z.infer<typeof GetMatchupInput>;
  • Result type definitions: `MatchupInfo` interface for successful matchups, and `GetMatchupResult` discriminated union for found/not-found cases.
    export interface MatchupInfo {
      archetype_a: string;
      archetype_b: string;
      favoured: string;
      reasoning: string;
      key_tension: string;
      archetype_a_priority: string;
      archetype_b_priority: string;
    }
    
    export type GetMatchupResult =
      | { found: true; matchup: MatchupInfo }
      | { found: false; message: string; suggestions?: string[] };
  • src/server.ts:248-273 (registration)
    Tool registration on the MCP server using `server.tool('get_matchup', ...)` with description, input schema, and handler that calls getMatchup and formats the result.
    // 8. get_matchup
    server.tool(
      'get_matchup',
      'Get the theoretical matchup dynamics between two Hearthstone archetypes. Explains who is favoured, why, the key strategic tension, and what each side should prioritise.',
      GetMatchupInput.shape,
      async (params) => {
        try {
          const result = getMatchup(db, params);
          return {
            content: [
              { type: 'text' as const, text: formatGetMatchup(result) },
            ],
          };
        } catch (err) {
          return {
            content: [
              {
                type: 'text' as const,
                text: `Error: ${err instanceof Error ? err.message : String(err)}`,
              },
            ],
            isError: true,
          };
        }
      },
    );
  • Formatter function `formatGetMatchup` that converts the GetMatchupResult into a human-readable Markdown string for display.
    export function formatGetMatchup(result: GetMatchupResult): string {
      if (!result.found) {
        let msg = result.message;
        if (result.suggestions && result.suggestions.length > 0) {
          msg += '\n\nAvailable archetypes:\n';
          msg += result.suggestions.map((s) => `- ${s}`).join('\n');
        }
        return msg;
      }
    
      const m = result.matchup;
      const lines: string[] = [];
      lines.push(`## ${m.archetype_a} vs ${m.archetype_b}`);
      lines.push('');
      lines.push(`**Favoured:** ${m.favoured}`);
      lines.push('');
      lines.push(`**Reasoning:** ${m.reasoning}`);
      lines.push('');
      lines.push(`**Key Tension:** ${m.key_tension}`);
      lines.push('');
      lines.push(`**${m.archetype_a} should prioritise:** ${m.archetype_a_priority}`);
      lines.push('');
      lines.push(`**${m.archetype_b} should prioritise:** ${m.archetype_b_priority}`);
      return lines.join('\n');
    }
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses the output content (favored, why, tension, priorities) but lacks details on data source, computation method, or limitations. It does not contradict annotations (none present).

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

Conciseness4/5

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

The description is a single clear sentence that conveys the core functionality. It is appropriately front-loaded but could be slightly more structured (e.g., separating output description).

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

Completeness4/5

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

Given the simple input (two strings) and no output schema, the description provides a good overview of what the tool returns. It covers the main aspects (favored side, reason, tension, priorities), which is adequate for the tool's complexity.

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

Parameters4/5

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

Schema coverage is 100% with clear parameter descriptions. The description adds value beyond the schema by explaining the type of analysis (theoretical) and the aspects covered (favor, tension, priorities), which helps the agent understand the output semantics.

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 tool's purpose: getting theoretical matchup dynamics between two Hearthstone archetypes. It specifies what it explains (favor, reason, tension, priorities) and distinguishes from siblings like 'analyze_deck' and 'get_archetype'.

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 the tool should be used when analyzing archetype matchups, but it does not explicitly state when to use it over alternatives like 'analyze_deck' or 'get_archetype', nor does it provide exclusions or prerequisites.

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

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