LLM CLI Gateway について
LLM CLI Gatewayは、単一ユーザーがMCP経由で、対応するローカルのコーディングエージェントや設定済みHTTP APIプロバイダーを操作するための制御プレーンです。永続的な非同期ジョブ、ワークスペース制限、承認ゲート、セッション継続、レビュー機能を備え、プロバイダーの認証情報はユーザー所有の環境に保管します。
主な機能
- 01同期・非同期エージェントツールの共通化
- 02復旧とキャンセルに対応する永続ジョブ
- 03ワークスペース単位のプロバイダー実行
- 04セッション追跡とCLI再開パス
- 05承認ゲートと検証レシート
- 06ワークフロースキルと決定的なプラン
活用シーン
- 01MCPクライアントからコーディングタスクを委任
- 02登録済みワークスペースでエージェントを実行
- 03切断後に長時間ジョブを再開・回収
- 04実装と複数エージェントのレビューを調整
MCP 対応
ゲートウェイはstdioまたは設定済みのリモートWebコネクターを通じて単一のMCPエンドポイントを提供し、対応クライアントからプロバイダーCLIやHTTP APIを操作できます。同期・非同期ツール、永続ジョブ、セッション・レビュー用ツール、ワークスペース単位の実行を備えています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
28掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| focus | string | いいえ | レビュアーが注目すべき点。 |
| models | array | いいえ | 問い合わせるプロバイダー。デフォルトは Claude と Codex です。 |
| question | string | はい | 検証する質問または内容。 |
| judgeModel | any | いいえ | 明示的な判定統合ジョブの実行に使用する任意のプロバイダー。 |
詳細
llm-cli-gateway
「相談がなければ計画は挫折しますが、多くの助言者がいれば成功します。」 — 箴言 15:22(LSB)
AI コーディングエージェント向けの安全なローカル制御プレーンです。
llm-cli-gateway を使うと、対応する MCP クライアントから、Claude Code、Codex、Gemini/Antigravity、Grok Build、Mistral Vibe、Cognition Devin、Cursor Agent、および設定済みの HTTP API プロバイダーを、ユーザー自身が所有する 1 つのゲートウェイ経由で操作できます。ネイティブ CLI セッション、ローカル認証情報、永続的な非同期ジョブ、検証レシート、レビューのワークフローはそのまま維持されます。
**開発者が試す理由:**普段使っているクライアントからローカルのコーディングエージェントに作業を委任し、リモート実行を登録済みのワークスペースに限定し、リスクの高い操作に制限を設け、接続が切れても処理を継続し、エージェントを汎用的なチャットプロキシに変えることなく、監査可能なレビューの証拠を収集できます。
現在の状況:main の CI とセキュリティのワークフローは成功しており、OpenSSF Scorecard が公開されています。OpenSSF Best Practices の要件を満たし、リリースには Sigstore 署名を使用しており、パッケージは MIT ライセンスです。
クイックスタート
npm install -g llm-cli-gateway
または、MCP クライアントから npx で直接利用します。
{
"mcpServers": {
"llm-gateway": {
"command": "npx",
"args": ["-y", "llm-cli-gateway"]
}
}
}
現在提供している機能
llm-cli-gateway は、サポート対象のローカルクライアントまたはリモートクライアントから AI コーディングエージェントを操作する、シングルユーザー向け MCP コントロールプレーンです。単なる CLI ラッパーではありません。
- 登録済みプロバイダーの CLI と設定済みの HTTP API プロバイダーを実行する、統一された同期・非同期 MCP ツールを提供します。
- 長時間実行されるジョブを永続化し、再起動後も安全に結果を収集できるほか、重複排除、キャンセル、同期処理から非同期処理への移行をサポートします。
- セッション、実際の CLI 再開パス、構造化レスポンスのメタデータ、キャッシュのテレメトリーを追跡します。
- 明示的に有効化した場合の Claude
cache_controlを含む、キャッシュ対応のpromptPartsをサポートします。 - ローカルのファイルベースまたは PostgreSQL のセッションマネージャーを使い、サポート対象のプロバイダーリクエストをゲートウェイ管理の Git ワークツリー内で実行できます。これにより、分離されたマルチエージェントのレビューおよび実装ループを実現します。セッションが PostgreSQL によってホスト間で共有されている場合でも、セッションに紐づくワークツリーの再利用とクリーンアップは、ファイルシステム上の成果物を所有するホストに限られます。セッションの削除後、
session_clear_allの実行後、またはファイルベースの TTL による削除後も、どちらのセッションマネージャーもクリーンアップに失敗した場合は記録を保持し、ワークツリーを所有するホストが再試行できるようにします。別のホストで処理された削除ではワークツリーは削除されず、その記録もそのまま残ります。データベース側のcleanup_expired_sessions関数は、ワークツリーを含むセッションを削除する代わりに、同じ記録を保留状態にします。この関数はゲートウェイのオブザーバーを呼び出さないため、自ら削除を試みることはありません。Grok、Devin、Mistral でゲートウェイのワークツリーを使用するには、プロバイダー固有のsessionIdを明示的に指定する必要があります。新規作成、createNewSession、またはresumeLatestのみを指定したワークツリーリクエストは、セッションを永続的に再選択できないため、安全のため失敗します。ワークツリーの作成時には、リポジトリ、システム、グローバルの Git フック、設定済みの clean、smudge、process チェックアウトフィルター、スパースチェックアウト、遅延オブジェクト取得を無効にします。Git LFS などのフィルターに依存するコンテンツは、ホストコマンドを実行せず、リポジトリ内の形式のまま保持されます。 - HTTP トランスポートとベアラートークン認証、
doctor --json、セットアップ UI の成果物、プロバイダーのセットアップ用スニペット、Docker フォールバック、検証済みリリースバンドルなど、個人用アプライアンスのセットアップ手段を提供します。 - リモートの Web コネクターは、MCP OAuth のディスカバリーと認可コードによるセットアップを、静的クライアントまたは共有シークレットのゲートとともに使用します。クライアントシークレットはローカルで生成され、ハッシュのみが保存されます。明示的な一度限りのコピーコマンドでのみ、シークレットが表示されます。
- プロバイダー CLI リクエストでは、
workspaceを使ってエイリアスで登録済みワークスペースを選択できます。HTTP/トンネル経由のリクエストはすべて、プロバイダーの実行前に、登録済みのエイリアス、セッションのワークスペース、または[workspaces].defaultを使用する必要があります。制限のないローカルファイルシステムアクセスには stdio トランスポートを使用します。
ワークフローアセット
このリポジトリには、非同期オーケストレーション、セッション継続性、複数 LLM によるレビュー、実装・レビュー・修正のループ、振り返りのエビデンスウォーク、安全な承認ゲート付きディスパッチ、Personal Agent Config Kit の運用に対応した、エージェント向けワークフロースキルが.agents/skillsに含まれています。公開 npm パッケージには、呼び出し元向けの次の 9 つのスキルが含まれています:async-job-orchestration、multi-llm-review、session-workflow、secure-orchestration、implement-review-fix、retrospective-walk、public-demo-session、least-cost-routing、personal-agent-config-kit。決定的な順序制御と検証ゲートが必要なワークフロー向けの、機械可読な DAG-TOML プランは、docs/plansとsetup/install-plan.dag.tomlにあります。
スキルパックは、ローカルのオペレーター管理パスにスキルディレクトリを配置することで、コア npm リリースとは別に更新できます。ゲートウェイは、まず同梱スキルを読み込み、次に[skills].paths、その次にLLM_GATEWAY_SKILLS_PATH、最後に~/.llm-cli-gateway/skillsが存在する場合はそこから読み込みます。後に読み込まれたルートのスキルは、名前が同じ場合、先に読み込まれたスキルを上書きします。各スキルはSKILL.mdを含むディレクトリです。ルートには、想定されるSKILL.mdのハッシュを固定するために、skill-pack.jsonを含めることもできます:
[skills]
paths = ["/opt/llm-cli-gateway/skills"]
export LLM_GATEWAY_SKILLS_PATH="/opt/team-skill-pack:/opt/incident-skill-pack"
{
"name": "team-pack",
"version": "1.0.0",
"skills": [
{
"name": "incident-retrospective",
"sha256": "<sha256 of incident-retrospective/SKILL.md>"
}
]
}
ローダーは意図的にローカルのみで動作し、起動時にリモートの Markdown を取得することはありません。パックを更新するには、パッケージマネージャーまたはデプロイシステムを通じてファイルをインストールまたは置き換えた後、ゲートウェイを再起動して、公開されるskills://...リソースを更新してください。
今後のドキュメントでは、送信 CLI および API プロバイダーファミリーごとに、プロバイダー固有のスキルと DAG-TOML のペアに重点を置きます。対象は Claude、Codex、Gemini/Antigravity、Grok、Mistral Vibe、Devin、Cursor Agent、OpenAI 互換エンドポイント、Anthropic Messages、xAI Responses です。実装計画はdocs/plans/provider-workflow-assets.dag.tomlで追跡しており、各プロバイダーのアセットでは、インストール/ログインの確認またはトークン環境変数の確認、セッションの動作、承認モード、キャッシュ/テレメトリーの表示領域、障害モード、スモークテストゲートを扱う予定です。
信頼とサプライチェーン
- CI では、ビルド、リンティング、フォーマット、テスト、パッケージチェック、npm audit を実行します。
- セキュリティ CI では、actionlint、zizmor、shellcheck、typos、osv-scanner、gitleaks、lychee を実行します。
- GitHub リリースのインストーラーアーティファクトにはチェックサムを付与し、Sigstore のキーレス署名で署名します。
- npm リリースでは、生成された本番依存のみの shrinkwrap とリリースセキュリティ監査を使用します。GitHub Actions Trusted Publishing では、ジョブの OIDC アイデンティティを短期間有効な npm 公開用認証情報と交換します。
- npm パッケージには、レジストリからのインストールで監査済みのリリースツリーが解決されるよう、生成された本番依存のみの
npm-shrinkwrap.jsonを意図的に含めています。リリースゲートでは、package-lock.jsonからこれを再生成して整合性を比較し、公開前にレジストリとの同等性を確認するコンシューマーインストールを実行します。 - Socket の動作アラートについては、
socket.ymlと、以下の「セキュリティ上の考慮事項」で説明しています。shellAccessとshrinkwrapは、この CLI アプライアンスでレビュー済みのパッケージ機能/設定であり、隠れたインストール動作ではありません。
パーソナル MCP アプライアンス
パーソナルアプライアンスの契約では、対象範囲を意図的に限定しています。信頼された 1 人のユーザーが、自身の所有するマシンまたはボリューム上でゲートウェイを実行し、1 つの MCP エンドポイントに接続して、対応クライアントから、ワークスペースの範囲に限定され、承認ゲートと監査の対象となるリクエストを通じて、ローカルのコーディングエージェントを操作します。 製品の契約内容はdocs/personal-mcp/PRODUCT_CONTRACT.mdに記載されています。単一ユーザーのスコープ、セキュリティ態勢、対象のサポートマトリックス、プロバイダーサポートの検証ゲートを定義しています。対応するプロバイダー/クライアント経路の検証が完了するまでは、公開セットアップガイドでChatGPT、Claude web、Claude Desktop、Codex、Gemini CLI、Gemini web、Grokからのインバウンドサポートを謳ってはなりません。
このプロジェクトでは、ホスト型のマルチテナント認証情報管理を提供していません。プロバイダーの認証情報は、ユーザーのマシンまたはユーザー所有のデプロイボリュームに保管されます。
複数のワークステーションとリポジトリで作業する単一の開発者向けに、Personal Agent Config Kit guideでは、Git同期される個人用ベースライン、リポジトリのオーバーレイ、不変のコンテキストスタンプ、ワークステーション間で安全に利用できるプロバイダー継続性モデルについて説明しています。ベースラインディレクトリは、ローカルのホームディレクトリ配下にあるシンボリックリンクではない子ディレクトリに限定されます。また、公開または同期のたびに、設定されたoriginのフェッチURLとプッシュURLがHTTPS/SSHのみを許可するポリシーに準拠しているか再検証されます。Kitは意図的にローカル呼び出し元のみに対応しています。Kitのプロバイダー実行と、許可されていない試行の復旧には、健全で永続性のあるSQLiteまたはPostgreSQLの非同期ジョブ登録が必要です。KitモードではClaude、Codex、Mistralをサポートします。有効時は、それ以外のすべてのプロバイダーをフェイルクローズします。Kitのスコープはゲートウェイプロセスのcwdを引き継ぎません。ClaudeとMistralでは、登録済みのワークスペースの選択または設定済みのデフォルトが必要です。Codexでは、明示的な絶対パスのworkingDirも使用できます。相対パスのKit workingDirは、ファイルシステムまたはGitを検査する前に拒否されます。有効時は、モデル間検証ツールを無効にします。また、HTTP/OAuth設定機能でもリモート実行機能でもありません。
保持期間固定のKit以外のClaude MCPリクエスト設定については、ローカル限定のsame-host recovery procedureに従ってください。SQLや任意のパスによる上書きは受け付けません。有効な復旧コマンドは、成功時にJSONを出力して終了コード0で終了します。安全に拒否された場合は終了コード2で終了します。使用方法が無効な場合、または永続ストレージを利用できない場合は、終了コード1で終了します。
リリース準備状況の履歴はdocs/personal-mcp/RELEASE_READINESS.mdで管理しています。ドッグフーディングのエビデンス(セットアップを導いた対象LLM、記録された危険な提案、初期のパーソナルアプライアンス展開から先送りされた所見)はdocs/personal-mcp/DOGFOODING_RESULTS.mdに記載されています。
現在のパーソナルアプライアンスの成果物には、次のものがあります。
- Streamable HTTP の起動:
LLM_GATEWAY_AUTH_TOKEN=<token> npm run start:http - 機械可読な診断:
npm run doctor - Go ブートストラッパー:
setup、doctor --json、start、stop、status、repair、upgrade、uninstall、print-client-config、検証済みバンドルのダウンロードコマンドを含むinstaller/。 - リリースのパッケージ化:公開ミラーでは、リリースワークフローにより、GitHub ホストの
ubuntu-latest上で Linux バイナリをビルドし、GitHub ホストの各プラットフォームランナー上で Windows/macOS バイナリをビルドします。非公開の上流リポジトリでは、社内のセルフホスト Linux ランナーを使用します。各リリースでは、ゲートウェイ、本番用依存関係、管理対象の Node ランタイムを含む、チェックサム付きのプラットフォーム別バンドルを公開します。installer/packaging/README.md を参照してください。 - Docker Compose による代替手段:すでにコンテナーを管理しているユーザー向けの docker/personal.compose.yml + docker/Dockerfile.personal。
- ローカルセットアップ UI のアーティファクト:setup/ui/index.html
- プロバイダーのセットアップスニペット:setup/providers/
- 相互検証ツール:
review_changes、validate_with_models、second_opinion、compare_answers、red_team_review、consensus_check、ask_model、synthesize_validation、job_status、job_result、validation_receipt(およびvalidation-receipt://{validationId}リソース)。review_changesと永続的なレシートを使用するには、SQLite または PostgreSQL の検証実行ストアが必要です。また、Personal Agent Config Kit モードでは利用できません。
インストール/アップグレード/アンインストール(単一バイナリ)
Windows PowerShell:
$Version = '<version>'
$Base = "https://github.com/verivus-oss/llm-cli-gateway/releases/download/v$Version"
$InstallDir = Join-Path (Join-Path $env:LOCALAPPDATA 'Programs') 'llm-cli-gateway'
$ExeName = "llm-cli-gateway-$Version-windows-amd64.exe"
$BundleName = "llm-cli-gateway-bundle-$Version-windows-amd64.tar.gz"
$Exe = Join-Path $InstallDir 'llm-cli-gateway.exe'
$Checksums = Join-Path $InstallDir 'SHA256SUMS'
$ChecksumBundle = Join-Path $InstallDir 'SHA256SUMS.sigstore.json'
New-Item -ItemType Directory -Force $InstallDir | Out-Null
Invoke-WebRequest -UseBasicParsing "$Base/$ExeName" -OutFile $Exe
Invoke-WebRequest -UseBasicParsing "$Base/SHA256SUMS" -OutFile $Checksums
Invoke-WebRequest -UseBasicParsing "$Base/SHA256SUMS.sigstore.json" -OutFile $ChecksumBundle
cosign verify-blob $Checksums --bundle $ChecksumBundle --certificate-identity "https://github.com/verivus-oss/llm-cli-gateway/.github/workflows/release-installer.yml@refs/tags/v$Version" --certificate-oidc-issuer "https://token.actions.githubusercontent.com"
if ($LASTEXITCODE -ne 0) { throw "Sigstore verification failed for SHA256SUMS" }
function Get-ReleaseSha256($Name) {
$line = Select-String -Path $Checksums -Pattern "^[a-fA-F0-9]{64}\s+$([regex]::Escape($Name))$" | Select-Object -First 1
if (-not $line) { throw "No SHA256SUMS entry found for $Name" }
return (($line.Line -split "\s+")[0]).ToLowerInvariant()
}
if ((Get-FileHash $Exe -Algorithm SHA256).Hash.ToLowerInvariant() -ne (Get-ReleaseSha256 $ExeName)) { throw "Checksum mismatch for $ExeName" }
$env:RVWR_GATEWAY_BUNDLE_URL = "$Base/$BundleName"
$env:RVWR_GATEWAY_BUNDLE_SHA256 = Get-ReleaseSha256 $BundleName
& $Exe setup
& $Exe stop
& $Exe install-bundle
& $Exe start
& $Exe status
& $Exe doctor
Windows インストーラーは、%LOCALAPPDATA%\Programs\llm-cli-gateway に安定した llm-cli-gateway.exe コマンドを保持し、そのディレクトリをユーザーの PATH に追加します。インストール後に、リリースバージョン付きの exe 名をスクリプトで使用しないでください。
# After downloading the binary that matches your OS/arch from a release:
cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/verivus-oss/llm-cli-gateway/.github/workflows/release-installer.yml@refs/tags/v<version>" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
sha256sum --check SHA256SUMS # verify before run (or `shasum -a 256 --check` on macOS)
chmod +x llm-cli-gateway-<ver>-<os>-<arch>
./llm-cli-gateway-<ver>-<os>-<arch> setup
./llm-cli-gateway-<ver>-<os>-<arch> install-bundle # uses the platform bundle URL/SHA256
./llm-cli-gateway-<ver>-<os>-<arch> start
./llm-cli-gateway-<ver>-<os>-<arch> doctor
# Upgrade: replace the binary, set the new bundle env vars, run upgrade.
./llm-cli-gateway-<new>-<os>-<arch> upgrade
# Uninstall: dry-run first, then run with --yes.
./llm-cli-gateway-<ver>-<os>-<arch> uninstall
./llm-cli-gateway-<ver>-<os>-<arch> uninstall --yes
Docker による代替手段:
LLM_GATEWAY_AUTH_TOKEN=$(openssl rand -hex 32) \
docker compose -f docker/personal.compose.yml up -d
docker compose -f docker/personal.compose.yml run --rm doctor
機能
主な機能
- 複数の LLM のオーケストレーション:Claude Code、Codex、Gemini、Grok、Mistral(Vibe)、Devin、Cursor Agent CLI の統一インターフェース
- セッション管理:ゲートウェイのセッションメタデータとプロバイダー固有の継続性を、永続ストレージで追跡します
- ゲートウェイ管理のワークツリー:ローカルのファイルベースまたは PostgreSQL のセッションマネージャーを使用して、管理対象の git ワークツリー内で、サポート対象の同期または非同期のプロバイダーリクエストを実行します。同一セッションを再利用するには、同一ホスト上での永続的な所有権に加え、一致する有効な Git 登録とゲートウェイブランチが必要です。マネージャーレベルでの名前付きパスの競合は、安全のため処理を失敗させます。共有 PostgreSQL セッション行によって、ファイルシステム上のワークツリーの所有権が別のホストに移ることはありません。Grok、Devin、Mistral では、プロバイダー固有の
sessionIdを明示的に指定する必要があります。新規、createNewSession、またはresumeLatestのみのワークツリーリクエストは安全のため処理を失敗させます。ワークツリーを使用するには、明示的に選択した登録済みワークスペース、呼び出し元が所有するセッションメタデータ、または設定済みのデフォルトが必要です。プロセスの cwd を引き継ぐことも、workingDir、addDir、includeDirsと組み合わせることもありません。マテリアライズ時には、リポジトリ、システム、グローバルの Git フック、設定済みの clean、smudge、process チェックアウトフィルター、スパースチェックアウト、遅延オブジェクト取得を無効にします。Git LFS などのフィルターに依存するコンテンツは、ホストコマンドを実行せず、リポジトリ内の表現のままになります。どちらのセッションマネージャーでも、セッションの削除、session_clear_all、ファイルベースの TTL による削除処理では、クリーンアップ中に永続的な所有権を持つワークツリーセッションを非表示にします。Git の削除に失敗した場合、マネージャーは永続的なクリーンアップ待ちのトゥームストーンを保持し、再利用をブロックします。所有ホスト上でマネージャーが登録されると、クリーンアップを再試行します。記録されたパスが存在しないことから推測せず、Git にワークツリーが登録されていないことを読み戻して確認した後にのみ、記録を確定します。移動されたワークツリーや、所有者マーカーを読み取れないワークツリーは削除済みとはみなしません。別のホストで処理された削除ではワークツリーは削除されず、所有ホストの記録もそのまま残ります。データベース側のcleanup_expired_sessions関数は、ワークツリーを含むセッションを削除する代わりに、同じトゥームストーンを作成します。ゲートウェイのオブザーバーは呼び出さないため、それ自体では削除を試みません。トゥームストーンに保持期間の上限はありません。 - トークンの最適化:
optimizePrompt/optimizeResponseによる、オプトイン方式のプロンプト/レスポンス圧縮です。どちらもデフォルトは false です。44%/37% という数値は、特定のコーパスにおける v1.0.0 の測定値であり、保証値ではありません。src/optimizer.tsは決定論的なフレーズ削除ツールで、実行時に圧縮率を測定する機能はありません。 - 相関 ID の追跡:すべての LLM インタラクションを対象とした、完全なリクエストトレース
- ツール間の連携:LLM は MCP を介して相互に利用できます(ドッグフーディングを通じて検証済み)
オブザーバビリティ
- 永続フライトレコーダー:プロバイダーのリクエストとレスポンスは、
[persistence].backendに従います。デフォルトでは SQLite は~/.llm-cli-gateway/logs.dbに書き込み、PostgreSQL は他の永続サブシステムとともに、設定されたデータベースに書き込みます。PostgreSQL に障害が発生すると、レコーダーは利用不可または機能低下の状態になり、ヘルス情報の表示では一般的な形で報告されます。SQLite へのフォールバックは行いません。バックエンドを変更しても、既存の行は移行されず、両方のバックエンドから読み取られることもありません。記録には、相関 ID、所要時間、プロバイダーが出力する場合はトークン使用量が含まれます(現時点で出力するのは、stream-json/json形式の claude、codex、および API プロバイダーです。grok、gemini、mistral、devin、cursor は CLI ワイヤー上で使用量を出力しません)。知っておくべき例外が 2 つあります。クロス LLM 検証用のシートはフライトレコーダーに行を一切書き込まないため、llm_request_resultは相関 ID で該当する行を読み戻せません。また、リポジトリレビュー用のシートも設計上除外されており、非期限付きのテーブルにレビューの証跡が保持されることはありません。retry_count列とcircuit_breaker_state列は、本番経路である非同期経路では固定値です。リトライとサーキットブレーカーが適用されるのは、直接実行へのフォールバック時のみです。履歴の読み取りにはllm_request_listとllm_request_resultを使用してください。プリンシパルごとの所有権チェックが引き続き適用されます。SQLite デプロイ環境で人が履歴を閲覧するには、datasette ~/.llm-cli-gateway/logs.dbを実行してください。 - 構造化メタデータ:ツールのレスポンスには、機械可読な
structuredContent(model、cli、correlationId、sessionId、durationMs、トークン数)が含まれます。 - キャッシュのオブザーバビリティリソース:
cache-state://global、cache-state://session/{id}、cache-state://prefix/{hash}の MCP リソースは、キャッシュのヒット数/ミス数/節約量を集計して返します。含まれるのはトークンとハッシュのみで、プロンプトのテキストは含まれません。セッションに過去のリクエストがある場合、session_getにはcacheStateブロックが含まれます。 - プロバイダー機能の一覧:
provider_tool_capabilitiesとprovider-tools://catalogは、ゲートウェイのリクエストフィールド、サポート対象または機能低下中のプロバイダー制御、ローカルのスキル/ツールの検出情報、および Claude Code、Codex CLI、Gemini/Antigravity、Grok CLI/API、Mistral Vibe、Cognition Devin、Cursor Agent に関する安全な設定項目のヒントを提供します。doctor --jsonには、セットアップアシスタント向けの簡潔なprovider_capabilitiesサマリーが含まれます。
キャッシュを考慮した動作
devin_request / devin_request_async と cursor_request / cursor_request_async を除くすべての *_request および *_request_async ツールは、キャッシュヒット率を高めるためにプロンプトを構造化する省略可能な promptParts フィールドを受け付けます(Devin と Cursor のヘッドレスパスで受け付けるのは、プレーンな prompt のみです)。ゲートウェイはパーツを正規の順序(system → tools → context → task)で連結します。そのため、安定したプレフィックスのバイト列が変動するタスク末尾より前に置かれ、呼び出しごとに変わりません。これにより、各プロバイダーの自動プロンプトキャッシュが毎回同じコンテンツハッシュを使用できます。
{
"promptParts": {
"system": "You are a helpful code reviewer.",
"tools": "You have access to Read, Grep, Bash.",
"context": "<long stable context block — file dumps, etc.>",
"task": "Review the changes in src/foo.ts for security issues."
}
}
prompt と promptParts は相互排他的です。いずれか一方だけを指定してください。
CLI ごとの機能マトリックス(Devin と Cursor には promptParts のインターフェースがないため、それらを除くすべてのプロバイダーでは promptParts によりプレフィックスの規律が自動的に適用されます。明示的な制御方法はプロバイダーによって異なります)。
| CLI | プレフィックスの規律 | 明示的な制御方法 |
|---|---|---|
| claude | あり | promptParts.cacheControl + outputFormat: "stream-json"(安定したブロックに Anthropic の cache_control ブレークポイントを設定。ttl="1h" を強制) |
| codex | あり | なし(OpenAI の暗黙的な処理) |
| gemini | あり | なし(サーバー側で暗黙的に処理) |
| grok | あり | compactionMode / compactionDetail(コンテキスト圧縮:`summary |
| mistral | あり | なし(暗黙的な処理) |
| devin | なし | プレーンな prompt のみ |
| cursor | なし | プレーンな prompt のみ |
Claude の例(明示的な cacheControl)
claude_request({
promptParts: {
system: "You are a helpful code reviewer.",
context: "<long stable file dump>",
task: "Review the diff.",
cacheControl: { system: true, context: true }, // task is never marked
},
outputFormat: "stream-json",
});
ゲートウェイは、マークされたブロックにのみ cache_control: {type:"ephemeral", ttl:"1h"} を設定した stream-json の stdin パスを出力します。
Grok の例(圧縮)
grok_request({
promptParts: { system: "...", context: "...", task: "..." },
compactionMode: "segments",
compactionDetail: "balanced",
});
--compaction-mode segments --compaction-detail balanced を出力します。
各プロバイダーのインターフェース、テレメトリの違い(例:Grok の -p と ACP)、正確な stream-json ペイロードの形式、LLM 間のレビューに関する注記については、docs/personal-mcp/PROVIDER_CACHE_SURFACES.md を参照してください。
オプトインフラグ(すべてデフォルトでオフ)は、~/.llm-cli-gateway/config.toml の [cache_awareness] の下にあります。
信頼性とパフォーマンス
- リトライロジック:一時的な障害に対する、サーキットブレーカー付きの指数バックオフ
- アトミックなファイル書き込み:データの整合性を保つ、プロセスごとの一時ファイルと fsync
- ホスト保護のバックプレッシャー:上限付きの HTTP セッションライフサイクル(セッション数の上限とアイドル状態のセッションを削除するリーパー)、グローバルおよびプロバイダーごとのジョブ実行制限と上限付き FIFO キュー、ジョブごとに設定可能な出力上限(デフォルトは 50MB)。ホスト保護の制限を参照してください。
- NVM パスのキャッシュ:リクエストごとに発生する I/O オーバーヘッドを排除
- 長時間実行ジョブ:
*_request_asyncとポーリングツールによる、時間制限のない非同期実行
セキュリティと品質
- 包括的なテスト:ユニット、統合、回帰の各シナリオを対象とした1,700件以上のテストを、実際のCLI実行を通じて実施しています
- 入力の検証:Zodスキーマによりインジェクション攻撃を防止します
- シークレットの漏えい防止:セッションの説明には汎用的な内容のみを使用します(ファイル権限は0o600)
- ReDoSの防止:正規表現パターンに上限を設け、壊滅的なバックトラッキングを防止します
- 型安全性:包括的なエラー処理を備えた厳格なTypeScriptを使用しています
- サプライチェーンの強化:専用の
.github/workflows/security.ymlにより、すべてのプッシュとPRでactionlint、zizmor、shellcheck、typos、osv-scanner、gitleaks、lycheeを実行します(脅威モデルについてはSECURITY.mdを参照してください)
プロバイダーの機能範囲
すべてのプロバイダーで同じリクエスト、セッション、ジョブ、検証の仕組みを利用できますが、基盤となるCLIが標準で公開する機能はそれぞれ異なります。この表には、プロバイダーごとに実際に提供されている機能を記載しています。実行時にprovider_tool_capabilities、list_models、およびprovider-acp://<provider> / provider-tools://<provider>リソースを使って、現在の機能を確認してください。
| プロバイダー | CLI リクエストツール | ネイティブ ACP | モデルのライブ検出 | 管理サーフェス |
|---|---|---|---|---|
Claude Code (claude) | claude_request / _async | なし(CLI 優先。追跡対象のバージョンには ACP エントリーポイントがありません) | モデルエイリアス、推論の労力レベル、フォールバックモデル | provider_admin_list / provider_admin_run 経由で読み取り専用 |
OpenAI Codex (codex) | codex_request / _async、codex_fork_session | なし(codex-cli が公開するのは mcp-server / app-server トランスポートであり、ネイティブ ACP ではありません) | codex debug models | provider_admin_list / provider_admin_run 経由で読み取り専用 |
Gemini / Antigravity (gemini, agy) | gemini_request / _async | なし(agy に ACP エントリーポイントはありません。旧 Gemini CLI の ACP に関する証拠は引き継がれません) | agy models | provider_admin_list / provider_admin_run 経由で読み取り専用 |
xAI Grok (grok) | grok_request(同期 transport: "acp")/ _async | grok agent stdio によるネイティブ対応 | grok models + ~/.grok/config.toml | provider_admin_list / provider_admin_run 経由で読み取り専用 |
Mistral Vibe (mistral) | mistral_request(同期 transport: "acp")/ _async | vibe-acp によるネイティブ対応 | Vibe の設定に加え、VIBE_ACTIVE_MODEL のアクティブモデルとエージェントプロファイル | provider_admin_list / provider_admin_run 経由で読み取り専用 |
Cognition Devin (devin) | devin_request(同期 transport: "acp"、agentType: summarizer|review)/ _async | devin acp によるネイティブ対応 | --model / DEVIN_MODEL | provider_admin_list / provider_admin_run 経由で読み取り専用 |
Cursor Agent (cursor) | cursor_request(同期 transport: "acp")/ _async | cursor-agent acp によるネイティブ対応(コンパニオン所有) | モデルエイリアス | provider_admin_list / provider_admin_run 経由で読み取り専用 |
- ネイティブ ACPは正確に報告されます。
grok、mistral、devin、cursorはネイティブ ACP エントリーポイントを公開しているため、provider-acp://<provider>にはネゴシエートされたinitializeの機能セットと、そこから導出されたセッションメソッドの利用可否が含まれます。また、同期版の*_requestはtransport: "acp"を受け付けます([acp]とプロバイダーのruntime_enabledゲートが設定されていない場合は、フェイルクローズします)。ACPルーティングは同期のみです。*_request_asyncの各バリアントは常にCLIトランスポートを実行し、transport: "acp"(およびDevinのagentType)を受け付けません。非同期ACPとの同等性は後続フェーズで対応します。ACPのワークスペース選択はゲートウェイが管理します。明示的に指定されたACPのworkspaceは、登録済みのエイリアスである必要があります。新規のリモートACPリクエストでは、そのエイリアスまたは[workspaces].defaultが使用されます。リモートの再開リクエストでは、記録された正規のエイリアスとcwdに固定されるため、異なるワークスペースや紐付けられていないワークスペースは拒否されます。ローカルACPではworkspaceを省略できます。スコープ指定のない各プロセスには、毎回新しい非公開の0o700中立ディレクトリが割り当てられ、プロセス終了後に削除されます。共有された予測可能な一時パスは使用されません。claude、codex、geminiは対象CLIのバージョンにネイティブ ACP エントリーポイントを備えていません。そのため、これらのprovider-acp://レコードは、メソッドなしでnative: falseを報告し、アダプターをネイティブとして偽装することはありません。また、transport: "acp"セレクターも公開しません。 - 現在、マネージド承認に対応しているのはClaudeのみです。
approvalStrategy:"mcp_managed"を実行できるのはClaude CLIアダプターのみで、リクエストごとに生成したMCP設定を使用してClaudeを起動し、--strict-mcp-configを指定します。許可されるのは、プロビジョニング済みでゲートウェイが管理するMCP定義のみです。動的なnpx、環境に存在するPATH、Codex設定による上書きは拒否されます。Codex、Gemini、Grok、Mistral、Devin、Cursorでは、現在のアダプターが環境に存在するMCP設定を隔離できないため、プロバイダーの起動前にmcp_managedを拒否します。これらのアダプターではapprovalStrategy:"legacy"を使用してください。approvalPolicyは効果がありません。 - ACPには独自の権限ブリッジがあります。
transport:"acp"を選択した場合、approvalStrategy:"mcp_managed"と、あらゆるapprovalPolicyが拒否されます。マネージド承認にはClaude CLIトランスポートを使用してください。ACPホストサービスはフェイルクローズし、エージェントが宣言するツール呼び出しカテゴリによって制御されます。allow_write_host_servicesが設定されていない場合はwriteが拒否され、allow_terminal_host_servicesが設定されていない場合はexecuteが拒否されます。それ以外のカテゴリはすべて無条件に拒否され、fetchや認識されないすべての種類も含まれます。これにより、新たに追加された上流のツール種類がデフォルトで自動承認されることはありません。承認は、エージェントが提示する単回使用の許可オプションを選択することでのみ行われます。永続的なallow_always許可しか提示しないエージェントは拒否されるため、ACPが生のCLIバイパス入力を永続的な権限付与に変換することはありません。この制御境界は、このカテゴリゲートです。これは、エージェントがゲートウェイに何を実行させられるかを制限するものであり、エージェント自身のプロセス内で何を実行するかを制限するものではありません。 - リソースは、すべてのCLIプロバイダーについてプロバイダーレジストリから生成されます。
models://<provider>、sessions://<provider>、provider-acp://<provider>、provider-tools://<provider>、provider-subcommands://<provider>が含まれます。 - モデルの検出は、リアルタイムでアカウントを考慮します。前述の検出機能は
models://<provider>とlist_modelsに反映され、リアルタイムのプローブを利用できない場合は静的なレジストリ情報にフォールバックします(リソースの読み取りによってCLIが起動されることはありません)。 - 管理機能は検出結果に基づき、出力が秘匿化されます。すべてのプロバイダーについて、
provider_admin_listとprovider_admin_runは読み取り専用です。状態を変更する管理操作はprovider_admin_mutateを通じてのみ公開され、[admin] allow_mutating_cli_admin_ops、リモートのcli:adminスコープ、承認ゲート、監査記録によって制御されます。状態を変更するACPセッション操作も、[acp] allow_mutating_session_opsによって制御されます。 - 検証コマンドは、すべてのプロバイダーで使用できます。
review_changes、validate_with_models、second_opinion、compare_answers、red_team_review、consensus_check、ask_model、synthesize_validationが含まれます。また、validation_receiptとvalidation-receipt://{validationId}リソースを通じて、正規の方式でハッシュ化された不変のレシートを取得できます。review_changesは完全なGit成果物を取得してハッシュ化し、リポジトリに紐付けられた読み取り専用のレビュアーを起動します。
前提条件
Node.js >= 24.4.0 が必要です(package.json の engines.node)。SQLite バックエンドでは Node.js に組み込まれた node:sqlite モジュールを使用するため、コンパイルが必要なネイティブバインディングはなく、インストールスクリプトも実行されません。SQLite の永続化レイヤーが依存する allowBareNamedParameters のデフォルト値が true になるのは、24.4 以降です。
ソースツリーのリリース監査を実行するには、Bash と util-linux の flock も必要です。この前提条件は、コミット
242e7669565ecc7c71183f5f7133791a1384ca7c に対して検証されています。リリース自動化では Ubuntu 上で監査を実行します。macOS では、npm run security:audit または完全な npm run check ゲートを実行する前に、互換性のある flock をインストールしてください。
このゲートウェイを使用する前に、使用する CLI ツールをインストールする必要があります。
Claude Code CLI
# Installation instructions for Claude Code
# Visit: https://docs.anthropic.com/claude-code
npm install -g @anthropic-ai/claude-code
Codex CLI
npm install -g @openai/codex
codex login
Gemini(Google Antigravity CLI)
Gemini プロバイダーは Google Antigravity CLI(agy)を通じて実行されます。
curl -fsSL https://antigravity.google/cli/install.sh | bash
# Docs: https://antigravity.google/docs
Grok Build CLI(xAI)
curl -fsSL https://x.ai/cli/install.sh | bash
grok login # OAuth flow; for headless auth, set XAI_API_KEY
# Docs: https://docs.x.ai/build/overview
Mistral Vibe CLI
# Pick one — the gateway's cli_upgrade auto-detects which one you used.
curl -LsSf https://mistral.ai/vibe/install.sh | bash
pip install mistral-vibe
uv tool install mistral-vibe
brew install mistral-vibe
vibe --setup
# Complete the API-key setup locally. Do not paste the key into a chat.
# Current Vibe defaults session logging to enabled. If an older config disabled it,
# edit ~/.vibe/config.toml and set:
# [session_logging]
# enabled = true
Vibe 固有の注意事項:
- モデルの選択には
VIBE_ACTIVE_MODEL環境変数を使用します — Vibe には--modelフラグがありません。ゲートウェイは~/.vibe/config.toml/VIBE_MODELSを検出し、モデルが明示的に要求された場合、または Vibe の設定を 復旧する必要がある場合にのみVIBE_ACTIVE_MODELを注入します。また、モデルが 見つからないエラーが発生すると、検出情報を更新してから一度だけ再試行します。 permissionModeは Vibe の--agent名です。 組み込みの値はdefault | plan | accept-edits | auto-approveです。Vibe はインストール状況に 依存する組み込みの値(例:lean)や、~/.vibe/agentsのカスタムエージェントも 受け付けます。リクエストでは選択した名前をそのまま渡し、Vibe が検証します。 Vibe ではmcp_managedを使用できません。- ツールの制御には Vibe ネイティブのフラグを使用します。 ゲートウェイは
allowedToolsの各エントリーに対して--enabled-tools <tool>フラグを1つ、disallowedToolsの各エントリーに対して--disabled-tools <tool>フラグを1つ 出力します。Vibe は有効なツールのフィルタリング後に、無効化されたツールを適用します。 - 使用状況のテレメトリーはベストエフォートです。 Vibe はプログラム実行時の標準出力に
トークン数やコストのデータを出力しません。ゲートウェイが Vibe ネイティブの
セッション UUID を把握している場合は、使用状況とコストを取得するために
~/.vibe/logs/session/session_<...>/meta.jsonを読み取ります。セッションログが 存在しない、形式が不正、またはまだ特定されていない場合、これらのフィールドは空のままです。 - セルフアップデートには対応していません:
cli_upgrade --cli mistralは pip / uv / brew のどれを使用したかを検出し、対応するアップグレードコマンドを実行します。vibe updateというコマンドはありません。
インストール
MCP サーバーとして(npm)
npm install -g llm-cli-gateway
または、npx から直接使用します。
{
"mcpServers": {
"llm-gateway": {
"command": "npx",
"args": ["-y", "llm-cli-gateway"]
}
}
}
ソースから
git clone https://github.com/verivus-oss/llm-cli-gateway.git
cd llm-cli-gateway
npm install
npm run build
使用方法
MCP サーバーとして
ローカルの stdio MCP サーバーにすでに対応しているクライアントでは、次のような設定を追加します。
{
"mcpServers": {
"llm-cli-gateway": {
"command": "node",
"args": ["/path/to/llm-cli-gateway/dist/index.js"]
}
}
}
制限のない、マシン上のローカル開発アクセスには stdio を推奨します。localhost HTTP やトンネル経由の HTTPS を含む HTTP MCP は、プロバイダーの実行においてリモートから利用可能なものとして扱われます。CLI を起動する前に、プロバイダーツールは登録済みのワークスペースエイリアス、セッションのワークスペース、または [workspaces].default を解決する必要があります。リモートクライアントは、選択したワークスペース内の相対パスで workingDir、addDir、インクルードディレクトリの値を指定してください。また、所有するゲートウェイ追跡対象のセッションのみ再開できます。ネイティブプロバイダーの生のセッション ID はローカル専用です。認証を無効にしても、認証なしのコネクター経由で接続しても、ファイルシステムの制限を回避することはできません。
workingDir、登録済みの workspace、またはゲートウェイ管理の worktree が解決されていないローカル CLI リクエストでは、子プロセスは新しいプライベートな 0o700 一時ディレクトリで実行され、プロセス終了後に削除されます。ゲートウェイのリポジトリの cwd や、プロバイダー固有の指示コンテキストを引き継ぐことはありません。ゲートウェイは一時ディレクトリのルートを正規化し、いずれかの祖先に .git、AGENTS.md、AGENTS.override.md、Agents.md、AGENT.md、CLAUDE.md、Claude.md、CLAUDE.local.md、.claude/CLAUDE.md、.claude/rules/、.cursor/rules/、.cursorrules、GEMINI.md、.vibe/config.toml が含まれている場合は拒否するか、別の場所に移します。シンボリックリンクや、コンテキスト配下にあるカスタム TMPDIR 経由の場合も対象です。このリストには、プロバイダーが cwd から上方向にたどって検出する項目が含まれています。~/.claude/settings.json などのユーザースコープの設定は意図的に対象外です。cwd に関係なく呼び出しごとに読み込まれるため、ワークスペースを移動しても分離できないからです。そのため、cwd スコープの最新セッションポインターを使用するプロバイダー固有の resumeLatest 操作では、明示的な workingDir、workspace、または設定済みのデフォルトワークスペースが必要です。いずれも使用できない場合は、安全側に倒して失敗します。複数のリポジトリが同時にアクティブな場合は、明示的に対象を選択してください。
CLI リクエストのスキーマでは最大 100,000 文字のプロンプトを受け付けますが、オペレーティングシステムは個々の argv 要素にもバイト数の上限を設けています。Codex の新規リクエストと再開リクエストでは、プロンプトをそのまま stdin 経由でストリーミングします。codex_fork_session は引き続き argv に依存するため、サイズ超過の UTF-8 プロンプトは spawn 前に、再試行不可の input_too_large として拒否されます。現在の CLI 契約で argv によるプロンプト指定が必要なその他のプロバイダーにも、同じ受け入れルールが適用されます。シリアライズされたエージェント/スキーマ JSON、結合されたツール一覧、指示の上書き、パス、モデル名、ネイティブセッション ID など、それ以外の呼び出し元が指定する argv 値も、最終的なエンコード後の形式でチェックされます。最終的な spawn 境界では、各 argv 要素と解決済みコマンドライン全体のバイト数を、プラットフォームごとに定めた保守的な上限および 2,048 要素の上限に照らしてチェックします。コマンドライン全体のバイト数の上限には環境変数は含まれませんが、環境変数用の余裕を確保しています。Windows では、コマンドの解決によってネイティブ実行ファイルだと確認されるまでは、より小さい npm の .cmd/.bat ラッパーの上限を前提として、解決前に受け入れ可否を判定します。Kit 以外のリクエストでは、ネイティブセッション用フラグと再開用フラグを、ワークスペース、セッション、プロバイダー成果物の引き渡し、または永続ジョブに関する副作用が発生する前にチェックします。Claude Kit は、コンパイル済みコンテキスト成果物の生成や永続 Kit セッションの割り当てより前に、最終的な argv を予測してチェックします。
コマンドまたはいずれかの argv 要素に埋め込み NUL バイトが含まれている場合、spawn 前に再試行不可の invalid_input として拒否されます。呼び出し元に返す結果、長期ジョブメモリ、永続ジョブ引数、非同期フライト行では、固定の無効 argv マーカーが使用されます。任意の重複した永続ペイロードは保存されません。拒否されたベクターや、値をエコーする Node のネイティブエラーが保持されることはありません。
環境変数に起因する失敗も含め、ネイティブの E2BIG は、ネイティブの spawnargs を保持せずに正規化されます。ゲートウェイは、指示やその他の値を切り詰めて制限に収めることはありません。stdin を使用するリクエストでは、ペイロード全体の書き込みコールバックが成功した場合に限り、プロバイダーの正常終了を受け入れます。パイプが閉じている、または書き込みが未完了のままの場合は、機密情報を含まない固定の不完全配信エラーとなります。タイムアウト、キャンセル、プロバイダーの非ゼロ終了は引き続き優先されます。
この汎用 stdio の例は、Personal MCP Appliance のプロバイダーサポートを検証するものではありません。ChatGPT、Claude web、Claude Desktop、Codex、Gemini CLI、Gemini web、Grok のクライアント別セットアップガイドは、引き続き docs/personal-mcp/PRODUCT_CONTRACT.md のプロバイダーサポートマトリクスに従います。
利用可能なツール
LLM 横断検証ツール
パーソナルアプライアンス向けのサーフェスでは、開発者以外のクライアント向けに、簡素化された検証ツールを提供します。これらのツールは、永続的な非同期ジョブマネージャーを通じてプロバイダー CLI のジョブを開始し、正規化されたプロバイダーのステータスと生のジョブ参照を返します。
validate_with_models:2 つ以上のプロバイダーに、ある質問をそれぞれ独立して検証させます。review_changes:完全な Git レビューアーティファクトを 1 つ取得し、リポジトリの内容を信頼できないデータとして区切ったうえで、読み取り専用の独立したレビュアーを開始します。リポジトリの変更レビューを参照してください。second_opinion:1 つのプロバイダーに回答をレビューさせます。red_team_review:計画、回答、またはドキュメントについて、リスクや失敗モードを検討します。consensus_check:プロバイダー間で主張への合意が得られているか確認します。ask_model:簡素化されたサーフェスを通じて、1 つのプロバイダーに質問します。synthesize_validation:プロバイダーの結果が収集された後、明示的に指定された審査モデルを実行します。一般的な検証では、呼び出し元の質問と、終端状態の正規化された結果が必要です。一方、review_changesの実行では、validationIdを使って所有権のある永続的な結果を正確に再読み込みします。呼び出し元が指定した質問や結果は無視されます。list_available_models:各プロバイダー CLI が簡素化されたサーフェスを通じて公開しているモデルを一覧表示します。job_statusとjob_result:検証ジョブの出力をポーリングして収集します。validation_receipt:終端状態の LLM 横断検証実行について、正規にハッシュ化された不変のレシートをvalidationIdで取得します(minted | pending | verification_failed | expired_unminted | not_foundを返し、所有者本人または未検出の結果となります)。verification_failedは、保存されたレシートが存在するものの、永続的な実行結果と一致しないことを意味し、調査すべき不具合です。expired_unmintedは常にレシートの不在のみを意味します。format: "markdown"は人が読みやすいレポートを生成します。includeRawResponsesを指定すると、関連するジョブで本人性が検証された出力が引き続き公開されている場合、プロバイダーの完全な回答テキストをインラインで含めます。永続的な検証実行ストア機能を提供するアタッチ済みジョブストア(sqliteおよびpostgres)がある場合にのみ登録されます。
同じレシートは、MCP リソース validation-receipt://{validationId} としても公開されます(永続的なゲートと所有者本人または未検出のスコープ設定は同じです)。
検証レポートでは、プロバイダーごとの意見の相違が保持されます。任意の審査モデルによる統合では、どのプロバイダーが審査ジョブを生成したかが明示されます。
リポジトリの変更レビュー
review_changes は、ローカルの絶対パス workingDir または登録済みの
workspace を受け取り、scope: "auto" | "uncommitted" | "branch" | "commit" を解決します。明示的な Git の base、リポジトリ相対パスを指定する
paths、stance: "standard" | "adversarial"、レビュアーの models、任意の
judgeModel、trustCursorWorkspace、およびフェイルクローズ方式のアーティファクト/プロンプトのバイト数上限を指定できます。
Cursor は信頼していないディレクトリのレビューを拒否するため、レビュー対象のディレクトリが登録済みの [[workspaces.repos]] パスで、その providers に cursor が含まれている場合に限り、Cursor のシートに --trust が付与されます(その配下のゲートウェイのワークツリーも該当し、最も近い登録が適用されます)。それ以外のディレクトリでは、実行可能な理由を示して Cursor のシートをスキップし、残りのレビュー担当者は引き続き実行されます。trustCursorWorkspace: true を指定すると、永続的なレビュー実行 1 回についてこの許可を与えます。この同意は、その実行のレビュー担当者リストに含まれる Cursor のシートと、後で synthesize_validation が起動する予定済みの Cursor 判定者に適用されます。実行の所有者、リポジトリ、予定済みの判定者に紐付けられるため、別の主体やレビュー実行で再利用することはできません。これは形式的な手続きではなく、実質的な判断です。信頼済みフォルダーは Cursor がプロジェクトのルールや AGENTS.md を読み込む場所でもあるため、レビュー対象のリポジトリが、自身のレビュー担当者にある程度影響を与えることになります。これは、フェンスで保護されたレビュープロンプトが通常禁止していることです。アーティファクトでは、コミット済み、ステージ済み、未ステージの変更と、通常の無視対象外の未追跡ファイルの証拠を個別に保持します。リポジトリ内の属性によって差分表示不可に指定されていても、追跡対象ファイルの差分は読み取り可能な状態に保ちます。review-evidence.v2 アーティファクトでは、committedPatch、stagedPatch、unstagedPatch を個別に公開します。各セグメントには、パスのソート済み一覧、エンコーディング、正確なバイト長、SHA-256 による識別情報、コンテンツが含まれます。これにより、インデックスの変更とワークツリーのみで行われた取り消しが相殺されることを防ぎます。アーティファクトは衝突を防止し、バイト数を計測し、SHA-256 で識別し、競合状態を確認したうえで、切り詰めることなく処理されます。auto モードでは、分岐したブランチはマージベースを起点に、ワーキングツリーの証拠も含めてレビューされます。それ以外の場合、ダーティーなツリーでは未コミットの変更が選択され、クリーンなツリーでは直近のコミット(HEAD^..HEAD)が選択され、ワーキングツリーの証拠は含まれません。安全でない種類の未追跡ファイルがある場合、または証拠の取得中にリポジトリが変更された場合は、処理を拒否します。
このツールは非同期のプロバイダージョブを開始し、validationId、アーティファクトとプロンプトの正確な識別情報、ファイル一覧、各レビュー担当者の rawJobReference を返します。これらの参照は検証用の job_status でポーリングし、検証用の job_result で収集してください。よく似た名前の llm_job_* ツールは使用しないでください。判定者が指定されている場合は、すべてのレビュー担当者が終端状態になるまで待ち、その後 validationId と同じ workingDir または workspace セレクターを指定して synthesize_validation を呼び出します。進行状況の確認と人による可視性確保のため、引き続き結果を収集しますが、それらをレビューの証拠として渡してはいけません。review_changes の実行では、ゲートウェイは呼び出し元から渡された question と providerResults を無視し、所有権が確認できる紐付け済みの終端ジョブを正確に再読み込みし、要求されたものの利用できなかったシートをスキップとして再構成します。一般的な検証の統合には、呼び出し元が指定する質問と、正規化済みの終端結果が引き続き必要です。
レビュー機能は、永続性のある SQLite または PostgreSQL のジョブストレージと検証実行ストレージが登録されている場合にのみ利用できます。各 CLI レビュージョブでは、有効期限付きの payload_json にフェンス付きプロンプトの正確な内容が保持され、永続化される argv にはハッシュマーカーのみが含まれます。有効期限のないフライトレコーダーには、リポジトリレビューのプロンプトは記録されません。設定済みの HTTP/API レビュアーシートを使用するには、完全な成果物がローカル CLI の境界外に出るため、明示的に allowApiUpload:true を指定する必要があります。リモート HTTP/OAuth ワークスペースのレビューでは、このフラグを指定していても API レビュアーへのアップロードは拒否されます。永続ジョブストアは機密情報として扱ってください。デフォルトでは保持期間に上限がありません。保持記録に上限が必要な場合は、オペレーターが [persistence.retention].jobs を設定できます。
judgeModel が HTTP/API プロバイダーの場合、review_changes は明示的な同意、判定プロバイダー、解決済みのリポジトリ、呼び出し元の ID を永続的な validationId に紐付けます。後続の synthesize_validation 呼び出しでは、その ID と同じリポジトリセレクターを指定する必要があります。保存された判定、リポジトリ、所有者、アップロードへの同意が正式な情報となります。ゲートウェイは計画済みの判定を一度だけアトミックに取得するため、合成を同時に実行したり繰り返したりしても、2 つ目の判定は開始されません。後続の引数でアップロードへの同意を与えたり、上書きしたりすることはできません。
LLM リクエストツール
claude_request
オプションのセッション管理を使用して、Claude Code リクエストを実行します。
パラメーター:
prompt(string, optional*): 送信するプロンプト(1~100,000文字)。*promptとpromptPartsのいずれか一方が必須です(相互排他的)。model(string, optional): モデル名またはエイリアス(使用可能な値はlist_modelsで確認できます。latestに対応しています)outputFormat(string, optional): 出力形式(text|json|stream-json)、デフォルト:stream-json— ゲートウェイは NDJSON の使用状況イベントを解析してトークン数とコストを可視化します。解析されていない標準出力が必要な場合に限り、textに変更してください。sessionId(string, optional): 使用する特定のセッション ID。mcp_managedでは、ネイティブ継続は未検証のプロバイダー設定を引き継ぐ可能性があるため、リスクの高い入力です。承認とLLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1が必要ですが、全権限プロファイルは選択されません。continueSession(boolean, optional): アクティブなセッションを継続します。sessionIdと同じ管理モードでの承認要件があります。Claude の--continueは cwd に基づいて選択するため、workingDirまたは明示的に選択された登録済みワークスペースが必要です。選択は呼び出し元が所有するセッションメタデータを通じて行うか、設定済みのデフォルトを使用します。そのワークスペースでは、任意でゲートウェイのワークツリーを指定できます。安定した cwd を提供する選択肢がない場合、リクエストはフェイルクローズで失敗します。createNewSession(boolean, optional): 常に新しいセッションを作成します。forkSession(boolean, optional): 再開したセッションに追記する代わりに、セッションをフォークします。mcp_managedでは、承認とLLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1が必要な、リスクの高いネイティブフォーク入力ですが、権限の範囲は限定されます。allowedTools(string[], optional): Claude のツールをこの許可リストに制限します。空でない許可リストは、ツールの利用設定を変更する可能性があるため、管理モードではリスクの高い入力です。disallowedTools(string[], optional): 指定した Claude ツールを明示的に拒否します。permissionMode(string, optional): Claude の権限モード(default|acceptEdits|plan|auto|dontAsk|bypassPermissions)。dangerouslySkipPermissionsより優先されます。bypassPermissionsはmcp_managedにおける、全権限を直接要求する設定です。dangerouslySkipPermissions(boolean, optional): 非推奨です。permissionMode: "bypassPermissions"にマッピングされます。両方が設定されている場合はpermissionModeが優先されます。mcp_managedにおける、全権限を直接要求する設定です。agent(string, optional): 実行する名前付きサブエージェント。値が空でない場合、ツールと権限の設定を変更する可能性があるため、管理モードではリスクの高い入力です。agents(string, optional): インラインのエージェント定義 JSON。同じ理由から、値が空でない場合は管理モードでリスクの高い入力です。systemPrompt/appendSystemPrompt(string, optional): システムプロンプトを置き換えるか、拡張します。値が空でない場合は管理モードでリスクの高い入力です。systemPromptFile/appendSystemPromptFile(string, optional): ファイルからシステムプロンプトを置き換えるか、拡張します。ファイルパスが空でない場合は管理モードでリスクの高い入力です。safeMode(boolean, optional):CLAUDE.md、スキル、プラグイン、フック、MCP、コマンド、エージェントなどのローカルカスタマイズを無効にして Claude を起動します。trueは管理モードでリスクの高い入力です。bare(boolean, optional): ローカルカスタマイズの検出を省略して、最小モードで Claude を起動します。trueは管理モードでリスクの高い入力です。debugFile(string, optional): Claude のデバッグ出力をファイルに書き込みます。パスが空でない場合は管理モードでリスクの高い入力です。maxBudgetUsd(number, optional): リクエストの USD 建て予算上限maxTurns(integer, optional): エージェントループのターン数上限effort(string, optional): 推論の労力(low|medium|high|xhigh|max)fallbackModel(string, optional): デフォルトモデルが過負荷の場合に自動で切り替えるモデルjsonSchema(string, optional): 構造化出力を制約する JSON Schema リテラルaddDir(string[], optional): 追加のワークスペースディレクトリ。値が空でない場合は管理モードでリスクの高い入力です。noSessionPersistence(boolean, optional): 一時的なセッション(ディスクに保存されません)settingSources/settings/tools(optional): 読み込む設定ソース、設定の JSON パスまたはリテラル、組み込みツールの制限。設定ソース、設定、ツールの選択が空でない場合は、管理モードでリスクの高い入力です。pluginDir/pluginUrl(string[], optional): ローカルディレクトリまたは URL から Claude プラグインを読み込みます。値が空でない場合は管理モードでリスクの高い入力です。excludeDynamicSystemPromptSections(boolean, optional): 動的なシステムプロンプトのセクションを削除します。approvalStrategy(string, optional):"legacy"(デフォルト)または"mcp_managed"。管理モードではデフォルトでacceptEditsを使用し、strictMcpConfig:trueを強制するため、Claude はゲートウェイが生成した MCP 設定のみを使用します。全権限を直接要求するには、呼び出し元による明示的な要求、承認マネージャーの承認、およびLLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1のすべてが必要です。その他のリスクの高い入力にも承認とオペレーター設定が必要ですが、権限の範囲は限定され、全権限が選択されることはありません。approvalPolicy(string, optional):"strict"、"balanced"、または"permissive"mcpServers(string[], optional): Claude に公開する MCP サーバーの名前(デフォルト:なし)。レガシーリクエストでは、ローカルレジストリまたは Codex MCP 設定から名前を解決します。不明な名前は利用不可として報告されます。mcp_managedでは、Claude は生成された設定のみを使用し、ゲートウェイ所有のローカルコマンドとして明示的にプロビジョニングされたレジストリエントリのみが対象となります。動的なnpxランチャー、環境の PATH 上にあるコマンド、Codex 設定によるオーバーライドは拒否されます。管理対象のエントリは、ゲートウェイ環境で設定してデプロイしてください。strictMcpConfig(boolean, optional): レガシーモードではデフォルトでfalseです。trueに設定すると、生成された MCP 設定のみを必須とし、要求されたサーバーが利用できない場合は失敗します。mcp_managedではゲートウェイがこれをtrueに強制するため、呼び出し元がfalseを指定しても、この制約を弱めることはできません。optimizePrompt(boolean, optional): トークン効率を高めるためにプロンプトを最適化します(44% 削減)。デフォルト:falseoptimizeResponse(boolean, optional): トークン効率を高めるために応答を最適化します(37% 削減)。デフォルト:falsecorrelationId(string, optional): リクエストのトレース ID(省略時は自動生成されます)idleTimeoutMs(integer, optional): 出力がない状態が続いたプロセスを終了します。30,000~3,600,000 ms。アイドル状態の強制終了はoutputFormatがstream-jsonの場合にのみ適用されます。text/json では実行完了まで出力がないため、無視されます。worktree(boolean|object, optional): ゲートウェイ所有の git ワークツリー内で実行します(slice λ)。ワークツリーを使用するには、明示的に選択された登録済みワークスペース、呼び出し元が所有するセッションメタデータを通じて選択されたワークスペース、または設定済みのデフォルトが必要です。プロセスの cwd を引き継ぐことはなく、workingDir、addDir、includeDirsと組み合わせることもできません。実体化時には、リポジトリ、システム、グローバルの Git フック、および設定された clean、smudge、process のチェックアウトフィルターが無効になります。そのため、Git LFS などのフィルターに依存するコンテンツは、ホストコマンドを実行せずにリポジトリ内の表現のまま保持されます。ワークツリーの要求は、承認とLLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1が必要な、管理モードでリスクの高い入力ですが、権限の範囲は限定されます。promptParts(object, optional): キャッシュ対応の構造化プロンプト{ system?, tools?, context?, task }。promptとは相互排他的です。forceRefresh(boolean, optional): 重複排除を回避して、新たに CLI を実行します。デフォルト:false ワークスペースの境界:stdio 呼び出し元は、マシンローカルのパスを直接使用できます。HTTP/トンネル呼び出し元は、workspaceを指定するか、設定済みのデフォルト/セッションのワークスペースを使用する必要があります。その場合、パスフィールドはそのワークスペースを基準に検証されます。[workspaces].allow_unregistered_working_dirは機能しないレガシーキーです。古い設定を引き続き読み込めるよう受け付けていますが、値にかかわらずどこからも読み取られず、現在これを設定すると起動時に警告がログに記録されます。このキーによって任意のHTTP作業ディレクトリや追加のディレクトリが許可されることはありません。
レスポンスの追加項目:
approval:approvalStrategy="mcp_managed"の場合の承認判断レコードmcpServers:この呼び出しで要求、有効化、または見つからなかったMCPサーバー
例:
{
"prompt": "Write a Python function to calculate fibonacci numbers",
"model": "sonnet",
"continueSession": true,
"optimizePrompt": true,
"optimizeResponse": true
}
codex_request
オプションのセッション追跡を使用して、Codex リクエストを実行します。
パラメーター:
-
prompt(文字列、任意*):送信するプロンプト(1~100,000 文字)。*promptまたはpromptPartsのいずれか一方が必須です(相互排他)。 -
model(文字列、任意):モデル名またはエイリアス(利用可能な値はlist_modelsで確認できます。latestに対応。推奨:gpt-5.5) -
fullAuto(ブール値、任意):非推奨 —--sandbox workspace-writeのみに展開されます(現在の Codex は承認ポリシーフラグを受け付けなくなりました)。sandboxModeの使用を推奨します。 -
sandboxMode(文字列、任意):Codex のサンドボックス(read-only|workspace-write|danger-full-access)。 -
dangerouslyBypassApprovalsAndSandbox(ブール値、任意):Codex の承認とサンドボックスを完全にバイパスするよう要求します。 -
dangerouslyBypassHookTrust(ブール値、任意):Codex のフック信頼チェックをバイパスするよう要求します。 -
approvalStrategy(文字列、任意):実行可能な戦略は"legacy"のみです。アダプターが環境に存在する MCP 設定を分離できないため、Codex の起動前に"mcp_managed"は拒否されます。 -
approvalPolicy(文字列、任意):mcp_managedが利用できないため、Codex には影響しません。 -
mcpServers(文字列[]、任意):メタデータのみです。Codex の MCP サーバーは設定も分離もされません。 -
sessionId(文字列、任意):追跡用のセッション識別子。 -
resumeLatest(ブール値、任意):以前の Codex セッションを再開します(codex exec resume --last)。--lastがどのセッションを選ぶか、または再開後の作業ディレクトリに依存しないでください(#258)。--lastは上流で cwd によってフィルタリングされ、子プロセスはゲートウェイが解決した cwd で引き続き起動されます。対象を確認するか、確実性が必要な場合は新しいセッションを開始してください。sessionIdが設定されている場合は無視されます。 -
createNewSession(ブール値、任意):常に新しいセッションを作成します。 -
forceRefresh(ブール値、任意):重複排除を回避し、新しい CLI 実行を強制します。デフォルト:false -
outputFormat(文字列、任意):text(デフォルト)またはjson(トークン使用量の抽出用の--jsonJSONL イベント) -
outputSchema(文字列|オブジェクト、任意):Codex の--output-schema。パスまたはインライン JSON Schema。 -
workingDir(文字列、任意):このセッションの作業ルート(-C/--cd。新しいセッションのみ)。Personal Agent Config Kit モードでは絶対パスが必要です。 -
addDir(文字列[]、任意):追加の書き込み可能なワークスペースディレクトリ(エントリごとに--add-dirを指定。新しいセッションのみ)。 -
ephemeral(ブール値、任意):Codex の--ephemeral(セッションを永続化しません)。 -
images(文字列[]、任意):画像の添付(パスごとに-i <path>を指定)。 -
profile(文字列、任意):Codex の--profile <name>(新しいセッションのみ。再開時はログに警告を記録して無視されます)。 -
configOverrides(オブジェクト、任意):Codex の-c key=valueによる上書き。ローカルの呼び出し元のみ使用できます。リモート HTTP/OAuth リクエストは拒否されます。 -
enable/disable(文字列[]、任意):Codex の--enable/--disableによる機能の上書き。これらは-c features.*と同等で、ローカルのみで使用できます。 -
ignoreRules/ignoreUserConfig(ブール値、任意):Codex の--ignore-rules/--ignore-user-config。 -
outputLastMessage(文字列、任意):Codex の--output-last-message <path>。 -
oss(ブール値、任意):Codex の--oss。オープンソースプロバイダーを選択します。 -
localProvider(文字列、任意):Codex の--local-provider <name>。 -
worktree(ブール値|オブジェクト、任意):ゲートウェイが管理する git ワークツリー内で実行します(スライス λ)。ワークツリーには、明示的に選択された登録済みワークスペースが必要です。呼び出し元が管理するセッションメタデータを通じて、または設定済みのデフォルトによって選択できます。プロセスの cwd を引き継ぐことはなく、workingDir、addDir、includeDirsと組み合わせることもできません。マテリアライズ時は、リポジトリ、システム、グローバルの Git フックと、設定済みの clean、smudge、process チェックアウトフィルターが抑止されます。そのため、Git LFS などフィルターに依存するコンテンツは、ホストコマンドを実行せず、リポジトリ内の表現のまま保持されます。 -
promptParts(オブジェクト、任意):キャッシュ対応の構造化プロンプト{ system?, tools?, context?, task }。promptとは相互排他です。 -
optimizePrompt(ブール値、任意):トークン効率を高めるようプロンプトを最適化します。デフォルト:false -
optimizeResponse(ブール値、任意):トークン効率を高めるよう応答を最適化します。デフォルト:false -
correlationId(文字列、任意):リクエストのトレース ID(省略時は自動生成)。 -
idleTimeoutMs(整数、任意):出力がない状態が続いた場合に Codex プロセスを終了します。30,000~3,600,000 ms レスポンスの追加情報: -
mcpServers:この呼び出しで要求された MCP サーバーのメタデータ
例:
{
"prompt": "Create a REST API endpoint",
"model": "gpt-5.5",
"sandboxMode": "workspace-write",
"optimizePrompt": true
}
codex_fork_session
既存の Codex セッションを新しいブランチにフォークします(codex fork <SESSION_ID|--last> <prompt>)。元のセッションの履歴を保持したまま、フォークしたセッションを別の方向へ進めます。Codex の新規リクエストや再開リクエストとは異なり、このコマンドは argv に紐付いたままで、UTF-8 のプロンプトが大きすぎる場合は、再試行不可の input_too_large として拒否します。
パラメーター:
prompt(string、必須):フォークしたセッションのプロンプトテキスト(1~100,000 文字)sessionId(string、省略可):フォーク元の Codex セッション UUID(forkLastとは併用できません)。forkLast(boolean、省略可):セッションを指定せず、最新の Codex セッションをフォークします。model(string、省略可):モデル名またはエイリアス(例:gpt-5.5、latest)sandboxMode(string、省略可):Codex のサンドボックス(read-only|workspace-write|danger-full-access)。approvalStrategy(string、省略可):実行可能な戦略は"legacy"のみです。アダプターでは MCP の周辺設定を分離できないため、Codex の起動前に"mcp_managed"は拒否されます。approvalPolicy(string、省略可):mcp_managedを利用できないため、Codex では効果がありません。correlationId(string、省略可):リクエストのトレース ID(省略した場合は自動生成)idleTimeoutMs(number、省略可):アイドルタイムアウト(ミリ秒、30秒~1時間。省略すると CLI のデフォルトが適用されます)
gemini_request
セッションに対応した Google Antigravity CLI(agy)のリクエストを実行します。
パラメーター:
prompt(文字列、任意*):送信するプロンプト(1~100,000 文字)。*promptとpromptPartsのどちらか一方が必須です(相互に排他的)。model(文字列、任意):モデル名またはエイリアス(利用可能な値はlist_modelsで確認できます。latest、pro、flashをサポートしています)。sessionId(文字列、任意):再開するセッション ID。resumeLatest(ブール値、任意):最新のセッションを自動的に再開します。createNewSession(ブール値、任意):常に新しいセッションを作成します。approvalMode(文字列、任意):レガシーモードでの Antigravity の承認モードです。defaultは agy に承認を求める設定のままにし、auto_editは--mode accept-editsを出力し、planは--mode planを出力し、yoloは--dangerously-skip-permissionsを出力します。approvalStrategy(文字列、任意):実行可能な戦略は"legacy"のみです。アダプターでは周囲の MCP 設定を分離できないため、Antigravity の起動前に"mcp_managed"は拒否されます。approvalPolicy(文字列、任意):mcp_managedを利用できないため、Antigravity には影響しません。includeDirs(文字列[]、任意):追加のワークスペースディレクトリ(--add-dirとして渡されます)。project(文字列、任意):このセッションで使用する Antigravity プロジェクトを選択します(--project <ID>)。newProjectとは相互に排他的です。newProject(ブール値、任意):このセッション用に新しい Antigravity プロジェクトを作成します(--new-project)。projectとは相互に排他的です。sandbox(ブール値、任意):Antigravity をサンドボックスモードで実行します(--sandbox)。workingDir(文字列、任意):ローカルの Antigravity プロセスの作業ディレクトリです。 Stdio/ローカルの呼び出し元はローカルパスを直接指定できます。リモート HTTP/OAuth の呼び出し元は、 選択した登録済みワークスペース内の相対パスを使用する必要があります。includeDirsは読み取りパスを 追加しますが、cwd は選択しません。workspace(文字列、任意):登録済みのゲートウェイワークスペースエイリアスです。リモート HTTP/OAuth の呼び出し元に対して、 Antigravity プロセスの cwd を選択します。outputFormat(文字列、任意):text(デフォルト)、json、またはstream-jsonです。非同期ジョブレコーダーは、要求された表示形式とは別に、トランスクリプト対応のstream-jsonワイヤーを起動します。mcpServers(文字列[]、任意):メタデータのみです。Antigravity は独自の MCP 設定を管理します。このフィールドで許可リストが作成されることはありません。allowedTools、policyFiles、adminPolicyFiles、attachments(文字列[]、任意)およびskipTrust(ブール値、任意):Antigravity CLI ではサポートされていません。空でない値、またはskipTrust: trueを指定すると、説明付きのエラーで拒否されます。yolo(ブール値、任意):すべてを自動承認します。approvalMode: "yolo"と同等です。レガシーモードでは--dangerously-skip-permissionsを出力します。worktree(ブール値またはオブジェクト、任意):ゲートウェイが所有する Git ワークツリー内で実行します(スライス λ)。ワークツリーを使用するには、登録済みのワークスペースを明示的に選択するか、呼び出し元が所有するセッションメタデータを通じて選択するか、設定済みのデフォルトを使用する必要があります。プロセスの cwd を引き継ぐことはなく、workingDir、addDir、includeDirsと組み合わせることもできません。マテリアライズ時には、リポジトリ、システム、グローバルの Git フックと、設定済みの clean、smudge、process チェックアウトフィルターが抑制されます。そのため、Git LFS などのフィルターに依存するコンテンツは、ホストコマンドを実行せずにリポジトリ内の表現のまま保持されます。promptParts(オブジェクト、任意):キャッシュ対応の構造化プロンプト{ system?, tools?, context?, task }です。promptとは相互に排他的です。optimizePrompt(ブール値、任意):トークン効率を高めるためにプロンプトを最適化します。デフォルト:falseoptimizeResponse(ブール値、任意):トークン効率を高めるためにレスポンスを最適化します。デフォルト:falsecorrelationId(文字列、任意):リクエストのトレース ID(省略時は自動生成されます)。idleTimeoutMs(整数、任意):アイドルタイムアウトではなく、総実行時間の上限です。このプロバイダーは終了するまで出力を行わないため、正常に動作している最中でも、この時間を過ぎるとプロセスは強制終了されます。30,000~3,600,000 ms、デフォルト:3,600,000 msforceRefresh(ブール値、任意):重複排除を回避して、新しい CLI 実行を強制します。デフォルト:false
レスポンスの追加項目:
mcpServers:この呼び出しで要求された MCP サーバーのメタデータ
例:
{
"prompt": "Explain quantum computing",
"model": "latest",
"resumeLatest": true,
"optimizePrompt": true
}
grok_request
セッションに対応した Grok CLI(xAI)のリクエストを実行します。
パラメーター:
prompt(文字列、任意*):送信するプロンプト(1~100,000 文字)。*promptまたはpromptPartsのいずれか一方が必須です(相互排他的)。model(文字列、任意):モデル名またはエイリアス(例:grok-4.6、grok-4.5)。list_modelsまたはmodels://grokによる最新情報の取得を推奨します。従来のgrok-buildID は上流で削除されており、現在はInvalid params: "unknown model id"で必ず失敗します。transport(文字列、任意):"cli"(デフォルト)は Grok CLI を実行します。"acp"は、[acp].enabledとプロバイダーのruntime_enabledが設定されている場合、Grok ネイティブのgrok agent stdioトランスポート経由で実行します(設定されていない場合は安全側に倒して失敗します)。どちらのトランスポートもapprovalStrategy:"mcp_managed"を拒否します。approvalPolicyは影響しません。同期のみ:grok_request_asyncは常に CLI トランスポートを実行し、transportは受け付けません。outputFormat(文字列、任意):"plain"(デフォルト)、"json"、または"streaming-json"sessionId(文字列、任意):再開するセッション ID(--resume <id>)。resumeLatest(ブール値、任意):現在の cwd で最新のセッションを再開します(--continue)。createNewSession(ブール値、任意):常に新しいセッションを作成します。alwaysApprove(ブール値、任意):レガシーモードですべてのツール実行を自動承認します(--always-approve)。permissionMode(文字列、任意):default|acceptEdits|auto|dontAsk|bypassPermissions|plan。effort(文字列、任意):low|medium|high|xhigh|maxreasoningEffort(文字列、任意):推論モデルの推論レベルapprovalStrategy(文字列、任意):実行可能な戦略は"legacy"のみです。アダプターでは暗黙の MCP 設定を分離できないため、Grok の起動前に"mcp_managed"は拒否されます。approvalPolicy(文字列、任意):mcp_managedを使用できないため、Grok では影響しません。mcpServers(文字列[]、任意):メタデータのみです。Grok は独自の MCP 設定をgrok mcpで管理します。このフィールドで許可リストが作成されることはありません。allowedTools(文字列[]、任意):許可する組み込みツール(カンマ区切りリストとして--toolsに渡されます)。disallowedTools(文字列[]、任意):許可しない組み込みツール(カンマ区切りリストとして--disallowed-toolsに渡されます)。maxTurns(整数、任意):エージェントループの反復上限(--max-turns)workingDir(文字列、任意):この呼び出しの作業ディレクトリ(--cwd)sandbox(文字列、任意):ファイルシステム/ネットワークアクセス用のサンドボックスプロファイル(--sandbox、自由形式。GROK_SANDBOXでも指定可能)。rules(文字列、任意):システムプロンプトに追加するルール(--rules。@fileプレフィックスに対応)。systemPromptOverride(文字列、任意):エージェントのシステムプロンプト全体を置き換えます。allow/deny(文字列[]、任意):権限の許可/拒否ルール(各エントリーにつき--allow/--denyを1つ指定)。compactionMode(文字列、任意):summary(デフォルト)|transcript|segmentscompactionDetail(文字列、任意):none|minimal|balanced|verbose(segments モードのみ)agent(文字列、任意):エージェント名または定義ファイルのパス。agents(文字列|オブジェクト、任意):インラインのサブエージェント定義 JSON。disableWebSearch(ブール値、任意):ウェブ検索およびリモート取得ツールを無効にします。todoGate(ブール値、任意):実行時のターン終了時 TodoGate を有効にします(セッション単位)。verbatim(ブール値、任意):指定されたプロンプトをそのまま送信します(ゲートウェイによるプロンプト最適化もスキップします)。promptFile/promptJson/single(任意):ファイル/JSON ブロック/リテラルによる単一ターンのプロンプト。experimentalMemory/noMemory(ブール値、任意):セッション間メモリを有効化/無効化します。noAltScreen/noPlan/noSubagents(ブール値、任意):代替画面/プランモード/サブエージェントの起動を無効にします。oauth(ブール値、任意):認証に OAuth を使用します。restoreCode(ブール値、任意):再開時に元のセッションのコミットをチェックアウトします。leaderSocket(文字列、任意):カスタムのリーダーソケットパス(--leader-socket、Grok 0.2.32 以降。デフォルトは~/.grok/leader.sock)。ローカル版やブランチ版の Grok など、分離されたリーダープロセスを対象にします。nativeWorktree(ブール値|文字列、任意):Grok 独自の--worktreeフラグ(trueは名前なし、文字列は名前付き)。ゲートウェイのworktreeオプションとは別のものです。worktreeRef(文字列、任意):ネイティブワークツリーのベースとなるブランチ/タグ/コミット(--worktree-ref)。nativeWorktreeが必要です。forkSession(ブール値、任意):再開したセッションに追記する代わりに、新しいブランチへ分岐します。jsonSchema(文字列|オブジェクト、任意):構造化出力を制約する JSON Schema(文字列またはオブジェクト)(--json-schema)worktree(ブール値|オブジェクト、任意):ゲートウェイが所有する git worktree 内で実行します(slice λ)。Grok ではプロバイダー固有のsessionIdの明示的な指定が必要です。新規、createNewSession、およびresumeLatestのみを指定したワークツリー要求は、ワークツリーを永続的に再選択できないため拒否されます。ワークツリーには、明示的に選択された登録済みワークスペース、呼び出し元が所有するセッションメタデータ、または設定されたデフォルトのいずれかが必要です。プロセスの cwd は継承されず、workingDir、addDir、includeDirsとの併用もできません。マテリアライズ時には、リポジトリ、システム、グローバルの Git フック、および設定済みの clean、smudge、process チェックアウトフィルターが抑止されます。そのため、Git LFS などフィルターに依存するコンテンツは、ホストコマンドを実行せず、リポジトリ内の形式のままになります。promptParts(オブジェクト、任意):キャッシュを考慮した構造化プロンプト{ system?, tools?, context?, task }。promptとは相互排他的です。optimizePrompt(ブール値、任意):トークン効率のためにプロンプトを最適化します。デフォルト:falseoptimizeResponse(ブール値、任意):トークン効率のために応答を最適化します。デフォルト:falsecorrelationId(文字列、任意):リクエストのトレース ID(省略時は自動生成)idleTimeoutMs(整数、任意):出力がない状態が続いた場合にプロセスを終了します。30,000~3,600,000 msforceRefresh(ブール値、任意):重複排除を回避し、CLI を新たに実行します。デフォルト:false 例:
{
"prompt": "Summarize the latest commit message in 1 sentence",
"model": "grok-4.6",
"effort": "low"
}
永続的なジョブ結果と自動重複排除
すべての非同期ジョブは、実行中 → 完了/失敗/キャンセルの状態遷移に応じてジョブストアに保存されます。これにより、ゲートウェイは永続的な収集レイヤーとして機能します。
- リクエストを再送しても安全です。 重複排除の時間枠内(デフォルトは 1 時間)に同一の
*_request/*_request_asyncを呼び出すと、既存の実行中または完了済みのジョブに処理が短絡され、重複した実行は開始されません。呼び出し元には新たなジョブを開始する代わりに、同じジョブ ID が返されます。これにより、「ポーリング中にエージェントがタイムアウトし、再送した結果、ジョブ全体が最初からやり直しになる」という障害パターンを直接解消します。 - ゲートウェイを再起動しても、
llm_job_statusとllm_job_resultは動作します。 オペレーターが上限を設定するまでジョブの行は保持されるため、インメモリーキャッシュから追い出された後も、呼び出し元は結果を取得できます。 - ジョブが
orphanedとしてマークされるのは、それを所有するゲートウェイインスタンスが確実に停止した場合に限られます。 別のインスタンスが再起動したことを理由にマークされることはありません。各インスタンスは定期的なハートビートリースを保持し、自身が所有するすべてのジョブに所有者情報を記録します。リカバリースイープでは、そのジョブ自身のリースが期限切れになった場合にのみ、queued/runningのジョブを孤立状態にします。共有ストア(backend = "postgres")では、新しいインスタンスが別の稼働中インスタンスの処理中ジョブを孤立状態にすることはありません。実際に孤立したジョブの取得済み部分出力は引き続き読み取り可能です。また、一時的に古い状態になった後に復旧した所有者が後からジョブを完了すると、正しい最終状態に自動修復されます(issue #139)。 - すべてのリクエストツールで
forceRefresh: trueを渡すと、重複排除を回避して新たに CLI を実行できます。
永続化の設定
永続バックエンドは ~/.llm-cli-gateway/config.toml で設定します(LLM_GATEWAY_CONFIG=/path/to/config.toml で上書きできます)。例:
[persistence]
backend = "sqlite" # "sqlite" | "memory" | "postgres" | "none"
path = "~/.llm-cli-gateway/logs.db" # for sqlite
# dsn = "postgresql://user:pw@host/db" # for postgres
# retentionDays = 30 # optional legacy JOB-store bound; omitted means unbounded
dedupWindowMs = 3600000
acknowledgeEphemeral = false # required to enable async tools with memory backend
# One retention policy, over every subsystem. Every destructive bound is OFF
# unless you write a number, because deleting prompt, response, or transcript
# history is destructive and no upgrade should do it for you. Unknown keys are
# refused rather than silently applying no bound.
# `llm-cli-gateway doctor --json` -> .storage.retention reports what each bound
# would delete BEFORE you set it.
[persistence.retention]
# jobs = 30 # overrides retentionDays above
# requests = 90 # flight-recorder transcripts, incl. bodies
# wedgedValidationRuns = 30 # validation runs nothing can ever finalize
# sweepIntervalMs = 3600000 # how often the sweeper ticks
# Issue #139 durable orphan-recovery lease (defaults shown). Each instance
# advances a per-job lease on every heartbeat; the sweep orphans a job only
# after its own lease expires, so a fresh instance never orphans another live
# instance's jobs on a shared store. Validated: leaseTtl >= 2*heartbeat and
# httpJobGrace >= leaseTtl.
instanceHeartbeatMs = 15000 # heartbeat cadence
instanceLeaseTtlMs = 90000 # per-job lease TTL (6x heartbeat)
httpJobGraceMs = 300000 # extra grace for no-pid http jobs (5 min)
orphanSweepIntervalMs = 30000 # reaper cadence
instanceGcMs = 3600000 # gateway_instances GC horizon
# ownsOrphanRecovery = false # DEPRECATED (#139): superseded by the lease; parsed + warned, no longer used
# Optional, postgres only. One credential per class of work, for a deployment
# that has provisioned the RBAC in docs/plans/postgres-security-hardening.md.
# `app` is not a key here: the runtime credential is [persistence].dsn above.
# `migrate` is not a key either, and must not be held by a running gateway.
# A role left out degrades onto `app`, which llm_process_health reports as
# `persistence.roles.degraded` rather than implying separation is in force.
# [persistence.roles]
# reader = "postgresql://llmgw_reader@host/db" # transcript read-back
# analytics = "postgresql://llmgw_analytics@host/db" # aggregates, no body text
# retention = "postgresql://llmgw_retention@host/db" # job expiry
バックエンド:
sqlite(デフォルト)— ファイルベースの永続ストレージです。単一インスタンスのデプロイに適しています。postgres:PostgreSQL が、非同期ジョブ、重複排除、孤立状態からの復旧、HTTP ジョブ、検証状態、セッションメタデータ、フライトレコーダーなど、バックエンドが管理するすべての永続サブシステムの権威ある保存先になります。承認、管理者監査、ワークスペースレジストリなど、ファイルベースのオペレーターレコードは SQLite/PostgreSQL エンジンの選択対象ではありません。複数インスタンスまたはサービスのデプロイでは、このバックエンドを使用してください。ゲートウェイと併せて、オプションのピア依存関係pgをインストールする必要があります。memory— プロセス内の Map です。ゲートウェイ終了時に失われます。読み込みにはacknowledgeEphemeral = trueが必要です。テストや、一時的な CI ゲートウェイに適しています。none— ストアなしです。*_request_async、llm_job_status、llm_job_result、llm_job_cancelはゲートウェイに登録されません。 これは構造上の不変条件です。backend = "none"のゲートウェイに対して非同期ツールを呼び出そうとするエージェントは、1 時間の TTL 経過後にインメモリーのデータがひそかに失われるのではなく、接続時に明確な「ツールが見つかりません」という結果を受け取ります。解決後の永続化状態をプログラムから調べるには、llm_process_healthを使用してください。
backend = "postgres" を選ぶことは、エンジン全体を選ぶことです。 設定された dsn は PostgreSQL の URL である必要があります。ゲートウェイはデプロイのトポロジーを推測したり、ホストを解決したり、PostgreSQL の接続先をローカルに制限したり、診断情報に DSN から導出した接続先を表示したりしません。移行、接続、または操作に失敗した場合、影響を受ける PostgreSQL サブシステムはフェイルクローズし、ゲートウェイが代替として SQLite を開くことはありません。ヘルス情報には選択されたエンジンが示され、PostgreSQL の障害は一般的な内容で報告されます。
エンジンを変更してもデータは移動しません。 既存の SQLite と PostgreSQL の行は、それぞれ元の保存先に残ります。自動移行、二重書き込み、エンジンをまたいだ読み取りは行われません。古い履歴をゲートウェイから引き続き利用できるようにする必要がある場合は、切り替え前に別途、データ移行を計画して実行してください。
backend = "none" と LLM_GATEWAY_LOGS_DB=none は異なるスイッチです。 前者は非同期ジョブの永続化を無効にし、後者はリクエスト履歴を無効にします。バックエンドを "none" に設定してもフライトレコーダーは書き込みを続け、レコーダーを無効にしてもジョブストアには影響しません。どちらの状態も起動時に stderr の Storage: ブロックに表示されます。llm_process_health は、設定された PostgreSQL の接続先を表示せずに、選択されたエンジン、レコーダーの状態、ロール設定、非推奨入力の処理内容を報告します。
DATABASE_URL は非推奨であり、[persistence] を上書きすることはありません。 選択肢としてこれだけが指定されている場合、これは backend = "postgres" と dsn の非推奨エイリアスとして機能するため、セッション、ジョブ、検証状態、リクエスト履歴は同じエンジンに保持されます。明示的なバックエンドが指定されている場合や、指定された dsn と一致しない場合は、理由とともに無視されます。結果は完全に確定しており、設定ファイルの内容どおりになるため、ゲートウェイは中断しません。
PostgreSQL の場合は、DML 専用のゲートウェイロールを起動する前に、スキーマ所有者または専用のマイグレーションロールを使ってスキーマを適用してください。
DATABASE_URL='postgresql://<user>:<password>@<host>/<database>' npm run migrate
ランナーはアドバイザリロックでマイグレーション作業を直列化し、各マイグレーションの SHA-256 を
schema_migrations.checksum_sha256 に記録します。以降の実行では、記録されたチェックサムの形式が不正な場合、または一致しない場合、保留中のマイグレーションを計算・適用する前にランナーを停止します。NULL チェックサムは、チェックサムの記録が始まる前の明示的なレガシー行です。警告付きで許可されますが、バックフィルは行われません。現在のソースファイルから、過去に実行された SQL を証明することはできないためです。リリース済みのマイグレーションファイルを編集したり、台帳のチェックサムを手動で入力したりしないでください。ランナーは過去の 002/003 の SQL を保持し、これらのレガシーバージョンのいずれかが保留中である間だけ、互換性対応を適用します。フォワードマイグレーション 018 は、すでに記録済みのレガシーなセッション/ビューのレイアウトを修復します。リリースチェックでは、公開済みのマイグレーションファイルのソース変更を拒否します。
レガシー環境変数(非推奨。起動時に警告が出力されます):
LLM_GATEWAY_LOGS_DB/LLM_GATEWAY_JOBS_DB:バックエンドが明示的に設定されていない場合、noneはbackend = "none"を選択し、それ以外の値はそのパスを指定したbackend = "sqlite"を選択します。明示的な[persistence].backendが優先されます。LLM_GATEWAY_LOGS_DBは、どのバックエンドでも引き続きレコーダーを個別に無効にし、選択されたレコーダーエンジンが SQLite の場合はそのパスを指定します。LLM_GATEWAY_JOB_RETENTION_DAYS—retentionDaysを上書きします。LLM_GATEWAY_DEDUP_WINDOW_MS—dedupWindowMsを上書きします。LLM_GATEWAY_ACKNOWLEDGE_EPHEMERAL—1/true/yesを指定すると、acknowledgeEphemeral = trueに設定されます。
ホスト保護の上限([http] と [limits])
ゲートウェイは HTTP セッションの増加と非同期/同期ジョブの実行に上限を設けており、クライアントやリクエストが急増しても、メモリ、プロセス、CPU、プロバイダーへのリクエストが際限なく増加しないようにします。すべてのキーは同じ ~/.llm-cli-gateway/config.toml に記述します。デフォルト値は控えめですが、ローカルの stdio 開発で予期しない動作にならないように選ばれています。
[http] # HTTP MCP transport session lifecycle
max_sessions = 100 # max concurrent live sessions; excess initialize returns HTTP 429
session_idle_ttl_ms = 1800000 # 30 min: reap a session idle longer than this (no client DELETE needed)
session_reaper_interval_ms = 60000 # 1 min: how often the idle reaper sweeps
[limits] # async + sync job-execution backpressure (per gateway process)
max_running_jobs = 32 # global concurrent running jobs (process CLI + HTTP API)
max_running_jobs_per_provider = 16 # per-provider concurrent running jobs
max_queued_jobs = 128 # bounded wait queue; a full queue rejects new work
queue_timeout_ms = 120000 # 2 min: max time a job waits in the queue before failing
completed_job_memory_ttl_ms = 3600000 # 1 h: in-memory retention for finished jobs (durable rows kept separately)
max_job_output_bytes = 52428800 # 50 MB: per-job stdout+stderr cap
障害時の動作(いずれも決定論的で、安全に再試行できます):
- HTTP セッションの上限に到達:初期化リクエストは
429とRetry-After: 5を返し、{ error, code: "session_capacity", retryable: true }という構造化された本文を返します。新しいセッションは作成されません。 - アイドル状態の HTTP セッション:クライアントが
DELETEを送信するかどうかにかかわらず、session_idle_ttl_msを超えてアイドル状態になると、リーパーがセッションを閉じます(トランスポートとゲートウェイサーバー)。処理中のリクエストがあるセッションは、リクエストの途中で削除されません。 - ジョブリミッターの飽和:実行中の上限に達し、キューも満杯の場合、
*_request/*_request_asyncと直接同期フォールバックは、再試行可能なsaturatedエラー(structuredContent.errorCategory = "saturated"、retryable: true)を返します。何も起動されません。キューに空きがある場合、ジョブはキューで待機し(FIFO、プロバイダーごとに公平)、queue_timeout_msが経過すると同じカテゴリのエラーになります。 - 同期の直接実行:
SYNC_DEADLINE_MS=0とストアを使用しない/backend="none"の経路は、プロセスを起動する前に同じプロセス実行許可を取得するため、リミッターを回避して実行されることはありません。 - 出力の超過:標準出力と標準エラーの合計が
max_job_output_bytesを超えたジョブは失敗(終了コード 126)となり、プロセスが終了させられ、完了状態が永続化され、実行枠が解放されます。 - メモリ内の保持期間と永続的な保持期間:
completed_job_memory_ttl_msは、完了したジョブをメモリ内マップから削除するまでの期間のみを制御します。永続ジョブストアはデフォルトでは無制限で、[persistence.retention].jobsまたは従来の[persistence].retentionDaysで上限を設定できます。そのため、メモリから削除された後もllm_job_result/llm_request_resultから結果を読み取れます。
稼働中のカウンターは、GET /healthz(認証不要の HTTP トランスポート)と、llm_process_health ツールの backpressure ブロックで確認できます。これには、セッションの現在数/最大数/最古の経過時間/アイドル TTL/飽和状態、全体およびプロバイダーごとの実行中ジョブ数とキュー内ジョブ数、リミッターの飽和カウンター、設定された TTL/出力上限、親プロセスの RSS/ヒープが含まれます。これらのインターフェースが報告するのは件数、経過時間、バイト数のみであり、プロンプトのテキスト、応答内容、トークン、セッション ID、ベアラー/OAuth トークン、API キー、マシンのシークレットは報告しません。
本番環境のユーザーサービスでは、予期しないバグ、プロバイダー CLI のリーク、評価の急増によってホストのリソースが使い果たされないよう、上記のプロセス内制限と systemd の外側の保護策を組み合わせてください。
systemctl --user edit llm-cli-gateway.service
[Service]
MemoryMax=2G
TasksMax=512
ワークロードに合わせて値を選択してください。MemoryMax は、ゲートウェイプロセス、設定した max_running_jobs に対応するプロバイダーの子プロセス、および通常の出力バッファリングをカバーできる値にします。TasksMax は、max_running_jobs に応じて必要となるプロセス/スレッド数に HTTP サーバーと SQLite の処理を加えた数を超える一方で、ホストのリソースを使い果たすには程遠い値にします。systemd によりこれらの上限でサービスが終了させられた場合でも、再起動後に永続ジョブを確認できます。[http]、[limits]、MemoryMax、TasksMax をまとめて調整する際は、llm_process_health.backpressure を活用してください。
プロジェクトごとの分離
デフォルトでは、ゲートウェイの状態はプロジェクトごとではなく、ユーザーごとに共有されます。オーバーライドを設定しない場合、すべてのリポジトリで Claude Code の各ウィンドウが独自のゲートウェイサブプロセスを起動しますが、すべて同じ状態を読み書きします。
-
[persistence].backend = "sqlite"の場合は~/.llm-cli-gateway/logs.db(非同期ジョブとフライトレコーダー)。backend = "postgres"の場合、これらの行は設定されたデータベースに保存されます。破壊的な保持上限はすべてデフォルトで無効です。[persistence.retention].jobsはジョブレコード全体を削除し、[persistence.retention].requestsはフライトレコーダーのrequestsテーブルとgateway_metadataテーブルを削除し、[persistence.retention].wedgedValidationRunsはvalidation_run_jobsリンクがあり、完了処理できない検証実行を削除します。運用担当者は、各上限を個別に有効にする必要があります。validation_receiptsは設計上不変であり、削除されることはありません。完了済みの実行も削除されないため、レシートが孤立することはありません。行を削除しても SQLite のページは解放されますが、バイト数は減らないため、ファイルは小さくなりません。空き領域を取り戻すには、ゲートウェイを停止した状態で
llm-cli-gateway storage compact --yesを実行してください。VACUUMはファイル全体を書き換える間、排他ロックを保持するためです。doctor --json->.storage.retentionでは、解決済みの上限、スイープで削除されるデータ、コンパクションで取り戻せるバイト数を確認できます。docs/plans/durable-state-lifecycle.dag.tomlを参照してください。 -
~/.llm-cli-gateway/sessions.json(デフォルトのファイルセッションバックエンド使用時のゲートウェイセッションメタデータ) -
~/.llm-cli-gateway/config.toml(解決済み設定)
[persistence].backend = "postgres" で PostgreSQL セッションマネージャーを選択すると、セッションメタデータは sessions.json ではなく PostgreSQL に保存されます。通常はこちらが望ましい構成です。リポジトリ A の session_list でリポジトリ B のセッションを表示でき、ウィンドウ A で開始した非同期ジョブをウィンドウ B からポーリングでき、1 時間の重複排除ウィンドウでウィンドウ間の再リクエストを検出できます。ゲートウェイ管理のワークツリーは PostgreSQL のセッションストレージで動作しますが、ファイルシステム上の所有権はホストローカルのままです。データベースを共有する別のホストから、そのワークツリーを再利用したりクリーンアップしたりすることはできません。ワークツリーの削除に失敗した場合は、所有ホストで再試行できるよう保持されます。また、別のホストで処理された削除によっても、そのレコードは維持されます。データベース側の cleanup_expired_sessions 関数は、ワークツリーを含むセッションを削除せず、同じレコードをステージングします。この関数はゲートウェイのオブザーバーを呼び出さないため、削除を試みることもありません。SQLite の WAL モードはデフォルトのジョブ/フライトレコーダーデータベースを保護し、ファイルセッションマネージャーはロック付きのアトミックな書き込みを使用します。
プロジェクトごとの永続ジョブの分離
無関係なリポジトリ間で非同期ジョブ、フライトレコーダーの行、重複排除の状態を共有したくない場合は、プロジェクトごとに異なる永続化設定を指定してください。プロジェクトの .claude/settings.local.json に、次のように設定します。
{
"mcpServers": {
"llm-gateway": {
"env": {
"LLM_GATEWAY_CONFIG": "${workspaceFolder}/.gateway/config.toml"
}
}
}
}
続いて、リポジトリ内にプロジェクトごとの config.toml を作成します。
[persistence]
backend = "sqlite"
path = "/srv/repos/.../my-repo/.gateway/logs.db"
これで、このリポジトリの Claude Code ウィンドウ用に起動されるすべてのゲートウェイサブプロセスは、独自の設定を読み込み、永続ジョブ、フライトレコーダーの行、重複排除の状態をそれぞれ専用の SQLite ファイルに書き込みます。他のリポジトリでは、引き続きグローバルデフォルトが使用されます。この [persistence] オーバーライドでは、デフォルトのファイルベースの sessions.json は移動しないため、セッション一覧は分離されません。エージェントは llm_process_health.persistence.sources.configFile を使って、実際にどの永続化設定で動作しているかを確認できます。
エージェント実行可能な仕様(DAG-TOML)
LLM エージェントにこのセットアップを推測ではなく、決定的に実行させたい場合は、以下の DAG-TOML をリポジトリにコピーし(例:docs/planning/per-project-gateway-isolation.toml)、エージェントに参照させてください。スキーマは agent-assurance の template_kind = "implementation-dag" です。エージェントはレイヤーの順序どおりにユニットを実行し、検証ユニットをスキップせず、失敗したゲートはすべてブロッキングとして扱う必要があります。
[meta]
schema_version = "1.0.0"
template_kind = "implementation-dag"
docs = "https://github.com/verivus-oss/agent-assurance/blob/main/SPEC.md"
confidentiality = "public"
title = "Per-project llm-cli-gateway durable-job isolation"
spec = "https://github.com/verivus-oss/llm-cli-gateway#per-project-durable-job-isolation"
created = "YYYY-MM-DD"
total_units = 5
tier1_units = ["U01","U02","U03","U04","U05"]
tier2_units = []
tier3_units = []
# ============================================================================
# [policy.agent] — persona for the agent performing the configuration.
# ============================================================================
[policy.agent]
name = "Gateway Persistence Isolator"
role = "Configuration Engineer"
purpose = "Configure the llm-cli-gateway MCP server so its SQLite durable state is scoped to THIS repository instead of the per-user default at ~/.llm-cli-gateway/. The default file-backed session metadata remains shared."
validation_type = "Structural + Runtime Verification"
workflow_initiator = false
description = "Writes a repo-local config.toml, registers an LLM_GATEWAY_CONFIG override in .claude/settings.local.json, restarts the MCP server, and confirms via llm_process_health that the gateway is now reading the repo-local config and writing to the repo-local SQLite path."
[policy.agent.orchestration]
consumes_events = ["PerProjectIsolationRequested"]
produces_events = ["PerProjectDurableJobIsolationComplete"]
[policy.agent.responsibilities]
items = [
"Create the repo-local gateway data directory and add it to .gitignore.",
"Write a config.toml that pins backend=sqlite to a repo-local path.",
"Register the LLM_GATEWAY_CONFIG env override in .claude/settings.local.json (NOT .mcp.json — that file is committed and shared).",
"Trigger an MCP server reconnect.",
"Verify via llm_process_health that the resolved configFile and dbPath are the repo-local values.",
]
# ============================================================================
# [policy.instance] — concrete paths the agent fills in for THIS repo.
# Agent MUST replace <REPO_ABS_PATH> with the absolute path to the repo
# before emitting any artefact. Relative paths in config.toml MUST be
# expanded to absolute — the gateway does not re-resolve them per cwd.
# ============================================================================
[policy.instance]
repo_abs_path = "<REPO_ABS_PATH>" # e.g. /srv/repos/me/my-project
gateway_data_dir_relative = ".gateway" # repo-relative directory
config_toml_relative = ".gateway/config.toml"
sqlite_db_relative = ".gateway/logs.db"
claude_local_settings_relative = ".claude/settings.local.json"
gitignore_relative = ".gitignore"
mcp_server_name = "llm-gateway" # must match the entry in .mcp.json
# ============================================================================
# [policy.gates] — blocking checks. Any failure stops the workflow.
# ============================================================================
[policy.gates]
gate_repo_abs_path_resolved = "policy.instance.repo_abs_path must NOT be the literal string '<REPO_ABS_PATH>' when U01 starts."
gate_config_is_committed = "policy.instance.config_toml_relative MAY be committed. policy.instance.claude_local_settings_relative MUST NOT be committed (it is per-developer). Agent MUST verify .gitignore covers .claude/settings.local.json if absent."
gate_no_legacy_env_leak = "Agent MUST grep the shell init files for LLM_GATEWAY_LOGS_DB / LLM_GATEWAY_JOBS_DB. An explicit [persistence].backend wins for job persistence, but LLM_GATEWAY_LOGS_DB still disables the recorder on every backend and paths it when SQLite is selected. Both variables remain deprecated. The agent reports either as a finding and asks the operator to unset it before proceeding."
gate_health_confirms_isolation = "U05 MUST observe llm_process_health.persistence.sources.configFile == policy.instance.repo_abs_path + '/' + policy.instance.config_toml_relative AND llm_process_health.persistence.path == policy.instance.repo_abs_path + '/' + policy.instance.sqlite_db_relative. Anything else means the override did not take effect."
# ============================================================================
# [policy.evidence] — what each unit must emit so the work is auditable.
# ============================================================================
[policy.evidence]
per_unit_required_fields = [
"unit_id", # U01..U05
"status", # "completed" | "failed"
"artefact_paths", # files written / modified
"stdout_tail", # last 20 lines of any command output
"verification_quote", # for U05, the verbatim llm_process_health.persistence block
]
findings_required_fields = [
"gate_id", # which gate failed
"observed",
"expected",
"remediation",
]
# ============================================================================
# Units. Execute in layer order. U01..U03 modify the working tree; U04
# triggers a reconnect; U05 is the verification gate that decides success.
# ============================================================================
[units.U01]
name = "create-repo-local-data-dir"
summary = "mkdir -p <repo>/.gateway and append /.gateway/ to .gitignore (creating .gitignore if missing). The gateway will write logs.db, logs.db-wal, logs.db-shm here — none should be committed."
layer = 0
tier = 1
status = "pending"
depends_on = []
blocks = ["U02"]
estimated_loc = 5
files_modify = [".gitignore"]
produces = ["ART:gateway-data-dir"]
consumes = []
[units.U02]
name = "write-config-toml"
summary = "Write <repo>/.gateway/config.toml with [persistence] backend='sqlite' and path=<absolute-path-to-repo>/.gateway/logs.db. Path MUST be absolute. Do NOT use ~ — the gateway expands ~ but [persistence].path is read literally if not prefixed with ~/, and Claude Code may launch the gateway with a HOME that surprises you."
layer = 1
tier = 1
status = "pending"
depends_on = ["U01"]
blocks = ["U03"]
estimated_loc = 10
files_modify = [".gateway/config.toml"]
produces = ["ART:gateway-config"]
consumes = ["ART:gateway-data-dir"]
[units.U03]
name = "register-llm-gateway-config-env-in-claude-local-settings"
summary = "Add (or merge) an mcpServers.<mcp_server_name>.env entry in .claude/settings.local.json that sets LLM_GATEWAY_CONFIG to the absolute path of .gateway/config.toml. Do NOT modify .mcp.json — that file is committed and the path would be wrong for every other developer. If .claude/settings.local.json already has an mcpServers.<mcp_server_name> entry, the agent MUST merge into the existing env map (preserving other keys), not overwrite the whole entry."
layer = 2
tier = 1
status = "pending"
depends_on = ["U02"]
blocks = ["U04"]
estimated_loc = 20
files_modify = [".claude/settings.local.json"]
produces = ["ART:claude-local-settings"]
consumes = ["ART:gateway-config"]
[units.U04]
name = "trigger-mcp-reconnect"
summary = "Ask the operator to run /mcp in Claude Code (or restart Claude Code) so the gateway subprocess is re-spawned under the new env. The agent cannot do this itself — MCP server lifecycle is owned by the host."
layer = 3
tier = 1
status = "pending"
depends_on = ["U03"]
blocks = ["U05"]
estimated_loc = 0
files_modify = []
produces = ["OUT:mcp-reconnected"]
consumes = ["ART:claude-local-settings"]
[units.U05]
name = "verify-via-llm-process-health"
summary = "Call llm_process_health and assert the returned persistence block satisfies policy.gates.gate_health_confirms_isolation. Quote the verbatim persistence block in evidence. If the assertion fails, the agent MUST NOT mark the workflow complete — it must emit a finding under policy.evidence.findings_required_fields, naming the observed vs. expected configFile/path, and stop."
layer = 4
tier = 1
status = "pending"
depends_on = ["U04"]
blocks = []
estimated_loc = 5
files_modify = []
produces = ["ART:durable-isolation-verification","OUT:per-project-durable-isolation-complete"]
consumes = ["OUT:mcp-reconnected"]
エージェントにとってこれが重要な理由: ゲートウェイには複数の設定箇所(TOML ファイル、環境変数によるオーバーライド、2 種類の MCP 設定ファイル)があり、よくある間違いのひとつである、ローカル限定の .claude/settings.local.json ではなくコミット対象の .mcp.json を編集すると、リポジトリを使う他の開発者全員のプロジェクト単位の永続化スコープが、気付かないうちに壊れてしまいます。上記の DAG には、正しい手順、検証ゲート、失敗時の動作が明示的に記載されているため、エージェントは推論に頼らず実行できます。デフォルトのファイルベースのセッションストアを分離できるとは、意図的に主張していません。
mistral_request
Mistral Vibe のエージェント型コーディングリクエストを実行します。形式は grok_request と似ていますが、Vibe 固有のインターフェースを使います。
model(文字列、省略可能):Vibe モデルのエイリアス(例:mistral-medium-3.5またはlatest)。解決された値はVIBE_ACTIVE_MODEL環境変数を通じて渡されます。省略すると、ゲートウェイが Vibe の設定を検出するため、古くなったハードコードのデフォルト値を避けられます。transport(文字列、省略可能):"cli"(デフォルト)は Vibe CLI を実行します。"acp"は、[acp].enabledとプロバイダーのruntime_enabledが設定されている場合に、Vibe ネイティブのvibe-acpトランスポート経由でルーティングします(それ以外の場合は安全側に倒して拒否します)。どちらのトランスポートもapprovalStrategy:"mcp_managed"を拒否します。approvalPolicyは影響しません。同期専用:mistral_request_asyncは常に CLI トランスポートを実行し、transportは受け付けません。permissionMode:Vibe の--agent名です。組み込みのdefault | plan | accept-edits | auto-approve、またはインストールが条件となるカスタムエージェントを指定できます。レガシーモードでは、リクエストに指定した名前が出力されます。allowedTools(文字列配列、省略可能):各エントリーにつき 1 つの--enabled-tools <tool>フラグを指定します。disallowedTools(文字列配列、省略可能):各エントリーにつき 1 つの--disabled-tools <tool>フラグを指定します。有効なツールのフィルター適用後に適用されます。outputFormat(文字列、省略可能):Vibe 2.x では"text"、"json"、"streaming"を指定します。レガシーエイリアスの"plain"と"stream-json"も受け付けられ、起動前に正規化されます。sessionId/resumeLatest/createNewSession:標準のセッション制御です。現在の Vibe では、セッションのログ記録はデフォルトで有効です。古い設定で[session_logging] enabled = falseの場合、doctor --jsonに実行可能な次のアクションが表示されます。trust(ブール値、省略可能):--trustを指定し、この呼び出しに限り Vibe が現在の作業ディレクトリを信頼するようにします(設定は保存されず、対話形式の信頼確認プロンプトはスキップされます)。maxTurns(整数、省略可能):エージェントループの反復回数の上限です(プログラムモードのみ--max-turns)。maxPrice(数値、省略可能):累積コストがこの USD 上限を超えたときに中断します(プログラムモードのみ--max-price)。maxTokens(整数、省略可能):プロンプトと生成の累積トークン数の上限です(プログラムモードのみ--max-tokens)。workingDir(文字列、省略可能):実行前にこのディレクトリへ移動します(--workdir)。addDir(文字列配列、省略可能):書き込み可能な追加ワークスペースディレクトリです(各エントリーにつき 1 つの--add-dir)。approvalStrategy(文字列、省略可能):実行可能な戦略は"legacy"のみです。アダプターでは環境に存在する MCP 設定を分離できないため、Vibe の起動前に"mcp_managed"は拒否されます。approvalPolicy(文字列、省略可能):mcp_managedは利用できないため、Vibe では影響しません。mcpServers(文字列配列、省略可能):メタデータのみです。Vibe はVIBE_HOMEの設定から MCP 設定を読み込みます。このフィールドによって許可リストが作成されることはありません。worktree(ブール値またはオブジェクト、省略可能):ゲートウェイが管理する git ワークツリー内で実行します(スライス λ)。Mistral ではプロバイダー固有のsessionIdの明示的な指定が必須です。ワークツリーを永続的に再選択できないため、新規、createNewSession、およびresumeLatestのみを指定したワークツリーのリクエストは拒否されます。ワークツリーを使うには、明示的に選択された登録済みワークスペース、呼び出し元が所有するセッションメタデータで選択されたワークスペース、または設定済みのデフォルトが必要です。プロセスの現在の作業ディレクトリを引き継ぐことはなく、workingDir、addDir、includeDirsと組み合わせることもできません。マテリアライズ時には、リポジトリ、システム、グローバルの Git フックと、設定済みの clean、smudge、process チェックアウトフィルターが抑制されます。そのため、Git LFS などのフィルターに依存するコンテンツはホストコマンドを実行せず、リポジトリ内の表現のまま保持されます。promptParts(オブジェクト、省略可能):キャッシュを考慮した構造化プロンプト{ system?, tools?, context?, task }です。promptとは併用できません。optimizePrompt/optimizeResponse(ブール値、省略可能):トークン効率を最適化します。デフォルト:false。correlationId(文字列、省略可能):リクエストのトレース ID です。省略すると自動生成されます。idleTimeoutMs(整数、省略可能):アイドル時間ではなく、実行時間の上限です。このプロバイダーは終了するまで出力を行わないため、正常に動作していても、この時間が経過するとプロセスは強制終了されます。30,000~3,600,000 ms。デフォルトは 3,600,000 ms です。forceRefresh(ブール値、省略可能):重複排除を回避し、新たに CLI を実行します。デフォルト:false。
devin_request
Cognition Devin CLI のリクエストを同期的に実行します(ヘッドレスのプリントモード、devin -p)。非同期ジョブが有効な場合、同期期限を過ぎると自動的にポーリング可能なジョブに切り替わります。
パラメーター:
prompt(string、任意*):Devin CLI 用のプロンプトテキスト(1~100,000 文字)。実際には必須です。promptFileで追加の内容を指定できますmodel(string、任意):モデル名またはエイリアス(例:opus、latest)transport(string、任意):"cli"(デフォルト)は Devin CLI を実行します。[acp].enabledとプロバイダーのruntime_enabledが設定されている場合、"acp"は Devin ネイティブのdevin acpトランスポートを経由します(それ以外の場合はフェイルクローズします)。どちらのトランスポートもapprovalStrategy:"mcp_managed"は受け付けません。approvalPolicyは影響しません。同期専用です。devin_request_asyncは常に CLI トランスポートを実行し、transportとagentTypeのどちらも受け付けませんagentType(string、任意):transport: "acp"用の ACP エージェントバリアント(devin acp --agent-type)。"summarizer"(ツールなし、テキストの要約)または"review"(読み取り専用、シェルによるコードレビュー)を指定します。CLI トランスポートでは無視されますpermissionMode(string、任意):Devin CLI の権限モード(--permission-mode)。auto(読み取り専用ツールを自動承認)、accept-edits(ワークスペースの編集も自動承認)、smart(高速モデルが安全と判断したアクションも自動実行)、dangerous(すべて自動承認)。省略すると、Devin のヘッドレス時のデフォルトを使用しますapprovalStrategy(string、任意):実行可能な戦略は"legacy"のみです。アダプターでは周辺の MCP 設定を分離できないため、Devin の起動前に"mcp_managed"は拒否されますapprovalPolicy(string、任意):mcp_managedは利用できないため、Devin では影響しませんpromptFile(string、任意):ファイルから初期プロンプトを読み込みます(--prompt-file)sessionId(string、任意):再開する Devin セッション ID(--resume <id>)。新しいセッションに割り当てられたgw-*ID はsessionIdで再開できません。resumeLatest: trueを指定して続行してくださいresumeLatest(boolean、任意):選択した cwd で最新の Devin セッションを再開します (--continue)。workingDir、workspace、または設定済みのデフォルトワークスペースが必要です。createNewSession(boolean、任意):新しいセッションを強制的に作成しますworkingDir(string、任意):ローカル Devin プロセスの cwd。CLI トランスポート専用です。workspace(string、任意):Devin プロセスの cwd を選択する、登録済みのゲートウェイワークスペースのエイリアスです。worktree(boolean|object、任意):ゲートウェイが所有する Git ワークツリー内で Devin CLI のリクエストを実行します。Devin ではプロバイダー固有の明示的なsessionIdが必要です。新規、createNewSession、またはresumeLatestのみを指定したワークツリーリクエストは、ワークツリーを永続的に再選択できないため拒否されます。ワークツリーには、明示的に、呼び出し元が所有するセッションメタデータを通じて、または設定済みのデフォルトから選択した、登録済みのワークスペースが必要です。プロセスの cwd を引き継ぐことはなく、workingDir、addDir、includeDirsと組み合わせることもできません。マテリアライズ時には、リポジトリ、システム、グローバルの Git フックと、設定済みの clean、smudge、process チェックアウトフィルターが無効になります。そのため、Git LFS などフィルターに依存するコンテンツは、ホストコマンドを実行せず、リポジトリ内の形式のまま保持されます。optimizePrompt/optimizeResponse(boolean、任意):トークン効率の最適化。デフォルト:falsecorrelationId(string、任意):リクエストのトレース ID(省略時は自動生成)idleTimeoutMs(integer、任意):アイドルタイムアウトではなく、合計実行時間の上限です。このプロバイダーは終了するまで出力を行わないため、正常に動作している場合でも、この時間が経過するとプロセスが終了されます。30,000~3,600,000 ms、デフォルト:3,600,000 msforceRefresh(boolean、任意):重複排除を回避し、新しい CLI 実行を強制します。デフォルト:false
cursor_request
Cursor Agent のリクエストを同期的に実行します。デフォルトの CLI トランスポートではヘッドレスのプリントモード(cursor-agent --print)を使用し、非同期ジョブが有効な場合、同期期限を過ぎるとポーリング可能なジョブに自動的に切り替わります。[acp].enabled、[acp.providers.cursor].enabled、および [acp.providers.cursor].runtime_enabled が有効な場合は、transport: "acp" を設定して Cursor のネイティブな cursor-agent acp トランスポートを使用します。ACP では、prompt、model、ゲートウェイが所有する ACP sessionId、および登録済みのゲートウェイ workspace エイリアスを指定できます。どちらの Cursor トランスポートも approvalStrategy:"mcp_managed" を拒否します。approvalPolicy は CLI では効果がなく、ACP では拒否されます。
パラメーター:
prompt(文字列、必須):Cursor Agent CLI のプロンプトテキスト(1~100,000 文字)model(文字列、任意):モデル名またはエイリアス(例:gpt-5、sonnet-4-thinking、latest)mode(文字列、任意):Cursor モード。"plan"または"ask"(--mode)outputFormat(文字列、任意):"text"(デフォルト)、"json"、または"stream-json"transport(文字列、任意):"cli"(デフォルト)または"acp"。ACP は、グローバルゲートと Cursor プロバイダーゲートが有効でない場合、フェイルクローズします。ACP が受け付けるのはprompt、model、sessionId、および登録済みのworkspaceのみです。デフォルト以外の Cursor CLI 制御項目(mode、テキスト以外のoutputFormat、workingDir、空でないaddDir、force、autoReview、sandbox、trust、resumeLatest、createNewSession、最適化または圧縮、idleTimeoutMs、forceRefresh)は拒否されます。同期専用:cursor_request_asyncは常に CLI トランスポートを実行し、transportを受け付けませんforce(ブール値、任意):非対話型の実行に--forceを付与します。autoReview(ブール値、任意):--auto-reviewを付与します。sandbox(文字列、任意):"enabled"または"disabled"(--sandbox)。trust(ブール値、任意):この呼び出しに--trustを付与します。workspace(文字列、任意):transport: "cli"の場合、Cursor ワークスペースのパスまたは名前(--workspace)です。リモート HTTP/OAuth 呼び出し元は登録済みのワークスペースエイリアスを渡す必要がありますが、ローカル stdio 呼び出し元はパスを渡せます。未登録の相対ローカル値は、プロバイダー固有の保存済みワークスペース名としてそのまま保持され、ゲートウェイプロセスの cwd に対して解決されることはありません。ローカルディレクトリの cwd を選択するには、絶対パスを渡してください。transport: "acp"の場合は、登録済みのゲートウェイワークスペースエイリアスである必要があります。新規のリモート ACP リクエストでは、指定されたエイリアスまたは[workspaces].defaultが使用されます。リモート ACP の再開では、記録済みの正規エイリアスと cwd が引き続き使用されますworkingDir(文字列、任意):ローカルの Cursor Agent プロセスの作業ディレクトリです。CLI トランスポート専用です。Cursor 独自のセレクターであるworkspaceとは異なります。workspaceにworkingDirと一致しない絶対パスを渡すと、暗黙に優先順位を付けずに拒否されます。独自のスコープを解決するtransport: "acp"では、受け付けて破棄するのではなく、拒否されます。addDir(文字列配列、任意):追加のワークスペースルートです(各エントリにつき--add-dirを 1 つ付与)。リモート HTTP/OAuth 呼び出し元は登録済みのワークスペースルートを使用する必要があります。sessionId(文字列、任意):transport: "cli"の場合、再開する Cursor チャット/セッション ID です(--resume <id>)。新規ゲートウェイセッション用に発行されたgw-*ID は CLI トランスポートでは再開できません。続行するにはresumeLatest: trueを使用してください。transport: "acp"の場合は、以前の ACP 呼び出しで返された、ゲートウェイが管理する ACP セッション ID を渡してください。Cursor 固有のセッション ID と CLI セッション ID は拒否されますresumeLatest(ブール値、任意):CLI 専用:最新の Cursor チャットを再開します(--continue)。ACP ではtrueは拒否されます。createNewSession(ブール値、任意):CLI 専用:新しいセッションを強制的に作成します。ACP ではtrueは拒否されます。approvalStrategy(文字列、任意):実行可能な CLI 戦略は"legacy"のみです。"mcp_managed"は Cursor の起動前に拒否されます。ACP には独自の権限ブリッジがあり、これも拒否されます。approvalPolicy(文字列、任意):mcp_managedは利用できないため、CLI では効果がありません。ACP は独自の権限ブリッジを使用するため、これを拒否します。optimizePrompt/optimizeResponse(ブール値、任意):トークン効率の最適化。デフォルト:falsecorrelationId(文字列、任意):リクエストのトレース ID(省略時は自動生成)idleTimeoutMs(整数、任意):アイドルタイマーではなく、実行時間の上限です。このプロバイダーは終了するまで出力を行わないため、プロセスが正常に動作していても、この時間が経過すると強制終了されます。30,000~3,600,000 ms。デフォルトは 3,600,000 ms です。これはデフォルトのテキスト呼び出しに適用されます。outputFormat: "stream-json"の場合は Cursor が段階的にストリーミングするため、同じタイマーが実際のアイドル時間として機能しますforceRefresh(ブール値、任意):重複排除を回避し、新しい CLI 実行を強制します。デフォルト:false
claude_request_async / codex_request_async / gemini_request_async / grok_request_async / mistral_request_async / devin_request_async / cursor_request_async
完了を同じ MCP 呼び出し内で待たずに、時間のかかる Claude、Codex、Gemini、Grok、Mistral、Devin、または Cursor へのリクエストを開始します。
分析や実行にかかる時間がクライアントのツール呼び出し制限を超える可能性がある場合は、次のフローを使用します。
*_request_asyncでジョブを開始しますllm_job_statusで状態を確認しますllm_job_resultで出力を読み取ります- 必要に応じて
llm_job_cancelで停止します
非同期リクエストツールは、同期版と同じストラテジーフィールドを受け付けます。
claude_request_asyncはapprovalStrategy:"legacy"(デフォルト)または"mcp_managed"と、approvalPolicy:"strict"|"balanced"|"permissive"をサポートします。管理モードではstrictMcpConfig:trueが強制され、生成された MCP 設定のみを使用して Claude が起動します。- その他すべての
*_request_asyncツールがサポートする実行可能なapprovalStrategyは"legacy"のみです。周囲の MCP 設定を分離できないため、プロバイダーの起動前にmcp_managedは拒否されます。approvalPolicyは効果がありません。 mcpServersは、Claude 用に生成された設定のみを構成します。その他の CLI アダプターではメタデータとしてのみ扱われ、MCP 許可リストは作成されません。
llm_job_status
非同期ジョブのライフサイクル状態(queued、running、completed、failed、canceled、orphaned)、メタデータ、および上限付きの正規化された進捗を返します。
afterProgressSeq は、それより大きいシーケンス番号のイベントを返し、progressLimit は前方のシーケンス順で最大 64 件のイベントを選択します。nextAfterSeq を使って続きを取得します。highWaterSeq(および互換性のためのエイリアス lastSeq)は、ジョブで観測された最大シーケンス番号を示し、hasMore は保持されている次のページをすぐに取得できるかどうかを示します。進捗スナップショットには、capability(structured、activity_only、または lifecycle_only)、lastActivityAt、カーソル/高水位のメタデータ、droppedCount、およびフェーズ、種類、タイムスタンプ、安全なメッセージ、ソースを含むイベントが含まれます。Claude の stream-JSON、Codex の JSONL、Grok の streaming-JSON、Gemini の stream-JSON、Mistral の streaming、Cursor の stream-JSON は、構造化されたアクティビティを公開します。Codex の検証およびリポジトリレビューの呼び出しでは JSONL を要求しないため、activity_only が報告されます。HTTP/API ジョブでは lifecycle_only が報告され、その他のプロセス出力モードでは、プライバシーに配慮したアクティビティ/ライフサイクルのシグナルのみが公開されます。生の推論、プロバイダーが提供するツール名、ツール引数、パス、プロバイダー ID、出力テキストは、進捗メッセージにコピーされません。ツール開始時のアクティビティには、固定メッセージ Using a provider tool が使用されます。
llm_job_watch
所有する非同期ジョブの新しい正規化済み進捗を、最大 30 秒間待機します。レスポンスの nextAfterSeq を afterProgressSeq として渡してください。レスポンスは llm_job_status と同じスナップショット形式を使用します。MCP リクエストに進捗トークンが含まれている場合、ゲートウェイはこの watch 呼び出しの実行中にのみ notifications/progress を送信します。このツールは待機中に所有者へのアクセスを再確認し、他のジョブツールと同じ、自分が所有しているか見つからない場合の結果を返します。
llm_job_result
非同期ジョブで取得した stdout/stderr を返します。デフォルトでは表示用の結果を返し、maxChars によって、呼び出しごとに stdout と stderr の各ストリームを 1,000~2,000,000 文字に制限します(デフォルトは 200,000 文字です)。
大きなプロバイダーのストリームを完全かつ再開可能な形で取得するには、rawOutput:true を設定します。レスポンスの result には、それぞれ独立した stdoutOffsetChars、stdoutTotalChars、stdoutNextOffsetChars フィールドと、対応する stderr* フィールドが含まれます。両方のオフセットをゼロに設定して開始し、各ストリームの次のオフセットが null になるまで、null ではない各次のオフセットを stdoutOffsetChars または stderrOffsetChars に渡します。raw ページは表示用に解析も圧縮もされません。ローカルの stdio サーフェスでは、ページをストリーム順に連結すると、取得した stdout または stderr ストリームになります。リモート呼び出しでも同じオフセットプロトコルを使用しますが、ページを返す前に、ページ境界をまたぐ ID を含め、プロバイダーセッション ID の範囲が秘匿されます。リモートの rawOutput:true は、取得したプロバイダー出力とバイト単位で同一の出力ではなく、再開可能でサニタイズされた出力として扱ってください。
デフォルトの表示モードでは、ゼロ以外のオフセットは拒否されます。表示モードでは、ストリーミング形式のプロバイダー出力を解析したり、Codex の返信を再構成したり、テキストを圧縮したりする場合があるため、取得したストリームの一部を使って、表示結果を安全に再開または連結することはできません。アプリケーションで出力収集を再開する必要がある場合は、必ず rawOutput:true を使用してください。
Kit 以外のすべての CLI ジョブでは、起動時の正確な argv、解決済みの cwd スコープ、取得可能な場合はリポジトリの HEAD、上限付きの SHA-256 指示ファイル証跡、キャプチャ文法、およびトランスクリプトが全体としてキャプチャされたか、明記された 50 MiB の合計上限までキャプチャされたか、またはキャプチャされなかったかが記録されます。Claude、Codex、Gemini、Grok、Mistral、Cursor は、トランスクリプトを取得できる最も充実したワイヤーを使って起動します。Devin はゲートウェイが管理する ATIF エクスポートパスを使って起動し、通常のシンボリックリンクではないエクスポートはプロセス終了後に永続的なジョブ行へコピーされ、その後、元のファイルが削除されます。ローカルの stdio 呼び出しでは、ネイティブトランスクリプトを raw モードでページ単位に取得できます。リモートの HTTP/OAuth 呼び出しでは、raw ジョブ結果、ネイティブトランスクリプト、指示ファイルのパス、リプレイコンテキストを取得できません。
llm_job_cancel
実行中の非同期ジョブをキャンセルします。
approval_list
ゲートウェイによって記録された、Claude MCP 管理の最近の承認判断を一覧表示します。
パラメーター:
limit(数値、省略可):最大レコード数(1~500)。デフォルト:50cli(文字列、省略可):"claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、または"cursor"で絞り込みます
承認レコードは ~/.llm-cli-gateway/approvals.jsonl に永続化されます。
llm_request_result
相関 ID を使って、同期または非同期を問わず、永続化されたリクエストを読み出します。すべてのレスポンスは structuredContent.correlationId で ID を返します。インライン結果が消えた後、永続化されたプロンプト/レスポンスを復元するには、この ID をここに渡します。フライトレコーダーを読み取るため、非同期ジョブの永続化とは独立して動作します(フライト記録が無効な場合は「not found」を返します)。
パラメーター:
correlationId(文字列、必須):以前のリクエストの相関 IDmaxChars(数値、省略可):返される永続化レスポンスの最大文字数(1,000~2,000,000)includePrompt(ブール値、省略可):永続化されたプロンプトテキスト全体を含めます。デフォルト:falseincludeJobRecord(ブール値、省略可):ローカル stdio 呼び出しの場合、リンクされた raw プロバイダーキャプチャとリプレイコンテキストを含めます。デフォルト:false。リモート呼び出しでは、トランスクリプトもホストパスも返されません。
llm_request_list
相関 ID なしで、最近永続化されたリクエストを新しい順に一覧表示します。相関 ID がないのは、相関 ID を見つけるためです。その他のフライトレコーダーの読み取りはすべて、リクエストを行った呼び出し元にインラインで渡された ID をキーにします。そのため、呼び出しを行っていないエージェント(または、呼び出し後にコンテキストが圧縮されたエージェント)は、ここから確認を始めます。返されるのはメタデータのみです。返された correlationId を llm_request_result に渡すと本文を取得でき、返された asyncJobId を llm_job_status に渡すとジョブの状態を取得できます。呼び出し元が参照できるのは、自身のリクエストのみです。リストが空でも、何も実行されなかった証拠にはなりません。また、作業の記録が残っていないという意味でもありません。LLM 間の検証シートはここには行を書き込みませんが、validation_runs と validation_run_jobs には書き込みます。これらはそれぞれ、起動時の argv とプロバイダーの出力を保持するジョブ行にリンクしています(validation_receipt で読み取り、続けて llm_job_result で読み取ってください)。フライトレコーダーは無効化されている場合もあります。ジョブとリクエストには、どちらもデフォルトで上限がありません。オペレーターは、それぞれの上限を個別に設定できます。
パラメーター:
limit(数値、任意):最大行数。1~200、デフォルト:25since(文字列、任意):ISO-8601 形式の下限。例:2026-08-21T00:00:00Zcli(文字列、任意):記録されたプロバイダーを 1 つに限定しますsessionId(文字列、任意):ゲートウェイのセッション ID を 1 つに限定します
llm_process_health
ゲートウェイプロセスの健全性を報告します。非同期ジョブマネージャーの状態、解決済みの永続化設定、および設定されたエンジン上のフライトレコーダーの健全性を返します。backend = "postgres" の場合、レコーダーは不透明な postgresql の接続先と汎用 PostgreSQL エラーを報告し、SQLite へのフォールバックは行いません。また、以前のエンジンに残っている行は移行されていないことも警告に記載されます。明示的な LLM_GATEWAY_LOGS_DB=none によるレコーダー無効化スイッチは、意図的に一時的な memory モードおよび無効な none ジョブストアモードとは別個です。
upstream_contracts
ゲートウェイで宣言されているプロバイダー CLI のコントラクトを返します。任意で、インストール済みバイナリを調査して差分を確認できます。
パラメーター:
cli(文字列、任意):フィルター(claude|codex|gemini|grok|mistral|devin|cursor)probeInstalled(ブール値、任意、デフォルトfalse):ローカルの--help調査を実行し、提示されるフラグを宣言済みコントラクトと比較します。プロバイダー CLI をアップグレードした後は、強く推奨されます。調査結果にはmissingFlags、extraFlags、acknowledgedExtraFlags(extraFlagsから除外された、既知の上流のみのフラグ)、discoveredFlags、および古いマーカーに関するwarningsが含まれます。
セッション管理ツール
session_create
特定の CLI 用に新しいセッションを作成します。
パラメーター:
cli(文字列、必須):セッションを作成する CLI("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor")description(文字列、任意):セッションの説明setAsActive(ブール値、任意):アクティブなセッションとして設定します。デフォルト:true
例:
{
"cli": "claude",
"description": "Code review session",
"setAsActive": true
}
session_list
すべてのセッションを一覧表示します。任意で CLI による絞り込みができます。
パラメーター:
cli(文字列、任意):CLI で絞り込みます("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor")
レスポンスに含まれる内容:
- セッションの合計数
- セッションの詳細(ID、CLI、説明、タイムスタンプ、アクティブ状態)
- 各 CLI のアクティブなセッション ID
session_set_active
特定の CLI のアクティブなセッションを設定します。
パラメーター:
cli(文字列、必須):アクティブなセッションを設定する CLIsessionId(文字列、必須):アクティブにするセッション ID(または、解除する場合は null)
session_get
特定のセッションの詳細を取得します。
パラメーター:
sessionId(文字列、必須):取得するセッション ID
session_delete
特定のセッションを削除します。
パラメーター:
sessionId(文字列、必須):削除するセッション ID
session_clear_all
すべてのセッションをクリアします。任意で、特定の CLI に限定できます。
パラメーター:
cli(文字列、任意):特定の CLI のセッションのみをクリアします
ユーティリティツール
list_models
各 CLI で利用可能なモデルを一覧表示します。
パラメーター:
cli(文字列、任意):モデルを一覧表示する特定のプロバイダー("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor"、または有効化された API プロバイダー名)。1 つ以上の[providers.<name>]API プロバイダーが有効な場合、フィルターなしのレスポンスにはapiProviders配列(各エントリにproviderKind: "api"のタグ付き)も含まれます。詳細は API providers (HTTP) を参照してください。
レスポンスに含まれる内容:
- モデル名と説明
- 各モデルに最適なユースケース
- CLI 固有の情報
- デフォルトが明示的に設定されている場合の
defaultModelとdefaultModelSource - ソース/信頼度(
fallback、config、env、observed)を含むmodelMetadata - 設定されている場合、または検出が正常に縮退する場合の
aliasesとwarnings
レジストリでは、明示的な設定を優先します。同梱のフォールバックモデルは信頼度の低いヒントであり、ローカルのセッション履歴から検出された Gemini モデルは信頼度の低いエントリとしてのみ統合されます。これらがデフォルトモデルになることはありません。
モデルレジストリの環境変数による上書き:
# Explicit defaults
CLAUDE_DEFAULT_MODEL=haiku
CODEX_DEFAULT_MODEL=<codex-model-id>
GEMINI_DEFAULT_MODEL=gemini-2.5-flash
# Additional models: comma/newline list, JSON array, or JSON object of model->description
GEMINI_MODELS='{"gemini-team-default":"Team-approved Gemini model"}'
# Aliases
GEMINI_MODEL_ALIASES='team=gemini-team-default'
LLM_GATEWAY_MODEL_ALIASES='codex.fast=gpt-5.3-codex-spark,gemini.fast=gemini-team-default'
# Deterministic config/discovery paths
CODEX_CONFIG_PATH=/path/to/config.toml
CLAUDE_SETTINGS_PATH=/path/to/settings.json
CLAUDE_SETTINGS_LOCAL_PATH=/path/to/settings.local.json
GEMINI_SETTINGS_PATH=/path/to/settings.json
GEMINI_HISTORY_ROOT=/path/to/.gemini/tmp
# Disable local model-history discovery
LLM_GATEWAY_DISABLE_MODEL_DISCOVERY=1
provider_tool_capabilities
プロバイダーのツールと機能のカタログを報告します。 プロバイダー固有のリクエストを調整する前にこれを使用すると、サポートされる制御項目、プロバイダー側で管理される設定、無視される互換性フィールド、サポートされない入力を区別できます。
パラメーター:
cli(文字列、任意):プロバイダーのフィルター("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor"、"grok_api"、または有効化された API プロバイダー名)includeSkills(ブール値、デフォルトはtrue):範囲を限定したローカルスキルの検出を含めますincludeProviderTools(ブール値、デフォルトはtrue):検出されたスキルから抽出したプロバイダー標準ツールを含めますincludeUnsupported(ブール値、デフォルトはtrue):サポートされない入力や機能が低下した入力の明示的な記録を含めますincludePaths(ブール値、デフォルトはfalse):検出結果にローカルファイルシステムのパスをそのまま含めますrefresh(ブール値、デフォルトはfalse):有効期間の短い機能キャッシュをバイパスします
レスポンスのスキーマは provider-tool-capabilities.v2 です。機能の検出は読み取り専用で、対象範囲が限定されています。includePaths が明示的に true でない限り、ローカルの生パスはマスキングされ、シークレットを含む認証ファイルは読み取られません。
同等の MCP リソース:
provider-tools://catalog:すべてのプロバイダーのカタログprovider-tools://claudeprovider-tools://codexprovider-tools://geminiprovider-tools://grokprovider-tools://grok_apiprovider-tools://mistralprovider-tools://devinprovider-tools://cursor- 有効化された各
[providers.<name>]API プロバイダーに対するprovider-tools://<api-provider>
doctor --json も、同じスキーマバージョン、プロバイダーごとのリクエストツール名、サポートされる機能名、サポートされない入力名、設定項目数、検出数、リソース URI を含む、簡潔な provider_capabilities ブロックを出力します。このブロックは、ローカルスキルの本文や生パスを必要とせず、簡潔な機能の概要を必要とするセットアップアシスタント向けです。API プロバイダーが有効な場合、doctor --json は api_providers ヘルスブロックも出力します。詳細は API providers (HTTP) を参照してください。
cli_versions
インストール済み CLI のバージョンを報告します。
パラメーター:
cli(文字列、任意):確認する特定の CLI("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor")
cli_upgrade
1 つの CLI のアップグレードを計画または実行します。
パラメーター:
cli(文字列、必須):アップグレードする CLI("claude"、"codex"、"gemini"、"grok"、"mistral"、"devin"、"cursor")target(文字列、任意):パッケージのタグ/バージョン/ターゲット。デフォルトはlatestですdryRun(ブール値、任意):実行せずにアップグレード計画を返します。デフォルトはtrueですtimeoutMs(数値、任意):dryRun=falseの場合のアップグレードのタイムアウト
アップグレード戦略:
- Claude の最新バージョン:
claude update - Claude の明示的なターゲット:
claude install <target> - Codex の最新バージョン:
codex update - Codex の明示的なターゲット:
npm install -g @openai/codex@<target> - Gemini の最新バージョン:
agy update(Antigravity のセルフアップデート。明示的なバージョンターゲットには対応していません) - Grok の最新バージョン:
grok update - Grok の明示的なターゲット:
grok update --version <target> - Mistral(Vibe):検出されたインストーラー(
pip/uv/brew)に処理を振り分けます。いずれも検出されない場合は、案内を表示してエラーになります(Vibe にはセルフアップデートコマンドがありません) - Devin の最新バージョン:
devin update(セルフアップデート。明示的なバージョンターゲットには対応していません) - Cursor の最新バージョン:
cursor-agent update(セルフアップデート。明示的なバージョンターゲットには対応していません)
ドライランの例:
{
"cli": "gemini",
"target": "latest",
"dryRun": true
}
API プロバイダー(HTTP)
起動可能な CLI ツールに加え、ゲートウェイはファーストクラスの HTTP/API プロバイダー(OpenRouter およびその他の OpenAI 互換エンドポイント、Anthropic Messages API、xAI Responses API)にもリクエストをルーティングできます。これらは CLI を起動するのではなく、Node の組み込み HTTP クライアント(node:https、またはループバックエンドポイントの場合は node:http)を使用します。また、CLI ツールと同じリクエスト/ジョブ/検証/フライトレコーダーの処理経路を通るため、セッション、非同期ジョブ、重複排除、再試行、使用量/コストの記録、LLM 間の検証において同等の機能を備えています。
プロバイダーの設定
API プロバイダーは ~/.llm-cli-gateway/config.toml 内の [providers.<name>] ブロックとして宣言します(LLM_GATEWAY_CONFIG で上書きできます)。<name> はすべてのツールとリソースでプロバイダーの識別子となるため、起動可能な CLI 名(claude、codex、gemini、grok、mistral、devin、cursor)と重複してはなりません。重複がある場合は警告が表示され、プロバイダーは無効になります。
# OpenRouter (OpenAI-compatible). The key is read from the named env var at
# request time and is never written to config, logs, the flight recorder, or
# the dedup key.
[providers.openrouter]
kind = "openai-compatible" # "openai-compatible" | "anthropic" | "xai-responses"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY" # env var NAME, not the key itself
default_model = "x-ai/grok-2"
models = ["x-ai/grok-2", "anthropic/claude-sonnet-4.6"] # optional allowlist: an explicit model must be listed (omit model to use default_model)
usage_include = true # OpenRouter token/cost reporting (usage:{include:true})
# Keyless-local: an openai-compatible provider on a loopback base_url (Ollama,
# llama.cpp) is enabled with no api_key_env at all.
[providers.ollama]
kind = "openai-compatible"
base_url = "http://127.0.0.1:11434/v1"
default_model = "qwen2.5"
プロバイダーは、api_key_env が空でない値を取得できる場合、またはループバックの base_url を使用するキー不要のローカル openai-compatible プロバイダーである場合に 有効 になります。base_url には、localhost/ループバックを対象とする場合を除き、https を使用する必要があります。単一の [providers.<name>] ブロックのスキーマが無効な場合、そのブロックのみが無効になり(警告が表示されます)、他のプロバイダーには影響しません。ファイル内のどこかに TOML の 構文 エラーがある場合は異なり、設定全体がデフォルトにフォールバックします。
既存の [providers.xai] ブロックは、専用の grok_api_request ツールと xAI の識別情報を維持します。また、有効な他のプロバイダーと同様に汎用インターフェースからも利用できるため、xAI キーを設定すると grok_api_request と汎用の api_xai_request の 両方 が登録されます(さらに、apiProviders、models://xai などにも xai の項目が表示されます)。
リクエストツール
有効なプロバイダーごとに、ゲートウェイは api_<name>_request(非同期ジョブが有効な場合は api_<name>_request_async も)を登録します。これらは、CLI のリクエストツールと同じ形式を受け付けます。
prompt(またはキャッシュ対応のpromptParts{ system?, tools?, context?, task }。両方を同時に指定することはできません)、任意のsystemmodel(省略するとdefault_modelが使用されます。明示的に指定した値が、設定済みのmodels許可リストに含まれていない場合は拒否されます)、maxOutputTokens、temperature、topPreasoningEffort(none|low|medium|high):xai-responsesアダプターのみが転送します。他の種類では受け付けますが無視しますtimeoutMs、optimizePrompt、optimizeResponse、forceRefresh、correlationId- 同期版の
api_<name>_requestで継続性を保つためのsessionId/createNewSession(下記を参照)。非同期版では現在、これらは機能しません
応答(および 50 MB の出力上限、重複排除ウィンドウ、キャンセル、保持)は CLI ツールとまったく同じように動作します。HTTP リクエストは、他のすべてと同様に、ステータス、使用量、コストとともにフライトレコーダーに記録されます。
継続性
継続性はプロバイダーの種類ごとに機能が異なり、セッションレコードに会話内容を保存することはありません(ゲートウェイでは「セッションに会話履歴を保存しない」という不変条件が維持されます)。
xai-responsesはサーバー側の継続機能を実際に使用します。ゲートウェイはプロバイダーのprevious_response_idをセッションメタデータに保存し、再開時に渡します。また、古くなったハンドルに対する 404 を自動的に復旧します。openai-compatibleとanthropicはステートレス再送方式です。セッションではプリンシパルの分離のためにアクティブ状態と所有者状態を追跡しますが、呼び出し元が以前のコンテキストを再送します(サーバー側の会話ハンドルはありません)。
検出用インターフェイス
有効な API プロバイダーは、CLI プロバイダーとともに、各種検出用インターフェイスに表示されます。以下のモデル、機能、診断、リソースの各インターフェイスでは、API プロバイダーが有効でない場合、API フィールド自体が省略されるため、出力は変更前とバイト単位で同一になります。例外は llm_process_health で、常に apiProviders 配列を含み、何も有効でない場合は空の配列になります。
list_models/list_available_models:providerKind: "api"のタグ、defaultModel、および任意の許可リストを含むapiProviders配列。API プロバイダーが有効でない場合は全体が省略されます。llm_process_health:常に存在するoutboundProviders.apiProviders配列(何も有効でない場合は空)には、同じ情報に加えて各プロバイダーのサーキットブレーカー状態が含まれます。provider_tool_capabilities:api種類ごとの機能メタデータ。モデル、サンプリング、(xai-responsesの場合は)推論、継続性に対応しています。ツールの許可/拒否リスト、MCP サーバー、ローカルスキル、ワークスペース/ワークツリーの制御には対応していません(これらは CLI 専用です)。doctor --json:api_providersのヘルス情報ブロック(種類、base_url、default_model、モデル、キーの環境変数名、キーの設定有無、ログイン方法の案内)。API プロバイダーが有効でない場合は全体が省略されます。任意のフラグdoctor --json --probe-api-providersを指定すると、プロバイダーごとのエンドポイント到達可能性の結果が追加されます(単純なGETを実行し、HTTP 応答があれば到達可能と判定します)。このプローブはオプトインで、デフォルトでは無効です。通常のdoctor実行ではソケットを開かず、トークンも消費しません(reachableはnullのままです)。- MCP リソース:有効なプロバイダーごとの
models://<provider>と、継続性を追跡する種類のプロバイダーごとのsessions://<provider>、およびprovider-tools://<provider>。provider-subcommands://リソースは CLI 専用のままです(API プロバイダーにはサブコマンドがありません)。
API キーの値は、これらのインターフェイスには一切出力されません(環境変数名と、設定されているかどうかを示すブール値のみ)。base_url は設定で指定され、URL のユーザー情報を含むことが合法なため、診断用インターフェイス(doctor、ログイン方法の案内)では、表示前に埋め込まれた認証情報をマスキングします。実際のリクエストパスと到達可能性プローブでは、設定された元の URL が引き続き使用されます。
セキュリティに関する注意
解決済みの API キーは、payloadJson、重複排除キー、ログ、フライトレコーダーには含まれません。通常の Kit 非同期ジョブでは、リクエストのプロンプトは平文で非同期ジョブストア([persistence].path に指定された SQLite、デフォルトは ~/.llm-cli-gateway/logs.db、または backend = "postgres" の場合は Postgres の行)に保存され、シークレットのマスキング対象にはなりません。これは、標準入力からストリーム送信されるのではなく、コマンド引数として渡された場合に、プロンプトが argsJson に保存される CLI ツールと同じ動作です。review_changes では、意図的に完全な CLI プロンプトを有効期限付きの payloadJson に保持し、argsJson にはハッシュマーカーのみを保存します。また、そのプロンプトをフライトレコーダーにコピーしません。Personal Agent Config Kit の永続行は、別個のプライバシー境界を設けています。コンパイル済みの指示やリクエスト引数は永続化せず、Kit が必要とする復旧状態と整合性状態のみを保持し、プロバイダーの出力やエラーは保存しません。ジョブストアは保存時点で機密情報として扱ってください。セキュリティに関する考慮事項とPersonal Agent Config Kit ガイドを参照してください。
セッション管理
仕組み
- 会話履歴ではなく、ゲートウェイのメタデータ:セッションレコードには、所有者、タイムスタンプ、アクティブポインター、プロバイダーのメタデータが記録されます。会話履歴は保存されません。
- ストレージバックエンド:セッションマネージャーは、
config.tomlの[persistence].backendに従います。sqlite/noneでは~/.llm-cli-gateway/sessions.jsonが使用され、postgresでは PostgreSQL セッションマネージャーが選択されます。DATABASE_URLによる上書きは互換性のために保持されていますが、非推奨(DEPRECATED)です。この設定は一度だけ警告され、明示的に指定された[persistence].dsnと一致しない場合は完全に拒否されます。PostgreSQL セッションストアには TTL による削除機能がありません。一方、ファイルストアでは 30 日後に古いデータが削除されます。3.1.0 のノートを参照してください。 - プロバイダー固有の継続動作:ゲートウェイのセッション ID は追跡用メタデータであり、自動的にプロバイダー固有の再開 ID になるわけではありません。ネイティブの動作はプロバイダーによって異なります。
claude_requestでcontinueSession:trueを指定すると、選択された作業ディレクトリを固定して Claude の最新の会話を使用します。workingDirがない場合、または呼び出し元が所有するセッションメタデータを介して明示的に選択された登録済みワークスペース、あるいは設定済みのデフォルトがない場合は、安全側に倒して失敗します。このワークスペースでは、オプションでゲートウェイの worktree を指定できます。codex_requestでは、sessionIdに実際の Codex UUID を指定するか、以前のセッションを再開するresumeLatest:trueが必要です。--lastがどのセッションを選択するかや、再開後の作業ディレクトリには依存しないでください(確認中)。 - 呼び出し元の分離:HTTP/OAuth の呼び出し元が取得または再利用できるのは、自身が所有するセッションのみです。呼び出し元向けのセッション表示では、ローカルパスとプロバイダー固有の識別子が非表示になります。
- Personal Kit:Personal Agent Config Kit が有効な場合、Claude、Codex、Mistral は、コンテキストに紐付いた専用のアクティブセッションポインターを使用し、ネイティブの継続ハンドルは現在のゲートウェイプロセス内にのみ保持します。Personal Agent Config Kit ガイドを参照してください。
セッションのワークフロー
// 1. Create a gateway tracking record when you need one.
// This ID is not automatically a native provider resume ID.
await callTool("session_create", {
cli: "claude",
description: "Debugging session",
setAsActive: true,
});
// 2. Use the provider's documented native continuity control.
await callTool("claude_request", {
prompt: "What's the bug in this code?",
continueSession: true, // Claude's latest conversation in this working directory
});
await callTool("codex_request", {
prompt: "Review the proposed fix.",
resumeLatest: true, // or pass a real Codex UUID as sessionId
});
// 3. Inspect or remove gateway tracking records.
await callTool("session_list", { cli: "claude" });
await callTool("session_delete", {
sessionId: "session-id-to-delete",
});
session_delete は、呼び出し元から見えるセッションの各場所からゲートウェイの追跡情報を削除します。どちらのセッションマネージャーを使用している場合も、削除を処理するホスト上で、管理対象のワークツリーなど、関連するゲートウェイ所有のライフサイクルリソースのベストエフォート方式のクリーンアップも呼び出します。永続的に所有されるワークツリーセッションは、Git での削除が確認されるまで、非表示のクリーンアップ待ちトゥームストーンとして残ります。削除に失敗した場合、所有ホストでマネージャーが登録されたときに再試行されます。プロバイダー自身が保存した会話は削除しません。
クリーンアップは、どちらのエンジンを使用する場合も所有ホストで行われます。別のホストで削除が処理された場合、ワークツリーは削除されず、追跡情報を破棄する代わりに、所有ホストのレコードがそのまま残ります。session_clear_all もセッションごとに同じ動作をします。データベース側の cleanup_expired_sessions 関数は、ワークツリーを含むセッションを削除する代わりに、同じトゥームストーンを作成します。この関数はゲートウェイのオブザーバーを呼び出さないため、それ自体では削除を試みません。トゥームストーンはクリーンアップが成功するまで保持され、保持期間の制限を受けません。
設定
環境変数
-
DEBUG:デバッグログを有効にします(任意の値を設定します)DEBUG=1 node dist/index.js -
LLM_GATEWAY_APPROVAL_POLICY:Claude のmcp_managedリクエストでapprovalPolicyが渡されなかった場合に適用するデフォルトの承認ポリシー(strict、balanced、permissive)です。起動前にmcp_managedを拒否するため、Claude 以外のアダプターには影響しません。LLM_GATEWAY_APPROVAL_POLICY=strict node dist/index.js -
LLM_GATEWAY_APPROVAL_ALLOW_BYPASS:Claude のapprovalStrategy:"mcp_managed"にのみ適用されます。bypassPermissionsの直接リクエスト、または設定、指示のオーバーライド、プラグイン、追加ディレクトリ、ワークツリー、ネイティブの継続など、検証されていない実行状態は、承認スコアにかかわらずデフォルトで拒否されます。通常の Claude の管理対象リクエストでは--permission-mode acceptEditsが使用されます。明示的な呼び出し元のリクエストを Claude の通常の承認判断に委ねる場合に限り、これを
1/trueに設定します。この環境設定だけで通常の Claude の管理対象リクエストの権限が昇格することはありません。この設定で Codex、Gemini、Grok、Mistral、Devin、Cursor のmcp_managedが有効になることはありません。これらのアダプターはプロバイダーの起動前にmcp_managedを拒否します。LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1 node dist/index.js -
LLM_GATEWAY_TRUSTED_PRINCIPAL_HEADER:信頼できるフロントドア(ID を認識するリバースプロキシ/IdP)によって認証済みユーザーの ID が設定される HTTP ヘッダーの名前です。この値を設定すると、ゲートウェイは、そのヘッダーの値をリクエストの所有者プリンシパルとして採用します。ただし、対象となるのはゲートウェイ独自の静的ベアラートークンで認証されたリクエスト(つまり、信頼できる上流プロキシ)だけであり、任意のリモートクライアントからのリクエストは対象外です。デフォルトでは無効で、特定の IdP に依存しません。プロキシ経由のマルチユーザー構成で、ユーザーごとの ID をゲートウェイに引き継げます。LLM_GATEWAY_TRUSTED_PRINCIPAL_HEADER=x-gateway-principal node dist/index.js -
LLM_GATEWAY_OAUTH_REQUIRE_CONSENT/LLM_GATEWAY_OAUTH_CONSENT_SECRET:組み込み OAuth サーバーで、人間による同意の確認をオプトインで有効にします。有効にすると(REQUIRE_CONSENT=1、またはCONSENT_SECRETの設定によって有効になる場合)、/oauth/authorizeにオペレーターの承認ページ(CSRF 対策済み)が表示され、専用の同意パスワードを入力した後にのみ認可コードが発行されます。自動発行は行われません。CONSENT_SECRETはプレーンテキストのパスワードです(メモリー内でハッシュ化されます。または[http.oauth]にconsent_secret_hashを保存できます)。デフォルトでは無効です。リモート OAuth では、検証用のシークレットなしに同意確認を有効にすることはできません。LLM_GATEWAY_OAUTH_REQUIRE_CONSENT=1 LLM_GATEWAY_OAUTH_CONSENT_SECRET='choose-a-strong-code' node dist/index.js -
LLM_GATEWAY_CONFIG:ゲートウェイの TOML 設定ファイルのパス(デフォルト:~/.llm-cli-gateway/config.toml)です。[persistence]のスキーマについては、上記の永続化の設定を参照してください。 -
LLM_GATEWAY_SKILLS_PATH:起動時に読み込む追加のローカルスキルパックのルートパスです。ホストのパス区切り文字(Linux/macOS では:、Windows では;)で区切ります。これらのパスは[skills].pathsの後に追加されます。~/.llm-cli-gateway/skillsが存在する場合は、引き続き最後に読み込まれます。 -
LLM_GATEWAY_LOGS_DB:非推奨です。バックエンドが明示的に設定されていない場合、このパスを使ってbackend = "sqlite"を選択します(値がnoneの場合はbackend = "none"を選択します)。ジョブの永続化では、明示的に指定されたバックエンドが優先されます。この変数は、すべてのバックエンドでレコーダーを独立して無効にし、SQLite が選択されている場合はそのパスも指定します。起動時に非推奨の警告が表示されます。config.tomlに移行してください。# Custom path LLM_GATEWAY_LOGS_DB=/var/log/gateway/logs.db node dist/index.js # Disable the recorder; with no explicit backend, also disable async persistence LLM_GATEWAY_LOGS_DB=none node dist/index.js -
LLM_GATEWAY_REDACT_LOGGED_SECRETS:フライトレコーダーログに書き込まれるプロンプト、システムメッセージ、レスポンスのコピーから、認識可能なシークレット(プロバイダー/クラウド/VCS キー、ベアラートークン、JWT、PEM 秘密鍵、key=value形式のシークレット代入)を秘匿します。デフォルトで有効です。内容をそのまま保存するには、0/false/off/noを設定してください。影響を受けるのは監査ログのみです。ライブ同期レスポンスと非同期のllm_job_result出力は変更されません。# Opt out of flight-recorder secret redaction LLM_GATEWAY_REDACT_LOGGED_SECRETS=0 node dist/index.js
CLI 固有の設定
各 CLI は、それぞれの設定ファイルで設定できます。
- Claude Code:
~/.claude/settings.json - Codex:
~/.codex/config.toml - Gemini/Antigravity(
agy):~/.gemini/settings.json
開発
プロジェクト構成
llm-cli-gateway/
├── src/
│ ├── index.ts # Main MCP server and tool definitions
│ ├── executor.ts # CLI execution with timeout support
│ ├── session-manager.ts # Session management logic
│ └── __tests__/
│ ├── executor.test.ts # Unit tests for executor
│ └── integration.test.ts # Integration tests
├── dist/ # Compiled JavaScript
├── package.json
├── tsconfig.json
└── vitest.config.ts
テストの実行
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Watch mode
npm run test:watch
ビルド
npm run build
サーバーの起動
npm start
エラー処理
ゲートウェイは、よくある問題について詳細なエラーメッセージを表示します。
CLI が見つからない
Error executing claude CLI:
spawn claude ENOENT
The 'claude' command was not found. Please ensure claude CLI is installed and in your PATH.
外部タイムアウト/レガシーなタイムアウトオプション
Error executing codex CLI: Command timed out
Process timed out after 120000ms
無効なパラメーター
Prompt cannot be empty
Prompt too long (max 100k chars)
ログ
ログは標準エラー出力に書き込まれます(標準出力は MCP プロトコル用に予約されています)。
[INFO] 2026-01-24T05:00:00.000Z - Starting llm-cli-gateway MCP server
[INFO] 2026-01-24T05:00:01.000Z - claude_request invoked with model=sonnet, prompt length=150
[INFO] 2026-01-24T05:00:05.000Z - claude_request completed successfully in 4523ms, response length=2048
[ERROR] 2026-01-24T05:00:10.000Z - codex CLI execution failed: spawn codex ENOENT
デバッグログを有効にします。
DEBUG=1 node dist/index.js
トラブルシューティング
CLI が見つからない
CLI がインストールされ、PATH に含まれていることを確認してください。
which claude
which codex
which agy
ゲートウェイは PATH を拡張して、以下の一般的な場所を追加します。
~/.local/bin/usr/local/bin/usr/bin- すべての
~/.nvm/versions/node/*/binディレクトリ
権限エラー
権限エラーが発生した場合は、CLI ツールに適切な権限が設定されていることを確認してください。
chmod +x $(which claude)
chmod +x $(which codex)
chmod +x $(which agy)
セッションストレージの問題
これらのファイル確認は、デフォルトのファイルセッションマネージャーにのみ適用されます。[persistence].backend = "postgres" によって PostgreSQL セッションストレージが選択されている場合、sessions.json は正確な状態を示すものではありません。ゲートウェイプロセス、プロバイダーの子プロセス、または Personal Agent Config Kit の試行が実行中の間は、セッションストレージを削除または編集しないでください。
- ローカルのゲートウェイプロセスを停止してから、ファイルのアクセス権を確認します。
ls -la ~/.llm-cli-gateway/
-
ゲートウェイの記録を意図的にクリーンアップするには、
session_deleteまたはsession_clear_allを使用してください。通常の復旧方法としてファイルを手動で編集しないでください。 -
ファイルベースのストアを読み取れない場合は、ゲートウェイを停止してからコピーを調べてください。
cat ~/.llm-cli-gateway/sessions.json
Personal Agent Config Kit の試行が停止している場合は、sessions.json をリセットしないでください。Personal Agent Config Kit ガイドに記載されているローカル環境のみでの復旧手順に従ってください。
パフォーマンス
タイムアウト
ゲートウェイは、LLM CLI リクエストにデフォルトの実行タイムアウトを設定しません。
MCP クライアント/ランタイムがツール呼び出しごとの期限を適用する場合は、非同期ツール(*_request_async と llm_job_status/llm_job_result)を使用すると、長時間実行されるジョブを単一の呼び出し時間枠の外で完了できます。
同時リクエスト
ゲートウェイは、異なる CLI 間での同時リクエストをサポートしています。各リクエストは個別のプロセスを起動します。
セキュリティに関する考慮事項
- 入力の検証:すべてのプロンプトを検証します(最小1文字、最大100k文字)。
- API プロバイダーのキー:
[providers.<name>]の HTTP プロバイダーでは、ゲートウェイはリクエスト時に限り、指定された環境変数からキーを読み取ります。解決されたキーは、永続化されるpayloadJson、重複排除キー、ログ、フライトレコーダーには含まれず、検出/診断の各サーフェスにも表示されません(報告されるのは環境変数名と、設定されているかどうかを示すブール値のみです)。診断サーフェスではbase_urlのユーザー情報がマスキングされます。API プロバイダー(HTTP)を参照してください。 - プロンプトの保存時の扱い:通常の Kit 以外の非同期ジョブ行には、リクエストのプロンプトが平文で保存されます(HTTP の
payloadJsonと、プロンプトを stdin 経由でストリームせずコマンド引数として渡す場合の CLI のargsJson)。これはシークレットのマスキング対象外です。review_changesでは CLI の保存形式が異なることが明示されており、完全なフェンス付きプロンプトは有効期限付きのpayloadJsonに保持され、永続化される argv にはハッシュマーカーのみが含まれ、プロンプトはフライトレコーダーにコピーされません。Personal Agent Config Kit の永続行には、コンパイル済みの指示やリクエスト引数は保存されず、プロバイダーの出力とエラーも保持されません。保持されるのは、プライバシーに配慮した復旧用および整合性確認用の状態のみです。SQLite のジョブストアファイル(デフォルトは~/.llm-cli-gateway/logs.db、[persistence].pathで設定可能)は、Windows 以外のホストではchmodにより0o600に設定されます。Postgres バックエンドでは、対応するフィールドがデータベース行に保存されます。どちらのバックエンドも機密情報として扱い、プロンプトログと同様にアクセス範囲を限定し、定期的にローテーションしてください。[persistence].backend = "none"を設定すると、非同期ジョブストア全体が無効になります(その場合、*_request_async/llm_job_*ツールは登録されません)。永続レコードの対象範囲がより限定されている点については、Personal Agent Config Kit ガイドを参照してください。 - コマンド実行:シェル経由で実行せず、引数を分けて
spawnを使用します。 - Eval の不使用:ソース内で動的コード評価は行いません(依存関係を介した
ajvのコード生成については、以下の「Socket アラート」を参照してください)。 - サンドボックス化:本番環境ではコンテナーでの実行を検討してください。
- npm 公開の管理:npm リリースは、生成された本番環境専用の shrinkwrap、リリースセキュリティ監査、パッケージ利用者向けチェック、および短期間有効な OIDC 由来の npm 公開認証情報を使用する GitHub Actions Trusted Publishing によって制限されています。
- リリースの署名:GitHub リリースのインストーラー成果物には、Sigstore のキーレス署名を付与しています。チェックサムファイルを信頼する前に、
SHA256SUMS.sigstore.jsonを検証してください。
Socket アラート — レビュアー向けの背景情報
Socket や同様のサプライチェーンスキャナーを使って llm-cli-gateway を審査すると、動作に関するアラートと、依存関係の所有者に関するアラートがいくつか表示されます。これらは、パッケージの動作と依存関係を正確に説明したものです。審査済みの shellAccess と shrinkwrap の項目は、リポジトリ/PR のポリシー向けに socket.yml で設定されていますが、Socket の公開パッケージページでは、公開済み npm 成果物に対して引き続き表示される場合があります。その理由は、引き続きここおよびパッケージ内に記載されています。
現在フラグが付けられているサーフェスは、2.6.x で新たに加わったものではありません。2.3.0、2.4.0、2.5.0、2.6.3 の npm tarball にはすべて npm-shrinkwrap.json が含まれており、プロバイダーの CLI を実行するために使用する、同一の dist/executor.js の子プロセス起動サーフェスも含まれています。2.4.0、2.5.0、2.6.0、2.6.3 の socket.yml ポリシーでは、shellAccess の設定に実質的な違いはありません。この README では今回、これまで記載されていなかった shrinkwrap についても開示しています。
| アラート | 該当箇所 | リスクが限定されている理由 |
|---|---|---|
| ネットワークアクセス | src/http-transport.ts は、npm run start:http で起動すると HTTP MCP トランスポートを開きます。src/endpoint-exposure.ts は、設定済みのパブリック URL/トンネル URL を検証するために HEAD プローブを実行します。Socket は v1.17.2 で、ネットワーク呼び出しではなく説明文を理由に dist/upstream-contracts.js にもフラグを付けました。 | トランスポートはデフォルトで 127.0.0.1 にバインドされ、LLM_GATEWAY_AUTH_TOKEN の設定が必要です。デフォルトの stdio MCP エントリーポイント(npm start)はソケットを開きません。src/upstream-contracts.ts はプロバイダーの CLI メタデータを保存しており、HTTP クライアント API はインポートしません。 |
| シェルアクセス | src/executor.ts は child_process.spawn(cmd, args, …) を使用して、基盤となる LLM CLI を呼び出します。 | spawn は引数配列を使って呼び出され、shell: true は決して指定されないため、呼び出し元の入力がシェル展開される経路はありません。コマンド名も呼び出し元の入力から取得されることはありません。CLI_TYPES のメンバーについてはプロバイダーレジストリを介して providerCommandName(cli) から取得するか、src/cli-updater.ts でゲートウェイが計算したアップグレードプラン(npm/pip/uv/brew)から取得します。MCP ツールでバイナリ名を受け取るものはありません。ただし、これはすべての呼び出し箇所における特性であり、command を文字列として受け取り、フィルタリングしない src/executor.ts 内のメンバーシップチェックによるものではありません。 |
| 公開 shrinkwrap | npm アーティファクトには npm-shrinkwrap.json が含まれます。package.json#files にも含まれており、scripts/make-prod-shrinkwrap.mjs が package-lock.json から生成します。 | これは CLI/アプリケーションパッケージです。npm は、レジストリ経由で公開するアプリケーション、デーモン、コマンドラインツール向けに shrinkwrap の用途を説明しています。この shrinkwrap は本番用のみを抽出したもので、コミット済みの開発用ロックファイル全体ではありません。scripts/release-security-audit.sh は監査済みのロックファイルとの整合性を検証し、scripts/verify-registry-install.sh はレジストリを新たに利用するユーザーの本番依存関係に better-sqlite3/prebuild-install/tar-fs/tar-stream のチェーンが含まれないことを証明します。 |
| eval の使用 | ソースコード内にはありません。推移的な依存関係では、@modelcontextprotocol/sdk → ajv@8 が ajv/dist/compile/index.js 内の new Function(...) を使って JSON Schema バリデーターをコンパイルします。 | これは ajv の標準的なコード生成経路です。既知のスキーマ(ソースコードおよび MCP SDK で定義されたもの)のみがこの処理に渡され、呼び出し元が提供したデータがコンパイル済み関数本体に渡されることはありません。 |
| SQLite アダプターによる隔離 | SQLite バックエンドは、単一のアダプター src/sqlite-driver.ts を介して、Node 組み込みの node:sqlite モジュールを使用します(ネイティブバインディングもインストールスクリプトもありません)。 | node:sqlite を使用する本番モジュールはアダプターの 1 つだけで、それ以外のすべてのモジュールは型付けされたインターフェースを通じて SQLite にアクセスします。db.pragma() ヘルパー(node:sqlite には存在しません)は呼び出していません。SQLite のセットアップには固定リテラルの db.exec("PRAGMA ...") ステートメントを使用します。npm run security:audit は、本番コードがアダプター以外で node:sqlite を参照するか、.pragma() 呼び出しが再導入された場合、リリースを失敗させます。 |
| 依存関係の所有元 | 少数の小規模な推移的パッケージ(例:@modelcontextprotocol/sdk 経由の media-typer)が、Socket の「所有元が不安定」または「難読化されたコード」というヒューリスティックに該当します。 | これらは Node エコシステムで広く知られた、既知の問題がないバージョン固定済みの小規模な依存パッケージです。package.json#overrides で content-type と type-is の直接的な上書きバージョンを固定しています。2.0.0 以降、本番依存関係グラフにはネイティブモジュールが含まれません(better-sqlite3 は devDependencies に移動し、node:sqlite は Node に組み込まれています)。これにより、prebuild-install/tar-fs/tar-stream のインストール時依存チェーン全体がなくなりました。以前は直接依存していた [email protected] は smol-toml に置き換えました。 |
機械可読形式で同じコンテキストを確認するには、socket.ymlをご覧ください。 |
貢献
- リポジトリをフォークします
- フィーチャーブランチを作成します
- 変更を加えます
- テストを実行します:
npm test - ビルドします:
npm run build - プルリクエストを送信します
ライセンス
MITです。詳細はLICENSEをご覧ください。
サポート
問題や質問がある場合:
- GitHubでissueを作成します
- 既存のissueとドキュメントを確認します
- CLI関連の問題については、CLI固有のドキュメントを確認します
変更履歴
詳細なリリース履歴はCHANGELOG.mdをご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。