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
import json
import logging
import traceback
from typing import Any, Dict
import httpx
from httpx import ConnectError, HTTPStatusError, ReadTimeout
logger = logging.getLogger("mealie-mcp")
class MealieApiError(Exception):
"""Custom exception for Mealie API errors with status code and response details."""
def __init__(self, status_code: int, message: str, response_text: str = None):
self.status_code = status_code
self.message = message
self.response_text = response_text
super().__init__(f"{message} (Status Code: {status_code})")
class MealieClient:
def __init__(self, base_url: str, api_key: str):
if not base_url:
raise ValueError("Base URL cannot be empty")
if not api_key:
raise ValueError("API key cannot be empty")
logger.debug({"message": "Initializing MealieClient", "base_url": base_url})
try:
self._client = httpx.Client(
base_url=base_url,
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
timeout=30.0, # Set a reasonable timeout for requests
)
# Test connection
logger.debug({"message": "Testing connection to Mealie API"})
self._client.get("/api/app/about")
logger.info({"message": "Successfully connected to Mealie API"})
except ConnectError as e:
error_msg = f"Failed to connect to Mealie API at {base_url}: {str(e)}"
logger.error({"message": error_msg})
logger.debug(
{"message": "Error traceback", "traceback": traceback.format_exc()}
)
raise ConnectionError(error_msg) from e
except Exception as e:
error_msg = f"Error initializing Mealie client: {str(e)}"
logger.error({"message": error_msg})
logger.debug(
{"message": "Error traceback", "traceback": traceback.format_exc()}
)
raise
def _handle_request(self, method: str, url: str, **kwargs) -> Dict[str, Any] | str:
"""Common request handler with error handling for all API calls."""
try:
logger.debug(
{
"message": "Making API request",
"method": method,
"url": url,
"body": kwargs.get("json"),
}
)
if "params" in kwargs:
logger.debug(
{"message": "Request parameters", "params": kwargs["params"]}
)
if "json" in kwargs:
logger.debug({"message": "Request payload", "payload": kwargs["json"]})
response = self._client.request(method, url, **kwargs)
response.raise_for_status() # Raise an exception for 4XX/5XX responses
logger.debug(
{"message": "Request successful", "status_code": response.status_code}
)
# Log the response content at debug level
try:
response_data = response.json()
logger.debug({"message": "Response content", "data": response_data})
return response_data
except json.JSONDecodeError:
logger.debug(
{"message": "Response content (non-JSON)", "content": response.text}
)
return response.text
except HTTPStatusError as e:
status_code = e.response.status_code
error_detail = f"HTTP Error {status_code}"
# Try to parse error details from response
try:
error_detail = e.response.json()
except Exception:
error_detail = e.response.text
error_msg = f"API error for {method} {url}: {error_detail}"
logger.error(
{
"message": "API request failed",
"method": method,
"url": url,
"status_code": status_code,
"error_detail": error_detail,
}
)
logger.debug(
{"message": "Failed Request body", "content": e.request.content}
)
raise MealieApiError(status_code, error_msg, e.response.text) from e
except ReadTimeout:
error_msg = f"Request timeout for {method} {url}"
logger.error({"message": error_msg, "method": method, "url": url})
logger.debug(
{"message": "Error traceback", "traceback": traceback.format_exc()}
)
raise TimeoutError(error_msg)
except ConnectError as e:
error_msg = f"Connection error for {method} {url}: {str(e)}"
logger.error(
{"message": error_msg, "method": method, "url": url, "error": str(e)}
)
logger.debug(
{"message": "Error traceback", "traceback": traceback.format_exc()}
)
raise ConnectionError(error_msg) from e
except Exception as e:
error_msg = f"Unexpected error for {method} {url}: {str(e)}"
logger.error(
{"message": error_msg, "method": method, "url": url, "error": str(e)}
)
logger.debug(
{"message": "Error traceback", "traceback": traceback.format_exc()}
)
raise