browse_franchise
Browse Disney Lorcana cards by franchise or story. List all franchises with card counts or view specific franchise cards and statistics.
Instructions
Browse Disney Lorcana cards by franchise (story). Without a franchise name, lists all franchises with card counts. With a franchise name, shows cards and statistics.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| franchise | No | Franchise/story name (e.g. "Frozen", "Moana"). Omit to list all franchises. |
Implementation Reference
- src/tools/browse-franchise.ts:45-119 (handler)The handler function for 'browse_franchise' which either lists franchises or retrieves card details for a specific franchise.
async (args) => { if (!args.franchise) { // List all franchises const franchises = listFranchises(db); if (franchises.length === 0) { return { content: [{ type: 'text' as const, text: 'No franchises found in the database.' }], }; } const lines = franchises.map( (f) => ` ${f.story} (${f.count} card${f.count !== 1 ? 's' : ''})`, ); return { content: [ { type: 'text' as const, text: `Found ${franchises.length} franchises:\n\n${lines.join('\n')}`, }, ], }; } // Browse specific franchise const { rows, total } = getCardsByFranchise(db, args.franchise, 1000, 0); if (total === 0) { // Try partial match const allFranchises = listFranchises(db); const matches = allFranchises.filter( (f) => f.story.toLowerCase().includes(args.franchise!.toLowerCase()), ); let text = `Franchise "${args.franchise}" not found.`; if (matches.length > 0) { text += `\n\nDid you mean one of these?\n${matches.map((f) => ` - ${f.story} (${f.count} cards)`).join('\n')}`; } return { content: [{ type: 'text' as const, text }], isError: true, }; } // Compute stats const inkDist = computeDistribution(rows, 'color'); const typeDist = computeDistribution(rows, 'type'); const rarityDist = computeDistribution(rows, 'rarity'); const setDist = computeDistribution(rows, 'set_code'); const header = [ `**${rows[0].story ?? args.franchise}** — ${total} card${total !== 1 ? 's' : ''}`, '', 'Stats:', ` Ink colors: ${formatDistribution(inkDist)}`, ` Types: ${formatDistribution(typeDist)}`, ` Rarities: ${formatDistribution(rarityDist)}`, ` Sets: ${formatDistribution(setDist)}`, '', 'Cards:', ].join('\n'); const cardLines = rows.map(formatCardBrief); return { content: [ { type: 'text' as const, text: header + '\n' + cardLines.join('\n'), }, ], }; }, ); - src/tools/browse-franchise.ts:37-44 (schema)Tool definition schema for 'browse_franchise'.
{ title: 'Browse Franchise', description: 'Browse Disney Lorcana cards by franchise (story). Without a franchise name, lists all franchises with card counts. With a franchise name, shows cards and statistics.', inputSchema: { franchise: z.string().optional().describe('Franchise/story name (e.g. "Frozen", "Moana"). Omit to list all franchises.'), }, }, - src/tools/browse-franchise.ts:34-120 (registration)Registration function for 'browse_franchise'.
export function registerBrowseFranchise(server: McpServer, db: Database.Database): void { server.registerTool( 'browse_franchise', { title: 'Browse Franchise', description: 'Browse Disney Lorcana cards by franchise (story). Without a franchise name, lists all franchises with card counts. With a franchise name, shows cards and statistics.', inputSchema: { franchise: z.string().optional().describe('Franchise/story name (e.g. "Frozen", "Moana"). Omit to list all franchises.'), }, }, async (args) => { if (!args.franchise) { // List all franchises const franchises = listFranchises(db); if (franchises.length === 0) { return { content: [{ type: 'text' as const, text: 'No franchises found in the database.' }], }; } const lines = franchises.map( (f) => ` ${f.story} (${f.count} card${f.count !== 1 ? 's' : ''})`, ); return { content: [ { type: 'text' as const, text: `Found ${franchises.length} franchises:\n\n${lines.join('\n')}`, }, ], }; } // Browse specific franchise const { rows, total } = getCardsByFranchise(db, args.franchise, 1000, 0); if (total === 0) { // Try partial match const allFranchises = listFranchises(db); const matches = allFranchises.filter( (f) => f.story.toLowerCase().includes(args.franchise!.toLowerCase()), ); let text = `Franchise "${args.franchise}" not found.`; if (matches.length > 0) { text += `\n\nDid you mean one of these?\n${matches.map((f) => ` - ${f.story} (${f.count} cards)`).join('\n')}`; } return { content: [{ type: 'text' as const, text }], isError: true, }; } // Compute stats const inkDist = computeDistribution(rows, 'color'); const typeDist = computeDistribution(rows, 'type'); const rarityDist = computeDistribution(rows, 'rarity'); const setDist = computeDistribution(rows, 'set_code'); const header = [ `**${rows[0].story ?? args.franchise}** — ${total} card${total !== 1 ? 's' : ''}`, '', 'Stats:', ` Ink colors: ${formatDistribution(inkDist)}`, ` Types: ${formatDistribution(typeDist)}`, ` Rarities: ${formatDistribution(rarityDist)}`, ` Sets: ${formatDistribution(setDist)}`, '', 'Cards:', ].join('\n'); const cardLines = rows.map(formatCardBrief); return { content: [ { type: 'text' as const, text: header + '\n' + cardLines.join('\n'), }, ], }; }, ); }