list_games
Browse and filter games in your Lutris library using criteria like runner, platform, installed status, or search terms, with pagination for large collections.
Instructions
List and filter games in the Lutris library with pagination
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| runner | No | Filter by runner (e.g. steam, wine, linux) | |
| platform | No | Filter by platform | |
| installed | No | Filter by installed status | |
| category | No | Filter by category name | |
| search | No | Search by name or slug | |
| service | No | Filter by service (e.g. steam) | |
| limit | No | Results per page | |
| offset | No | Offset for pagination | |
| sort_by | No | Sort column | name |
| sort_order | No | Sort direction | asc |
Implementation Reference
- src/tools/games.ts:46-64 (handler)The MCP tool handler for 'list_games', which calls the database function `listGames` and returns the formatted results.
async (params) => { try { const result = listGames(params); return { content: [ { type: "text", text: JSON.stringify( { total: result.total, count: result.games.length, games: result.games }, null, 2 ), }, ], }; } catch (error) { return handleError(error); } } - src/tools/games.ts:27-45 (registration)Registration of the 'list_games' tool in the MCP server, including input schema validation via Zod.
export function registerGameTools(server: McpServer) { server.tool( "list_games", "List and filter games in the Lutris library with pagination", { runner: z.string().optional().describe("Filter by runner (e.g. steam, wine, linux)"), platform: z.string().optional().describe("Filter by platform"), installed: z.boolean().optional().describe("Filter by installed status"), category: z.string().optional().describe("Filter by category name"), search: z.string().optional().describe("Search by name or slug"), service: z.string().optional().describe("Filter by service (e.g. steam)"), limit: z.coerce.number().min(1).max(200).default(50).describe("Results per page"), offset: z.coerce.number().min(0).default(0).describe("Offset for pagination"), sort_by: z .enum(["name", "sortname", "playtime", "lastplayed", "installed_at", "year", "updated"]) .default("name") .describe("Sort column"), sort_order: z.enum(["asc", "desc"]).default("asc").describe("Sort direction"), }, - src/db/queries.ts:35-84 (helper)The database query implementation of `listGames` that executes the SQL to retrieve and filter game records.
export function listGames(opts: ListGamesOptions): { games: Game[]; total: number } { const db = getDatabase(); const conditions: string[] = []; const params: Record<string, unknown> = {}; if (opts.runner) { conditions.push("g.runner = :runner"); params.runner = opts.runner; } if (opts.platform) { conditions.push("g.platform = :platform"); params.platform = opts.platform; } if (opts.installed !== undefined) { conditions.push("g.installed = :installed"); params.installed = opts.installed ? 1 : 0; } if (opts.service) { conditions.push("g.service = :service"); params.service = opts.service; } if (opts.search) { conditions.push("(g.name LIKE :search OR g.slug LIKE :search)"); params.search = `%${opts.search}%`; } let joins = ""; if (opts.category) { joins = "JOIN games_categories gc ON gc.game_id = g.id JOIN categories c ON c.id = gc.category_id"; conditions.push("c.name = :category"); params.category = opts.category; } const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : ""; const sortCol = ALLOWED_SORT_COLUMNS.has(opts.sort_by) ? opts.sort_by : "name"; const sortDir = opts.sort_order === "desc" ? "DESC" : "ASC"; const countRow = db .prepare(`SELECT COUNT(DISTINCT g.id) as count FROM games g ${joins} ${where}`) .get(params) as { count: number }; const games = db .prepare( `SELECT DISTINCT g.* FROM games g ${joins} ${where} ORDER BY g.${sortCol} ${sortDir} LIMIT :limit OFFSET :offset` ) .all({ ...params, limit: opts.limit, offset: opts.offset }) as Game[]; return { games, total: countRow.count }; } - src/db/queries.ts:12-23 (schema)The `ListGamesOptions` interface defining the input parameters accepted by the database query.
export interface ListGamesOptions { runner?: string; platform?: string; installed?: boolean; category?: string; search?: string; service?: string; limit: number; offset: number; sort_by: string; sort_order: "asc" | "desc"; }