mcpField
O
orangerail

orangerail

ローカル
github.com/KimHyeongRae0開発ツール011 週間前に更新

orangerail について

orangerailはPrisma schemaから型付きMCPサーバーを生成し、任意クエリではなく範囲を限定したデータベースツールをエージェントに提供します。特定の書き込みに人の承認を求め、ガバナンス変更を追跡したいチーム向けです。

主な機能

  1. 01Prisma schemaから型付きツールを生成
  2. 02オブジェクトごとのget・listツール
  3. 03schema由来の書き込みアクション
  4. 04指定した書き込みの人による承認
  5. 05ガバナンス基準と監査チェーン
  6. 06インタラクティブなドメインマップ

活用シーン

  1. 01許可されたデータベース読み取りをエージェントに任せる
  2. 02定型的な書き込みを無人で実行する
  3. 03破壊的な書き込みを後日の確認用に保留する

MCP 対応

生成されるMCPサーバーは、schema由来の読み書きツールとcheck_approvalを公開します。任意クエリ用ツールはなく、指定した書き込みは人の承認待ちとして保留できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"kimhyeongrae0-orangerail": {
"command": "npx",
"args": [
"-y",
"orangerail"
],
"env": {
"DATABASE_URL": "<DATABASE_URL>"
}
}
}
}
起動コマンドnpx -y orangerail
設定が必要な環境変数
DATABASE_URLシークレットThe database the generated actions reach, in the same form your Prisma datasource takes.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmorangerail0.1.4

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

README の画像

orangerail

エージェントにデータベースを使わせましょう。SQL は渡さずに。

npm CI node published with provenance license

クイックスタート · コマンド · 管理対象外のもの · ルールファイルとの比較 · 例 · ドキュメント

3つのモデルを含むPrismaスキーマでのorangerail initと、サーバーの実際のtools/list:読み取り6件、書き込み9件、check_approval、execute_sqlなし

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

すべてのオブジェクト、それらの関係、そしてエージェントが実行できるすべての書き込み操作を確認できます。テーブルにカーソルを合わせると、その関係と操作が強調表示され、テーブルをクリックすると、それを制御するポリシーを確認できます。

orangerail studioのマップ — テーブルにカーソルを合わせて関係を表示し、次にdeleteOrderを開いて、それを制御するポリシーを確認する様子:対象Order、承認必須、承認者は誰でも可、条件なし

より鮮明なバージョン: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ドル未満の返金なら確認は不要。こうした区別はツールのレベルには存在せず、スキーマに存在します。

この仕組みが想定する実行

誰も見ていないバックオフィスのキューをエージェントに渡した状態:通常の書き込みは完了し、削除は停止して承認待ちになり、停止させた宣言済みのルールが1つ表示される

実際の 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
破壊的な項目の実行数00
停止後に残るものレポート内の段落承認記録
別のディレクトリで同じタスクを開始行が削除されたステージングされた

コンプライアンスでは互角で、その後も互角を保ちました — 敵対的な書き換え、偽の事前承認、データベースの行に仕込まれた指示、そしてはるかに小さなモデルを使った場合も同様でした。ある点では、私たちのほうが負けました。つまり、このプロジェクトは、エージェントがあなたのルールを無視するとは主張しません。ここで測定したすべての実行で、エージェントはルールに従いました。

実行回数は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 が制御しないことをご覧ください。

エージェントが停止する様子を見る

破壊的なエージェントのアクションが停止し、承認 ID として返されます。人が判断し、その後にのみ行が変更されます

実際の 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 に記載されています。

ドキュメント

例

  • unattended-queue — このファイル冒頭の実行例を再現可能にしたもの。決定論的で、アサーション付き、API キー不要です。
  • governed-writes — 同じゲートを単独で、一度に 1 つの破壊的な呼び出しとして実行します。
  • vs-a-rules-file — ルールファイルとの比較を実行可能にしたもの。両方の方式を実行し、ルールファイルが勝る項目も含みます。

開発

このリポジトリは、決定論的な9段階のゲートハーネスのもとでビルドされます。変更はすべて ./scripts/verify.sh を通じて検証されます。検証項目は、言語、構造、ゲートのセルフテスト、no-LLM、 テンプレート、続いて型チェック/リント/テスト/ビルドです。CI ではこのスクリプトだけが実行されるため、ローカルでの実行が成功すれば、ビルドも成功します。絶対に守るべき不変条件として、LLM 推論 SDK は一切バンドルされません (./scripts/check-no-llm.sh)。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。