mcpField
M
mcp-voice-summary

mcp-voice-summary

ローカル
github.comメディア・デザイン04 週間前に更新

mcp-voice-summary について

mcp-voice-summaryは、AIアシスタントがコード関連の作業を行った後、その概要を読み上げるローカルMCPサーバーです。オフラインのSAPI5とオンラインのニューラル音声に対応し、設定またはシステム言語に基づいて音声を選びます。

主な機能

  1. 01コード変更やコマンドの概要を読み上げ
  2. 02再生を非同期でキューに追加
  3. 03オフラインのSAPI5とオンラインのEdge音声
  4. 04実行中の言語と音声の選択
  5. 05音声、速度、音量、キュー上限の設定

活用シーン

  1. 01全文を読まずにコーディングエージェントの作業概要を聞く
  2. 02コード作業の状況を音声で確認しアクセシビリティを向上
  3. 03インターネット接続がない環境でオフライン音声合成を利用

MCP 対応

MCPクライアントに読み上げるテキストを送る`speak_summary`ツールと、実行中に言語や性別を変える`set_language`を公開します。stdioでローカル実行します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"eduplopez-mcp-voice-summary": {
"command": "uvx",
"args": [
"mcp-voice-summary"
],
"env": {
"VOICE_ENGINE": "<VOICE_ENGINE>",
"VOICE_LANGUAGE": "<VOICE_LANGUAGE>",
"VOICE_GENDER": "<VOICE_GENDER>",
"VOICE_RATE": "<VOICE_RATE>",
"VOICE_VOLUME": "<VOICE_VOLUME>",
"VOICE_MUTE": "<VOICE_MUTE>",
"VOICE_MODE": "<VOICE_MODE>"
}
}
}
}
起動コマンドuvx mcp-voice-summary
設定が必要な環境変数
VOICE_ENGINESynthesis engine: 'edge' for Azure neural voices (needs internet), 'sapi5' for fully offline native speech.
VOICE_LANGUAGEISO 639-1 code such as 'es' or 'en', optionally with a region such as 'pt-BR'. 'auto' detects it per summary, which is unreliable on short text. Empty follows the system language.
VOICE_GENDER'female' or 'male'. Requires the edge engine; sapi5 does not expose the gender of its voices.
VOICE_RATEReading speed. 100 is normal, 120 is faster, '-15%' is relative.
VOICE_VOLUMEVolume, 0 to 100.
VOICE_MUTESet to 1 to validate and queue summaries without playing anything. Useful in shared spaces.
VOICE_MODE'full' speaks the sanitized summary, 'short' replaces it with a fixed generic message so no summary content reaches the speakers or the cloud engine.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypimcp-voice-summary0.1.1

ツール

3

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
textstringはい

詳細

MCP 音声サマリーサーバー

CI PyPI Python Downloads License: MIT

AI アシスタントがコードに対して実行した操作の概要を読み上げる、ローカルのMCPサーバーです。アクセシビリティ機能として構築されており、応答全体を読まなくても、エージェントが実行したことを音声で聞けます。

ユーザーの言語に合わせて自動的に読み上げ、女性と男性の音声に対応しています。また、必要であれば完全にオフラインで動作します。

クイックスタート

pip install mcp-voice-summary

次に、インストールしたコマンドをMCPクライアントに指定します。Claude Desktop、Cursor、Clineでは、claude_desktop_config.jsonに次のように記述します。

{
  "mcpServers": {
    "voice-summary": {
      "command": "mcp-voice-summary",
      "env": {
        "VOICE_ENGINE": "edge",
        "VOICE_LANGUAGE": "es",
        "VOICE_GENDER": "male"
      }
    }
  }
}

envブロックは必要ありません。サーバーはシステムの言語から音声を選択します。上記の値は、音声を指定する場合にのみ使用します。

何もインストールせず、uvxを使う場合:

{
  "mcpServers": {
    "voice-summary": {
      "command": "uvx",
      "args": ["mcp-voice-summary"],
      "env": { "VOICE_ENGINE": "edge" }
    }
  }
}

このサーバーはMCP Registryにもio.github.eduplopez/mcp-voice-summaryとして登録されています。レジストリのメタデータは、このリポジトリ内のserver.jsonにあります。

次に、たとえば「タスクを完了したら、短い概要を声に出して読み上げてください」のように、アシスタントに使うよう伝えます。

プラットフォームのサポート

プラットフォーム推奨エンジン音声のソース追加インストール
Windows品質重視ならedge、オフラインならsapi5システム音声、またはニューラル音声オフライン用にpip install -e ".[sapi5]"
macOS品質重視ならedge、オフラインならsapi5システム音声、またはニューラル音声オフライン用にpip install pyttsx3
Linuxedgeニューラル音声再生用にpip install ffmpeg
Linux オフラインsapi5espeak-ngsudo apt install espeak-ng libespeak-ng1

edgeエンジンは、音声がMicrosoftのサーバーで生成されるため、読み上げのたびにインターネット接続が必要です。sapi5エンジンは完全にオフラインで動作します。

Linuxではオーディオプレーヤーが自動検出されます。何も見つからない場合は、ffmpeg(ffplayを提供)またはmpg123をインストールしてください。

Windowsで高品質な音声をオフラインで使う

Windowsには、デフォルトで公開されている3種類より高品質な音声が含まれていますが、SAPI5が読み取らないレジストリキーの下に隠されています。管理者として一度実行してください:

powershell -Command "Start-Process powershell -Verb RunAs -ArgumentList '-ExecutionPolicy Bypass -File .\register_voices_onecore.ps1'"

その後、Microsoft LauraとMicrosoft Pabloをsapi5で使用できるようになります。

できること

コードの変更、ファイルの作成、コマンドの実行後にアシスタントが呼び出す、MCPツール speak_summaryを提供します。

概要の長さは、実行した作業量に応じてアシスタントが決定します。小さな変更なら短い文、大きなタスクや複数の手順がある場合は、より詳しい概要になります。概要の長さの制御を参照してください。

再生は非同期です。ツールはテキストをキューに追加してすぐに戻るため、読み上げによってアシスタントの処理がブロックされることはありません。

要件

  • Python 3.10以降。
  • Windows、Linux、またはmacOS。

システム依存関係(ネイティブシンセサイザー)が必要なのはsapi5エンジンだけです。edgeエンジンにはPython以外は必要ありません。

動作確認

mcp-voice-summary

サーバーはstdio経由で音声を出力するため、コンソールには何も表示されません。これは正常です。stdoutに出力すると、プロトコルが壊れてしまいます。停止するにはCtrl+Cを押してください。

オフラインエンジンを使う場合は、まず追加パッケージをインストールしてください:

pip install -e ".[sapi5]"

設定

すべて環境変数で制御します。

変数値デフォルト説明
VOICE_ENGINEedge または sapi5sapi5音声合成エンジン
VOICE_NAME音声 ID または名前自動指定した音声。ほかのすべての設定より優先されます
VOICE_LANGUAGEes、en、pt-BR、autoシステム言語音声の言語
VOICE_GENDERfemale、male言語のデフォルト音声の性別
VOICE_RATE100、110、-15%100速度
VOICE_VOLUME100100音量
VOICE_PLAYERパスまたは名前自動検出強制的に使用する MP3 プレーヤー
MAX_SUMMARY_WORDS整数400要約の単語数の上限
MAX_QUEUE_SIZE2020音声読み上げ待ちの要約の最大数
PLAYBACK_TIMEOUT秒30再生が終了せずに応答が返らない場合に中断するまでの時間
VOICE_MUTE1、true、yes未設定サイレントモード。有効にするとキューには追加しますが、再生はしません
VOICE_REDACT0、false、noオン0 に設定すると、認証情報の除去を停止します
VOICE_RATE_LIMIT1 分あたりの通知数30クライアントによるキューへの大量送信を防ぎます
MAX_SUMMARY_AGE秒120この秒数より古いキュー内の要約は破棄されます
VOICE_MODEfull、shortfullshort は決まった汎用メッセージを読み上げます

VOICE_RATE と VOICE_VOLUME は、絶対値形式(100 を通常とする SAPI5 のスケール)と相対形式(+10%、-15%)の両方を受け付けます。サーバーは 各エンジンに必要な形式へ自動的に変換します。

設定を変更した後は、MCP クライアントを再起動してください。

言語

使用する言語に合わせて設定する必要はありません。 サーバーが自動的に音声を 選択します。優先順位は次のとおりです。

  1. VOICE_NAME が設定されている場合:手動で指定した値として常に優先されます。
  2. set_language がセッション中にアシスタントから呼び出された場合。
  3. 設定で VOICE_LANGUAGE が指定されている場合。
  4. オペレーティングシステムの言語。
  5. 最後の手段として英語。
言語と性別の変更

設定で永続的に変更する場合:

"environment": { "VOICE_LANGUAGE": "fr", "VOICE_GENDER": "male" }

または、何も編集せずに実行時に変更できます。ユーザーが自然言語で依頼すると、 アシスタントがツールを呼び出します。

set_language("en")             -> Language English (en), gender default
set_language("pt-BR", "male")  -> Language Portuguese (pt), gender male
set_language("", "f")           -> keep the language, switch to a female voice
set_language("system")         -> back to the OS language
set_language("", "any")         -> back to the language default gender

実行時の変更は、その後の発話に適用され、サーバーを再起動するか、別の値を指定して ツールを再度呼び出すまで有効です。

性別の指定が機能するのは edge エンジンのみです。SAPI5 は音声の性別を 公開していないため、sapi5 ではその旨を伝え、対応しているかのように装いません。 性別を選ぶにはニューラル音声が必要です。

言語の自動検出

VOICE_LANGUAGE=auto にすると、サーバーは各要約のテキストから言語を推定します。

この設定の使用には注意してください。 短いテキストでは言語検出の信頼性が低く、 短い要約はこのプロジェクトの主な用途です。実際の要約で検証した結果:

テキスト実際の言語検出された言語
"Done."スペイン語チェコ語(確信度 100 %)
"Listo"スペイン語ドイツ語
"Test 123"何語でもないフランス語
"I updated the login endpoint and fixed the dependencies"英語英語

検出器は誤っていても高い確信度を返すため、確率を使って誤検出を除外することは できません。つまり、長い文では機能しますが、短い文ではうまく機能しません。 言語を固定する場合は、VOICE_LANGUAGE を指定するほうが常に確実です。

langdetect がインストールされていない場合、auto は警告を記録し、英語に フォールバックします。それ以外のモードは、この依存関係がなくても動作します。

対応範囲

edge エンジンは、322 種類の音声を通じて 142 のロケールに対応しています。次の 34 言語には、女性と男性の音声がそれぞれ割り当てられています。

言語女性男性言語女性男性
esXimenaÁlvarodaChristelJeppe
enAvaAndrewfiNooraHarri
frVivienneRémynlColetteMaarten
deSeraphinaFlorianplZofiaMarek
itElsaGiusepperuSvetlanaDmitry
ptThalitaAntonioukPolinaOstap
caJoanaEnriccsVlastaAntonín
glSabelaRoiskViktoriaLukáš
huNoémiTamásroAlinaEmil
bgKalinaBorislavelAthinaNestoras
svSofieMattiastrEmelAhmet
nbPernilleFinnarSalmaShakir
jaNanamiKeitaheHilaAvri
koSun-HiHyunsuhiSwaraMadhur
zhXiaoxiaoYunxianthPremwadeeNiwat
viHoaiMyNamMinhidGadisArdi
msYasminOsman

(短縮名です。正確な識別子には Neural 接尾辞が付き、list_voices または python -m edge_tts --list-voices で確認できます。)

142 のロケールのうち、性別が一方のみなのは 2 つだけです。それは中国語の方言である zh-CN-liaoning と zh-CN-shaanxi です。選択したロケールに存在しない性別を指定すると、サーバーは警告をログに記録し、音声を無音にする代わりに利用可能な音声を使用します。

厳選された音声がない言語も利用できます。サーバーは 322 種類の音声から、指定された言語と性別に一致する最初の音声を検索します。たとえば、sw(スワヒリ語)は sw-KE-RafikiNeural に解決されます。

特定の地域バリエーションを指定した場合は、性別も含めてその指定が尊重されます。

指定女性男性
en-GBen-GB-LibbyNeuralen-GB-RyanNeural
pt-PTpt-PT-RaquelNeuralpt-PT-DuarteNeural
es-MXes-MX-DaliaNeurales-MX-JorgeNeural
zh-TWzh-TW-HsiaoChenNeuralzh-TW-YunJheNeural
fr-CAfr-CA-SylvieNeuralfr-CA-ThierryNeural

sapi5 エンジンで使用できるのはシステムにインストールされている音声のみです。そのため、対応言語はオペレーティングシステムが提供するものに限られ、性別を選択することもできません。Windows にはスペイン語と英語が付属していますが、その他の言語では音声を追加する必要があります。

音声

ニューラル音声(edge エンジン)

全 322 種類の音声カタログ:

python -m edge_tts --list-voices

スペイン語の音声 45 種類には、次のものが含まれます。

音声地域
es-ES-AlvaroNeuralスペイン、男性
es-ES-XimenaNeuralスペイン、女性
es-ES-ElviraNeuralスペイン、女性
es-MX-DaliaNeuralメキシコ、女性
es-MX-JorgeNeuralメキシコ、男性
es-US-PalomaNeuralアメリカ合衆国、女性
Windows ネイティブ音声(sapi5 エンジン)

初期状態では、非常に基本的な音声が 3 種類だけ表示されます。Windows には Microsoft Laura や Microsoft Pablo などの優れた音声も付属していますが、レジストリキー Speech_OneCore に登録されており、SAPI5 は読み取りません。

register_voices_onecore.ps1 は、これらのキーを SAPI5 が読み取るブランチにコピーします。管理者として PowerShell のプロンプトから 1 回だけ実行してください。

powershell -Command "Start-Process powershell -Verb RunAs -ArgumentList '-ExecutionPolicy Bypass -File .\register_voices_onecore.ps1'"

これは読み取り専用のコピーです。既存の音声が削除または上書きされることはなく、すでに存在するキーはスキップされます。その後、MCP クライアントを再起動し、list_voices を呼び出して確認してください。以降は、オフラインでも Laura と Pablo として利用できます。

MCP クライアントとの連携

OpenCode

すべてのプロジェクトで使えるように、グローバルに追加します。

opencode mcp add voice-summary -- "C:\path\mcp-voice-summary\.venv\Scripts\python.exe" "C:\path\mcp-voice-summary\mcp_voice_summary.py"

opencode mcp list で接続を確認してください。

エンジン、音声、言語を固定するには、~/.config/opencode/opencode.json を編集します。

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "voice-summary": {
        "type": "local",
        "command": ["mcp-voice-summary"],
        "environment": {
          "VOICE_ENGINE": "edge",
          "VOICE_LANGUAGE": "en",
          "VOICE_RATE": "120"
        }
      }
    }
  }
}

注:VOICE_NAME を設定すると、特定の音声が固定され、自動的な言語と性別の選択が無効になります。これらの機能を維持するには、代わりに VOICE_LANGUAGE と VOICE_GENDER を使用してください。

Claude Desktop

%APPDATA%\Claude\ にある claude_desktop_config.json:

{
  "mcpServers": {
    "voice-summary": {
      "command": "mcp-voice-summary",
      "env": {
        "VOICE_ENGINE": "edge",
        "VOICE_LANGUAGE": "en",
        "VOICE_RATE": "120"
      }
    }
  }
}
Cursor

プロジェクト内の .cursor/mcp.json:

{
  "mcpServers": {
    "voice-summary": {
      "command": "mcp-voice-summary",
      "env": { "VOICE_ENGINE": "edge", "VOICE_LANGUAGE": "en" }
    }
  }
}
その他のクライアント

これは標準的な stdio MCP サーバーなので、コマンド、引数、環境変数を指定するだけで十分です。

ツール

speak_summary(text)

システムのスピーカーからテキストを読み上げます。長さに制限はありません。アシスタントは作業量に応じて、短い要約または詳しい要約を送信します。テキストが安全上の上限を超えた場合は切り詰められ、その旨が応答に含まれます。

list_voices()

現在使用中の言語と音声、およびシステムにインストールされている音声を表示します。

set_language(language="", gender="")

設定を編集せずに、音声の言語と性別を設定します。

  • language:ISO 639-1 コード(es、en、fr)、地域バリアント(pt-BR、en-GB)、OS の設定に従う "system"、または要約ごとに検出する "auto" を指定します。空欄の場合は現在の言語を維持します。
  • gender:"f" または "m"、もしくは言語のデフォルトに従う "any" を指定します。空欄の場合は現在の性別を維持します。

要約の長さを調整する

長さはサーバーによって決められるわけではありません。アシスタントが作業量に応じて決定します。調整方法は2段階あり、その違いを理解しておくと便利です。

1. アシスタントが選ぶ長さ(推奨)

アシスタントがタスクに応じて長さを選びます。アシスタントに与える指示で調整します。作業に合わせて自動で調整されるため、ほとんどの場合はこの方法を使ってください。

バランスの取れた例:

When calling `speak_summary`, match the summary length to the size of the work:

- Small or single change: one short sentence, 10 to 20 words.
- Medium task or several files: two or three sentences, 30 to 60 words.
- Large task or long project: a summary of 80 to 150 words that walks through
  the main actions performed.

Always write in the first person, without reading out literal code.

より会話的な口調にしたい場合は、数値を大きくします。簡潔にしたい場合は、小さくします。唯一の正解はありません。タスクにかかる時間や、応答全体も読むかどうかによって異なります。

2. サーバーの安全上の上限

MAX_SUMMARY_WORDS は長さの推奨値ではなく、緊急ブレーキです。長すぎる text が数分間のアナウンスにならないようにします。上限を超えると、サーバーは要約を切り詰め、その旨を応答で伝えます。

"environment": { "MAX_SUMMARY_WORDS": "400" }
値おおよその長さ使用する場面
0切り詰めなしアナウンスを無制限にしたい場合のみ
150約1分大きなタスクでも短い要約を好む場合
400約2~3分デフォルト。バランスの取れた設定
800約5分作業が非常に長く、待つことが気にならない場合

英語のニューラル音声は、1秒あたり約2.5語を読み上げます。そのため、100語で約40秒かかります。理解しやすさには、正確な語数よりも短い文と間のほうが重要です。

長い要約では詳細が足りない場合は、上限を引き上げるのではなく、タスクを複数回に分けて呼び出すのがおすすめです。そうすれば最後に長い内容を一度に聞くのではなく、各段階の進行に合わせて聞くことができます。

3. 読み上げ速度を調整する

要約が遅すぎると感じる場合は、長さではなく速度を調整してください。

"environment": { "VOICE_RATE": "120" }  // 20% faster

動作ルールの設定

アシスタントにこの動作を自動で使わせるには、クライアントのルールに次の指示を追加します。OpenCode では ~/.config/opencode/AGENTS.md に記述します。

## Voice accessibility rule

You have access to the `voice-summary` MCP server with the `speak_summary`
tool. You MUST use it right after you finish modifying code, creating files or
running commands.

When calling it, match the summary length to the size of the work:

- Small or single change: one short sentence, 10 to 20 words.
- Medium task or several files: two or three sentences, 30 to 60 words.
- Large task or long project: a summary of 80 to 150 words that walks through
  the main actions performed.

Always write in the first person, without reading out literal code.

ユーザーから別の言語や音声、または男性・女性の音声で読み上げるように求められた場合は、set_language を呼び出してください。言語はデフォルトでシステムの設定に従うため、設定する必要はありません。

プライバシーとセキュリティ

このサーバーは、MCP クライアントが子プロセスとして起動し、自分のマシン上でローカル実行することを想定しています。ポートを開いたり、接続を待ち受けたりすることはありません。

エッジエンジンでマシン外に送信される情報

edge エンジンは音声を生成するため、要約テキストを Microsoft のサーバーに送信します。送信されるのは要約テキストのみで、コードは送信されません。ただし、要約にはファイル名、関数名、エラーメッセージなど、非公開にしておきたい情報が含まれる場合があることに注意してください。

この点が環境にとって問題となる場合は、代わりに sapi5 エンジンを使用してください。完全にオフラインで動作し、マシン外に何も送信されません。

エンジンネットワーク音声品質
edge要約テキストを Microsoft に送信高
sapi5マシン外に何も送信されない基本的。音声の種類は少ない
実装済みのセキュリティ対策
  • シェルは使用しません。 外部オーディオプレーヤーは引数リストで起動し、shell=True は使用しません。VOICE_PLAYER は shutil.which を通じて実在する実行可能ファイルに解決される必要があります。
  • 子プロセスが標準入力にアクセスすることはできません。 stdio MCP サーバーでは、標準入力と標準出力が JSON-RPC ストリームを運びます。stdin=DEVNULL を指定せずに起動したプレーヤーは、サーバー宛てのプロトコルメッセージを読み取る可能性があります。読み取り用の子プロセスでこれを検証し、現在は timeout やパイプ出力とともにブロックしています。
  • ログ出力に標準出力は使用しません。 音声合成器のインポート中に出力される内容はすべて標準エラー出力にリダイレクトされます。
  • あらゆる処理にタイムアウトを設定しています。 ネットワーク音声合成呼び出しとプレーヤープロセスはどちらも、ワーカーがいつまでも停止しないよう、PLAYBACK_TIMEOUT を過ぎると処理を中断します。
  • 入力をサニタイズします。 制御文字とマークアップを除去し、テキストだけが音声として読み上げられるようにしています。edge-tts は SSML 自体をエスケープしますが、sapi5 はテキストをそのまま OS の音声合成器に渡します。
  • 要約をログに記録することはありません。 失敗時のログには、行を関連付けられるよう、単語数と短い sha256 ダイジェストのみが記録されます。ファイル名、エラーテキスト、シークレットは保存されません。
  • 認証情報は、テキストを読み上げたり送信したりする前に除去されます。 秘密鍵ブロック、プロバイダートークン(OpenAI、GitHub、Slack、Google、AWS)、JWT、key=value 形式のシークレット、メールアドレスは [redacted] に置換されます。オープンオフィスで読み上げる要約や、クラウド TTS に送信する要約は、情報漏えいの経路になります。置換はプレースホルダーを経由するため、あるパターンが別のパターンの出力を壊すことはありません。要約に機密情報が含まれない場合に限り、VOICE_REDACT=0 で無効にできます。
  • 秘匿化は、統合したスパンを対象とする単一パス処理です。 元のテキストに対して各パターンを照合し、一度だけ置換するため、あるパターンが別のパターンの出力に再マッチすることはありません。また、この関数はべき等です。2回秘匿化しても同じ文字列になります。
  • 3つの軸で過剰な利用を抑制します。 キューサイズで一時的な集中を抑え、レート制限でサイズチェックをすり抜ける継続的なスパムを防ぎ、連続して同一の要約が送られた場合はスキップします。これらすべてを単一のロック下で実行するため、並行するハンドラーが制限を超えることはありません。
  • ツールを増やさず、カウンターで対応します。 list_voices は、受け付け済み、レート制限、キュー満杯、重複排除、切り詰め、秘匿化、古い通知の破棄、エラーの各件数を報告します。あらゆるツールが各ターンでコンテキストを消費するため、診断用に4つ目のツールを設ける必要はありません。
  • 古い通知は破棄されます。 MAX_SUMMARY_AGE を超えて待機した要約は、作業完了から数分後に読み上げられることがないよう破棄されます。
  • 孤立プロセスには標準ライブラリで対処します。 subprocess.run はタイムアウト時に子プロセスを強制終了します。自身の PID を書き出すプロセスを使って検証済みです。
  • 音声名は、キューに追加する前に現在のカタログと照合して検証されます。 そのため、VOICE_NAME の入力ミスは、無駄なネットワーク通信の後ではなく、すぐにわかりやすいメッセージとともに検出されます。
  • キューには MAX_QUEUE_SIZE による上限があります。 上限がなければ、再生より速く speak_summary を呼び出すクライアントによってキューが際限なく増加し、メモリを使い果たすおそれがあります。上限を超えるリクエストは拒否され、黙って破棄されることはありません。
  • ツールのアノテーションで副作用を明示しています。speak_summary は読み取り専用ではなく、べき等でもなく、外部に作用します。
  • 動的なコード実行はありません。 ソース内に eval、exec、pickle、os.system は一切ありません。
サイレントモード

VOICE_MUTE=1 を設定すると、音を出さずにサーバーを実行できます。要約は引き続き検証、キューへの追加、受領確認が行われるため、オフィスや会議中も安全にサーバーを有効にしておけます。speak_summary は "Muted." を返すため、実際に再生された場合と区別できます。

汎用メッセージモード

VOICE_MODE=short を設定すると、アシスタントが送信した内容にかかわらず、音声テキストは固定の "Task completed." になります。要約の内容がスピーカーやクラウドエンジンに渡ることはありません。

要約に機密情報が含まれる可能性がある場合や、生のテキストを聞きたくない場合に使います。ただし、情報は失われます。何が終わったのかではなく、「何かが終わった」ことしか分かりません。

リリースの前に毎回実行
.venv\Scripts\python.exe pre_release_check.py

テストスイート、pip-audit、標準出力の純粋性チェック、危険な呼び出しのスキャン、ツールカタログの予算、カウンターにテキストが含まれていないことのチェックを実行します。失敗するとゼロ以外のコードで終了するため、リリースのゲートとして使えます。

シークレットのパターンを追加するとき

秘匿化テストは、tests/test_server.py の先頭にあるテーブルで管理されています。パターンを追加するには、SECRET_CASES に行を追加します(該当するケースと、残ってはならない断片を指定します)。また、正当なテキストにも一致する可能性が十分にある場合は、BENIGN_CASES にも行を追加します。その後、すべてのケースについて、冪等性、マーカーの安全性、複数行への対応、空白や大文字・小文字の違いが自動的にチェックされます。

テスト

テストスイートでは、入力処理、キューの上限、音声の解決、プラットフォームのフォールバック、ログのプライバシー、トークン予算を確認します。実際の音声は再生しないため、オフラインで数秒で実行できます。

python -m unittest discover -s tests
既知の制限事項
  • 秘匿化は防御的なものであり、網羅的ではありません。 秘密鍵ブロック、一般的なプロバイダートークンの形式、JWT、key=value 形式のシークレット、メールアドレスを検出します。マーカーのない Base64 データ、Unicode の類似文字で表記されたシークレット、特殊な内部形式は検出できません。これだけを唯一の対策として頼らないでください。また、一致した範囲は全体が置き換えられるため、その前後の文脈も削除されます。
  • 音声と言語はプロセス全体で共有されます。 set_language はサーバー全体の状態を変更するため、2 つの MCP セッションが同じサーバープロセスと通信している場合、一方がもう一方の音声を変更できます。想定されている単一ユーザーのローカル環境では問題ありませんが、セッションごとに分離されるわけではありません。
  • 想定外のツール引数は拒否されず、無視されます。 SDK は関数のシグネチャからスキーマを導出し、additionalProperties: false を設定する方法を提供していません。speak_summary に tts_endpoint や api_key を渡しても、黙って破棄され、効果はありません。これは、追加フィールドを指定してツールを呼び出すことで検証されています。モデルが渡せる引数がネットワーク、ファイルシステム、コマンドラインに到達しないため、ここでは無視しても安全です。
  • 同期ツールの本体はイベントループではなく、ワーカースレッドで実行されます。 SDK はこれらを anyio.to_thread.run_sync 経由でディスパッチするため、秘匿化の正規表現によってサーバーが停止することはありません。
  • VOICE_PLAYER はプログラムを実行します。 これは本来の目的であり、ユーザー自身の設定からのみ読み込まれますが、信頼できない入力を使って設定しないでください。
  • langdetect の精度。 詳しくは自動言語検出をご覧ください。

実装に関する注意事項

変更する前に知っておくと役立つ、見落としやすい詳細です。

  • pyttsx3 は、あるスレッドでエンジンを作成して別のスレッドで使用すると、永久にブロックします。 COM はアパートメントスレッドモデルです。そのため、エンジンは遅延初期化され、常に同じワーカースレッドから使用されます。
  • 単一のワーカースレッドが queue を消費するため、連続する 2 つの発話が重なったり、途中で途切れたりすることはありません。
  • SAPI5 の runAndWait は発話が終わる前に戻ることがあるため、isBusy() を使って終了を待機します。edge エンジンはブロッキング方式で MCI 再生を行うため、タイミングは正確です。
  • ワーカースレッドはデーモンです。音声再生がプロセスの終了を妨げることはありません。
  • pyttsx3、edge_tts、langdetect のインポートは遅延されるため、いずれかが見つからなくてもサーバーは起動します。
  • 言語による音声の選択には、3 段階のフォールバックがあります。言語に対応する厳選された音声、次に優先する地域変種の任意の音声、最後にその言語の任意の音声です。そのため、厳選された音声がない言語でも動作します。
  • 音声に関するエラーはすべて捕捉され、ログに記録されます。音声を再生できないことが原因で MCP サーバーが停止することはありません。

トラブルシューティング

クライアントにツールが表示されません。 設定を編集した後、MCP クライアントを再起動してください。ほとんどのクライアントは起動時にのみ設定を読み込みます。コマンドが解決されることを確認してください。ターミナルで mcp-voice-summary を実行すると、stdio で何も出力せずに待機するため、出力はまったく表示されないはずです。

何も読み上げられません。 システムの音量と既定の出力デバイスを確認してください。edge エンジンを使用している場合は、インターネット接続を確認してください。設定と再生を切り分けるには、list_voices を呼び出して、報告された音声を確認します。問題がなさそうであれば、問題はサーバーではなく音声出力にあります。

機密情報がまだ読み上げられます。 VOICE_REDACT が 0 に設定されていないことを確認してください。秘匿化は安全対策として行われますが、あらゆる形式に対応できるわけではありません。そのため、本当に機密性の高い内容には、読み上げや送信の前にテキストを固定メッセージに置き換える VOICE_MODE=short をお勧めします。

音声が途中で切れたり、メッセージが重なったりします。 MCP サーバーが 1 つだけ実行されていることを確認してください。

No audio player was found。 edge エンジンを使用する Linux と macOS のみで発生します。ffmpeg、mpg123、vlc のいずれかをインストールするか、VOICE_PLAYER を設定してください。MCI を使用する Windows では発生しません。

Linux で sapi5 エンジンが音声を検出しません。 システム音声合成ソフトウェアをインストールしてください。sudo apt install espeak-ng libespeak-ng1。espeak の音声は edge-tts よりもかなり劣る点にご注意ください。

ImportError: No module named mcp.server.fastmcp。 これは v1 のコードです。FastMCP が MCPServer に名称変更された mcp>=2.0 をインストールしてください。このプロジェクトには 2.x が必要です。

予期しない言語で読み上げられます。 テキストが不自然なアクセントで読み上げられる場合、VOICE_LANGUAGE=auto による誤検出が原因である可能性が高いです。非常に短いテキストの言語検出は信頼性が低いことが知られています。set_language("fr") または VOICE_LANGUAGE で言語を固定してください。検出に失敗するケースの表を参照してください。

Windows の音声が単調に聞こえます。 管理者として register_voices_onecore.ps1 を一度実行してから、VOICE_NAME=Laura または VOICE_NAME=Pablo を使用してください。

ライセンス

MIT。LICENSEを参照してください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。