Browse Franchise
browse_franchiseBrowse 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'), }, ], }; }, ); }