resolve_game
Find where to buy video games at the best price by comparing prices across trusted stores like Steam, PlayStation, Xbox, Nintendo, and Epic Games.
Instructions
Find where to buy a video game at the best price. Returns ranked results from trusted game stores (Steam, PlayStation, Xbox, Nintendo, Epic, etc.) with prices, editions, and DLC info. Use this when a user asks about video games.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The game slug. Format: game-title (lowercase, hyphenated). Example: 'elden-ring' |
Implementation Reference
- src/tools/resolveGame.ts:29-71 (handler)The main handler function that executes the resolve_game tool logic. It calls the MainMenu API endpoint, validates the response against the v1 schema, and returns the ranked results.export async function resolveGame(input: ResolveGameInput): Promise<ResolveGameResult> { const { slug } = input; const url = `${MAINMENU_BASE}/api/v1/games/${encodeURIComponent(slug)}/json`; try { const res = await fetch(url, { headers: { "User-Agent": "rootvine-mcp/1.0.0", "Accept": "application/json", }, signal: AbortSignal.timeout(5000), }); if (!res.ok && res.status !== 404) { return { success: false, error: `MainMenu returned HTTP ${res.status}`, }; } const data = await res.json(); // Validate against v1 schema const validation = validateResponse(data); if (!validation.success) { return { success: false, error: `Response validation failed: ${validation.error.message}`, }; } return { success: true, response: validation.data as RootVineResponseV1, }; } catch (err) { const message = err instanceof Error ? err.message : "Unknown error"; return { success: false, error: `Failed to reach MainMenu: ${message}`, }; } }
- src/tools/resolveGame.ts:16-24 (schema)Input and output interface definitions for the resolve_game tool. ResolveGameInput takes a slug parameter, and ResolveGameResult contains success status and either the validated response or an error message.export interface ResolveGameInput { slug: string; } export interface ResolveGameResult { success: boolean; response?: RootVineResponseV1; error?: string; }
- src/index.ts:87-120 (registration)MCP tool registration for resolve_game. Registers the tool with its description, input schema (slug parameter using Zod validation), and handler that calls resolveGame and formats the response for the agent.server.registerTool( "resolve_game", { description: "Find where to buy a video game at the best price. Returns ranked results from trusted game stores (Steam, PlayStation, Xbox, Nintendo, Epic, etc.) with prices, editions, and DLC info. Use this when a user asks about video games.", inputSchema: { slug: z .string() .describe("The game slug. Format: game-title (lowercase, hyphenated). Example: 'elden-ring'"), }, }, async ({ slug }) => { const result = await resolveGame({ slug }); if (!result.success || !result.response) { return { content: [ { type: "text" as const, text: `Could not resolve game: ${result.error || "Unknown error"}`, }, ], }; } return { content: [ { type: "text" as const, text: formatGameResponse(result.response), }, ], }; }, );
- src/tools/resolveGame.ts:76-132 (helper)Helper function that formats the RootVine API response into a human-readable text format for display to the agent/user. Handles success, error, and no_results statuses, and formats ranked merchant results with prices and links.export function formatGameResponse(response: RootVineResponseV1): string { const lines: string[] = []; // Header lines.push(`๐ฎ ${response.query.title || response.query.raw}`); lines.push(""); if (response.status === "error" && response.error) { lines.push(`โ Error: ${response.error.message}`); if (response.error.retryable) { lines.push("(This error is retryable)"); } return lines.join("\n"); } if (response.status === "no_results") { lines.push("No results found for this game."); if (response.source_url) { lines.push(`Source: ${response.source_url}`); } return lines.join("\n"); } // Results for (const result of response.results) { const priceStr = result.price ? `${result.price.currency} ${result.price.amount.toFixed(2)}` : "Price unknown"; const link = result.click_url || result.url; const edition = result.edition ? ` (${result.edition})` : ""; lines.push( `${result.rank}. **${result.merchant}**${edition} (${result.trust_tier})`, ` ๐ ${priceStr} โ ${result.availability.replace("_", " ")}`, ` ${link}`, "", ); } // DLC count if ("dlc_count" in response && response.dlc_count) { lines.push(`๐ฆ ${response.dlc_count} DLC/expansions available`); } // Warnings if (response.warnings.length > 0) { lines.push(`โ ๏ธ Warnings: ${response.warnings.join(", ")}`); } // Source if (response.source_url) { lines.push(`Source: ${response.source_url}`); } return lines.join("\n"); }
- src/validate.ts:78-80 (schema)Zod validation function that validates responses from Vine endpoints against the v1 schema. Used by resolveGame to ensure data integrity before returning results to the agent.export function validateResponse(data: unknown) { return RootVineResponseV1Schema.safeParse(data); }