mcp-speak
Provides text-to-speech playback on macOS by driving the built-in say command, allowing AI clients to speak text aloud with selectable system voices and speaking rates, list available voices, and manage a shared playback queue with status, stop, mute (hold/discard) and unmute controls.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
mcp-speak
macOS標準の say コマンドを使い、MCPクライアントからテキストを読み上げるローカルサーバーです。読み上げ処理に外部の音声合成APIやAPIキーは使いません。
複数のClaude Codeスレッド・MCPプロセスからの依頼を、同じログインユーザーの共有ワーカーで順番に再生します。Rustや別の音声サーバーの導入は不要です。
ブラウザの操作画面で、発話履歴の確認、保留・破棄ミュート、音声と速度の設定、試聴ができます。PCでは履歴と操作パネルを並べ、スマートフォンでは画面下部の「操作・設定」からパネルを開きます。
初めて使う場合は「必要な環境」「インストール」「MCPクライアントへの登録」の順に進めてください。ツールの引数や開発手順は、必要なときに参照できます。
必要な環境
macOS(
/usr/bin/sayが利用可能な環境)Node.js 22以上とnpm
ローカルの標準入出力(stdio)接続に対応したMCPクライアント
音声は、このサーバーを実行するMacから再生されます。音声ファイルやストリームをクライアントへ送る機能はありません。
Related MCP server: mcp-speak
インストール
git clone https://github.com/mumei/mcp-speak.git
cd mcp-speak
npm cipackage-lock.json をGitで管理し、npm ci で依存関係を再現します。npmレジストリへの公開は行っていないため、GitHubから取得してください。
MCP受付プロセスを手動で起動する場合は、次のコマンドを使います。
npm start起動後はMCPクライアントからの入力を待ちます。ターミナルに通常の文章を入力して読み上げるCLIではありません。終了は Ctrl+C です。Claude Codeに登録した場合はClaude Codeが受付プロセスを起動するため、通常は npm start の手動実行は不要です。
MCPクライアントへの登録
Claude Codeのコマンド登録
上記の npm ci を済ませてから登録します。まず claude mcp get mcp-speak または claude mcp list で、同名の登録がないか確認してください。登録済みの場合は内容を確認し、削除・上書きせずに既存の設定を使えるか判断します。
新規登録のコマンドは次のとおりです。
claude mcp add --transport stdio --scope user mcp-speak -- "/absolute/path/to/node" "/absolute/path/to/mcp-speak/index.js"command -v node でNode.jsの場所を確認し、例の2つのパスをNode.jsと取得した index.js の絶対パスに置き換えてください。空白を含むパスも渡せるよう、引用符は残します。
--scope user は、同じユーザーの全プロジェクトで使うための登録先です。-- より後ろは、MCPサーバーを起動するコマンドと引数です。
登録後は、次のコマンドで登録内容と接続状態を確認できます。Claude Code内では /mcp でも確認できます。
claude mcp get mcp-speak
claude mcp list登録形式・スコープ・確認方法は Claude Code公式のMCPドキュメント を参照してください。
設定ファイルの登録例
クライアントの設定に、次のようなstdioサーバーを登録します。設定キーや保存先はクライアントによって異なります。
{
"mcpServers": {
"mcp-speak": {
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/mcp-speak/index.js"]
}
}
}command -v node でNode.jsの場所を確認し、command をその絶対パスに置き換えてください。args も取得した index.js の絶対パスにします。クライアントの作業ディレクトリやGUIアプリのPATHに依存せず起動できます。
各Claude Codeスレッドには、このstdio設定をそのまま使えます。各スレッドのMCPプロセスは別々に起動しても、再生ワーカーは1つです。クライアント設定や CLAUDE.md、hooksをこのプロジェクトが書き換えることはありません。
MCP受付と共有再生ワーカー
Claude Code A → MCPプロセスA ─┐
├→ 共通FIFO → 再生ガード → say(1つずつ)
Claude Code B → MCPプロセスB ─┘MCPプロセスは入力検証・キュー受付・操作を担当します。共有ワーカーは受け取った順に依頼を並べ、前の say の終了を確認してから次を再生します。同時送信の順番はワーカーが受け取った順番です。他アプリが直接起動した say や別ログインユーザーの音声は、このキューの対象外です。
最初のキュー操作で、画面のないNode製ワーカーが自動で起動します。通常は npm run worker の手動実行も不要です。最後のクライアントが切断し、再生・待機分がなくなると60秒後に終了します。Web受付はMCP起動時に自動で用意します。メニューバーUI・ログイン時の自動起動登録はありません。ワーカーを手動で起動したい場合は npm run worker を使い、終了は Ctrl+C です。
接続先は 127.0.0.1 のみです。既定ポートは 43000 + ユーザーID % 1000 で、OSの排他的bindにより二重起動を防ぎます。/tmp/mcp-speak-<ユーザーID>-v1 に権限700の専用ディレクトリを作り、権限600のランダムトークンで認証します。同じOSユーザーによる操作は信頼境界の内側です。
テストなどで変える場合は、全クライアントに同じ MCP_SPEAK_QUEUE_DIR(絶対パス)と MCP_SPEAK_QUEUE_PORT を設定します。別のディレクトリやポートに分けると共通FIFOを共有できません。既定ポートを他アプリが使っている場合は、そのアプリを停止する代わりに共通の別ポートを指定してください。
ブラウザの操作画面
MCPが起動すると、同じOSユーザー・キュー設定のWeb受付も自動起動します。複数のMCPで共通の受付を使い、ブラウザは自動で開きません。画面を開くには、依存関係を npm ci で用意したあと、MCPと同じチェックアウト・環境設定で次を実行します。
npm run web起動済みのWeb受付があれば再利用し、なければ起動して、ターミナルにURLを表示します。既定の画面URLは http://127.0.0.1:44501/ です。同じMacのブラウザで開いてください。認証キーは不要で、新しいタブでも同じURLを使えます。npm run web の終了は Ctrl+C です。
ポートを変更するには、MCPと手動CLIの両方に同じ MCP_SPEAK_WEB_PORT を設定します。たとえば MCP_SPEAK_WEB_PORT=44502 npm run web を使う場合は、MCP登録の環境変数にも MCP_SPEAK_WEB_PORT=44502 を設定します。
Web受付は、接続中のMCPまたは npm run web が一つでもあれば維持します。すべてが終了してから60秒後にWeb受付を終了します。ブラウザのタブだけでは受付を維持しません。Web終了時も共有ミュートを解除せず、MCPからの再生や待機分を破棄しません。受付が異常終了した場合は、接続中のMCP・手動CLIが再起動を試み、画面も同じURLで接続を再確認します。
自動Webが不要な環境では、MCP登録の環境変数に MCP_SPEAK_WEB_AUTOSTART=0 を設定します。読み上げ・共有キューはそのまま利用でき、必要なときだけ npm run web で受付を起動できます。自動起動の失敗もMCPの読み上げを止めません。Webポートが他のアプリ・別ユーザー・別キューの受付と重複した場合は、エラーを報告します。自動で別番号へ変更したり、その受付へ接続したりはしません。MCPと手動CLIの両方で、競合しない共通ポートを指定してください。
画面は共有ワーカーにつながります。通常はワーカーが最初の操作で自動起動します。MCPクライアントと同じ MCP_SPEAK_QUEUE_DIR・MCP_SPEAK_QUEUE_PORT を使ってください。接続数にはWeb画面の受付プロセスも含まれます。
PCでは左に発話履歴、右に再生操作・音声設定を表示します。履歴は最新が上、古いものが下に並びます。再生中の文章は履歴の該当行で確認できます。狭い画面では、右上に固定した「操作・設定」から右側のドロワーを開きます。長い履歴の途中や末尾からも操作できます。ミュート中はヘッダーに「保留中」「破棄中」を表示します。
ヘッダーに接続状態・再生状態・待機数・接続数を表示します。接続状態は点の色と短いラベルで示し、未取得の数値は「—」を表示します。ヘッダーはスクロール中も上部に残り、「履歴を消去」から確認画面を開けます。消去するのは履歴だけで、再生中・待機中の依頼は止まりません。
ドロワーでは背景の操作を止め、内容だけをスクロールできます。上部の「閉じる」、Escape、背景クリックで閉じ、履歴のスクロール位置と未保存の選択を保ちます。キーボードのフォーカスはパネル内で循環し、閉じると開いたボタンへ戻ります。PC幅へ変えると同じ入力欄を右パネルへ戻します。画面を開く・閉じる・幅を変える操作だけで、発話や設定保存は行いません。
「保留」は現在の再生を停止して待機分・新規分を保留し、「破棄」は現在の再生を停止して待機分・新規分を破棄します。「解除」で保留分を順番に再生します。停止した現在の文章は再送しません。画面の更新や接続復帰が勝手にミュートを解除することはありません。
「声と話す速さ」では、このMacで利用可能な音声と1〜500単語/分の速度を選べます。音声一覧は言語別にまとめ、言語名と地域を表示します。各グループ内は音声名順です。音声の再取得でも入力途中の選択を保ちます。速度はスライダーと数値のどちらでも調整できます。「試聴する」は選択中の設定で短い確認文を共有キューへ送り、履歴に「試聴」と表示します。試聴だけでは設定を保存しません。保留中は試聴も待機し、破棄中は試聴も破棄します。音声はほかの発話と順番に再生し、試聴のためにミュートを自動解除することはありません。
「設定を保存」で、今後受け付ける通常の発話の既定値を変更します。voice と rate はそれぞれ、発話時の明示指定 → Webの保存値 → Macの既定音声・175単語/分 の順に決まります。たとえばKyoko・220を保存したあと rate: 140 だけを指定すると、Kyoko・140で受け付けます。再生中・待機中の依頼は受付時の設定を維持します。ブラウザの定期更新は入力途中の選択を上書きせず、保存済みの値を別に表示します。
選択を変えたら「設定を保存」を押してください。保存成功は画面に表示します。試聴や選択の変更だけでは保存されません。通常の保存先は ~/Library/Application Support/mcp-speak/speech-settings.json(ディレクトリ権限700、ファイル権限600)です。ページの再読込・ワーカーの再起動・一時キューディレクトリの削除後も保存値を使います。旧キューディレクトリに保存値が残っている場合は、最初の起動で引き継ぎます。
独自の MCP_SPEAK_QUEUE_DIR を指定すると、音声設定もそのディレクトリに保存します。キューとは別の場所に保持するには、すべての接続元で同じ MCP_SPEAK_SETTINGS_DIR を指定してください。macOS全体の既定音声・音量は変更せず、音声をダウンロードしません。保存した音声がMacから削除された場合は、利用可能な音声を選び直して保存してください。音声一覧の取得に失敗した場合は「音声を再取得」を使えます。
履歴は共有ワーカーのメモリ内に直近100件を保持します。文章は各依頼の先頭512文字、エラー理由は先頭160文字です。受付・再生準備・再生中・再生完了・失敗・破棄・停止/取消を区別します。ワーカーの終了・再起動で履歴は消えます。 ブラウザを閉じるだけでは履歴は消えません。画面の「履歴を消去」で削除できます。履歴の消去は再生や待機分を停止しません。音声ファイル保存、マイク録音、画面録画は行いません。
Web受付は 127.0.0.1 だけで待ち受け、Macの外からは接続できません。Webには認証がないため、同じMac上のプログラムは、別のOSユーザーのプログラムも含め、認証キーなしで履歴の閲覧・ミュートなどの操作が可能です。 HostとOriginの検証、操作APIのJSON限定、CSP、文章のテキスト表示により、別サイトからの操作やHTML実行を防ぎます。
共有キュー内部は、OSユーザーごとの専用ディレクトリと認証トークンで保護します。Web受付の起動情報はそのディレクトリ内に権限600で保存し、正常終了時に削除します。MCPと手動CLIは所有者・キュー設定・受付の識別情報を照合して再利用します。この識別情報はWebへのアクセスを制限するキーではありません。MCPの標準出力にはURLやログを混ぜず、文章・履歴を外部サービスへ送信しません。
確認する場合はMCPクライアントから短い文章を依頼し、履歴が受付から完了へ変わることを確認してください。保留・破棄・解除は共有キュー全体に作用するため、ほかのクライアントの依頼にも反映されます。接続できないときは操作ボタンを無効にして状態を「不明」と表示し、読み取りだけを再試行します。操作の応答を失った場合は自動再送しません。
ツールと引数
speak:テキストの読み上げ
引数 | 型 | 必須 | 内容 |
| 文字列 | はい | 読み上げる文章。空文字・空白のみは不可。UTF-8で64KiB以内 |
| 文字列 | いいえ | このMacで利用可能な音声名。省略時はWebの保存値、未設定ならMacの既定音声。256文字以内 |
| 整数 | いいえ | 1分あたりの単語数。1〜500。省略時はWebの保存値、初期値175 |
{
"text": "作業が完了しました。",
"voice": "Kyoko",
"rate": 175
}通常の発話では text だけを渡し、voice・rate は省略してWebで保存した共有設定を使います。ユーザーが特定の声や速度を求めた発話など、変更が必要なときだけ明示指定でその発話を上書きできます。初期値や任意の音声を毎回指定する必要はありません。
Kyoko は例です。使用する音声は list_voices で確認してください。音声の追加や既定音声の変更はmacOS側で行います。
テキストは say の標準入力へ渡すため、先頭の - やシェルの記号をコマンドの引数として扱いません。未対応の引数、不正な型、範囲外の速度は isError: true で返します。
list_voices:利用可能な音声一覧
引数は不要です。空オブジェクト {} でも呼び出せます。音声名・言語・サンプル文章を含む一覧を返します。
ターミナルから音声を確認する場合は、次のコマンドも使えます。
say -v '?'応答は再生完了を保証しません
speak は共通FIFOへの受付後に応答し、受付IDとその時点の順番を返します。応答は再生開始・完了を意味しません。破棄ミュート中は、再生せず破棄したことを返します。受付後の失敗は依頼元MCPの標準エラーへ記録します。
再生中と待機分を合わせて100件までです。満杯になった場合は新しい依頼を isError: true で拒否し、既存の順番を保ちます。1件の再生は最大120秒で停止します。再生完了を待つMCPツールはありません。
状態・停止・ミュートを操作する
MCPツール | 引数 | 共有ワーカーでの動作 |
| なし | 再生中か、待機件数、ミュート状態・モード、異常状態を表示 |
| なし | 現在の発声を止め、待機分を消す。ミュート状態は維持 |
|
| 現在の発声を止め、待機分と新規依頼を上限付きでFIFO保留 |
|
| 現在の発声を止め、待機分を消し、新規依頼も破棄 |
| なし | ミュートを解除。保留分があれば順番に再生 |
どちらのミュートも途中の発声を再キューしません。保留から破棄へ切り替えると待機分を消します。破棄から保留へ切り替えると、その後の新規依頼から保持します。OSの音量や他アプリの音声は変更しません。
ミュート状態・モードは権限600の mute-state.json に保存し、ワーカーが再起動しても維持します。待機テキストはメモリ内だけに保持し、ディスクへ保存しません。
ターミナルからも同じ操作が可能です。状態確認CLIはワーカーを新しく起動しません。
npm run queue:status
npm run queue:mute -- hold
npm run queue:mute -- discard
npm run queue:unmute
npm run queue:stop
npm run queue:shutdownqueue:shutdown はこの共有ワーカーを終了します。接続中のMCPは切断され、次の操作で接続し直します。ミュートは自動解除しません。
AIへ発話の使い方を伝える
MCP初期化応答の正式な instructions フィールドと、tools/list のツール説明・入力説明に、AI向けの使用方針を載せています。対応クライアントではMCP登録と接続だけで受け取れます。方針を受け取るためにClaude側の CLAUDE.md やhooksの追加は必須ではありません。ただし、クライアントが指示をモデルへ渡すことや、AIが必ず従うことは保証できません。
方針は「必要な完了報告」「問題やユーザー判断が必要な場面」「明示された読み上げ依頼」に、短い要点だけを発話するものです。細かな途中経過・長いコード・生ログ・認証情報を読まず、同じ内容を繰り返しません。ユーザーのミュートや停止を尊重し、AIが勝手に解除・モード変更・再送しないよう伝えます。
読み上げは、AIが使用方針を踏まえて speak を呼んだときに実行します。
ソース更新を反映する
ソースを更新したら、動作中のMCP受付・共有ワーカー・Web受付を再起動して変更を反映します。
再生中・待機中の依頼が終わるのを待ちます。
同じ共有キューを使うMCP接続と、手動で起動した
npm run webを終了します。ワーカーをnpm run workerで手動起動している場合も終了します。自動起動した共有ワーカーとWeb受付が終了するまで60秒待ちます。
更新したチェックアウトで
npm ciを実行し、MCPクライアントの接続を再開します。ブラウザは同じURLで開けます。
切断・失敗・異常終了
MCP接続が切断すると、その接続が依頼した待機分と再生中の発声だけをキャンセルします。他クライアントの待機分は維持します。受付前のMCPリクエスト取消にも対応します。受付後の発声は stop_speech などで操作してください。通常の再生失敗・キャンセルでは、所有する say の終了を確認してから次へ進みます。
ワーカーが強制終了しても、再生ガードが親との切断を検知し、自分が起動した say だけを停止します。別ワーカーは playback.json が解放されるまで次を始めません。ガード自体が強制終了するなど、前の発声の停止を確認できない場合は、新規再生を拒否して異常状態を返します。killall say は使いません。
異常状態では queue:status を確認し、queue:shutdown でワーカーを終了してください。自分のツールの発声が停止したと確認できた場合だけ、専用ディレクトリに残った playback.json を削除して再起動します。停止確認なしに再生記録を消すと音声が重なるおそれがあります。認証トークンを削除するとクライアント間の認証が変わるため、復旧時にディレクトリ全体を削除しないでください。
ワーカーの異常終了や接続喪失では、未完了の受付分を自動再送しません。待機分は失われる場合があります。ミュート状態は保存済みの設定を維持します。
開発とテスト
npm ci
npm run check
npm testnpm test はNode.js標準のテストランナーを使います。専用の一時ディレクトリ・ポート・疑似プレイヤーで、2つの実MCPプロセスのFIFOと重複なし、ミュート2モードと切替、上限、停止・切断・ワーカー強制終了、認証、初期化のAI向け方針、音声設定の優先順位・保存・受付時固定、ミュート中の試聴、Web APIの音声名・Origin・JSON検証を検査します。通常のテストで音声は再生しません。
Macの実際の say とMCP接続を確認するには、次を実行します。短い音声を1回再生するため、音を出せる環境で実行してください。
npm run test:smokeスモークテストは接続、音声一覧、不正入力の拒否、読み上げの受付を検査します。再生完了や音質は検査しません。接続を閉じるとその発声がキャンセルされるため、実際の再生確認には2クライアント検証を使います。
npm run test:queue:smoke専用の一時ディレクトリ・ポートを使い、独立した2つのMCPプロセスから「一番です。」「二番です。」だけを送ります。実際の say の正常終了と、前の再生終了後に次が始まることを検査します。普段使っている共有キューやミュート設定には触れません。
GitHub Actionsでも、macOS上のNode.js 22・24で構文チェックと自動テストを実行します。CIでは音声再生を伴うスモークテストを実行しません。
配布内容の確認には npm pack --dry-run を使います。パッケージには実装・README・LICENSEのみを含め、IDE設定、テスト、ローカル設定は除外します。
問題が起きたとき
接続できない場合は、登録したNode.jsと index.js のパス、npm ci の完了を確認してください。音が出ない場合は、Macの出力先・音量と say 'テストです' の動作を確認します。標準エラーのログには、受付後に発生した音声処理の失敗も出力されます。
不具合の報告は GitHub Issues へお願いします。macOSとNode.jsのバージョン、再現手順を添え、読み上げ文章に含まれる個人情報や秘密情報は伏せてください。
MCPはアプリからツールを呼び出すためのプロトコルです。このサーバーのstdio接続では、標準入力でリクエストを受け、標準出力で応答を返します。ログには標準エラーを使います。
ライセンス
MIT。
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted text-to-speech MCP server: 66 voices in 9 languages, long-form narration, podcasts.
MCP server for Text-to-Speech
Create, inspect, and manage Wubble music, speech, voice, and sound-effect requests through MCP.
Remote text-to-speech MCP server with text_to_speech and list_voices tools. Free plan.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides text-to-speech conversion through a unified MCP interface, supporting both local Kokoro and cloud OpenAI TTS engines with streaming audio, voice selection, and customization via natural language instructions.7-
- AlicenseAqualityBmaintenanceEnables AI agents to speak using MacOS native text-to-speech, with support for blocking and non-blocking speech and a sequential queue.215MIT
- AlicenseAqualityDmaintenanceMCP server for text-to-speech using macOS say command, enabling speech synthesis, audio file generation, and voice management.521 npm1MIT
- AlicenseAqualityCmaintenanceEnables MCP clients to synthesize text into speech locally and play it through the machine's audio, with selectable voices and playback speed.255 PyPIApache 2.0