Skip to main content
Glama
message-manager.ts5.15 kB
/** * Navidrome MCP Server - One-Time Message Manager * Copyright (C) 2025 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ /** * Manages one-time messages for LLM assistants * Ensures tips, reminders, and helpful messages are shown only once per session */ export class MessageManager { private static instance: MessageManager | null = null; private readonly shownMessages: Set<string>; private readonly messageTemplates: Map<string, string>; private constructor() { this.shownMessages = new Set(); this.messageTemplates = new Map(); this.initializeMessages(); } /** * Get the singleton instance of MessageManager */ public static getInstance(): MessageManager { MessageManager.instance ??= new MessageManager(); return MessageManager.instance; } /** * Initialize predefined message templates */ private initializeMessages(): void { // Radio validation reminder this.messageTemplates.set('radio.validation_reminder', ` 🎵 STREAM VALIDATION RECOMMENDED Use 'validate_radio_stream' tool first to test your URL Many internet radio URLs change frequently Validation checks: accessibility, audio format, streaming headers 💡 TIP: Find reliable streams at radio-browser.info or somafm.com`); // Radio list tip this.messageTemplates.set('radio.list_tip', "💡 TIP: Use 'validate_radio_stream' to test station URLs if playback issues occur"); // Radio creation success this.messageTemplates.set('radio.creation_success', "✅ Station created successfully! Remember to validate streams periodically as URLs may change."); // General validation advice this.messageTemplates.set('radio.validation_advice', "🔍 Pro tip: Radio streams can go offline. Validate regularly for best experience."); // Add more message templates as needed this.messageTemplates.set('general.welcome', "🎶 Welcome to Navidrome MCP! Type 'test_connection' to verify your setup."); } /** * Get a message if it hasn't been shown yet * @param messageKey The unique key for the message * @param customMessage Optional custom message to use instead of template * @returns The message if not shown before, null otherwise */ public getMessage(messageKey: string, customMessage?: string): string | null { // Check if message was already shown if (this.shownMessages.has(messageKey)) { return null; } // Mark as shown this.shownMessages.add(messageKey); // Return custom message or template if (customMessage !== null && customMessage !== undefined && customMessage !== '') { return customMessage; } return this.messageTemplates.get(messageKey) ?? null; } /** * Check if a message has been shown * @param messageKey The unique key for the message */ public hasShownMessage(messageKey: string): boolean { return this.shownMessages.has(messageKey); } /** * Manually mark a message as shown without returning it * @param messageKey The unique key for the message */ public markAsShown(messageKey: string): void { this.shownMessages.add(messageKey); } /** * Reset all shown messages (useful for testing) */ public reset(): void { this.shownMessages.clear(); } /** * Get all available message keys (for debugging) */ public getAvailableMessageKeys(): string[] { return Array.from(this.messageTemplates.keys()); } /** * Add a new message template at runtime * @param key The unique key for the message * @param message The message content */ public addMessageTemplate(key: string, message: string): void { this.messageTemplates.set(key, message); } /** * Format a message with dynamic values * @param messageKey The message key * @param values Object with key-value pairs to replace in message */ public getFormattedMessage( messageKey: string, values: Record<string, string | number>, customMessage?: string ): string | null { const message = this.getMessage(messageKey, customMessage); if (message === null || message === undefined || message === '') return null; let formatted = message; for (const [key, value] of Object.entries(values)) { formatted = formatted.replace(new RegExp(`{{${key}}}`, 'g'), String(value)); } return formatted; } } // Export singleton getter for convenience export function getMessageManager(): MessageManager { return MessageManager.getInstance(); }

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/Blakeem/Navidrome-MCP'

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