Search Beer Styles
search_stylesSearch BJCP beer styles by name, category, or characteristics. Returns vital statistics, typical ingredients, and commercial examples.
Instructions
Search BJCP beer styles by name, category, or characteristics. Returns vital statistics, overall impression, typical ingredients, and commercial examples.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Style name, category, or characteristic to search for |
Implementation Reference
- src/tools/search-styles.ts:37-63 (handler)The async handler function that runs when 'search_styles' is invoked. It takes a 'query' string, runs fuzzySearch on STYLES data across multiple fields (name, category, overallImpression, ingredients, tags), returns up to 5 results formatted with vital stats, or a 'no results' message.
async ({ query }) => { const results = fuzzySearch( STYLES, query, ["name", "category", "overallImpression", "ingredients", "tags"], ).slice(0, 5); if (results.length === 0) { return { content: [ { type: "text" as const, text: `No styles found matching '${query}'. Try broader terms like 'IPA', 'stout', 'lager', or 'Belgian'.`, }, ], }; } return { content: [ { type: "text" as const, text: results.map(formatStyle).join("\n\n---\n\n"), }, ], }; }, - src/tools/search-styles.ts:22-65 (registration)Registers the 'search_styles' tool on the MCP server using server.registerTool(), with a title, description, and inputSchema defined via Zod.
export function registerSearchStyles(server: McpServer): void { server.registerTool( "search_styles", { title: "Search Beer Styles", description: "Search BJCP beer styles by name, category, or characteristics. Returns vital statistics, overall impression, typical ingredients, and commercial examples.", inputSchema: { query: z .string() .describe( "Style name, category, or characteristic to search for", ), }, }, async ({ query }) => { const results = fuzzySearch( STYLES, query, ["name", "category", "overallImpression", "ingredients", "tags"], ).slice(0, 5); if (results.length === 0) { return { content: [ { type: "text" as const, text: `No styles found matching '${query}'. Try broader terms like 'IPA', 'stout', 'lager', or 'Belgian'.`, }, ], }; } return { content: [ { type: "text" as const, text: results.map(formatStyle).join("\n\n---\n\n"), }, ], }; }, ); } - src/tools/search-styles.ts:25-35 (schema)Input schema for the tool: a single 'query' string parameter described as 'Style name, category, or characteristic to search for'.
{ title: "Search Beer Styles", description: "Search BJCP beer styles by name, category, or characteristics. Returns vital statistics, overall impression, typical ingredients, and commercial examples.", inputSchema: { query: z .string() .describe( "Style name, category, or characteristic to search for", ), }, - src/register-tools.ts:10-10 (registration)Calls registerSearchStyles(server) to register the tool when the server starts up.
registerSearchStyles(server); - src/tools/search-styles.ts:7-20 (helper)Helper function that formats a BeerStyle object into a markdown string containing name, ID, category, vital stats (OG, FG, IBU, SRM, ABV), overall impression, ingredients, and examples.
function formatStyle(style: BeerStyle): string { const { vitalStats: v } = style; return [ `## ${style.name} (${style.id})`, `Category: ${style.category}`, `OG: ${v.ogMin}-${v.ogMax} | FG: ${v.fgMin}-${v.fgMax}`, `IBU: ${v.ibuMin}-${v.ibuMax} | SRM: ${v.srmMin}-${v.srmMax} | ABV: ${v.abvMin}-${v.abvMax}%`, "", style.overallImpression, "", `Ingredients: ${style.ingredients}`, `Examples: ${style.examples}`, ].join("\n"); }