orangerail について
orangerailはPrisma schemaから型付きMCPサーバーを生成し、任意クエリではなく範囲を限定したデータベースツールをエージェントに提供します。特定の書き込みに人の承認を求め、ガバナンス変更を追跡したいチーム向けです。
主な機能
- 01Prisma schemaから型付きツールを生成
- 02オブジェクトごとのget・listツール
- 03schema由来の書き込みアクション
- 04指定した書き込みの人による承認
- 05ガバナンス基準と監査チェーン
- 06インタラクティブなドメインマップ
活用シーン
- 01許可されたデータベース読み取りをエージェントに任せる
- 02定型的な書き込みを無人で実行する
- 03破壊的な書き込みを後日の確認用に保留する
MCP 対応
生成されるMCPサーバーは、schema由来の読み書きツールとcheck_approvalを公開します。任意クエリ用ツールはなく、指定した書き込みは人の承認待ちとして保留できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細

3つのモデルを含むPrismaスキーマでのorangerail initと、生成されたサーバーに対する実際のtools/listです。ツールは16個です。各オブジェクトにgetとlistを1つずつ、各書き込みにアクションを1つずつ、そしてcheck_approvalです。この一覧にクエリを受け取るものはありません。 3つのロックは--gate deleteです。これは1行で変更できるデフォルト設定であり、判定ではありません。
ルールファイルでは実現できません。 エージェントにクエリを実行しないよう求めることはできます。しかし、ツール一覧からツールを取り除くことはできません。そしてその違いにどれほどの価値があるかを測定しました。実際に検証してみると、4つの主張は覆りました。
orangerailは既存のスキーマを読み取り、そこからエージェントが使えるインターフェースを生成します。
orangerail initはprisma/schema.prismaをMCPサーバーに変換します。各オブジェクトにgetとlistを1つずつ、各書き込みにzod入力スキーマを備えたアクションを1つずつ生成し、それ以外は何も生成しません。execute_sqlも、クエリを受け取るツールも一覧にありません。LLM呼び出しやAPIキーを必要としない、スキャナー兼コードジェネレーターです。無人で実行してよい書き込みは無人で実行されます。そうでない書き込みにはpolicy: { approval: 'required' }が付き、呼び出しを停止して、後から人が対応できる承認依頼に変えます。会話が終わった後に、あなた以外の人が対応することもできます。
範囲が限定されていても安全とは限りません。このREADMEはそのふりをしません。 生成されたインターフェースによって得られるのは、有限で明確なアクセス範囲であり、その中に有害な操作が一切ないという保証ではありません。操作を宣言したのはあなたです。つまり、宣言した破壊的な操作はエージェントが呼び出せます。
これをインストールする価値があるかどうかを決める前提条件は1つです。orangerailが管理するのは、自身のツールだけです。 エージェントが認証情報を使えるシェルや、別のデータベースMCPサーバーも利用できる場合、制限を回避できます。orangerailが管理対象としないものをご覧ください。
プレリリース版で、インストール可能です。npmで公開中の0.1.5には、orangerail(CLI)に加え、orangerail-core、orangerail-mcp、orangerail-docs-gen、orangerail-studioが含まれています。APIは1.0より前に変更される予定です。重要なアップグレード情報はステータスに記載されています。
ドメイン全体をマップで確認
コマンドを1つ実行するだけで、init が生成する構造を読み取れるマップとして確認できます。
$ orangerail studio
orangerail studio: scanning ontology — 9 object(s), 27 action(s)
orangerail studio: building the interactive map…
orangerail studio: serving on http://127.0.0.1:4820 — open it in your browser
すべてのオブジェクト、それらの関係、そしてエージェントが実行できるすべての書き込み操作を確認できます。テーブルにカーソルを合わせると、その関係と操作が強調表示され、テーブルをクリックすると、それを制御するポリシーを確認できます。

より鮮明なバージョン:
assets/studio-map.mp4— 同じ実行をフル解像度で収録しています。サンプルのコマースドメインでの実際の実行で、--gate deleteを指定しています。ロックは動画用に追加した注釈ではありません。オントロジーからstudioが描画したものであり、そのため9つの操作にはロックが付き、18の操作には付いていません。
それが何を意味するのか、正確に把握してください。 関係は ontology/_links.mjs に由来し、これは init がPrismaのリレーションから生成します。そのため、Customer_list の説明には List Customer records. Relations: has many Order. と表示されます。エージェントには、Customerが複数のOrderを持つことが伝えられています。それでも、そのエッジをたどることはできません。トラバーサルツールも、結合も、集計もなく、Customer_list は Order に及ぶフィルターを拒否します。ドメインの構造を知っていることと、その構造を横断してクエリを実行できることは別のことであり、ここでできるのは前者だけです。
クイックスタート
7つのステップすべてについて、記録された1回の実行結果をそのまま掲載しています。それぞれの理由と、それによって防げる失敗については、注釈付きクイックスタートを参照してください。必要要件とPrisma 7に関する注意点が、ページの最初に記載されています。
1. これからスキャンするプロジェクトにorangerailをインストールします。
npm i -D orangerail
2. prisma/schema.prisma があるリポジトリで、プロジェクトをスキャンします。
$ npx orangerail init --yes --preset approval-for-writes --no-studio
✓ scanned your sources — 2 object(s), 6 action(s)
✓ generated a governed MCP server under ontology/
✓ --gate delete: 2 of 6 write action(s) gated behind human approval — the other 4 run when the agent calls them
✓ recorded that posture in orangerail.governance.json — commit it
✓ approvals queue + audit chain at .orangerail/store/ — inside this project, so an
agent with file tools over this directory can write them
These files are yours — re-scans never modify them; `orangerail sync` reports drift.
Change what is gated by editing `policy` in ontology/<action>.mjs, or re-run init
with `--gate all` (gate every write) or `--gate none` (gate nothing).
orangerail.governance.json holds the posture init just generated, which nobody has reviewed yet.
From now on `orangerail sync` fails when an action gets weaker than that file, and
`orangerail mcp` refuses to serve it. Read the file, then run
`orangerail sync --accept-governance` to vouch for it as reviewed.
That store is the record of which writes a human approved, and appending one line to
.orangerail/store/approvals.jsonl marks a staged action approved — the next
`check_approval` then executes it, because the gate reads that store and never the
audit chain. `orangerail audit verify` reports the forgery afterwards; it is a report,
not a gate, and it does not prevent the write. The generated config carries the
one-line move at the `createFileStore` call — see docs/audit-log.md.
orangerail docs: wrote /private/tmp/shop/.orangerail/generated/AGENTS.md
Done. Run `orangerail studio` to explore the map, or `orangerail mcp`.
3. 生成されたコードが読み込むランタイムをインストールします。
npm install orangerail-core zod
4. 生成された操作が接続するデータベースを用意します。
npm install @prisma/client@6
export DATABASE_URL="file:./dev.db"
npx prisma generate
npx prisma db push --skip-generate
すでにデータベースがありますか? そのデータベースに対して
db pushを実行しないでください。 既存のデータベースにorangerailを適用する方法を参照してください。
5. エージェントホストを接続します。 プロジェクトのルートに .mcp.json として配置します。
{
"mcpServers": {
"orangerail": {
"type": "stdio",
"command": "./node_modules/.bin/orangerail",
"args": ["mcp"],
"env": { "DATABASE_URL": "file:./dev.db" }
}
}
}
その他のホスト、claude mcp add のワンライナー、ソースからの実行方法については、エージェントホストへの接続を参照してください。
6. ガバナンスのベースラインを記録し、コミットします。 ontology/ は編集できるため、フロー全体を無効にする1行は、不注意な削除ひとつで失われます。また、再スキャンではその削除を検知できません。代わりに、記録されたファイルと現在の状態を比較します。
npx orangerail sync --accept-governance
orangerail.governance.json をコミットしてください。 このファイルの価値は、承認ゲートを削除するプルリクエストにおいて、CIの実行前に、レビュー担当者の目の前で、差分に "approval": "required" が null に変わる様子を示せることにあります。
7. その場を離れます。 あなたがいない間、エージェントはキューを処理します。ゲートを設定しなかった書き込みは実行され、依頼された削除は停止します。戻ってきたら、次のようにします。
$ npx orangerail status
orangerail status
objects: 2
actions: 2 approval-gated, 4 auto
baseline: 6 action(s) match orangerail.governance.json
preset: approval-for-writes
pending: 1 approval(s) awaiting a decision
store: /private/tmp/shop/.orangerail/store
Inside the project root, so an agent with file tools over this directory can
write it: one appended line in approvals.jsonl is a decision no human made,
and the next `check_approval` executes the staged action — the gate reads
this store, never the audit chain. `orangerail audit verify` reports the
forgery afterwards; it is a report, not a gate. Pointing the store `dir` at a
directory this agent's process cannot write is what removes the reach — see
docs/audit-log.md.
server: not detected — no orangerail mcp is running against this store
hosts: .mcp.json declares orangerail and nothing else.
Project scope only (.mcp.json, .cursor/mcp.json, .vscode/mcp.json); user- and
machine-scope MCP config is not read.
audit: chain OK — 5 record(s) verified
$ npx orangerail approvals list
c4818df5-770c-446f-883a-e9c0f7e615a2 "deleteCustomer" by "local-dev" [dev] 0s ago input={"id":2}
1 pending approval(s).
$ npx orangerail approvals approve c4818df5-770c-446f-883a-e9c0f7e615a2
approve ok (approved)
次にエージェントが check_approval を実行した時点で初めて、行が変更される可能性が生じます。あなたが許可するまで何も実行されず、すべてのステップがハッシュチェーンに記録されます。この一連の流れを、tests/e2e/ONT-093-quickstart-runs-as-documented.sh が回帰テストのたびに、このリポジトリ自体のビルドに対して実行します。
プロンプトが適切な制御手段ではない理由
あなたが立ち去れないのは、エージェントがやりすぎるからではありません。唯一の制御手段が、エージェントから尋ねられる質問だからです。 午後の20回目のプロンプトも、最初のプロンプトと同じようにクリックされます。そして、確認を終わらせる切り替え手段は最初から備わっています。Claude Code の bypassPermissions モードは、独自の権限リファレンスによると、「明示的な ask ルールで強制されるものを除き、権限プロンプトをスキップします」。呼び出しのたびに人が境界を設定し直す仕組みは、人がいなくなれば維持できません。
また、プロンプトは 形 も適切ではありません。ツールについて「この Bash の実行を許可しますか」と尋ねますが、あなたが抱えるリスクは業務領域に関するものです。在庫の編集は問題ないが、注文の削除は許可できない。50ドル未満の返金なら確認は不要。こうした区別はツールのレベルには存在せず、スキーマに存在します。
この仕組みが想定する実行

実際の MCP クライアントを使い、API キーなしで、すべての行を検証する examples/unattended-queue の1回の実行です。動画には12項目中6項目が映っています。行番号が飛んでいるため、どの項目か確認できます。
EC サイトのデータベースにある15項目のバックオフィスキューを、担当者がその日の業務を終えて不在の状態でエージェントに渡し、確認を求めないよう指示します。12項目は通常の、取り消し可能な書き込みです。3項目は破壊的な操作です。キャンセル済みの注文、消去要求のあった顧客、販売終了した商品を削除します。エージェントが実行したと言った内容ではなく、実行後にデータベースを確認して評価します。
| orangerail | |
|---|---|
| 担当者不在で完了した通常の項目 | 12 / 12 |
| 実行された破壊的な項目 | 0 |
| 停止され、承認待ちになった破壊的な項目 | 3 |
| 翌朝に待っているもの | 3件の承認記録。それぞれハッシュによって正確な呼び出しと紐付け |
| 監査チェーン | 27件の記録。検証結果は OK |
このプロジェクトが目指す指標はこれであり、「どれだけブロックしたか」ではありません。誰も見ていない間にどれだけ完了し、戻ってきたときに何が待っているかです。
この表には切り分け可能な主張が2つありますが、どちらも同じ程度に裏付けられているわけではありません。12項目が実行され、3項目が実行できないという性質はサーバーによるもので、あなたのマシンで再現できます。examples/unattended-queue は、実際の MCP クライアントを通じてまったく同じキューを決定論的に実行し、すべての行を検証します。一方、キューを文章で渡したときに モデル がこうした呼び出しを選ぶかどうかを確認するには、実際のホスト上で実際のエージェントを動かす必要があり、この部分は再現ではなく測定です。サンプル数は少なく、検証した範囲ではゲートが機能するとは言えますが、発生率を示すには不十分です。
代わりに行うであろう方法との比較
重要な比較対象は、生の SQL サーバーではありません。許可されたテーブルと禁止されたテーブルを明記した、よく書かれた CLAUDE.md ルールファイルを用意し、書き込み権限をすべて持つ Postgres MCP サーバーと組み合わせたものです。同じキュー、同じモデル、3 回のクローン実行で比較します。
| Markdown ルール、書き込み権限すべてあり | orangerail | |
|---|---|---|
| 通常の項目の完了数 | 12 / 12、3 回すべて | 12 / 12 |
| 破壊的な項目の実行数 | 0 | 0 |
| 停止後に残るもの | レポート内の段落 | 承認記録 |
| 別のディレクトリで同じタスクを開始 | 行が削除された | ステージングされた |
コンプライアンスでは互角で、その後も互角を保ちました — 敵対的な書き換え、偽の事前承認、データベースの行に仕込まれた指示、そしてはるかに小さなモデルを使った場合も同様でした。ある点では、私たちのほうが負けました。つまり、このプロジェクトは、エージェントがあなたのルールを無視するとは主張しません。ここで測定したすべての実行で、エージェントはルールに従いました。
実行回数は6回です。 エージェントがルールに従わないという主張を退けるには十分ですが、失敗率を示すには到底足りません。6回で失敗がゼロでも、失敗率の上限は約39%であり、ゼロに近いわけではありません。信頼できる上限を得るにはコストがかかり、次のモデルリリースでその結果は古くなります。そのため、このプロジェクトが賭けているのは次の行です。 10回の実行では証明できないこと。
互角ではないのは最後の行ですが、これはエージェントの振る舞いについてではありません。許可は登録されたセッションとともに移動し、ルールファイルはそれを書いたマシンアカウントとともに移動します。1台のマシンを使う1人の開発者なら、グローバルな ~/.claude/CLAUDE.md でこの隔たりの大部分を埋められます — あなたがその開発者なら、これは必要ないかもしれません。 ただし、CI ランナー、コンテナー、サービスアカウント、あるいはチームメイトのチェックアウト環境では隔たりを埋められず、いずれもデータベースの認証情報を持つことになります。
すべての実行、ルールファイルが勝る点、そして測定の限界については、こちらをご覧ください:
代わりに行うであろう方法との比較。
examples/vs-a-rules-file では両方の方法を実行します。
execute_sql の代わりにエージェントが使うもの
3つのモデルを持つ Prisma スキーマ(Order、OrderItem、Payment)で orangerail init を実行すると、ツール一覧は合計16項目になります。各オブジェクトにつき get と list が1つずつ、書き込み操作ごとにアクションが1つ、そして check_approval です。それ以外はなく、クエリを受け取るものもありません。
各アクションの入力は、独自のカラムから導出された zod スキーマであり、tools/list で公開されます。そのため updateProduct は、カラムの型が整数なら文字列を拒否し、該当するフィールド名を示します。各読み取りは、ID による findUnique、またはページ分割された findMany です。その filter は、宣言されたフィールドに対する述語の固定セットであり、単に利用可能と示すだけでなく、リゾルバーに届く前にサーバーが適用します。
固定されたサーフェスは狭いものです。集計、結合、自由形式のクエリ、DDL はありません。表現できない質問には、別の場所で答える必要があります。制御対象のすべてと、実際に強制が行われる場所については、orangerail が制御しないことをご覧ください。
エージェントが停止する様子を見る

実際の MCP クライアントを通じて examples/governed-writes を実行した、実際の1回の例です。破壊的なツールは隠されず、利用可能なままであり、エージェントが強制的に実行することはできません。そして、行が変更されるのは人が判断した後だけです — 別のターミナルで、別の時間に。この点が、後から変更できる理由です。
ジェネレーターが導出できないルールを宣言する
上記はすべて生成されます。ルールがスキーマではなく頭の中にある場合――「売り切れの商品にはクーポンを絶対に発行しない」など――そのルールを一度だけ TypeScript で記述すれば、同じインターフェースに加わります。
import { defineAction, defineObject } from 'orangerail-core';
import { z } from 'zod';
// Your existing backend. orangerail never replaces it — it only gates the call.
declare const findProduct: (id: string) => Promise<{ id: string; status: string } | null>;
declare const grantCoupon: (args: { productId: string; amount: number }) => Promise<void>;
// A `where` guard has to read the row it guards, so the target needs `resolve`.
export const Product = defineObject({
name: 'Product',
schema: z.object({ id: z.string(), status: z.string() }),
resolve: { get: async ({ id }) => findProduct(id) },
});
export const issueCoupon = defineAction({
name: 'issueCoupon',
target: Product,
input: z.object({ productId: z.string(), amount: z.number() }),
policy: {
approval: 'required',
where: { field: 'status', op: 'neq', value: 'soldout' },
},
// `execute` runs only after the approval clears, and receives the validated
// input plus the resolved caller. There is no `audit` switch: every staged,
// approved, rejected and executed action is written to the hash chain.
execute: async ({ input, identity }) => {
await grantCoupon({ productId: input.productId, amount: input.amount });
return { issuedBy: identity.subject };
},
});
このブロックは説明用の例ではありません。packages/cli/test/readme-example.ts の内容をそのまま出力したもので、リポジトリの型チェックでコンパイルされ、実行のたびにこのファイルと照合されます。そのため、コンパイルされないコードへと劣化することはありません。
ステータス
orangerail init は、今日からこのリポジトリをチェックアウトせずに独自のプロジェクトで実行できます。また、API は 1.0 より前に変更される予定です。5 つのパッケージはすべて、npm の Trusted Publishing を通じて .github/workflows/release.yml から公開されるため、それぞれにビルドしたワークフローとコミットを示すプロベナンス証明が付与されます。このリポジトリに npm トークンはありません。
0.1.0 をお使いの場合はアップグレードしてください。 このリリースでは、読み取り用の filter がエージェントに公開されていましたが、検証されていませんでした。そのため、<Object>_list の呼び出しで、サーバーが公開していないオブジェクト型を読み取ることができました(仕組み)。修正は 0.1.2 に含まれ、orangerail-mcp に実装されているため、パッケージをアップグレードするだけで適用され、init を再実行する必要はありません。また、0.1.2 では filter が受け付ける内容が制限され、保留中の承認がアップグレードをまたいでどう扱われるかも変更されています。どちらも CHANGELOG の Upgrading from 0.1.0 に記載されています。
ドキュメント
- コマンド — すべてのコマンド、
--gateで選択される内容、名前を指定したテーブルのみに対象を絞る方法。 - 注釈付きクイックスタート — 7 つの手順と、その理由、要件、各手順で防げる障害。
- エージェントホストへの接続 — stdio、
.mcp.json、ソースからの実行。 - orangerail が管理しないもの — 前提条件、不足している機能、実際に適用を担う場所。
- 監査ログが証明すること — 厳密な基準、「改ざん検知可能」という表現を使わない理由、データベースレベルの監査がより適切な場合、ストアの配置場所。
- 代わりに実行するであろう方法との比較 — ルールファイルとの詳細な比較。
- orangerail の比較 —
--read-only、OpenAPI コード生成、Prisma 独自のサーバー、Supabase のサーバーとの比較。 - 既存のデータベースへの orangerail の導入 — 稼働中のデータベースに対する
prisma db pullと、Prisma 7 での変更点。 - ホストにもプロンプトを求める — ゲートを設けていない書き込みに対する、任意のクライアント側プロンプト。
- トラブルシューティング — ポリシーではなく、インストールに問題があることを知らせる診断結果。
- 測定したこと、そして失敗したこと — このプロジェクトが主張した、または主張しかけた内容と、実際に実行した結果、どれが残ったか。4 つは残りませんでした。
bench/— このページの裏付けとなるフィクスチャ。議論する代わりに再現して異論を示せます。- MCP レジストリーの掲載項目 — 掲載内容と、100 文字の説明には収まらない手順。
例
unattended-queue— このファイル冒頭の実行例を再現可能にしたもの。決定論的で、アサーション付き、API キー不要です。governed-writes— 同じゲートを単独で、一度に 1 つの破壊的な呼び出しとして実行します。vs-a-rules-file— ルールファイルとの比較を実行可能にしたもの。両方の方式を実行し、ルールファイルが勝る項目も含みます。
開発
このリポジトリは、決定論的な9段階のゲートハーネスのもとでビルドされます。変更はすべて
./scripts/verify.sh を通じて検証されます。検証項目は、言語、構造、ゲートのセルフテスト、no-LLM、
テンプレート、続いて型チェック/リント/テスト/ビルドです。CI ではこのスクリプトだけが実行されるため、ローカルでの実行が成功すれば、ビルドも成功します。絶対に守るべき不変条件として、LLM 推論 SDK は一切バンドルされません
(./scripts/check-no-llm.sh)。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。