send_notification
Send macOS notifications with custom title, message, subtitle, and sound using osascript.
Instructions
Send a notification on macOS using osascript
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Title of the notification | |
| message | Yes | Main message content | |
| subtitle | No | Optional subtitle | |
| sound | No | Whether to play the default notification sound |
Implementation Reference
- src/index.ts:54-85 (registration)Tool registration: The 'send_notification' tool is registered in the ListToolsRequestSchema handler with name, description, and inputSchema (title, message, subtitle, sound).
private setupToolHandlers() { // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'send_notification', description: 'Send a notification on macOS using osascript', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Title of the notification', }, message: { type: 'string', description: 'Main message content', }, subtitle: { type: 'string', description: 'Optional subtitle', }, sound: { type: 'boolean', description: 'Whether to play the default notification sound', default: true, }, }, required: ['title', 'message'], additionalProperties: false, }, }, - src/index.ts:222-246 (handler)Handler/router case: The CallToolRequestSchema routes 'send_notification' to extract params (title, message, subtitle, sound) and calls the imported sendNotification function.
switch (request.params.name) { case 'send_notification': { const { title, message, subtitle, sound } = request.params.arguments as Record<string, unknown>; if (typeof title !== 'string' || typeof message !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Title and message must be strings'); } const params: NotificationParams = { title, message, subtitle: typeof subtitle === 'string' ? subtitle : undefined, sound: typeof sound === 'boolean' ? sound : undefined }; await sendNotification(params); return { content: [ { type: 'text', text: 'Notification sent successfully', }, ], }; } - src/types.ts:1-13 (schema)NotificationParams interface defines the type schema for the tool: title, message, subtitle (optional), sound (optional).
/** * Parameters for sending a notification */ export interface NotificationParams { /** Title of the notification */ title: string; /** Main message content */ message: string; /** Optional subtitle */ subtitle?: string; /** Whether to play the default notification sound */ sound?: boolean; } - src/features/notification.ts:52-81 (handler)Core handler function: sendNotification validates params, builds AppleScript command, executes it via osascript, with error handling for command failures and permission errors.
export async function sendNotification(params: NotificationParams): Promise<void> { try { validateParams(params); const command = buildNotificationCommand(params); await execAsync(command); } catch (error) { if (error instanceof NotificationError) { throw error; } // Handle different types of system errors const err = error as Error; if (err.message.includes('execution error')) { throw new NotificationError( NotificationErrorType.COMMAND_FAILED, 'Failed to execute notification command' ); } else if (err.message.includes('permission')) { throw new NotificationError( NotificationErrorType.PERMISSION_DENIED, 'Permission denied when trying to send notification' ); } else { throw new NotificationError( NotificationErrorType.UNKNOWN, `Unexpected error: ${err.message}` ); } } } - src/utils/command.ts:9-14 (helper)Helper utility: escapeString escapes special characters for AppleScript/shell usage within the notification command.
export function escapeString(str: string): string { // Escape for both AppleScript and shell return str .replace(/'/g, "'\\''") .replace(/"/g, '\\"'); }