ratchet について
ratchetは、AIエージェントが取り消せない操作を行う前に永続的な判断を記録し、重複試行を抑えるエフェクトゲートです。操作自体は実行せず、重複、実行中、承認待ち、不確定な結果を明示して再試行を管理します。
主な機能
- 01操作前に実行許可を要求
- 02冪等キーによる重複抑止
- 03実行中・不確定状態の記録
- 04操作記録の参照と解決
- 05ポリシーによる予算と試行の制限
- 06RESTおよびMCPインターフェース
活用シーン
- 01再試行によるメールの重複送信を防止
- 02決済操作の重複実行リスクを低減
- 03デプロイや公開前に承認を要求
- 04結果が不確定な場合に確認を要求
MCP 対応
ratchetはStreamable HTTPとstdioでMCPサーバーを提供し、操作の開始、報告、参照、解決、一覧、ポリシーと使用量の確認ツールを公開します。外部操作は実行せず、判断を記録します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://ratchetgate.com/mcpclaude mcp add --transport http com-ratchetgate-ratchet https://ratchetgate.com/mcp{"mcpServers":{"com-ratchetgate-ratchet":{"type":"http","url":"https://ratchetgate.com/mcp"}}}Cursor で開く{"servers":{"com-ratchetgate-ratchet":{"type":"http","url":"https://ratchetgate.com/mcp"}}}VS Code で開く{"mcpServers":{"com-ratchetgate-ratchet":{"type":"http","url":"https://ratchetgate.com/mcp"}}}{"mcpServers":{"com-ratchetgate-ratchet":{"serverUrl":"https://ratchetgate.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
15このツールにパラメーターはありません。
詳細
AI エージェント向けのエフェクトゲートです。 エージェントは、取り消せない操作を行う前に確認を求めます。 カードへの請求、デプロイの実行、パッケージの公開、メールの送信などです。そして永続的な判断記録を取得し、 クラッシュや再試行があっても、同じ現実世界のアクションが試行されるのは最大 1 回です。エージェントは、 実行中にすでに行った操作を読み返したり、上限を引き上げられない制限の範囲内で処理したりすることもできます。
エージェントは再試行します。LLM の制御フローは非決定的で、ネットワーク呼び出しは結果が曖昧なまま失敗し、 プロセスは操作の途中で停止します。その結果、メールの重複送信、二重請求、書き込みの繰り返しが発生しますが、 スタック内のどこにも、それがどれなのかを把握する仕組みはありません。ベンダーの冪等性キーは、対応する一部の ベンダーでは役立ちますが、別々のエージェントプロセスやモデルプロバイダーをまたいで機能することはありません。
Ratchet はアクションを実行しません。アクションの前に、永続的な判断記録を保持します。
POST /v1/effects/begin → decision: execute | duplicate | in_flight
| blocked | approval_required | denied
呼び出し元に操作の実行を許可するのは、execute だけです。
プロジェクトのドキュメント
| アーキテクチャ | 高レベルの設計 — ゲートとは何か、そして意図的に何をしないのか |
| 保証ケース | 脅威モデル、信頼境界、各セキュリティ要件の根拠 — 防御対象ではないものも含みます |
| ロードマップ | 今後 1 年の予定と、決して構築しないもの |
| ガバナンス | 誰が意思決定するのか、そしてその人たちが活動を停止した場合に何が起きるのか |
| コントリビューション | バグの報告や変更の提案方法 |
| セキュリティポリシー | 脆弱性の報告方法と、どれくらいの速さで返答があるか |
| 行動規範 | 求められる行動と、連絡先 |
| 既知の制限事項 | まだ実現できていないことを、すべて率直に記載しています |
重要な点
「実行」と「完了」の間にプロセスが停止した場合、ほとんどのシステムは次の呼び出し元に何事もなかったかのように再試行させます。
Ratchet はそうしません。リースが期限切れになると、エフェクトは**indeterminate**になります — 既知の未知として、
埋もれずに表面化します。その後の処理は、そのエフェクトタイプに対して宣言したポリシーに従います。
on_indeterminate | 動作 | 用途 |
|---|---|---|
block(デフォルト) | 自動再試行は行いません。人間または検証エージェントが解決します。 | 取り消し不能な操作全般 |
retry | max_attempts まで、新しい試行が許可されます。 | 真に冪等なベンダー |
probe | 呼び出し元はベンダー側で確認し、証拠を記録してから進める必要があります。 | 請求、送金、支払い |
分散システムで厳密に 1 回だけ配信することは実現できず、このプロジェクトもそれを主張しません。 Ratchet が保証するのは、開始が最大 1 回であること、後続の呼び出し元が再利用する記録済みの結果、 そして、他の誰も認めようとしない状況に対する明示的な状態です。
クイックスタート
必要条件:Node 20.11 以降、Docker(ローカルの Postgres 用)。
npm install
cp .env.example .env # defaults work for local development
npm run dev:db # Postgres on :5433 via Docker
npm run migrate
npm run dev # control plane on :8787
npm run dev:worker # lease reaper + webhook delivery (separate terminal)
その後、http://localhost:8787 を開くか、シェルから操作します。
bash examples/curl/walkthrough.sh
npm run seed を実行すると、完了済みのエフェクト、重複したエフェクト、結果が不確定なエフェクト、承認待ちのエフェクトを含む、現実的な状態のワークスペースが作成されます。コンソールに表示するデータを用意できます。
または Docker Compose を使用する場合
AUTH_SECRET=$(openssl rand -base64 32) docker compose up --build
基本のループ
# 1. Ask, before you act.
curl -X POST http://localhost:8787/v1/effects/begin \
-H "Authorization: Bearer $RATCHET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"effect_type": "email.send",
"idempotency_key": "welcome:user_123",
"payload": { "to": "[email protected]" },
"estimated_cost_micros": 800
}'
# → { "decision": "execute", "effect_id": "eff_...", "lease_token": "lt_..." }
# 2. Do the real thing, yourself. Ratchet never touches it.
# 3. Say what happened.
curl -X POST http://localhost:8787/v1/effects/eff_.../report \
-H "Authorization: Bearer $RATCHET_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "lease_token": "lt_...", "outcome": "succeeded",
"result": { "message_id": "msg_9f2" } }'
# Any later caller with the same key now gets:
# → { "decision": "duplicate", "result": { "message_id": "msg_9f2" } }
ルールは 1 つです。 アクションが外部に到達しなかったと確信できる場合に限り、failed と報告してください。確信がない場合(タイムアウトや接続切断など)は、何も報告しないでください。リースが期限切れになり、Ratchet は正直に indeterminate を記録します。誤った failed は、重複を許すことになるため、何も報告しないよりも問題です。
冪等性キー
作業内容から、決定論的にキーを導出してください。
| 適切な例 | 不適切な例 |
|---|---|
welcome-email:user_123 | uuid4() |
invoice:2026-08:acct_88123 | "send-" + Date.now() |
pr:acme/api:feature-auth | f"job-{attempt_number}" |
試行ごとに変わるキーを使うと、リトライのたびに新しい作業として扱われてしまいます。
Ratchet に接続できない場合
Ratchet はクリティカルパスに位置するため、統合する前に障害時の動作を決めてください。障害時にエージェントがゲートなしで動作する(フェイルオープン)か、動作を拒否する(フェイルクローズ)かを選びます。謝罪が必要になるような処理にはフェイルクローズを、ベンダー側で重複が排除される場合にはフェイルオープンを使用してください。
完全な仕様、クライアントの実装パターン、可用性に関する誠実な方針については、docs/FAILURE_MODES.md を参照してください。
アーキテクチャ
┌──────────────────────────────┐
agents ──────────▶│ control plane (stateless) │
REST + MCP │ Fastify · /v1 · /mcp · web │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Postgres │
│ effects · policies · ledger │
│ spend windows · audit │
└──────────────▲───────────────┘
│
┌──────────────┴───────────────┐
webhooks ◀────────│ worker (long-running) │
│ lease reaper · delivery · GC│
└──────────────────────────────┘
コントロールプレーンはステートレスで、水平方向にスケールできます。サーバーレスインフラストラクチャ上でも実行できます。ワーカーは実行できません。 リクエストが処理中かどうかにかかわらず、タイマーによってリースを期限切れにするためです。長時間稼働するコンテナとして実行してください。複数のレプリカを使用しても安全です(すべてのクレームで FOR UPDATE SKIP LOCKED を使用します)。
最大 1 回の実行は、アプリケーションロジックではなく、(workspace_id, effect_type, idempotency_key) に対するデータベースの一意制約によって保証されます。
詳細については、docs/handoff/ARCHITECTURE.md を参照してください。
デプロイ
コントロールプレーンはステートレスで、自由にスケールできます。ワーカーはスケールできません。 リクエストの有無にかかわらず、タイマーによってリースを期限切れにするため、長時間稼働するプロセスである必要があります。この制約があるため、より手軽なホストであっても、純粋なサーバーレスホスト(Vercel、Netlify functions)は使用できません。そのため、fly.toml では 1 つのイメージから両方のプロセスグループを実行します。
brew install flyctl && fly auth login # once, needs your browser
npm run deploy:fly
このスクリプトは冪等です。アプリを作成し、マネージド Postgres をプロビジョニングし、AUTH_SECRET を一度だけ生成して(変更するとすべての API キーが無効になるため、再生成しません)、両方のプロセスをデプロイし、準備状態を確認します。プリフライトに合格しない限り、処理を続行しません。
npm run deploy:preflight
プリフライトでは、すべてのテストと本番ビルドを実行した後、AUTH_SECRET が強度要件を満たし、開発用のデフォルト値ではないこと、PUBLIC_URL が設定されていること(未設定の場合、マニフェストに localhost が記載されるため)、RATE_LIMIT_OVERRIDE が未設定であること、プライベートネットワークへの Webhook が無効であること、CORS にワイルドカードが含まれていないこと、さらに Stripe を選択した場合はキーと Webhook シークレットの両方が設定されていることを確認します。シークレットの値は出力しません。
どのコンテナプラットフォームでも使用できます。fly.toml のみ Fly 固有です。DATABASE_URL、AUTH_SECRET、PUBLIC_URL、NODE_ENV=production を設定し、node dist/api/server.js(自由にスケール可能)と node dist/worker/main.js(常時稼働のインスタンスを少なくとも 1 つ)を実行してください。
本番環境と同じコンテナをローカルでテストするには、次のようにします。
AUTH_SECRET=$(openssl rand -base64 32) docker compose up --build
コマンド
| コマンド | 内容 |
|---|---|
npm run dev | コントロールプレーンをリロード付きで起動します |
npm run dev:worker | ワーカーをリロード付きで起動します |
npm run dev:db / dev:db:down | Docker でローカルの Postgres を起動/停止します |
npm run migrate | マイグレーションを適用します(アドバイザリロックを使用し、並行実行しても安全です) |
npm run seed | ワークスペースに現実的な状態のデータを投入します |
npm test | 破棄可能なデータベースに対して、型チェック、ユニットテスト、統合テスト、E2E テストを実行します |
npm run test:unit / test:integration / test:e2e | 各テスト層を個別に実行します |
npm run typecheck / lint | 厳格モードで TypeScript をチェックします |
npm run build | dist/ にコンパイルします |
npm start / start:worker | コンパイル済みビルドを実行します |
npm run mcp:stdio | stdio 経由で MCP サーバーを起動します |
npm run openapi | OpenAPI ドキュメントをディスクに書き込みます |
npm run deploy:preflight | ビルドと設定が安全にデプロイできることを検証します |
npm run deploy:fly | コントロールプレーン、ワーカー、データベースを Fly.io にデプロイします |
npm run metrics | 価格レビューのしきい値に照らして運用メトリクスを確認します |
npm run stripe:check | 決済設定を報告し、Stripe に対して検証します |
npm run stripe:listen | Stripe イベントをローカルインスタンスに転送し、Webhook シークレットを表示します |
npm run audit | 本番環境の依存関係を監査します |
環境
デフォルト値と安全性に関する注意事項を含むすべての変数は、.env.example に記載されています。必須の変数は次の 2 つです。
| 変数 | 説明 |
|---|---|
DATABASE_URL | Postgres の接続文字列 |
AUTH_SECRET | 32 文字以上のランダムな文字列です。API キーのペッパーとコンソールのセッション ID を生成します。この値を変更すると、すべての API キーとセッションが無効になります。 |
NODE_ENV=production の場合、AUTH_SECRET が開発用のデフォルト値であるか 32 文字未満の場合、CORS_ORIGINS に * が含まれる場合、または WEBHOOK_ALLOW_PRIVATE_NETWORK が有効な場合、プロセスは起動を拒否します。
エージェント向け
| インターフェース | パス |
|---|---|
| OpenAPI 3.1 | /openapi.json — ルートが検証に使用するスキーマから生成されます |
| 機能マニフェスト | /.well-known/agent-manifest.json — Ratchet が行わないことも記載されています |
| マシン向けドキュメント | /llms.txt |
| MCP ツールのスキーマ | /mcp/info |
| MCP(Streamable HTTP) | Authorization: Bearer <key> を指定して POST /mcp |
| MCP(stdio) | RATCHET_API_KEY を設定して npx -y ratchet-mcp を実行します — packages/ratchet-mcp を参照してください |
MCP ツールは 7 つです:ratchet_begin_effect、ratchet_report_effect、
ratchet_get_effect、ratchet_resolve_effect、ratchet_list_effects、ratchet_get_policy、ratchet_get_usage。
すぐに使える設定とコード:examples/ — Python、TypeScript、curl、Claude Desktop、
Cursor、および HTTP 経由の汎用 MCP に対応しています。
セキュリティ対策
- 保存されるのはペイロードのSHA-256 フィンガープリントのみで、ペイロード自体は保存されません。
- API キーはサーバーシークレットでペッパー処理した HMAC-SHA256として保存されます。データベースが漏えいしただけでは、利用可能なキーは得られません。比較は一定時間で実行され、未知のプレフィックスに対しても実行されます。
- すべてのクエリはワークスペースのスコープ内で実行されます。テナントをまたぐ検索では、手がかりを与えずに
404を返します。 - SSRF 対策は 2 層構成です。静的な URL 検証の後、配信を試みるたびに DNS を再解決し、ソケットを検証済みアドレスに固定します。リダイレクトは追跡しません。
- エージェントが提供したテキストは、指示ではなくデータとして扱われます。判断は保存されたポリシーとデータベースの状態に基づきます。ペイロード内の情報によってスコープを広げたり、予算を増やしたり、ポリシーを変更したりすることはできません。
- 不明なリクエストフィールドは黙って破棄せず、拒否されます。
第三者による監査は実施されていません。SOC 2 レポートおよび侵入テストはありません。詳細と脅威モデルについては、docs/handoff/SECURITY_REVIEW.md を参照してください。
料金
課金対象は 1 つです。特定の (effect_type, idempotency_key) に対する最初の begin が、ゲート付きエフェクトとして課金されます。重複の抑制、実行中の確認、再試行、レポート、読み取り、ポリシーの変更、Webhook はすべて無料です。この製品が吸収するために存在する再試行の動作に対して、料金が発生することはありません。
| プラン | 価格 | 月あたりのエフェクト数 | 超過料金 |
|---|---|---|---|
| Free | $0 | 1,000 | $1.50 / 1,000、プリペイドクレジットのみ |
| Pro | $29/mo | 25,000 | $1.50 / 1,000 |
| Custom | お問い合わせ | 250,000 超 | 個別交渉 |
Free は、プリペイドクレジットを追加しない限り、上限に達すると利用できなくなります。自動的な超過料金は発生せず、請求書も発行されません。月におよそ 19,300 エフェクトを超えると、Free でクレジットを購入するより Pro のほうが安くなるため、アップグレードの判断は明快です。
プランは 3 つではなく 2 つです。3 段階の料金体系は、3 つの顧客セグメントがあると示すものですが、それを裏付ける利用履歴はまだありません。以前の価格設定では、20 倍の利用範囲に同じ料金を設定していた理由を含む検討内容については、
docs/handoff/PRICING_AND_DISTRIBUTION_REVIEW.md
を参照してください。
超過分はプリペイドクレジットから差し引かれるため、エージェントが暴走しても、請求書が発生するのではなく残高が尽きた時点で停止します。コストモデルと前提条件については、
docs/handoff/PRICING_AND_UNIT_ECONOMICS.md
を参照してください。
決済
Stripe は完全に接続されています。startCheckout は実際の Checkout Session を作成し、署名済みの
checkout.session.completed Webhook が台帳にクレジットを加算します。カード情報は Stripe のページで入力され、Ratchet に渡ることはありません。また、クレジットは署名済み Webhook によってのみ適用され、ブラウザーが成功 URL に戻ったことによって適用されることはありません。
チェックアウトを開始するには、STRIPE_SECRET_KEY と STRIPE_WEBHOOK_SECRET の両方が必要です。キーだけを設定した場合も Stripe が選択されますが、チェックアウトは無効のままです。確認できない決済を受け付けると、顧客に課金されてもクレジットが加算されないためです。npm run stripe:check を実行すると、何が設定されているかを正確に確認できます(シークレット値は出力されません)。
ローカル開発では、公開 URL を使わずに Webhook シークレットを取得できます。
npm run stripe:listen # prints whsec_… ; put it in .env and restart
Stripe のオンボーディングチェックリストの大部分は該当しません。Ratchet は明細項目をインラインで作成し、Stripe カタログを参照しないため、作成する商品はありません。Stripe Invoicing も使用しません。また、ノーコードビルダーではなく API 経由で Checkout Session を作成します。実際の決済を開始する前に必要なのは、アカウントの確認(Stripe の KYC)、デプロイ済みの /v1/billing/webhook/stripe を指定するWebhook エンドポイントの作成と、本番環境でそのエンドポイントの署名シークレットを使用すること、そして税金の徴収(デフォルトでは無効の STRIPE_AUTOMATIC_TAX)が必要かどうかの判断です。
Stripe の認証情報がまったくない場合は、組み込みのテストアダプターが代わりに動作します。カードへの課金は行われず、外部リクエストも送信されません。現時点で確認済みなのは Stripe のテストモードのみです。本番稼働前に
docs/handoff/KNOWN_LIMITATIONS.md
を参照してください。特に返金に関する注意事項を確認してください。
ドキュメント
| ドキュメント | 内容 |
|---|---|
PROJECT_MAP.md | 各ファイルの場所 |
ARCHITECTURE.md | 状態マシン、並行処理、デプロイのトポロジー |
DECISIONS.md | 重要な決定事項とその理由 |
API_AND_DATA_CONTRACTS.md | エンドポイント、スキーマ、エラーコード |
SECURITY_REVIEW.md | 脅威モデルと実装済みの対策 |
PRICING_AND_UNIT_ECONOMICS.md | コストモデルとシナリオ |
VALIDATION_REPORT.md | テストおよび測定の内容 |
KNOWN_LIMITATIONS.md | 未対応の内容と、対応に必要なこと |
ライセンス
Apache-2.0。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。