Skip to main content
Glama

Toast MCP Server

by naru-sensei
macos.py9.13 kB
""" macOS Notification implementation for toast-mcp-server. This module provides functionality to display macOS notifications using the osascript command to interact with the macOS Notification Center. """ import logging import subprocess import platform from typing import Dict, Any, Optional, List, Union from src.mcp.protocol import NotificationType logger = logging.getLogger(__name__) class MacOSNotificationManager: """ Manager for macOS Notifications. This class handles the creation and display of macOS notifications using the osascript command to interact with the Notification Center. """ def __init__(self): """Initialize the macOS notification manager.""" if not self._is_macos(): logger.warning("MacOSNotificationManager initialized on non-macOS platform") logger.info("macOS notification manager initialized") def _is_macos(self) -> bool: """ Check if the current platform is macOS. Returns: True if the current platform is macOS, False otherwise """ return platform.system() == "Darwin" def show_notification(self, title: str, message: str, notification_type: NotificationType = NotificationType.INFO, duration: int = 5, sound: bool = True, subtitle: Optional[str] = None) -> bool: """ Show a macOS notification. Args: title: Title of the notification message: Content of the notification notification_type: Type of notification (info, warning, error, success) duration: Duration parameter is ignored on macOS (included for API compatibility) sound: Whether to play a sound with the notification subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ if not self._is_macos(): logger.error("Cannot show macOS notification on non-macOS platform") return False logger.debug(f"Showing notification: {title} ({notification_type.value})") try: script = self._build_notification_script(title, message, subtitle, sound) result = subprocess.run( ["osascript", "-e", script], capture_output=True, text=True, check=True ) if result.returncode == 0: return True else: logger.error(f"Failed to show notification: {result.stderr}") return False except subprocess.SubprocessError as e: logger.error(f"Failed to show notification: {str(e)}") return False except Exception as e: logger.error(f"Unexpected error showing notification: {str(e)}") return False def _build_notification_script(self, title: str, message: str, subtitle: Optional[str] = None, sound: bool = True) -> str: """ Build the AppleScript command for displaying a notification. Args: title: Title of the notification message: Content of the notification subtitle: Optional subtitle for the notification sound: Whether to play a sound with the notification Returns: AppleScript command string """ title_escaped = title.replace('"', '\\"') message_escaped = message.replace('"', '\\"') script = f'display notification "{message_escaped}" with title "{title_escaped}"' if subtitle: subtitle_escaped = subtitle.replace('"', '\\"') script += f' subtitle "{subtitle_escaped}"' if sound: script += " sound name \"Ping\"" return script class MacOSNotificationFactory: """ Factory for creating macOS notifications based on notification type. This class provides methods for creating and displaying different types of notifications with appropriate default settings. """ def __init__(self): """Initialize the notification factory.""" self.notification_manager = MacOSNotificationManager() def create_info_notification(self, title: str, message: str, subtitle: Optional[str] = None) -> bool: """ Create and show an information notification. Args: title: Title of the notification message: Content of the notification subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ return self.notification_manager.show_notification( title=title, message=message, notification_type=NotificationType.INFO, subtitle=subtitle ) def create_warning_notification(self, title: str, message: str, subtitle: Optional[str] = None) -> bool: """ Create and show a warning notification. Args: title: Title of the notification message: Content of the notification subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ return self.notification_manager.show_notification( title=title, message=message, notification_type=NotificationType.WARNING, subtitle=subtitle ) def create_error_notification(self, title: str, message: str, subtitle: Optional[str] = None) -> bool: """ Create and show an error notification. Args: title: Title of the notification message: Content of the notification subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ return self.notification_manager.show_notification( title=title, message=message, notification_type=NotificationType.ERROR, subtitle=subtitle ) def create_success_notification(self, title: str, message: str, subtitle: Optional[str] = None) -> bool: """ Create and show a success notification. Args: title: Title of the notification message: Content of the notification subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ return self.notification_manager.show_notification( title=title, message=message, notification_type=NotificationType.SUCCESS, subtitle=subtitle ) macos_notification_factory = MacOSNotificationFactory() def show_macos_notification(title: str, message: str, notification_type: str = "info", subtitle: Optional[str] = None) -> bool: """ Show a macOS notification with the specified parameters. This is a convenience function for showing notifications without directly interacting with the MacOSNotificationFactory or MacOSNotificationManager classes. Args: title: Title of the notification message: Content of the notification notification_type: Type of notification ("info", "warning", "error", "success") subtitle: Optional subtitle for the notification Returns: True if the notification was successfully displayed, False otherwise """ try: notification_type_enum = NotificationType(notification_type) except ValueError: logger.warning(f"Invalid notification type: {notification_type}, using INFO") notification_type_enum = NotificationType.INFO if notification_type_enum == NotificationType.INFO: return macos_notification_factory.create_info_notification(title, message, subtitle) elif notification_type_enum == NotificationType.WARNING: return macos_notification_factory.create_warning_notification(title, message, subtitle) elif notification_type_enum == NotificationType.ERROR: return macos_notification_factory.create_error_notification(title, message, subtitle) elif notification_type_enum == NotificationType.SUCCESS: return macos_notification_factory.create_success_notification(title, message, subtitle) return macos_notification_factory.create_info_notification(title, message, subtitle)

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/naru-sensei/-toast-mcp-server'

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