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
| Name | Required | Description | Default |
|---|---|---|---|
| background | No | Background color for the message (default: #333333) | |
| color | No | Text color for the message (default: #ffffff) | |
| duration | No | Duration in seconds to display the message (default: 5) | |
| message | Yes | The message to display in polybar |
Implementation Reference
- src/notification-utils.ts:18-107 (handler)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)}` ); } }
- src/index.ts:40-54 (schema)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), },
- src/index.ts:95-111 (handler)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}` : ''}`, }, ], }; }
- src/notification-utils.ts:6-10 (helper)TypeScript interface PolybarMessageOptions defining the options structure used by the handler.export interface PolybarMessageOptions { duration: number; color: string; background: string; }