proceed-mcp について
proceed-mcpは、Telegramのプライベートチャットを通じて人間に承認を求めるプレビュー版MCPサーバーです。判断を記録して待機中のMCP呼び出しに返しますが、要求された操作は実行しません。実運用は未検証です。
主な機能
- 01Telegramでの承認依頼
- 02承認・拒否・返信の選択
- 03依頼の期限切れとキャンセル
- 04権限トークンによる結果取得
- 05判断受領の確認
活用シーン
- 01エージェントの操作前に人間の承認を求める
- 02Telegramの判断を待機中のMCP呼び出しに返す
MCP 対応
承認の準備、依頼、取得、キャンセル、確認を行う5つのMCPツールを提供します。ローカルMCPアダプターがループバック上のブローカーに接続し、ブローカーがTelegramと通信します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
proceed-mcp
プライベートな Telegram チャットに承認リクエストを送信し、対応する人間の判断を、待機中の MCP 呼び出しを通じて返す MCP サーバーです。人間は Telegram から承認、拒否、または回答できます。proceed-mcp は結果を記録します。要求されたアクションは実行しません。
プレビュー状況:@meshimize/[email protected] は npm で公開されています。実環境での使用は検証されていません。 ソースは、Node 24.22.2 を使用する Windows 環境でオフラインテストの証拠があります。公開は、変更がマージされる前に手動で実施されました。npm が latest の削除リクエストを HTTP 400 で拒否したため、現在 preview と latest の両方の dist-tag がこのバージョンを指しています。どちらかのタグに依存せず、正確なバージョンを指定してください。このプレビューでは、実際の Telegram ペアリング、質問の配信、人間による判断、OpenCode V2 ホストでの実行、クリーンな状態での公開 npm インストールのいずれも検証されていません。
実装済みの範囲は、ループバックブローカー、プライベートな Telegram ペアリングと質問表示、承認/拒否/回答、有効期限、キャンセル、権限に基づく取得、および確認応答です。MCP Events、タイムアウト後の自動続行、doctor、retry はこのプレビューでは実装されていません。
配布
@meshimize/proceed-mcp は、この製品の npm パッケージです。proceed-mcp コマンドとそのランタイムソースをインストールします。ホスト型の MCP エンドポイントではなく、クラウドブローカーもありません。MCP アダプターとブローカーは、お使いのマシン上で実行されます。ブローカーは 127.0.0.1 のみで待ち受け、Telegram との通信には https://api.telegram.org を呼び出します。
公開済みの npm アーティファクトは、パブリックプレビュー版の @meshimize/proceed-mcp バージョン 0.1.0-preview.1 です。preview dist-tag で公開されており、npm が latest の削除リクエストを HTTP 400 で拒否したため、latest タグもこのバージョンを指しています。どちらかのタグに依存せず、正確なバージョンを指定してください。これは変更がマージされる前に手動で公開されたものであり、リリースワークフローの結果ではありません。リリース自動化による保護付き公開は計画されていますが、まだ実装されておらず、自動公開も実行されていません。
公式 MCP レジストリへの掲載は、このプレビューで承認済みの配信タスクであり、npm パッケージの公開とは別に追跡・報告されています。掲載は検出用のメタデータにすぎず、npm パッケージを参照するもので、ブローカーをホストまたは実行するものではありません。npm プレビューが公開され、正確なバージョンを指定したインストール確認に合格した後にのみ実施する予定です。選定された掲載名は、リポジトリ https://github.com/renl/proceed-mcp に対する io.github.renl/proceed-mcp です。この選定には、レジストリの名前空間とレジストリへの公開権限の確認が必要ですが、これらは未解決のままです。また、レジストリ認証やスキーマ検証を行ったことを示すものではありません。掲載はまだ公開されておらず、レジストリへの配信も検証されていません。掲載がブロック中または保留中であっても、npm での公開結果が変更されたり隠されたりすることはありません。
要件
- Node.js 24 以降。
package.jsonでは>=24が宣言されています。このプレビューは、Node 24.22.2 を使用する Windows 環境でのみ動作確認されています。その他のオペレーティングシステムと Node のバージョンは未テストです。 - 専用の Telegram ボットを 1 つと、そのボットとのプライベートチャットを 1 つ用意してください。別のポーラーや Webhook とボットを共有しないでください。
- ブローカーと MCP アダプターは同じマシン上で実行する必要があります。人間はリモートでも構いません。
- Windows では、所有者のみの ACL チェックに
powershell.exeとicaclsが必要です。POSIX では、状態ディレクトリが所有者のみのモードビットに対応している必要があります。 - ビルドツール、ネイティブアドオン、postinstall スクリプトは不要です。
インストール
プレビューの正確なバージョンをグローバルにインストールします。
npm install --global @meshimize/[email protected]
proceed-mcp --help
または、グローバルインストールせずに実行します。
npx --yes --package @meshimize/[email protected] -- proceed-mcp --help
スコープ付きパッケージをインストールすると、同じ proceed-mcp コマンドがインストールされます。バージョン 0.1.0-preview.1 は preview タグで公開されており、latest タグもこのバージョンを指しているため、どちらかのタグに依存せず、正確なバージョンを指定してください。インストールに成功することは最初のリリース確認であり、承認フローが実環境で動作する証明ではありません。また、クリーンな状態での公開インストールは検証されていません。
ブローカーと Telegram のセットアップ
1. 保護された状態を作成する
空の、またはまだ存在しない絶対パスのディレクトリを選択します。リポジトリの外に置いてください。
proceed-mcp init --state-dir <absolute-state-dir>
init は、保護された config.json、ローカル制御用の認証情報、空のジャーナルを作成します。既存の状態を上書きすることはありません。状態のパスを表示しますが、認証情報の値は表示しません。
2. オーナーを 1 人追加する
オーナーは、MCP アダプターが使用するトランスポートの主体です。
proceed-mcp owner add <owner-id> --label "<display-label>" --state-dir <absolute-state-dir>
<owner-id> は [a-z0-9_-]{1,64} に一致する必要があります。ラベルは表示専用で、Telegram に表示されます。owner add はブローカーの所有権レコードがある間は拒否されるため、最初の serve の前に実行してください。オーナーレコードと認証情報は変更できません。
3. 専用の Telegram ボットを作成する
@BotFather で新しいボットを作成し、そのトークンを秘密にしてください。このボットは、このブローカー専用で使用します。Webhook を設定したり、このボットに対して別のポーラーを実行したりしないでください。proceed-mcp が Webhook を削除したり、保留中の更新を巻き戻したり破棄したりすることはありません。Telegram が競合するコンシューマーを検出すると、診断メッセージを表示して Telegram の処理を停止します。その場合は、ボットを修復して serve を再起動してください。
4. ブローカーをフォアグラウンドで起動する
トークンは、ブローカー自身のプロセス環境にのみ設定してください。
PowerShell:
$env:PROCEED_TELEGRAM_BOT_TOKEN = '<bot-token>'
proceed-mcp serve --state-dir 'C:\absolute\path\to\proceed-state'
POSIX:
export PROCEED_TELEGRAM_BOT_TOKEN='<bot-token>'
proceed-mcp serve --state-dir /absolute/path/to/proceed-state
proceed-mcp: broker ready on http://127.0.0.1:43189 と状態ディレクトリの行が表示されるまで待ちます。このターミナルは開いたままにしてください。
トークンは、ブローカープロセスの環境からのみ読み取られます。状態ディレクトリ、ジャーナル、Telegram、リクエスト履歴に保存されることはありません。この製品は .env ファイルを読み取りません。トークンを MCP アダプターの環境や MCP クライアントの設定に絶対に追加しないでください。
トークンが未設定または空の場合でも、ブローカーはローカルで起動し、警告を表示します。人間とのペアリングが完了するまではリクエストを作成できないため、テストの前に Telegram の設定を完了してください。トークンが拒否された場合、または別のコンシューマーがボットを使用している場合、ローカルブローカーは稼働を続けたまま、診断メッセージを表示して Telegram の処理を停止します。ボットを修復して serve を再起動してください。
5. プライベートチャットをペアリングする
2 つ目のターミナルで、次を実行します。
proceed-mcp pair --state-dir <absolute-state-dir>
このコマンドは Pairing code: と Expires at: を表示します。ボットとのプライベートチャットで /start を送信し、有効期限までに /pair <code> を正確に送信してください。グループチャットは拒否されます。/start だけでは何も許可されません。ボット名のサフィックスが付いたコマンドや、形式が不正なコマンドではペアリングされません。コードは 1 回のみ使用でき、有効期限は 5 分です。平文では保存されません。
ペアリングに成功するのは最初の 1 回だけです。チャット内で再ペアリングしたり、ID を変更したりすることはできません。
6. MCP クライアントを接続する
OpenCode V2
opencode.jsonc の mcp.servers にローカルサーバーを追加します。この形式はOpenCode V2 MCP ドキュメントに準拠しています。
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"proceed": {
"type": "local",
"command": [
"npx",
"--yes",
"--package",
"@meshimize/[email protected]",
"--",
"proceed-mcp",
"mcp",
"--owner",
"<owner-id>",
"--state-dir",
"/absolute/path/to/proceed-state",
],
"codemode": false,
},
},
},
}
<owner-id> と状態のパスを置き換えてください。Windows では、JSON 文字列内のバックスラッシュをエスケープするか、スラッシュを使用してください。codemode: false にすると、ツールが直接公開されます。保存すると OpenCode が MCP の設定を再読み込みします。opencode mcp list で接続を確認してください。
--package 引数でスコープ付き npm パッケージを選択し、-- の後の引数でそのパッケージの proceed-mcp コマンドを指定します。パッケージをグローバルにインストールした場合は、command 配列を proceed-mcp から始め、同じ mcp --owner ... --state-dir ... 引数を指定してください。
このサーバー名を使うと、OpenCode ではツールが proceed_prepare_approval、proceed_request_approval、proceed_get_approval、proceed_cancel_approval、proceed_acknowledge_approval として公開されます。Code Mode を有効にしたままにすると、OpenCode ではこれらのツールが tools.proceed の下にまとめられます。
PROCEED_TELEGRAM_BOT_TOKEN を environment に追加しないでください。アダプターにこのトークンは不要であり、受け取ってはなりません。
その他の stdio MCP クライアント
ローカルの stdio サーバーを起動できる任意のクライアントで、次のコマンドを使用してください。
proceed-mcp mcp --owner <owner-id> --state-dir <absolute-state-dir>
グローバルインストールせずに公開済みバージョンを実行するには、次のコマンドを使用してください。
npx --yes --package @meshimize/[email protected] -- proceed-mcp mcp --owner <owner-id> --state-dir <absolute-state-dir>
このアダプターに OpenCode API、パスワード、プロバイダーの認証情報、独自のセッションメタデータは必要ありません。
ローカルブローカーにのみ接続します。serve は実行したままにしてください。
サーバーは MCP プロトコル 2025-11-25 を通知し、5 つのツールを公開します:prepare_approval、
request_approval、get_approval、cancel_approval、acknowledge_approval。
MCP ツール
| ツール | 引数 | 効果 |
|---|---|---|
prepare_approval | 任意の session_label | 永続的なリクエスト識別子と、非公開のリクエスト機能を予約します。Telegram への質問は送信されません。 |
request_approval | request_handle、request_capability、client_request_id、action、context、任意の expires_in_seconds | 1 つのリクエストを作成または再実行し、解決、期限切れ、またはキャンセルまで待機します。終端状態のリクエストを再実行すると、ただちに返されます。 |
get_approval | request_id、request_capability | 許可されたリクエストを読み取り、まず期限切れを適用します。配信による副作用やエージェントの起動はありません。 |
cancel_approval | request_id、request_capability | 保留中のリクエストをキャンセルします。すでに終端状態になっている結果は変更せずに返されます。 |
acknowledge_approval | request_id、request_capability、decision_id | 対応する終端状態の決定を受信したことを記録します。冪等であり、2 つ目の決定は作成されません。 |
action は Unicode スカラー値を 1~1000 個、context は 0~1000 個、session_label は 1~128 個を受け付けます。
client_request_id は [A-Za-z0-9_-]{1,128} に一致する必要があります。expires_in_seconds は 60~86400 の整数で、デフォルトは 3600 です。
request_approval は待機する呼び出しです。作成確認ではなく、実際の結果を返します。
prepare_approval だけでは Telegram への質問は送信されず、実行可能なリクエストも作成されません。
通常のエージェントのフローは次のとおりです。
prepare_approvalを呼び出し、返されたrequest_handle、request_id、request_capabilityをまとめて保持します。- そのハンドルと機能、一意の
client_request_id、正確なアクション、および人間がリクエストを識別できる十分なコンテキストを指定して、request_approvalを呼び出します。 - 返された
resolutionとdelivery_stateを使用します。この呼び出しは、人間による判断そのものを返します。 - 結果に
decision_idが含まれている場合は、その決定を正確に指定してacknowledge_approvalで確認します。 - 結果が
approvedの場合に限り、かつ自身の権限ルールの範囲内でのみ実行します。
リクエスト機能は、所有者プリンシパルと組み合わせることで、その後の get_approval、cancel_approval、acknowledge_approval の呼び出しを許可します。これを Telegram、アシスタントのメッセージ、ログ、session_label、action、context に含めないでください。これらのテキストフィールドは Telegram の質問に表示されます。ラベルは呼び出し元が指定する表示用コンテキストであり、認証された ID ではありません。
同じ所有者の別のコンテキストと機能を共有すると、そのコンテキストは該当する 1 つのリクエストにアクセスできます。元の待機中の呼び出し先が変更されることはなく、別の所有者に権限が付与されることもありません。
決定と配信
| 結果 | 意味 |
|---|---|
approved | 対応する人間がこのリクエストを明示的に承認しました。 |
rejected | 対応する人間が拒否しました。これはアクションを許可するものではありません。 |
responded | 対応する人間が指示を入力しました。これは承認ではありません。 |
expired | 決定がないまま期限が過ぎました。これは承認ではありません。 |
cancelled | 権限を持つ呼び出し元が保留中のリクエストをキャンセルしました。これは承認ではありません。 |
承認が得られるのは、明示的に「承認」を選択した場合のみです。「拒否」を選択すると拒否が記録されます。「応答」を選択すると、有効な関連付けが確認されたテキストがある場合に限り、リクエスト固有の指示が記録されます。指示を送るには、「応答」を押してプロンプトに返信するか、/respond <request_id> <text> をそのまま送信してください。「応答」のテキストに承認を示すような言葉が含まれていても、承認にはなりません。「応答」のテキストは、空白も含めて一切変更せずに保存され、返されます。
各リクエストに対する解決結果は最大1つです。重複する更新や競合する選択によって、その結果が置き換えられることはありません。アクションを実行する前に、(request_id, decision_id) を基準に重複を排除してください。
クライアントまたはトランスポートのタイムアウトによって、リクエストがキャンセルまたは期限切れになることはありません。待機中の呼び出しが失われた場合も、キャンセルされることはありません。保持されているリクエストの識別情報と権限を維持し、後のターンで get_approval を使用して、変更されていない結果を読み取ってください。結果の取得によって、エージェントが再開したり、新しいアシスタントターンが開始されたりすることはありません。
このプレビューでは MCP Events はサポートされていません。タイムアウト後に自動的に再開することも、自動的にセッションを再接続することもありません。承認によって結果が記録されるだけです。アクションが実行されるわけではありません。
delivery_state は決定ではなく、結果の報告状況を示します。
not_applicable:まだ最終決定がありません。pending:決定は記録されていますが、配信は確認されていません。returned:アダプターが、元の呼び出しへの結果の書き込みを報告しました。受信は確認されていません。confirmed:リクエストの権限を持つユーザーが、その決定を確認しました。unavailable:自動配信を利用できません。保持されている権限を使って結果を取得してください。blocked:配信がブロックされています。proceed-mcp statusを確認してください。
初回の手動テスト
安全な操作を使います。製品が操作を実行することはありません。
serveを実行したままにし、MCP クライアントを接続しておきます。- 新しいエージェントセッションで
prepare_approvalを要求し、続けてclient_request_idをmanual-approve-1、操作をReport the text PROCEED TEST、コンテキストをHarmless first-use check. Do not modify files.、expires_in_secondsを 300 としてrequest_approvalを要求します。 - 2 回目の呼び出しがまだ待機中の間に、Telegram で「承認」を押します。
- 待機中の呼び出しが、同じ
request_idを含むresolution: approvedを返すことを確認します。返されたdecision_idをacknowledge_approvalで確認応答します。ファイル操作やコマンドの実行は不要です。 - 次のアシスタントターンで、後続の確認応答を確認します。同じ
request_idと、記録された結果approvedが示されている必要があります。request_capabilityを 繰り返してはならず、操作も実行してはなりません。これは必須の手動確認であり、検証済みプレビューの結果ではありません。 - 新しい準備済みハンドルと
client_request_idmanual-reject-1を使って同じ手順を繰り返し、今度は「拒否」を押します。 呼び出しは、操作を実行する権限ではなく、rejectedを返す必要があります。次のアシスタントターンも同様に確認します。request_idと結果rejectedが一致し、権限の再提示も操作の実行もないことを確認します。 manual-respond-1を使って同じ手順を繰り返します。「応答」を押し、プロンプトに正確なテキストRead only. Do not modify files.で返信し、呼び出しがそのテキストを変更せずに含むrespondedを返すことを確認します。 このテキストに承認を示す言葉が含まれていても、指示として扱われます。次のアシスタントターンで、対応するrequest_idと、承認ではなく指示を記録した結果respondedが示され、権限の再提示も操作の実行もないことを確認します。
選択する前に待機中の呼び出しがタイムアウトした場合でも、リクエストは期限まで保留状態のままです。後のターンで、保持している
request_id と request_capability を指定して get_approval を使います。取得しても
エージェントは再開しません。
ブローカーのターミナルで Ctrl+C を一度押し、proceed-mcp: broker stopped が表示されるまで待って終了します。
コマンド
| コマンド | 目的 |
|---|---|
init --state-dir <dir> | 保護された空の状態を作成します。既存の状態への上書きは拒否されます。 |
owner add <id> --label <label> --state-dir <dir> | 不変のオーナーとその認証情報を追加します。ブローカーの停止が必要です。 |
serve --state-dir <dir> | フォアグラウンドでブローカーを実行します。Telegram トークンはブローカーの環境から読み込みます。 |
pair --state-dir <dir> | 実行中のブローカーに対し、一度だけ使用できる有効期限 5 分のペアリングコードを要求します。 |
mcp --owner <id> --state-dir <dir> | 1 人のオーナー用に stdio MCP アダプターを実行します。 |
status --state-dir <dir> [--request <id>] [--json] | リクエスト、解決結果、Telegram と配信の状態、および次の操作を表示します。 |
retry <request_id> --state-dir <dir> | このプレビューではリクエストを再試行できないことを報告します。 |
doctor は実装されていないため、不明なコマンドとして失敗します。ヘルプ出力にある以前の origin add コマンドは、
廃止された origin ベースの設定用であり、この状態では拒否されます。オーナーモードを使用してください。
終了コードは、完了時が 0、引数または設定が無効な場合が 2、前提条件を満たせない場合が 3、ストレージまたは整合性の障害が
4 です。診断情報は stderr に出力されます。MCP の stdout にはプロトコルフレームのみが出力されます。
状態、プライバシー、シャットダウン
| パス | 内容 |
|---|---|
config.json | スキーマバージョン 2:Telegram トークンの変数名、ブローカーポート、所有者レコード。 |
credentials/control.token | ペアリング、ステータス、その他の制御操作に使用するローカル制御資格情報。 |
credentials/owner.<owner-id>.token | MCP リクエストルート用の所有者ごとの資格情報。 |
journal.log | 追記専用のトランザクションジャーナル。唯一の可変な製品状態です。 |
broker.lock | 実行中のブローカーが書き込み、正常終了時に削除する所有権レコード。 |
状態ディレクトリとそのファイルへのアクセスは、現在の OS アカウントに制限されています。init、owner add、serve はこの保護を検証し、確立できない場合は続行せずに失敗します。Windows の検査では、PowerShell と icacls を使用して所有者限定の ACL を設定します。POSIX では、所有者のみがアクセスできるモードビットを使用します。
ジャーナルには、リクエストテキスト、レスポンステキスト、ペアリング識別子、判断、タイムスタンプ、配信状態が保存されます。状態ディレクトリは機密性の高いローカルデータとして扱ってください。停止したブローカーの状態ディレクトリ全体をバックアップしてください。このプレビューには、履歴の削除や圧縮機能はありません。
リクエストのケイパビリティは SHA-256 検証値としてのみ保存されます。平文のケイパビリティは、ツールの結果とお客様の保持領域に存在します。資格情報やトークンの値はコマンドから出力されません。
ブローカーは 127.0.0.1 のみで待ち受け、すべてのルートで資格情報を要求し、ブラウザーのオリジンを拒否します。公開ブローカーリスナーも、リモートでのブローカーのホスティングもありません。
Ctrl+C でブローカーを停止し、proceed-mcp: broker stopped と表示されるまで待ってください。正常終了すると、所有権レコードが解放されます。シャットダウンに失敗した場合やプロセスが強制終了された場合は、broker.lock が残り、次回の serve は起動を拒否することがあります。保護された状態ディレクトリを保持し、ロックやジャーナルを削除しないでください。このプレビューには、古いロックを自動的に回復する機能はありません。
よくあるエラー
BROKER_UNAVAILABLE:serveを起動するか、アダプターとブローカーで同じ--state-dirが使用されていることを確認してください。NOT_PAIRED:リクエストを作成する前に/pairを完了してください。NOT_FOUND:所有者または状態ディレクトリが間違っている、ハンドルが未使用である、またはリクエストのケイパビリティが一致していません。DECISION_MISMATCH:リクエストが終端状態ではないか、decision_idが一致していません。- Telegram の処理が停止した場合:ボットトークンを確認し、Webhook や 2 つ目のポーラーがボットを使用していないことを確認してください。修復後に
serveを再起動してください。
制限事項
- ブローカーごとに、ペアリングされた人間 1 人とボットトークン 1 つを使用します。最初のペアリングのみ成功します。チャット内での ID 変更や再ペアリングはできません。
- 状態ディレクトリごとにブローカーは 1 つです。別の所有者は別のトランスポートプリンシパルであり、別の人間やボットではありません。
- ホステッドサービスやリモートブローカーはありません。ブローカーはループバックのみで使用できます。
- MCP Events はサポートされていません。ツールのタイムアウト後に自動で処理を続行することはなく、タイムアウトしてもリクエストはキャンセルされません。
- 取得によってエージェントが起動することはなく、新たな判断も作成されません。
- この製品はアクションを実行せず、OpenCode の権限ルールも適用しません。承認は協調的な仕組みです。
- 終了した MCP クライアントまたはハーネスプロセスの復旧や、セッションの自動再アタッチには対応していません。
- OpenCode V2 は最初の検証用ハーネスです。他のハーネスはテストされていません。汎用の stdio コマンドは利用できますが、複数のハーネスとの互換性は保証されていません。
- マニフェストで必要な Node.js の最低バージョンは 24 です。オフラインテストの証拠があるのは、Node 24.22.2 を使用した Windows のみです。他のオペレーティングシステムや Node のバージョンがサポートされているとは限りません。
doctorは実装されていません。retryは利用不可と報告します。- npm プレビューは公開されています。クリーンな公開インストール、および Telegram や OpenCode を使用した実環境での結果は検証されていません。
ライセンス
MIT。著作権者は Ng Cheng Leong、2026 年です。リリースパッケージには、標準の MIT LICENSE
ファイルをルートに含める必要があります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。