speak
Convert text to speech on macOS using customizable voice and rate settings. Ideal for notifications or accessibility needs within the Apple ecosystem.
Instructions
Speak text using macOS text-to-speech
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| rate | No | Speech rate (-50 to 50, defaults to 0) | |
| text | Yes | Text to speak | |
| voice | No | Voice to use (defaults to system voice) |
Implementation Reference
- src/features/speech.ts:60-88 (handler)Core handler function for the 'speak' tool. Validates SpeechParams, builds macOS 'say' command with voice and rate options, executes it, and handles errors appropriately.export async function speak(params: SpeechParams): Promise<void> { try { validateSpeechParams(params); const command = buildSpeechCommand(params); await execAsync(command); } catch (error) { if (error instanceof NotificationError) { throw error; } const err = error as Error; if (err.message.includes('execution error')) { throw new NotificationError( NotificationErrorType.COMMAND_FAILED, 'Failed to execute speech command' ); } else if (err.message.includes('permission')) { throw new NotificationError( NotificationErrorType.PERMISSION_DENIED, 'Permission denied when trying to speak' ); } else { throw new NotificationError( NotificationErrorType.UNKNOWN, `Unexpected error: ${err.message}` ); } } }
- src/index.ts:118-142 (registration)MCP tool registration entry for 'speak', including name, description, and JSON input schema defining parameters text (required), voice, and rate.{ name: 'speak', description: 'Speak text using macOS text-to-speech', inputSchema: { type: 'object', properties: { text: { type: 'string', description: 'Text to speak', }, voice: { type: 'string', description: 'Voice to use (defaults to system voice)', }, rate: { type: 'number', description: 'Speech rate (-50 to 50, defaults to 0)', minimum: -50, maximum: 50 } }, required: ['text'], additionalProperties: false, }, },
- src/types.ts:53-60 (schema)TypeScript interface defining the input parameters for the speak tool, matching the JSON schema.export interface SpeechParams { /** Text to speak */ text: string; /** Voice to use (defaults to system voice) */ voice?: string; /** Speech rate (-50 to 50, defaults to 0) */ rate?: number; }
- src/index.ts:269-287 (handler)MCP CallToolRequestSchema handler case for 'speak', which parses arguments into SpeechParams and delegates to the speak implementation.case 'speak': { const { text, voice, rate } = request.params.arguments as Record<string, unknown>; const params: SpeechParams = { text: text as string, voice: typeof voice === 'string' ? voice : undefined, rate: typeof rate === 'number' ? rate : undefined }; await speak(params); return { content: [ { type: 'text', text: 'Speech completed successfully', }, ], }; }
- src/features/speech.ts:7-36 (helper)Helper function to validate SpeechParams: checks text is string, voice is string if present, rate is number between -50 and 50.function validateSpeechParams(params: SpeechParams): void { if (!params.text || typeof params.text !== 'string') { throw new NotificationError( NotificationErrorType.INVALID_PARAMS, 'Text is required and must be a string' ); } if (params.voice && typeof params.voice !== 'string') { throw new NotificationError( NotificationErrorType.INVALID_PARAMS, 'Voice must be a string' ); } if (params.rate !== undefined) { if (typeof params.rate !== 'number') { throw new NotificationError( NotificationErrorType.INVALID_PARAMS, 'Rate must be a number' ); } if (params.rate < -50 || params.rate > 50) { throw new NotificationError( NotificationErrorType.INVALID_PARAMS, 'Rate must be between -50 and 50' ); } } }