Skip to main content
Glama
index.ts8.57 kB
/** * Zod validation schemas for BBQ MCP Server tools */ import { z } from "zod"; // Response format enum export const ResponseFormatSchema = z.enum(["markdown", "json"]).default("markdown"); // Temperature unit enum export const TemperatureUnitSchema = z.enum(["fahrenheit", "celsius"]).default("fahrenheit"); // Protein type enum export const ProteinTypeSchema = z.enum([ "beef_brisket", "beef_ribeye", "beef_tri_tip", "beef_prime_rib", "beef_short_ribs", "pork_shoulder", "pork_butt", "pork_ribs_spare", "pork_ribs_baby_back", "pork_loin", "pork_tenderloin", "pork_belly", "chicken_whole", "chicken_breast", "chicken_thighs", "chicken_wings", "turkey_whole", "turkey_breast", "lamb_shoulder", "lamb_leg", "lamb_rack", "salmon", "other", ]); // Cook method enum export const CookMethodSchema = z.enum([ "smoke_low_slow", "smoke_hot_fast", "grill_direct", "grill_indirect", "reverse_sear", "spatchcock", "rotisserie", ]); // Doneness level enum export const DonenessLevelSchema = z.enum([ "rare", "medium_rare", "medium", "medium_well", "well_done", "pullable", "usda_safe", ]); // ===== Tool Input Schemas ===== /** * Schema for getting cooking guidance */ export const GetCookingGuidanceSchema = z .object({ protein_type: ProteinTypeSchema.describe( "Type of protein being cooked (e.g., 'beef_brisket', 'pork_shoulder', 'chicken_whole')" ), weight_pounds: z .number() .positive() .max(50) .describe("Weight of the protein in pounds (e.g., 12.5 for a 12.5 lb brisket)"), target_doneness: DonenessLevelSchema.optional().describe( "Desired doneness level. If not specified, will use the recommended doneness for the protein type." ), cook_method: CookMethodSchema.optional().describe( "Cooking method to use. If not specified, will recommend the best method for this protein." ), serving_time: z .string() .optional() .describe( "Target serving time in ISO 8601 format (e.g., '2024-12-25T18:00:00'). Used to calculate when to start cooking." ), response_format: ResponseFormatSchema.describe("Output format: 'markdown' for human-readable or 'json' for structured data"), }) .strict(); export type GetCookingGuidanceInput = z.infer<typeof GetCookingGuidanceSchema>; /** * Schema for analyzing current temperature */ export const AnalyzeTemperatureSchema = z .object({ current_temp: z.number().min(-40).max(500).describe("Current internal temperature reading in Fahrenheit"), target_temp: z.number().min(100).max(250).describe("Target internal temperature in Fahrenheit"), protein_type: ProteinTypeSchema.describe("Type of protein being cooked"), cook_method: CookMethodSchema.optional().describe("Cooking method being used"), cook_start_time: z .string() .optional() .describe("When the cook started in ISO 8601 format (e.g., '2024-12-25T06:00:00')"), previous_readings: z .array( z.object({ temp: z.number().describe("Temperature reading"), timestamp: z.string().describe("Time of reading in ISO 8601 format"), }) ) .optional() .describe("Previous temperature readings to calculate trend (most recent last)"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type AnalyzeTemperatureInput = z.infer<typeof AnalyzeTemperatureSchema>; /** * Schema for getting target temperature */ export const GetTargetTemperatureSchema = z .object({ protein_type: ProteinTypeSchema.describe("Type of protein"), doneness: DonenessLevelSchema.optional().describe("Desired doneness level"), include_pull_temp: z .boolean() .default(true) .describe("Whether to include pull temperature (accounting for carryover)"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type GetTargetTemperatureInput = z.infer<typeof GetTargetTemperatureSchema>; /** * Schema for listing proteins */ export const ListProteinsSchema = z .object({ category: z .enum(["beef", "pork", "poultry", "lamb", "seafood", "all"]) .default("all") .describe("Filter by protein category"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type ListProteinsInput = z.infer<typeof ListProteinsSchema>; /** * Schema for estimating cook time */ export const EstimateCookTimeSchema = z .object({ protein_type: ProteinTypeSchema.describe("Type of protein being cooked"), weight_pounds: z.number().positive().max(50).describe("Weight of the protein in pounds"), cook_method: CookMethodSchema.describe("Cooking method to use"), smoker_temp: z .number() .min(200) .max(500) .optional() .describe("Smoker/grill temperature in Fahrenheit. Defaults based on cook method."), target_doneness: DonenessLevelSchema.optional().describe("Target doneness level"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type EstimateCookTimeInput = z.infer<typeof EstimateCookTimeSchema>; /** * Schema for detecting stall */ export const DetectStallSchema = z .object({ protein_type: ProteinTypeSchema.describe("Type of protein being cooked"), current_temp: z.number().min(100).max(250).describe("Current internal temperature in Fahrenheit"), readings: z .array( z.object({ temp: z.number().describe("Temperature reading"), timestamp: z.string().describe("Time of reading in ISO 8601 format"), }) ) .min(3) .describe("At least 3 temperature readings to analyze trend (most recent last)"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type DetectStallInput = z.infer<typeof DetectStallSchema>; /** * Schema for getting cooking tips */ export const GetCookingTipsSchema = z .object({ protein_type: ProteinTypeSchema.describe("Type of protein"), cook_method: CookMethodSchema.optional().describe("Specific cooking method for targeted tips"), current_phase: z .enum(["prep", "cooking", "stall", "wrapping", "final_push", "resting", "serving"]) .optional() .describe("Current phase of the cook for phase-specific tips"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type GetCookingTipsInput = z.infer<typeof GetCookingTipsSchema>; /** * Schema for calculating rest time */ export const CalculateRestTimeSchema = z .object({ protein_type: ProteinTypeSchema.describe("Type of protein"), current_temp: z.number().min(100).max(250).describe("Current internal temperature when removed from heat"), target_final_temp: z.number().min(100).max(250).optional().describe("Desired final temperature after resting"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type CalculateRestTimeInput = z.infer<typeof CalculateRestTimeSchema>; /** * Schema for simulating ThermoWorks device data * This simulates what we'd receive from the ThermoWorks Cloud API */ export const SimulateDeviceReadingSchema = z .object({ device_type: z.enum(["Signals", "Smoke", "BlueDOT"]).describe("Type of ThermoWorks device"), probe_readings: z .array( z.object({ probe_id: z.string().describe("Probe identifier (e.g., 'probe1', 'ambient')"), name: z.string().optional().describe("Custom name for this probe"), temperature: z.number().describe("Temperature reading"), }) ) .min(1) .max(4) .describe("Temperature readings from each probe"), protein_type: ProteinTypeSchema.optional().describe("Type of protein being cooked (if known)"), target_temp: z.number().optional().describe("Target temperature set on device"), response_format: ResponseFormatSchema.describe("Output format"), }) .strict(); export type SimulateDeviceReadingInput = z.infer<typeof SimulateDeviceReadingSchema>; /** * Schema for temperature conversion */ export const ConvertTemperatureSchema = z .object({ temperature: z.number().describe("Temperature value to convert"), from_unit: TemperatureUnitSchema.describe("Source temperature unit"), to_unit: TemperatureUnitSchema.describe("Target temperature unit"), }) .strict(); export type ConvertTemperatureInput = z.infer<typeof ConvertTemperatureSchema>;

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jweingardt12/bbq-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server