mcpField
C
cursor-chat-bridge

cursor-chat-bridge

ローカル
github.com/udah1コミュニケーション212 週間前に更新

cursor-chat-bridge について

cursor-chat-bridgeはCursorエージェントをTelegram、Discord、GitHubにつなぎ、スマートフォンから質問に返信して会話を続けられるようにします。Cursorの会話ごとにスレッドを分け、フックを使って返信待ちと作業再開を自動化できます。

主な機能

  1. 01Telegram、Discord、GitHubでのやり取り
  2. 02Cursorの会話ごとの個別スレッド
  3. 03返信後のエージェント自動再開
  4. 04画像添付と音声のテキスト化
  5. 05拡張可能なトランスポートアダプター

活用シーン

  1. 01席を離れている間にスマートフォンからCursorエージェントへ返信
  2. 02チャットスレッドから画像を送りエージェントに確認させる
  3. 03音声メッセージでエージェントにテキスト指示を伝える
  4. 04複数のCursor会話間でメッセージを分離

MCP 対応

MCPサーバーはbridge_start、bridge_send、bridge_await、bridge_send_and_await、bridge_stop、bridge_statusツールを提供します。自動再開にはCursorフックの導入も必要で、MCPのみの構成では手動操作が可能です。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"udah1-cursor-chat-bridge": {
"command": "npx",
"args": [
"-y",
"cursor-telegram-chat"
],
"env": {
"BRIDGE_PLATFORM": "<BRIDGE_PLATFORM>"
}
}
}
}
起動コマンドnpx -y cursor-telegram-chat
設定が必要な環境変数
BRIDGE_PLATFORMWhich chat adapter to use: telegram | discord | github. Optional — defaults to activeAdapter in ~/.cursor/chat-bridge/config.json.

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

パッケージ
npmcursor-telegram-chat0.1.23

ツール

6

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

パラメーター型必須説明
titlestringいいえスレッドに名前を付けます。Cursor のチャット一覧での表示に合わせて、この会話のトピックを簡潔に(≤6 語で)要約します(例:"GitHub Actions autopublish")。指定しない場合はフォルダー名を使用しますが、複数の会話でワークスペースを共有していると適切なラベルになりません。
adapterenumいいえこのセッションで使用するチャットチャンネル。設定済みの既定値を上書きします。github | telegram | discord
sessionstringいいえ以前の bridge_start が返したハンドル。2 つ目のスレッドを開かずに既存のセッションを再開します。新規に開始する場合は省略してください。

詳細

🌉 cursor-chat-bridge (Telegram、Discord、GitHub)

スマートフォンから Telegram、Discord、または GitHub 経由で Cursor エージェントを操作できます。

(どの言語でも)「リモートチャットモードを開始して」と伝えると、Cursor は各ターンの終了時に会話ごとのスレッドへ要約と質問を投稿し、返信を待ってから自動で続行します。停止するまでこれを繰り返します。キーボードから離れても、スマートフォンから開発を続けられます。

npm version GitHub stars license Made for Cursor

npm downloads node TypeScript CI Glama MCP server

cursor-chat-bridge の往復フロー
チャットアプリのセッションごとのチャンネル
セッションごとのチャンネル — Cursor の会話ごとに1つ
エージェントが投稿した要約にスマートフォンから返信できます
スマートフォンから返信 — エージェントは中断したところから再開します

YouTube で cursor-chat-bridge のデモを見る
▶ デモを見る(YouTube)

目次


理由

Cursor でタスクを開始したあと、席を離れる必要が出てきます。通常、エージェントは判断が必要になると、その時点で作業を止めてしまいます。cursor-chat-bridge は、あらゆるチャットアプリをリモート操作用に変えます。エージェントはスレッドで状況を報告し、質問を投げかけます。スマートフォンから返信すれば、ノートパソコンが手元になくても、返信した瞬間にエージェントが自動で作業を再開します。

  • 会話ごとにスレッドを作成。 Cursor のチャットごとに専用の issue/チャンネル/トピックが割り当てられます。同じワークスペース内の複数のチャットも、それぞれ分離されます。
  • ハンズフリーのループ。 返信は自動で再投入されるため、作業を続けるために Cursor を操作する必要はありません。
  • チャンネルを追加可能。 現在は Telegram、Discord、GitHub Issues に対応しており、約 100 行で独自のチャンネルを追加できます。
  • デフォルトで安全。 リモートからの返信は信頼できないものとして扱われ、破壊的な操作にはスレッド経由で明示的な確認を返す必要があります。
  • プロキシに対応。 GitHub と Discord は、TLS インターセプトを行う企業プロキシ経由で接続できます。

機能

機能内容
スマートフォン優先GitHub/Discord/Telegram のモバイルアプリからエージェントに返信でき、ネイティブのプッシュ通知も届きます。
自動再開stop フックが返信を待ち、返信を followup_message として再投入します。
セッションごとの分離Cursor の conversation_id をキーにするため、チャット間で会話が混線しません。
長時間の低コストな待機再アームごとに約 60 分のブロッキング待機を 1 回行うため、アイドル中の有料ターンを最小限に抑えられます。
入力中はオフbeforeSubmitPrompt フックにより、Cursor で入力した瞬間にループが無効になります(有効のままにするには stopRemoteChatOnLocalMessage: false を設定します)。
トークン認証付きローカル APIデーモンの制御 API はループバック接続のみを許可し、トークンで保護されています。
オプションの ntfy プッシュ通知GitHub でもスマートフォンに通知が届きます(GitHub は自分の投稿を通知しないため)。
画像添付スマートフォンから写真を送信するとローカルに保存され、エージェントが Read ツールで開きます。
音声 → テキストオプションの音声テキスト変換(OpenAI またはローカル)により、音声メモは文字起こしされたテキストとしてエージェントに届きます。
アダプター SDK1 つの TransportAdapter インターフェースを実装すれば、あらゆるチャンネルに対応できます。
更新を確認有効化時に npm を確認し、新しいリリースがあれば更新を提案します。

チャンネル一覧

アダプター状態モデルモバイルプッシュ通知
Telegram (デフォルト)✅ コード完成、単体テスト済みボットを介してセッションごとに フォーラムトピック を作成✅ ネイティブ
Discord✅ 動作確認済みボットを介してセッションごとに チャンネル を作成(REST ポーリング)✅ ネイティブ
GitHub Issues✅ エンドツーエンドテスト済みIssue = セッション、コメント = チャット✅(GitHub アプリ)+ オプションの ntfy

クイックスタート

クローンは不要です。1 つのコマンドですべてを設定できます。

npx cursor-telegram-chat@latest install

ランタイムを ~/.cursor/chat-bridge/app にインストールし(本番用の依存関係も含まれるため、npx のキャッシュが削除されたあとも動作します)、3 つの連携ポイントを設定します。すでに存在するものはバックアップし、決して上書きしません。

  • MCP サーバーを ~/.cursor/mcp.json に登録します。
  • stop と beforeSubmitPrompt フックを ~/.cursor/hooks.json に追加します。
  • 有効化ルールを ~/.cursor/rules/ にインストールします。

フックはリモートチャットモードが有効なとき以外は何もしないため、通常の Cursor の使用には影響しません。次に、チャンネルを選んで開始します。

# 1. edit ~/.cursor/chat-bridge/config.json  (choose an adapter + credentials)
# 2. validate it:
chat-bridge doctor
# 3. reload Cursor, open a chat, and say:  "start remote chat mode"
アップグレード/アンインストール
npx cursor-telegram-chat@latest install               # re-run to upgrade
npx cursor-telegram-chat@latest uninstall             # remove, keep config + state
npx cursor-telegram-chat@latest uninstall --purge     # remove everything
MCP のみ(ライト版)— 自動再開ループなしでツールを利用

標準の Cursor MCP フローで MCP ツールだけを使いたい場合(ハンズフリーループは不要な場合)は、install を実行する代わりに、以下を ~/.cursor/mcp.json に追加します。

"cursor-chat-bridge": {
  "command": "npx",
  "args": ["-y", "cursor-telegram-chat", "chat-bridge-mcp"]
}

bridge_send/bridge_await を手動で実行できますが、返信時の自動継続ループには、通常の install で設定されるフックが必要です。

## 仕組み

トランスポートに依存しないコアの上に、連携する3つのレイヤーがあります。

  • ルール(rules/chat-bridge-mode.mdc)— どの言語でも起動フレーズを検出し、モード中のエチケットを設定します(セッションハンドルを取得して渡す、各ターンの最後に要約と質問を添える、返信を信頼できないものとして扱う、破壊的な操作は確認する)。
  • MCP サーバー(src/mcp.ts)— bridge_start、bridge_send、bridge_await、 bridge_send_and_await、bridge_stop、bridge_statusを公開します。
  • フック(hooks/)— 自動ループを構成します。
    • stopはリモートからの返信を待ち、followup_messageとして再注入します(loop_limitで上限を設定)。
    • beforeSubmitPromptはCursorで入力したときにループを無効にします(ループ自身が注入した返信では無効にならないようガードします)。

単一のローカルデーモン(src/daemon.ts)が、チャネル接続と、MCPおよびフックが使用するループバック専用のトークン認証付きHTTP APIを管理します。セッションごとのルーティング、ロングポーリング、自分自身が送信したメッセージのフィルタリング、停止/生成ロジックを処理します。

turn ends ─▶ stop hook ─▶ daemon /poll ─▶ adapter
   ▲                                          │
   └───── followup_message (your reply) ◀─────┘

(アダプターはGitHub/Discord/Telegram。conversation_idをキーとして使用します。)

セッションの識別 — 会話を分離する仕組み

セッションはCursorの**conversation_id**をキーとするため、各会話はそれぞれ1つのスレッドに対応します。Cursorはフックにはconversation_idを渡しますが、MCPツール呼び出しには渡さないため、MCPは簡単なハンドシェイクを通じてこれを取得します。

  1. beforeSubmitPromptは、実際に送信するたびに会話ごとの開始待ちレコード(markers/pending/<conversation_id>.json)を書き込みます。これは識別の信頼できる情報源です(診断とアップグレード時のバージョン差異にのみ使用される、従来のlast-submit/wsポインターもあります)。
  2. bridge_startは、唯一の新しい開始待ちレコードを取得し、実際のconversation_idをキーにセッションを作成してから、セッションハンドルを返します。ランダムなIDは生成せず、自身のBRIDGE_WORKSPACE(誤ってルーティングされている可能性があります)も無視します。取得したレコードのワークスペースが優先されます。
  3. bridge_startは推測せず、安全側に倒して失敗します。新しいハンドシェイクがない場合、古くなっている場合、または複数のチャットが同時に送信された場合は、誤ったスレッドに紐付ける代わりに、案内を返します。
  4. エージェントは以降のすべてのbridge_*呼び出しでsession=<handle>を渡します。これは必須となり(直近のセッションやキャッシュへのフォールバックはありません)、同じワークスペース内の2つの会話が別々のスレッドに紐付けられます。

フックはそれぞれ自身のconversation_idのみをキーとして使用します(グローバルなフォールバックはありません)。そのため、ある会話のターンが別の会話をポーリングしたり、別の会話に注入したりすることはありません。handshakeFreshMs(設定またはBRIDGE_HANDSHAKE_FRESH_MS。デフォルトは600000ms)で有効期限を調整できます。chat-bridge doctorは、MCPプロセスのワークスペース紐付け、保留中のレコード/取得状態、バージョン差異を報告します。

トラブルシューティング:数分後にセッションが停止する

ハンズフリーの待機時間(デフォルトは60分)は、bridge_await(呼び出しごとに約50秒間ポーリングするだけ)ではなく、stopフックの再アームループによって決まります。~/.cursor/hooks.jsonに大きなtimeoutが設定されていない場合、Cursorは短く、文書化されていない上限時間を過ぎるとstopフックを終了します。インストーラーはtimeout: 3660を設定します。セッションが数分で停止する場合は、次を確認してください。

  1. MCPのみの(軽量)セットアップを使用していますか? フックがないため、自動再開されません。完全版のnpx cursor-telegram-chat@latest installを実行してください。
  2. インストール後、Cursorを完全に終了して再起動してください。再読み込みではhooks.jsonが再読み込みされないことがあります。
  3. ~/.cursor/hooks.jsonにtimeout: 3660が設定されたstopフックがあることを確認してください(最新のinstallを再実行すると、古い設定が修正されます)。
  4. お使いのCursorのビルドで依然として早期に終了する場合は、各待機時間を短くして、より早く再アームされるようにしてください。~/.cursor/chat-bridge/config.jsonに"stopWindowMin": 5を設定します(合計60分の上限はstopBudgetMinです)。
## 画像の添付

チャットスレッドに写真(または画像ファイル)を送信すると、エージェントが画像を確認できます。

  1. アダプターがメッセージの添付ファイル(Discord の attachments、Telegram の photo/画像の document)を取得します。
  2. デーモンがバイトデータを ~/.cursor/chat-bridge/media/<session>/ にダウンロードし、ローカルパスを記載したメモをメッセージ本文に追加します。
  3. エージェントが Read ツールでそのパスを開くため、画像はビジョン入力としてモデルに渡されます。

企業の TLS プロキシ経由の場合: Discord の cdn.discordapp.com はブロックされ、media.discordapp.net は許可されていることがよくあります。Discord アダプターは添付ファイルの URL を自動的に media ホストに書き換えるため、このようなネットワークでもダウンロードできます。

音声メッセージ(音声テキスト変換)

ボイスメモ(Telegram)または音声添付ファイル(Discord)を送信すると、入力したテキストと同じようにエージェントに文字起こしが届きます。デフォルトでは無効です。 設定の stt で有効にします。

"stt": {
  "enabled": true,
  "provider": "openai",     // "openai" (OpenAI-compatible via baseUrl) or "local"
  "tryLocalSttFirst": false,// true = force the local transcriber even if a cloud provider is set
  "apiKeyCommand": "…",     // or "apiKey", or env BRIDGE_STT_API_KEY
  "language": "auto",       // auto-detect, or force "he" / "en"
  "keepAudio": true         // false = delete the audio after transcribing
}
  • local プロバイダー(オフライン。機密性の高い音声におすすめ):文字起こしを stdout に出力する CLI を localBin/localArgs に設定します(例:whisper.cpp)。設定された provider は常に優先されます。ブリッジが暗黙に local へフォールバックすることはありません。クラウドプロバイダーが設定されている場合でもローカルの文字起こしを強制するには、"tryLocalSttFirst": true(または BRIDGE_STT_TRY_LOCAL_FIRST=1)を使用します。
  • 文字起こしはデーモン内で非同期に実行されるため、ポーリングウィンドウをブロックしません。文字起こし結果は次の返信サイクルで送信されます。設計の詳細は docs/stt-plan.md を参照してください。

既読通知(確認応答)

この機能がない場合、スマートフォンからメッセージを送信しても、エージェントが一連の処理を完了するまで何も応答がなく、メッセージが届いたかどうかもわかりません。有効にすると、メッセージが届いた時点で、時間のかかる処理(添付ファイルのダウンロードや文字起こし)を始める前にデーモンが返信します。デフォルトでは無効です。

"ack": {
  "enabled": true,
  "language": "auto",                     // "auto" matches you; force with "en" or "he"
  "adapters": ["discord", "telegram"],    // bot-identity channels only (see below)
  "echoTranscript": true,                 // repeat back what a voice note said
  "maxTranscriptChars": 200
}

メッセージの種類ごとの応答は次のとおりです。

送信内容ブリッジの返信
テキスト了解しました。対応します…
画像画像を受け取りました。確認します…
ボイスメモ音声メッセージを受け取りました。文字起こししています…、文字起こし後に ご依頼を受け取りました:「…」
stopリモートチャットセッションを停止しました。

確認応答はエージェントではなくデーモンから送信されます。エージェントがメッセージを見るのは次のターンが始まってからなので、エージェントが確認応答を作成すると LLM のターンを消費し、返信も遅れます。

"auto" に設定すると、返信は入力した言語に合わせられます。ヘブライ語のテキストにはヘブライ語で返信し、ボイスメモの場合は文字起こしサービスが検出した言語に従います。判断材料のないメッセージ(キャプションのない画像や、単独の stop)には、そのセッションで最後に使用した言語が使われます。初期設定は英語です。

タイミング: デーモンがチャネルを読み取るのは、ポーリングが実行中の場合のみです。つまり、エージェントが返信を待っている間、または stop フックが待機している間です。エージェントがターンの途中に送信されたメッセージは、エージェントが処理を終えるまで確認されず、確認応答も送られません。メッセージが失われることはありませんが、遅れて処理されます。

GitHub を対象外とする理由: GitHub ではエージェントがあなた自身のアカウントでコメントするため、確認応答を送ると自分自身に返信したように見えてしまいます。それでも利用したい場合は、adapters に "github" を追加してください。

設定

~/.cursor/chat-bridge/config.json(このファイルの変更は次回のポーリング時に自動的に反映されるため、デーモンの再起動は不要です。再起動が必要なのは mcp.json の環境変数の変更とアダプターの認証情報のみです):

{
  "activeAdapter": "telegram",
  "pollIntervalMs": 10000,   // check for replies every N ms (lower = snappier, more API calls)
  "minPollIntervalMs": 2000, // floor for the above; lower it if you set pollIntervalMs < 10000
  "stopBudgetMin": 60,       // wait budget (mins); resets on every reply
  "stopWindowMin": 60,       // mins per window (keep < hooks.json timeout)
  "caCertPath": "",          // corporate CA bundle (PEM) if behind a TLS proxy
  "requireConfirmForDestructive": true,
  "stopRemoteChatOnLocalMessage": true, // typing in Cursor turns remote mode off (set false to keep it on)
  "adapters": {
    "github": {
      "owner": "you",
      "repo": "cursor-bridge-inbox",
      "tokenCommand": "gh auth token --user you"
    },
    "discord":  { "botToken": "", "channelId": "", "allowedUserIds": [] },
    "telegram": { "botToken": "", "chatId": "", "allowedUserIds": [] }
  },
  "ack": { "enabled": false, "language": "auto" } // read receipts; see above
}

通常、caCertPath は空のままで構いません。問題が起きない限り変更しないでください。一部の企業ネットワークでは、Node が信頼していない独自のルート証明書を使って HTTPS を傍受するため、curl は動作するのに TypeError: fetch failed が発生してリクエストが失敗します。その場合は、caCertPath(または BRIDGE_CA_CERT)にマシンの CA バンドル(PEM)を指定してください。doctor、デーモン、更新チェックはいずれもこの設定を使用します。

ntfy プッシュ通知はデフォルトでは無効で、このファイルでは設定できません。有効にするには BRIDGE_NTFY_* 環境変数のみを使用してください(下記を参照)。

環境変数による上書き

config.json を編集せずに上書きするには、~/.cursor/mcp.json の cursor-chat-bridge エントリーにある env ブロック(またはシェル)で設定します。すべての名前空間付き変数は BRIDGE_* です。実行中のデーモンに変更を反映するには、デーモンを再起動する必要があります(chat-bridge shutdown)。

環境変数上書き対象例
BRIDGE_PLATFORMactiveAdaptergithub | telegram | discord
BRIDGE_POLL_INTERVALポーリング間隔(秒)30
BRIDGE_STOP_BUDGET_MIN待機時間の上限(分)。返信があるとリセットされます ¹60
BRIDGE_STOP_WINDOW_MINブロッキングウィンドウごとの時間(分) ²60
BRIDGE_CA_CERTcaCertPath/path/to/ca.pem
BRIDGE_GITHUB_REPOGitHub の owner/repoyou/inbox
BRIDGE_GITHUB_TOKENGitHub トークンgho_…
BRIDGE_TELEGRAM_BOT_TOKENTelegram ボットトークン—
BRIDGE_TELEGRAM_CHAT_IDTelegram フォーラムグループ ID—
BRIDGE_TELEGRAM_ALLOWED_USER_IDS許可リスト(CSV)123,456
BRIDGE_DISCORD_BOT_TOKENDiscord ボットトークン—
BRIDGE_DISCORD_CHANNEL_IDDiscord チャンネル ID ³—
BRIDGE_DISCORD_ALLOWED_USER_IDS許可リスト(CSV)123,456
BRIDGE_WORKSPACEウィンドウごとのセッションキー${workspaceFolder}
BRIDGE_NTFY_TOPICntfy を有効にしてトピックを設定cursor-bridge-…
BRIDGE_NTFY_PRIORITYプッシュ通知の優先度 0~5(0 = オフ)2
BRIDGE_NTFY_SERVERntfy サーバーのベース URLhttps://ntfy.sh

¹ config.json の stopBudgetMin も設定できます。フックは MCP エントリーの環境変数を引き継がないため、こちらが確実な設定方法です。 ² config.json の stopWindowMin も設定できます。~/.cursor/hooks.json の stop フックの timeout より短くしてください。 ³ サーバー内に既存のテキストチャンネルがあれば使用できます。サーバーとカテゴリの特定に使われ、セッションごとにその横に新しいチャンネルが作成されます(例:#General)。

会話ごとに使用するプラットフォームを実行時に選ぶこともできます。「Telegram でリモートチャットを開始」と伝えると、エージェントはその会話に限り bridge_start(adapter: "telegram") を渡します。

待機ループ(stop フック)

リモートモードが有効な間、各ターンの終了時に stop フックがブロックし、返信を待ちます。これを制御する設定は 2 つあります。

  • stopWindowMin(デフォルトは 60)— 1 回のフック呼び出しがブロックする時間です。時間が経過すると、サイレントなキープアライブを返して再度待機を開始します。Cursor は ~/.cursor/hooks.json の timeout(デフォルトは 3660s / 61 min)で stop フックの実行時間を制限します。検証したところ、それより短い隠れた上限は確認されませんでした。そのため、約 60 分のウィンドウを 1 回設定すれば、離席中の有料キープアライブターンは1 時間に 1 回だけになります。
  • stopBudgetMin(デフォルトは 60)— 再待機を繰り返す際の合計待機時間です。返信のたびにリセットされるため、実際には「最後のメッセージから最大 N 分間待機する」という設定です。

返信する、Cursor に入力する、スレッドで stop を送信する、または bridge_stop を呼び出すと、ループは終了します。

プッシュ通知(ntfy)

GitHub は、自分自身のアクティビティについては通知しません。エージェントはあなたとして投稿するため、自分自身へのメンションや自分自身のアサインでも通知されません。そこで、2 つ目のアカウントを使わずに GitHub チャンネルの通知をスマートフォンで受け取れるよう、cursor-chat-bridge は各サマリーの送信時に ntfy 経由で別経路のプッシュ通知を送信できます。無料で、アカウント不要、オープンソース、セルフホスト可能で、課題へのディープリンクにも対応しています。

デフォルトでは無効です。MCP エントリの環境変数で有効にします。

  1. ntfy アプリ(iOS/Android)をインストールするか、ウェブアプリを使用します。
  2. 長く推測されにくいトピック(トピックは推測されにくいことを前提に公開されています)を選び、購読します。
  3. ~/.cursor/mcp.json の cursor-chat-bridge エントリにある env ブロックに、BRIDGE_NTFY_TOPIC=cursor-bridge-<random> を設定します。

BRIDGE_NTFY_PRIORITY は有効/無効を切り替える設定です。0 = オフ(デフォルト)、1 が最低、5 が最高です。プッシュ通知は、優先度が 1 以上かつトピックが設定されている場合にのみ送信されます。ネイティブ通知に対応しているTelegramとDiscordでは、プッシュ通知はスキップされます。

プラットフォーム別のセットアップ

Telegram — デフォルト、チャットの使い勝手が最適
  1. @BotFather でボットを作成します → ボットトークンを取得します。
  2. グループを作成し、トピックを有効にして、トピックの管理 権限を付与し、ボットを管理者として追加します。
  3. グループの chatId と数値の allowedUserIds(許可リスト)を設定に記入します。 activeAdapter: "telegram" を設定します。

getUpdates によるペアリングで chatId/ユーザー ID を取得します(グループでメッセージを送信し、更新内容を確認します)。 デーモンが api.telegram.org に接続できる必要があります。ネットワークでブロックされている場合は、接続可能なホストでデーモンを実行するか、代わりに Discord/GitHub を使用してください。

Discord — スマートフォンでの利用を重視、プロキシ経由でも動作
  1. Discord のサーバーを作成します(自分が所有するサーバーを使用してください)。ボットはその中にセッションごとのチャンネルを作成します。
  2. https://discord.com/developers/applications でアプリとボットを作成します。BotでReset Tokenをクリックし、表示されたボットトークンをCopyします。
  3. BotでMessage Content Intentを有効にします。
  4. ボットを招待します。OAuth2 → URL Generatorで、スコープに bot、権限にManage Channels、View Channels、Send Messages、Read Message History を指定します(ボットはセッションごとにチャンネルを作成・削除するため、_Manage Channels は必須_です)。生成された URL をコピーして新しいブラウザータブで開き、手順 1 で作成したサーバーを選択します。
  5. チャンネル ID(channelId)を取得します。そのサーバーにある既存のテキストチャンネル(例:#general)ならどれでも構いません。ボットはそれを使ってサーバーとカテゴリーを特定し、その隣にセッションごとの新しいチャンネルを作成します。Developer Mode(User Settings → Advanced)を有効にし、チャンネルを右クリックしてCopy Channel IDを選択します。または、ボットがサーバーに参加した後で Cursor に取得を依頼することもできます。ボットトークンを Cursor に渡せば、ボットのチャンネル一覧を取得して ID を返せます。
  6. botToken と channelId(必要に応じて allowedUserIds)を設定に記入します。activeAdapter: "discord" を設定します。
  7. TLS を傍受するプロキシ経由で TypeError: fetch failed が発生する場合は、caCertPath に社内 CA バンドル(PEM)のパスを指定します。

ヒント: ボットに Cursor のアバターを設定し(Developer Portal → Bot → 編集アイコン)、サーバーアイコンには Cursor のロゴを設定すると、セッションごとのチャンネルがアプリ内で自然に見えます。

GitHub — どのネットワークでも動作
  1. 受信箱として使うプライベートリポジトリを作成します(例:cursor-bridge-inbox)。
  2. owner/repo と、token または tokenCommand(gh auth token が使用できます)を設定します。
  3. activeAdapter: "github" を設定します。

各セッションで課題が作成され、ターンのサマリーはコメントとして投稿されます。GitHub モバイルアプリから返信できます。コメントに stop と入力するか、課題をクローズするとセッションが終了します。

エージェント向け — オンボーディングのチェックリスト ユーザーの `cursor-chat-bridge` のセットアップを支援するエージェントの場合は、まずユーザーが選んだプラットフォームの仕組みを説明してから、不足している値だけを確認し、それらを `~/.cursor/chat-bridge/config.json` に書き込み、`chat-bridge doctor` を実行して動作を確認してください。**シークレットをユーザーに再表示してはいけません。**次の点を伝えてください。チャンネルからの返信は信頼できないものであり、破壊的な操作にはスレッドへの明示的な確認の返信が必要です。停止するには、Cursor で `stop` と入力するか、スレッドで `stop` を送信するか、`bridge_stop` を呼び出してください。

ランタイムの依存関係がインストールされていることを確認してください。install はランタイムを ~/.cursor/chat-bridge/app にコピーし、そこで本番環境用の依存関係を自動的にインストールします。この手順が省略されたか失敗した場合(オフライン/企業プロキシ)は、MCP サーバーが起動しません — (cd ~/.cursor/chat-bridge/app && npm install --omit=dev) を実行して完了してください。代わりに git クローンから実行していますか?その場合は、まずリポジトリで npm install を実行してください。

**ボイスメモを文字起こし(STT)するかどうかを確認してください。**デフォルトではオフです。希望する場合は、選択肢を提示して選んでもらってください。

  • Groq(推奨) — 高速で、無料枠が充実しており、OpenAI 互換です。stt.provider: "openai"、 stt.baseUrl: "https://api.groq.com/openai/v1"、stt.model: "whisper-large-v3-turbo" を設定し、 stt.apiKey に https://console.groq.com/keys から取得した gsk_… キーを設定します。
  • OpenAI — stt.provider: "openai"(デフォルトの baseUrl)、stt.model: "whisper-1"(または gpt-4o-transcribe)、stt.apiKey に sk-… キーを設定します。
  • ローカル — whisper.cpp / openai-whisper バイナリを使って stt.provider: "local" を設定します。データがマシンの外に送信されないため、セキュリティが厳格な企業ネットワークに最適です。stt.localBin を設定します。

次に stt.enabled: true を設定し、chat-bridge doctor を実行してください。可能であれば、インラインのキーより stt.apiKeyCommand を優先し、キーをユーザーに再表示してはいけません。

新しいアダプターの作成

TransportAdapter(src/types.ts)を実装し、src/adapters/index.ts に登録します。

interface TransportAdapter {
  capabilities: { globalIngest: boolean; separateBotIdentity: boolean };
  init(): Promise<void>;
  ensureThread(sessionId: string, title: string, meta?: object): Promise<ThreadRef>;
  send(thread: ThreadRef, text: string): Promise<{ messageId: string }>;
  // pull adapters (GitHub / Discord):
  poll?(thread: ThreadRef, cursor?: string): Promise<PollResult>;
  // push / global adapters (Telegram):
  startIngest?(router: Router): Promise<() => void>;
  stop?(thread: ThreadRef): Promise<void>;
}
メンバー必須目的
capabilities✅globalIngest:すべてのセッションに対する 1 つのストリーム(Telegram)か、スレッドごとのポーリングかを指定します。separateBotIdentity:投稿がユーザー本人ではなくボットとして表示されるかを指定します。
init()✅認証情報と接続状態を検証します。
ensureThread()✅セッションごとのスレッド/チャンネルを作成または検索し、ThreadRef を返します。
send()✅メッセージを投稿します(プラットフォームの文字数制限や分割に対応します)。
poll()プル型アダプターcursor 以降の新しいメッセージを返し、許可されたユーザーのものだけに絞り込みます。
startIngest()プッシュ型アダプター単一のグローバルストリームを開始して更新を振り分け、停止関数を返します。
stop()任意クリーンアップします(例:Discord ではセッションごとのチャンネルを削除します)。

セキュリティ

  • ループバック制御 API はトークン認証されています — トークンを持つローカルプロセス(MCP およびフック)のみがデーモンを操作できます。
  • 受信メッセージは、allowedUserIds の許可リストでフィルタリングされます(Telegram/Discord)。
  • リモートからの返信はすべてラップされ、信頼できないものとしてマークされます。スレッドへの明示的な確認の返信がない限り、破壊的な操作を行わないようルールで定められています。
  • トークンは ~/.cursor/chat-bridge/config.json(chmod 600)に保存され、コミットされることはありません。可能であれば、保存済みトークンより tokenCommand を優先してください。
権限 — デーモンが必要とする権限と、スキャナーが警告を出す理由

チャットアプリからエージェントを操作するには、本質的に強力な機能が必要です。このパッケージでは、以下を使用します。

  • 子プロセス — デーモンの起動、tokenCommand(例:gh auth token)の実行、ローカルの whisper バイナリ(ローカル STT を選択した場合のみ)の実行、およびインストーラー内での npm install の実行に使用します。
  • ネットワークアクセス — ループバック限定の制御サーバー、および選択したチャネル(Telegram/Discord/GitHub)への外部呼び出し、音声テキスト変換のアップロード(有効にした場合)、npm の更新確認に使用します。
  • ファイルシステムアクセス — 設定、メディア、ログのために ~/.cursor/chat-bridge/ を読み書きします。

このため、サプライチェーンスキャナー(Socket、Snyk など)では、純粋なロジックライブラリよりも サプライチェーンセキュリティ のスコアが低く表示されます。ただし、これは既知の脆弱性がないにもかかわらずです。このスコアが反映しているのは、検出されたエクスプロイトではなく、機能とパッケージの公開期間(このプロジェクトは新しく、メンテナーは 1 人です)です。透明性のために説明すると、postinstall/install スクリプトはありません。唯一のライフサイクルスクリプトは prepublishOnly(公開者のマシン上で実行されるビルドで、インストール時には実行されません)です。ネットワーク/ファイルシステム/プロセスに関する処理は、ご自身がデーモンを実行したときにのみ行われます。また、制御 API はループバック限定で、トークンによって保護されています。ソースは MIT ライセンスで、このリポジトリで監査できます。

検証状況

マシン上でエンドツーエンドの検証済みです(Cursor の再起動は不要です)。

  • GitHub アダプター — イシューの作成、送信、ポーリング、自分のメッセージのフィルタリング、stop キーワード、クローズ検出。
  • デーモン — トークン認証、ロングポーリング、停止/世代管理、永続化。
  • MCP サーバー — 実際の stdio JSON-RPC ハンドシェイクを介したすべてのツール。
  • フック — stop-loop の followup_message 注入、送信前のオフスイッチと注入ガード、非アクティブ時の即時 no-op。
  • 会話ごとのルーティング(node scripts/e2e-conv.mjs)— 別々の会話で別々のイシューを開きます。同じワークスペース内の 2 つの会話も個別に保たれます。停止したセッションを再アクティブ化すると新しいスレッドが開きます。未設定のチャネルにはオンボーディングの案内が返されます。
  • ユニットテスト — npm test(ルーティング、ストアのセマンティクス、メッセージのフィルタリング)。

コントリビューション

イシューや PR を歓迎します。ローカルでの開発方法:

npm install
npm run build        # tsc → dist/
npm run typecheck
npm test             # node --test
npm run dev:daemon   # run the daemon from source (tsx)

新しいチャネルの追加は、最も簡単なコントリビューションです。TransportAdapter を 1 つ実装してください(上記を参照)。

ライセンス

MIT

コメント

MCP は初めてですか?

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

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