Nofax について
Nofax は AI コーディングエージェントと人をつなぐオープンソースのブリッジで、ローカルでの承認要求、通知、明示的な判断を扱います。任意でセルフホストする Cloudflare Worker は、通知と安全なリクエスト確認に絞ったリモートインターフェースを提供します。
主な機能
- 01ワークフローを一時停止して人の明示的な判断を待機
- 02スマートフォンへの通知
- 03承認、選択、修正案の要求
- 04タイムアウトや通信エラー時は許可しない
- 05任意のリモート通知とリクエスト確認
活用シーン
- 01エージェントの処理続行前に人の承認を求める
- 02選択肢の決定やリクエストの修正を依頼
- 03ワークフローに対応が必要な際にスマートフォンへ通知
- 04セルフホストした Worker で保留中のリクエストを確認
MCP 対応
ローカル stdio MCP サーバーは、通知、承認・選択の要求、修正依頼、応答待機、リクエスト確認のツールを公開します。任意のリモート MCP インターフェースは一方向通知と読み取り専用の確認を提供し、リモート承認や応答のツールは含みません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
7掲載時のツール一覧 · 3 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| title | string | いいえ | ユーザーに表示する任意の通知タイトル。デフォルトは "Nofax" です。 |
| message | string | はい | ユーザーに表示する通知本文。 |
詳細
Nofax
Nofax SaaSを実行せずに、AIコーディングエージェントの承認と通知を人間が介在して行います。
Nofaxは、エージェントと人間をつなぐ小さなオープンソースのブリッジです。ローカルモードでは、AIワークフローを一時停止してスマートフォンに通知し、明示的な判断を返せます。オプションのセルフデプロイ型Cloudflare Workerは、一方向の通知と安全なリクエスト確認に限定した、より狭い範囲のリモートMCP機能を提供します。
Nofaxアカウントは不要です。有料のモデルAPIも不要です。マシンでインバウンドポートを開く必要もありません。MITライセンスです。
現在の状況: ローカル版Nofaxは安定版の
0.2.x系列です。オプションのCloudflare Workerは、今後提供予定のリモート機能0.3.0であり、ローカルパッケージと並行して開発されています。
Nofaxを選ぶ理由
エージェントのワークフローでは、次の問いに明確に答える必要性が高まっています。自動化が人間の判断を必要とする境界に達したとき、沈黙を承認とみなさずに、どう確認を求めるのでしょうか。
Nofaxはその境界を明確に保ちます。
- 保留中の状態が承認になることはありません。
- タイムアウトや通信障害が発生した場合は、安全側に倒して拒否します。
- 最初に受理された終端応答が優先されます。
- エージェント固有のフックスキーマはアダプター内に分離されます。
- リモートアクセスは、意図的にローカルアクセスより制限されています。
- Nofaxが、呼び出し元のエージェントに元からない権限を付与することはありません。
2つの動作モード
| 機能 | ローカル版Nofax 0.2 | リモートWorker 0.3 |
|---|---|---|
| トランスポート | stdio / CLIフック | MCP Streamable HTTP |
| 一方向の通知 | はい | はい |
| 許可 / 拒否 | はい | いいえ |
| 明示的な選択肢 | はい | いいえ |
| 自由記述による修正 | はい | いいえ |
| 人間の応答を待機 | はい | いいえ |
| リクエストのメタデータを読み取り | はい | はい |
| 永続状態 | ローカルファイル | 既存のSQLite Durable Object行 |
| Nofaxによるホスティング | いいえ | いいえ — セルフデプロイ型Worker |
| リモート認証 | ローカルプロセス境界 | プライベートなBearerキー |
リモートWorkerは、**ホスト型のリモート承認サービスではありません。**情報通知を送信し、既存のリクエスト状態を確認できますが、承認コールバック、選択、修正、待機、Webhook、または任意のリモート書き込みエンドポイントは備えていません。
クイックスタート
1. インストール
npm install -g nofax
Node.js 20以降が必要です。
2. 初期化
nofax init
Nofaxは~/.nofax/config.jsonを作成し、エントロピーの高い通知トピックを生成します。デフォルトのトランスポートを使用する場合は、ntfyモバイルアプリで表示されたトピックを購読してください。
3. テスト
nofax test
4. 使用する
nofax notify --title "Build finished" "All tests passed"
nofax approve --title "Deploy?" "Release 1.4.0 is ready"
nofax refine --title "Refine draft" "Tell me what to change"
承認結果は、安定した終端JSONとして解決されます。
{"decision":"allow"}
または:
{"decision":"deny"}
リクエストが保留中のままの場合、タイムアウトした場合、接続が切断された場合、またはトランスポートエラーが発生した場合、Nofaxがその状態を承認に変換することはありません。
MCP
ローカルのstdio MCPサーバーを起動します。
nofax mcp
MCP クライアントを接続する
Claude Code は、公開済みのローカル MCP サーバーを直接起動できます。
claude mcp add nofax -- npx -y nofax mcp
Codex CLI には、同じ stdio サーバーを登録できます。
codex mcp add nofax -- npx -y nofax mcp
Gemini CLI では、ユーザー設定に登録できます。
gemini mcp add --scope user --transport stdio nofax npx -- -y nofax mcp
現在のワークスペースが信頼されていない場合、Gemini CLI は設定済みサーバーを 無効 として表示することがあります。Gemini の通常の信頼フローを通じて、自分が管理するワークスペースのみを確認して信頼してください。MCP ツール呼び出しの確認を回避するために --trust を使用しないでください。MCP サーバーを登録しても、以下で説明する別個の権限フックが自動的にインストールされるわけではありません。
VS Code では、ユーザープロファイルの MCP 設定に Nofax を登録できます。コマンドパレットを開き、MCP: Open User Configuration を選択して、mcp.json に次のエントリを追加します。
{
"servers": {
"nofax": {
"type": "stdio",
"command": "npx",
"args": ["-y", "nofax", "mcp"]
}
}
}
既存のサーバーを置き換えるのではなく、nofax エントリを統合してください。起動前に VS Code の通常のサーバー信頼プロンプトを確認してください。MCP を登録しても、別個の権限フックはインストールされません。
その他の stdio MCP クライアントでは、コマンドを npx に設定し、引数として ["-y", "nofax", "mcp"] を指定します。最後の mcp 引数は必須です。これを付けずに npx -y nofax を実行すると、CLI の使用方法が表示されて終了し、サーバーは起動しません。通知ツールや承認ツールを使う前に、クイックスタートの設定を完了してください。
ローカル MCP では、次のツールを利用できます。
nofax_notifynofax_request_approvalnofax_request_choicenofax_request_refinementnofax_wait_for_responsenofax_get_requestnofax_list_pending
対話型リクエストは、永続的なリクエスト ID を返します。nofax_wait_for_response は上限時間付きで待機します。リクエストが保留中の場合、呼び出し元は承認されたと推測せず、待機を繰り返す必要があります。
エージェント連携
Claude Code
Nofax を ~/.claude/settings.json でローカルの PermissionRequest フックとして使用します。
{
"hooks": {
"PermissionRequest": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "nofax hook claude"
}
]
}
]
}
}
Codex
Codex のフックはデフォルトで有効です。~/.codex/hooks.json を設定してください。
{
"hooks": {
"PermissionRequest": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "nofax hook codex",
"statusMessage": "Waiting for Nofax approval"
}
]
}
]
}
}
Codex を再起動し、/hooks を実行して、Nofax フックの定義が正確であることを確認し、信頼してから使用してください。Codex は、信頼されるまで管理対象外のフックを実行しません。また、フックの定義を変更した場合は再度確認する必要があります。管理者またはローカルポリシーによってフックが明示的に無効化されている場合は、~/.codex/config.toml の [features] hooks = true で再有効化してください。
Codex は現在、設定済みの承認レビュアーより先に PermissionRequest フックを評価します。そのため、Nofax の最終的な Allow/Deny によってリクエストが解決され、Codex が approvals_reviewer = "auto_review"(または旧式の guardian_subagent 値)にルーティングする前に処理が完了します。Nofax を人間による承認窓口として使う場合は、approvals_reviewer = "user" を使用してください。両方のレビュアーが実行されることを期待して、この Nofax 承認フックを Auto-review/Guardian と併用しないでください。現在の Codex フック入力には有効なレビュアーが公開されないため、Nofax はユーザーにルーティングされた承認と、Codex が自動レビューを意図した承認を安全に区別できません。
PermissionRequest フックは Codex のネイティブ承認 UI とも直列に実行されます。Nofax が待機中は、通常の Codex 承認プロンプトは同時に利用できません。Nofax が判断を返さない場合(たとえば、タイムアウトまたは通信障害の後)、Codex は通常の承認フローにフォールバックします。Nofax がこのフォールバック状態を承認に変換することはありません。
Gemini CLI
現在の Gemini CLI ビルドでは、ツール呼び出しを許可または拒否できる同期型の BeforeTool フックが公開されています。選択したツールを ~/.gemini/settings.json で Nofax 経由にルーティングします。
{
"hooks": {
"BeforeTool": [
{
"matcher": "run_shell_command|write_file|replace",
"hooks": [
{
"name": "nofax-approval",
"type": "command",
"command": "nofax hook gemini",
"timeout": 305000
}
]
}
],
"Notification": [
{
"matcher": "ToolPermission",
"hooks": [
{
"name": "nofax-notification",
"type": "command",
"command": "nofax hook gemini"
}
]
}
]
}
}
BeforeTool は、Nofax から明示的な Allow/Deny の結果が返るまで待機します。Nofax がタイムアウトした場合や通信に失敗した場合、Gemini は ask の判断を返し、ネイティブの対話型確認を必須にします。これにより、自動承認ポリシーが Nofax の判断がないことを許可として扱うのを防ぎます。Notification フックは引き続き参考情報として扱われ、電話通知としてのみ転送されます。
Nofax に制御させたいツールに合わせてマッチャーを調整してください。フックのタイムアウトは、Nofax に設定した承認タイムアウト(timeoutSeconds。デフォルトは 300 秒)より長くしてください。
Pi(ネイティブ MCP サポート)
リリース版の @earendil-works/pi-coding-agent など、ネイティブ MCP サポートを備えた Pi では、ローカルの Nofax stdio サーバーを起動できます。nofax init の実行後、登録して確認します。
pi mcp add nofax -- npx -y nofax mcp
pi mcp list
Pi の MCP リクエストのデフォルトのタイムアウトは 60 秒です。Nofax の最大値である 240 秒までの、これより長い待機時間を nofax_wait_for_response で使用する場合は、~/.pi/agent/mcp.json の既存の nofax エントリーに "timeout": 300 を追加してください。関係のないサーバーエントリーや設定は置き換えないでください。
{
"mcpServers": {
"nofax": {
"command": "npx",
"args": ["-y", "nofax", "mcp"],
"timeout": 300
}
}
}
これにより登録されるのは MCP ツールであり、自動的な権限フックやアイドル状態のセッションを起こす機能ではありません。リクエストが保留中の場合、エージェントは nofax_wait_for_response を再度呼び出す必要があります。返信がない場合、タイムアウト、切断は、いずれも承認を意味しません。Pi の通常の信頼/権限ワークフローを使用し、これらの手順を適用する前に、インストール済みの Pi ビルドで pi mcp が利用できることを確認してください。
オプションのリモート Cloudflare Worker
worker/ パッケージは、非公開のセルフデプロイ型 MCP エンドポイントを提供します。
remote MCP client
|
| authenticated Streamable HTTP
v
Cloudflare Worker
|
+--> nofax_notify ------> ntfy ------> phone
|
+--> SQLite Durable Object
|
+--> get request metadata
+--> list pending requests
公開するツールは、次の 3 つのみです。
nofax_notify— 一方向の通知のみ。nofax_get_request— 安全なリクエストの概要を 1 件読み取ります。nofax_list_pending— 未解決で有効期限内のリクエストの概要を読み取ります。
worker/ からデプロイします。
npm ci
npx wrangler login
npx wrangler secret put NOFAX_REMOTE_KEY
npx wrangler secret put NTFY_TOPIC
npm run check
npm run deploy
推奨される MCP 接続方法:
https://<worker>.workers.dev/mcp
Authorization: Bearer <NOFAX_REMOTE_KEY>
静的な認証ヘッダーを付加できないクライアントでは、互換性のためのケイパビリティ経路を使用できます。
https://<worker>.workers.dev/mcp/<NOFAX_REMOTE_KEY>
ケイパビリティ URL 全体をパスワードと同様に扱ってください。
デプロイ、脅威の境界、適格性の詳細については、docs/remote-mcp.md を参照してください。
重要:公開 ntfy とサーバーレス環境からの送信通信
デフォルトの公開 ntfy.sh サービスには、発行者ごとのクォータが適用されます。Cloudflare Workers などのサーバーレスプラットフォームでは、送信元 IP が共有されることがあります。そのため、個々の Worker の通信量がごく少ない場合でも、Worker が ntfy の 42908 日次クォータ超過応答を受け取ることがあります。この制限は ntfy が課すものであり、Cloudflare Workers のリクエストクォータではありません。
信頼性が重要なデプロイでは、クォータが自身の認証済みアカウント/ID に紐づく通知プロバイダーを使用するか、信頼できるセルフホスト型のトランスポートを運用してください。匿名で利用する公開トピックのクォータに関する想定を前提として、重要なワークフローを構築しないでください。
セキュリティモデル
Nofax はトランスポートおよび人間との対話のコンポーネントであり、認可ポリシーエンジンではありません。
ローカルモード:
- 保留、タイムアウト、切断、不正な状態、ネットワーク障害は、いずれも承認を意味しません。
- 最初に届いた有効な終端応答が優先されます。
- 通知トピックと一度限りの応答トピックは、ケイパビリティです。
- 公開 ntfy では、プロバイダーからのエンドツーエンド暗号化は行われません。
- 情報の秘匿化はベストエフォートであり、自由形式のテキストに埋め込まれた秘密情報を確実に特定することはできません。
リモートモード:
- 外部メッセージングの副作用を発生させるのは、明示的な
nofax_notifyのみです。 - リクエストの検査操作は読み取り専用で、非表示のクリーンアップ書き込みは行いません。
- リモートでの承認、コールバック、Webhook、詳細化、選択、待機の機能はありません。
NOFAX_REMOTE_KEYはベアラー認証情報です。- リモートの概要には、コールバック用ケイパビリティ、プロンプト/メッセージのテキスト、内部の許可判断リストは含まれません。
機密情報を扱う場合は、Nofax を使用する前に SECURITY.md をお読みください。
設定
デフォルトのローカル設定は ~/.nofax/config.json にあります。
{
"version": 1,
"server": "https://ntfy.sh",
"topic": "nofax_<random>",
"timeoutSeconds": 300
}
NOFAX_HOME でホームディレクトリを上書きします。
NOFAX_HOME=/path/to/nofax-home nofax config
別の ntfy 互換サーバーを使用する場合:
nofax init --server https://ntfy.example.com --force
開発
ローカルパッケージ:
npm ci
npm run check
npm test
npm pack --dry-run
リモート Worker:
cd worker
npm ci
npm run check
CI では、ローカルパッケージについて Node.js 20、22、24 の適格性を確認します。Worker のゲートでは、TypeScript、Vitest、本番依存関係の監査、Wrangler のデプロイのドライランを実行します。
プロジェクトのドキュメント
docs/architecture.md— 信頼境界とデータフローdocs/remote-mcp.md— リモート Worker のデプロイと適格性確認SECURITY.md— セキュリティ上の前提と脆弱性の報告CONTRIBUTING.md— コントリビューションとテストに関する要件CHANGELOG.md— リリース履歴
対象外
Nofax が意図的に提供しないもの:
- Nofax が運営する承認 SaaS;
- 有料モデル API への依存;
- 永続的な
always approveポリシー; - 任意のリモートシェルエンドポイント;
- 共有デプロイキー 1 つで運用する、一般公開のマルチユーザー向け Worker;
- MCP アノテーション自体がセキュリティ境界であるという主張。
ライセンス
MIT © Tomi Šeregi. LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。