Skip to main content
Glama
khughitt

Polybar Notification MCP

by khughitt

display_polybar_message

Send custom notifications to the polybar status bar for user alerts or operation status. Configure message content, duration, text color, and background color to fit specific needs.

Instructions

Display a message in polybar status bar. Useful for notifying the user when an operation is complete or when waiting for user input.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
backgroundNoBackground color for the message (default: #333333)
colorNoText color for the message (default: #ffffff)
durationNoDuration in seconds to display the message (default: 5)
messageYesThe message to display in polybar

Implementation Reference

  • The core handler function implementing the display_polybar_message tool logic. It attempts multiple methods to display the message in Polybar: polybar-msg hook with file write, fallback to named pipe/file writes, and finally xsetroot, with automatic cleanup after duration.
    export async function displayPolybarMessage( message: string, options: PolybarMessageOptions ): Promise<string> { try { // Method 1: Try to send message to polybar via polybar-msg try { await execAsync(`polybar-msg hook polybar-notification-mcp 1`); // Write the message to /tmp/polybar-mcp-message (for polybar to read) await execAsync(`echo '{"message": "${message.replace(/'/g, "'\\''")}"}' > /tmp/polybar-mcp-message`); // Schedule cleanup after duration: clear the message setTimeout(async () => { try { await execAsync(`echo '{"message": ""}' > /tmp/polybar-mcp-message`); await execAsync(`polybar-msg hook polybar-notification-mcp 2`); } catch (error) { console.error('Error cleaning up polybar message:', error); } }, options.duration * 1000); return `Message sent to polybar via polybar-msg (duration: ${options.duration}s)`; } catch (polybarError) { // Method 2: Try to write to a named pipe or file that polybar might be monitoring try { const pipePath = '/tmp/polybar-mcp-pipe'; const messageData = JSON.stringify({ message, color: options.color, background: options.background, duration: options.duration, timestamp: Date.now(), }); // Try to write to named pipe await execAsync( `echo '${messageData}' > ${pipePath} 2>/dev/null || true` ); // Also write to a regular file as fallback await execAsync(`echo '${messageData}' > /tmp/polybar-mcp-message`); // Schedule cleanup after duration: clear the message setTimeout(async () => { try { const emptyMessageData = JSON.stringify({ message: '', color: options.color, background: options.background, duration: 0, timestamp: Date.now(), }); await execAsync(`echo '${emptyMessageData}' > ${pipePath} 2>/dev/null || true`); await execAsync(`echo '${emptyMessageData}' > /tmp/polybar-mcp-message`); } catch (cleanupError) { console.error('Error clearing polybar message (pipe/file):', cleanupError); } }, options.duration * 1000); return `Message written to polybar communication files`; } catch (fileError) { // Method 3: Use xsetroot to set window manager info (visible in some status bars) try { const displayMessage = `${message} [${new Date().toLocaleTimeString()}]`; await execAsync(`xsetroot -name "${displayMessage}"`); // Reset after duration setTimeout(async () => { try { await execAsync(`xsetroot -name ""`); } catch (error) { console.error('Error resetting xsetroot:', error); } }, options.duration * 1000); return `Message set via xsetroot (duration: ${options.duration}s)`; } catch (xsetError) { throw new Error( `All polybar methods failed. Last error: ${xsetError}` ); } } } } catch (error) { throw new Error( `Failed to display polybar message: ${error instanceof Error ? error.message : String(error)}` ); } }
  • Zod schema (DisplayPolybarMessageSchema) defining the input parameters for the tool: message (required string), duration/color/background (optional).
    const DisplayPolybarMessageSchema = z.object({ message: z.string().describe('The message to display in polybar'), duration: z .number() .optional() .describe('Duration in seconds to display the message (default: 5)'), color: z .string() .optional() .describe('Text color for the message (default: #ffffff)'), background: z .string() .optional() .describe('Background color for the message (default: #333333)'), });
  • src/index.ts:76-80 (registration)
    Tool registration in the ListToolsRequestSchema handler, specifying name 'display_polybar_message', description, and inputSchema.
    { name: 'display_polybar_message', description: 'Display a message in polybar status bar. Useful for notifying the user when an operation is complete or when waiting for user input.', inputSchema: zodToJsonSchema(DisplayPolybarMessageSchema), },
  • The dispatcher case in the CallToolRequestSchema handler that validates input with the schema, sets defaults, calls displayPolybarMessage, and formats the MCP response.
    case 'display_polybar_message': { const { message, duration, color, background } = DisplayPolybarMessageSchema.parse(args); const result = await displayPolybarMessage(message, { duration: duration || 5, color: color || '#ffffff', background: background || '#333333', }); return { content: [ { type: 'text', text: `Polybar message displayed: "${message}"${result ? ` - ${result}` : ''}`, }, ], }; }
  • TypeScript interface PolybarMessageOptions defining the options structure used by the handler.
    export interface PolybarMessageOptions { duration: number; color: string; background: string; }

Other Tools

Related Tools

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/khughitt/polybar-dunst-mcp'

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