import json import logging import traceback from typing import Optional from mcp.server.fastmcp import FastMCP from mealie import MealieFetcher from utils import format_error_response logger = logging.getLogger("mealie-mcp") def register_food_tools(mcp: FastMCP, mealie: MealieFetcher) -> None: """Register all food and unit-related tools with the MCP server.""" @mcp.tool() def get_foods( search: Optional[str] = None, page: Optional[int] = None, per_page: Optional[int] = None, ) -> str: """Get a list of foods from your Mealie database. Args: search: Search term to filter foods page: Page number for pagination per_page: Number of items per page Returns: str: JSON list of foods """ try: logger.info({"message": "Fetching foods", "search": search}) result = mealie.get_foods(search=search, page=page, per_page=per_page) return json.dumps(result, indent=2) except Exception as e: error_msg = f"Error fetching foods: {str(e)}" logger.error({"message": error_msg}) logger.debug({"message": "Error traceback", "traceback": traceback.format_exc()}) return format_error_response(error_msg) @mcp.tool() def get_units() -> str: """Get a list of all units from your Mealie database. Returns: str: JSON list of units """ try: logger.info({"message": "Fetching units"}) result = mealie.get_units() return json.dumps(result, indent=2) except Exception as e: error_msg = f"Error fetching units: {str(e)}" logger.error({"message": error_msg}) logger.debug({"message": "Error traceback", "traceback": traceback.format_exc()}) return format_error_response(error_msg) @mcp.tool() def create_food(name: str, description: Optional[str] = None) -> str: """Create a new food item in Mealie. Args: name: Name of the food description: Optional description Returns: str: Confirmation with created food details """ try: logger.info({"message": "Creating food", "name": name}) result = mealie.create_food(name=name, description=description) return json.dumps(result, indent=2) except Exception as e: error_msg = f"Error creating food '{name}': {str(e)}" logger.error({"message": error_msg}) logger.debug({"message": "Error traceback", "traceback": traceback.format_exc()}) return format_error_response(error_msg) @mcp.tool() def create_unit(name: str, abbreviation: Optional[str] = None) -> str: """Create a new unit in Mealie. Args: name: Name of the unit (e.g., "Teaspoon", "Gram") abbreviation: Optional abbreviation (e.g., "tsp", "g") Returns: str: Confirmation with created unit details """ try: logger.info({"message": "Creating unit", "name": name}) result = mealie.create_unit(name=name, abbreviation=abbreviation) return json.dumps(result, indent=2) except Exception as e: error_msg = f"Error creating unit '{name}': {str(e)}" logger.error({"message": error_msg}) logger.debug({"message": "Error traceback", "traceback": traceback.format_exc()}) return format_error_response(error_msg)