Skip to main content
Glama

Mealie MCP Server

by rldiao
recipe_tools.py7.23 kB
import logging import traceback from typing import Any, Dict, List, Optional from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp.exceptions import ToolError from mealie import MealieFetcher from models.recipe import Recipe, RecipeIngredient, RecipeInstruction logger = logging.getLogger("mealie-mcp") def register_recipe_tools(mcp: FastMCP, mealie: MealieFetcher) -> None: """Register all recipe-related tools with the MCP server.""" @mcp.tool() def get_recipes( search: Optional[str] = None, page: Optional[int] = None, per_page: Optional[int] = None, categories: Optional[List[str]] = None, tags: Optional[List[str]] = None, ) -> Dict[str, Any]: """Provides a paginated list of recipes with optional filtering. Args: search: Filters recipes by name or description. page: Page number for pagination. per_page: Number of items per page. categories: Filter by specific recipe categories. tags: Filter by specific recipe tags. Returns: Dict[str, Any]: Recipe summaries with details like ID, name, description, and image information. """ try: logger.info( { "message": "Fetching recipes", "search": search, "page": page, "per_page": per_page, "categories": categories, "tags": tags, } ) return mealie.get_recipes( search=search, page=page, per_page=per_page, categories=categories, tags=tags, ) except Exception as e: error_msg = f"Error fetching recipes: {str(e)}" logger.error({"message": error_msg}) logger.debug( {"message": "Error traceback", "traceback": traceback.format_exc()} ) raise ToolError(error_msg) @mcp.tool() def get_recipe_detailed(slug: str) -> Dict[str, Any]: """Retrieve a specific recipe by its slug identifier. Use this when to get full recipe details for tasks like updating or displaying the recipe. Args: slug: The unique text identifier for the recipe, typically found in recipe URLs or from get_recipes results. Returns: Dict[str, Any]: Comprehensive recipe details including ingredients, instructions, nutrition information, notes, and associated metadata. """ try: logger.info({"message": "Fetching recipe", "slug": slug}) return mealie.get_recipe(slug) except Exception as e: error_msg = f"Error fetching recipe with slug '{slug}': {str(e)}" logger.error({"message": error_msg}) logger.debug( {"message": "Error traceback", "traceback": traceback.format_exc()} ) raise ToolError(error_msg) @mcp.tool() def get_recipe_concise(slug: str) -> Dict[str, Any]: """Retrieve a concise version of a specific recipe by its slug identifier. Use this when you only need a summary of the recipe, such as for when mealplaning. Args: slug: The unique text identifier for the recipe, typically found in recipe URLs or from get_recipes results. Returns: Dict[str, Any]: Concise recipe summary with essential fields. """ try: logger.info({"message": "Fetching recipe", "slug": slug}) recipe_json = mealie.get_recipe(slug) recipe = Recipe.model_validate(recipe_json) return recipe.model_dump( include={ "name", "slug", "recipeServings", "recipeYieldQuantity", "recipeYield", "totalTime", "rating", "recipeIngredient", "lastMade", }, exclude_none=True, ) except Exception as e: error_msg = f"Error fetching recipe with slug '{slug}': {str(e)}" logger.error({"message": error_msg}) logger.debug( {"message": "Error traceback", "traceback": traceback.format_exc()} ) raise ToolError(error_msg) @mcp.tool() def create_recipe( name: str, ingredients: List[str], instructions: List[str] ) -> Dict[str, Any]: """Create a new recipe Args: name: The name of the new recipe to be created. ingredients: A list of ingredients for the recipe include quantities and units. instructions: A list of instructions for preparing the recipe. Returns: Dict[str, Any]: The created recipe details. """ try: logger.info({"message": "Creating recipe", "name": name}) slug = mealie.create_recipe(name) recipe_json = mealie.get_recipe(slug) recipe = Recipe.model_validate(recipe_json) recipe.recipeIngredient = [RecipeIngredient(note=i) for i in ingredients] recipe.recipeInstructions = [ RecipeInstruction(text=i) for i in instructions ] return mealie.update_recipe(slug, recipe.model_dump(exclude_none=True)) except Exception as e: error_msg = f"Error creating recipe '{name}': {str(e)}" logger.error({"message": error_msg}) logger.debug( {"message": "Error traceback", "traceback": traceback.format_exc()} ) raise ToolError(error_msg) @mcp.tool() def update_recipe( slug: str, ingredients: List[str], instructions: List[str], ) -> Dict[str, Any]: """Replaces the ingredients and instructions of an existing recipe. Args: slug: The unique text identifier for the recipe to be updated. ingredients: A list of ingredients for the recipe include quantities and units. instructions: A list of instructions for preparing the recipe. Returns: Dict[str, Any]: The updated recipe details. """ try: logger.info({"message": "Updating recipe", "slug": slug}) recipe_json = mealie.get_recipe(slug) recipe = Recipe.model_validate(recipe_json) recipe.recipeIngredient = [RecipeIngredient(note=i) for i in ingredients] recipe.recipeInstructions = [ RecipeInstruction(text=i) for i in instructions ] return mealie.update_recipe(slug, recipe.model_dump(exclude_none=True)) except Exception as e: error_msg = f"Error updating recipe '{slug}': {str(e)}" logger.error({"message": error_msg}) logger.debug( {"message": "Error traceback", "traceback": traceback.format_exc()} ) raise ToolError(error_msg)

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/rldiao/mealie-mcp-server'

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