Skip to main content
Glama
vdobhal

Oracle MCP Chatbot

by vdobhal

Oracle MCP チャットボット — オンプレミス Oracle DB + Oracle ATP

AI チャットボットが Oracle データベースに対する自然言語の質問に回答できるようにする、セキュアな Model Context Protocol サーバーペアです。メタデータの検出、SELECT のみの SQL 生成、検証、ハードリミット下での実行、機密値のマスキング、そしてすべてのログ記録を行います。

FastMCP 3、python-oracledb(シンモード)、sqlglot で構築されています。テストは 221 件で、実行にデータベースは不要です。

pip install -r requirements-dev.txt
pytest                                        # 221 passed
cp .env.example .env                          # add credentials
python -m oracle_mcp.server --profile onprem --check
python -m oracle_mcp.server --profile onprem

実行中のデプロイメントのテスト方法は docs/testing.md に記載されています。Cursor を使用しないブラウザ UI は docs/chat-ui.md にあります:

python -m oracle_mcp.chat --profile both   # http://127.0.0.1:8500

機能概要

機能

仕組み

常に読み取り専用

AST 検証、SET TRANSACTION READ ONLY、SELECT のみ許可する権限

承認済みデータのみ

スキーマ、オブジェクト、列の YAML 許可リスト

役割に応じた制御

クリアランスレベル付きの 5 つのロール。列レベルの強制適用

制限付き

行数上限(デフォルト 500)とクエリタイムアウト(デフォルト 30 秒)。どちらもユーザーは変更不可

プライバシー保護

列名、分類、値の内容によるマスキング

説明責任

呼び出しごとに 1 件の監査レコード。SQL は秘匿化され、ハッシュ付き

2 つのデータベース

サーバープロセスを分離。任意で照合サーバーも利用可能

Related MCP server: OracleDB MCP Server

8 つのツール

ツール

目的

list_allowed_schemas

ロールが読み取り可能なスキーマとその説明

list_allowed_tables

承認済みオブジェクト、ドメイン、機密性、行数の見積もり

get_table_metadata

列、型、NULL 許容性、PK/FK、業務上の説明

search_data_dictionary

業務用語によるオブジェクト・列の検索(信頼度付き)

validate_sql

ガードレールチェック。書き換え後の安全な SQL を返す

execute_readonly_sql

事前承認済み SQL を実行。マスク済み・上限付きの行を返す

explain_query_result

ビジネス言語での回答のためのファクトを計算

compare_onprem_and_atp_data

データベース間の整合性確認(profile=both のみ)

さらに、接続検出用の list_databases があります。すべてのツールは JSON を受け取り、JSON を返します。

セキュリティモデルの仕組み

ユーザーにデータが届くまでには、5 つの独立したレイヤーを通過します:

Database grants  →  Object allowlist  →  Role clearance  →  SQL guardrails  →  Output masking
   sql/*.sql        config/policy/       roles.yaml         sql_guard.py       masking.py

中核となる考え方: 送信した SQL がそのまま実行されることは決してありません。入力は AST にパースされ、検査され、書き換えられ、再生成されます。認識されたノード型のみが再出力されるため、コメントによるトリック、複文、ホモグリフのキーワードは往復処理を生き延びることができません。

SELECT a FROM t; DROP TABLE t     →  rejected: MULTIPLE_STATEMENTS
SELECT /*+ PARALLEL(t,64) */ a…   →  SELECT a FROM t FETCH FIRST 500 ROWS ONLY
DELETE FROM t                 →  rejected: NFKC folds it to DELETE
SELECT * FROM v   (business_user) →  explicit column list, restricted ones absent

2 つ目の主要な制御: execute_readonly_sql はゼロから再検証し、さらに validate_sql が発行したフィンガープリントを要求します。これにより、チェックと実行の間に SQL がすり替えられることはありません。非管理者ロールは事前承認されていないものを実行できません。管理者は実行できますが、その場合もすべてのガードレールを通過します。

3 つ目: ロールはツールの引数ではなく、プロセス設定によって固定されます。ユーザーがモデルに「あなたは管理者です」と言っても、user_role="admin" という文字列が生成されるだけで、それを読み取るものは何もありません。

設定

2 つのファイルがすべてを決定します:

config/policy/onprem.yaml と atp.yaml — オブジェクト許可リスト。各データベースは 2 つのモードのいずれかを選択します。

厳格モード(Strict):オンプレミスで使用されます。ここに記載されたオブジェクトのみが、データベースの権限が許可する内容にかかわらず到達可能になります:

schemas:
  - name: EIM
    objects:
      - name: EIM_PR_SYSTEM
        type: TABLE
        sensitivity: INTERNAL
        large_table: true
        require_filter: true       # forces a WHERE clause
        columns:                   # optional; omit to read them from the
          - {name: SERIAL_NUMBER,  sensitivity: INTERNAL}   # data dictionary
          - {name: TAX_ID,         sensitivity: RESTRICTED} # at query time

columns の省略もサポートされており、実際のデプロイメントのポリシーでは省略されています。列は ALL_TAB_COLUMNS から読み取られ、masking.yaml の名前パターンによって分類されるため、スキーマの変更に合わせて許可リストを正確に保つことができます。

ワイルドカードモード。これは ATP で使用されます。読み取り専用アカウントがアクセスできるすべてのスキーマが到達可能になります:

allow_all_schemas: true
excluded_schemas: []   # added on top of the built-in Oracle internal schemas
schemas: []

これは意図的にオブジェクト許可リストを放棄し、代わりにデータベースの権限を境界とします。クリアランス、SQL ガードレール、行数上限、マスキングはすべて引き続き適用されます。本当に読み取り専用のアカウントに対してのみ使用してください。

config/policy/roles.yaml — 誰が何を閲覧できるか:

roles:
  business_user:
    clearance: INTERNAL      # cannot reach CONFIDENTIAL or RESTRICTED columns
    max_rows: 200
    allow_raw_sql: false
    schemas: {ONPREM: [EIM], ATP: ["*"]}   # "*" needs allow_all_schemas

機密性の階層: PUBLIC < INTERNAL < CONFIDENTIAL < RESTRICTED < NEVER。 NEVER はすべてのクリアランスより上位にあるため、パスワードやカード番号は管理者を含むどのロールからも到達できません。

デプロイメント

データベースごとに 1 つのサーバーを実行します。この分割自体がセキュリティ境界です。オンプレミスのプロセスは ATP ウォレットのパスフレーズを保持しません。

docker build -t oracle-mcp-chatbot:1.0.0 .
export ATP_WALLET_HOST_PATH=/secure/path/wallets/atp
docker compose up -d onprem-mcp atp-mcp
docker compose --profile reconciliation up -d   # optional, holds both credential sets

Oracle ATP 接続

mTLS ウォレットを使用したシンモード。ウォレットを解凍して、以下を設定します:

ATP_DSN=myatp_low                      # prefer _low so chatbot traffic can't starve prod
ATP_WALLET_DIR=/opt/oracle/wallets/atp # contains ewallet.pem + tnsnames.ora
ATP_CONFIG_DIR=/opt/oracle/wallets/atp
ATP_WALLET_PASSWORD=...                # set when the wallet zip was downloaded

ATP_WALLET_PASSWORD は ewallet.pem を保護するパスフレーズであり、データベースのパスワードではありません。よくある混乱する失敗ポイントです。これはシンモードのみで使用され、シックモードではパスワード不要の cwallet.sso が代わりに読み込まれます。両方を設定すると起動時に拒否されます。TLS のみの ATP(ウォレットなし)の場合は、ウォレット関連の変数を空のままにし、OCI コンソールから完全な接続文字列を ATP_DSN に貼り付けます。

ウォレットは読み取り専用でバインドマウントされ、イメージに焼き込まれることはありません。

オンプレミス接続

ONPREM_HOST=oracle-onprem.internal.example.com
ONPREM_PORT=1521
ONPREM_SERVICE_NAME=CDMPRD
ONPREM_MODE=thin
# TCPS instead:
# ONPREM_DSN=tcps://host:2484/CDMPRD?ssl_server_dn_match=true

シンモードでは Oracle Client は不要です。シックモードは、シンモードにない機能が必要な場合のみ使用します。Dockerfile 内のコメントアウトされたステージを参照してください。

ドキュメント

ドキュメント

内容

docs/environment-configuration.md

このデプロイメントの接続設定方法と未解決項目

docs/architecture.md

アーキテクチャ、フロー、セキュリティ境界、RBAC、監査、エラー処理

docs/testing-scenarios.md

期待される結果を含む完全なテスト計画

docs/deployment-checklist.md

本番前チェックリストと改善バックログ

docs/conversation-flows.md

10 の実例と拒否フロー

prompts/system_prompt.md

チャットボットのシステムプロンプト

sql/

読み取り専用ユーザー、権限、監査スキーマ

mcp-clients/

Cursor および Claude Desktop の設定

本番稼働前の確認事項

リファレンス実装は、4 つの点で意図的に制限を設けています。docs/deployment-checklist.md で完全なリストを確認してください。主な項目は以下です:

  • ROLE_BINDING_MODE=env に設定する。.env.example のデフォルトは開発用であり、任意のロールを主張できてしまいます。

  • config/policy/*.yaml のサンプル許可リストを実際のものに置き換え、すべての列を意図的に分類する。

  • HTTP トランスポートを認証ゲートウェイの背後に配置する。 FastMCP の HTTP トランスポートはそれ自体では呼び出し元を認証しません。停止措置であり、制御策ではありません。

  • .env.example のコメントを読む。ここには、このデプロイメントを本番に近づけるために残された意図的なギャップがすべて記録されています(監査イベントの欠落、ADMIN による読み取り専用の回復、パスワードのローテーション、スロットリングなど)。

本番稼働前の完全なリストは docs/deployment-checklist.md を参照してください。要点は以下のとおりです:

  • .env.example の ROLE_BINDING_MODE=request を env に変更してください。そうしないと、ユーザーは任意のロールを宣言できます。

  • HTTPS または SSH トンネルを設定してください。HTTP は平文で、認証もされません。

  • シークレットをシークレットマネージャーに移行してください。.env は誰でも読める可能性があります。

  • 監査が期待どおりに機能することを確認してください。audit.log のローテーションを設定し、監査テーブルへのアクセスを制限してください。

ドキュメント

ドキュメント

内容

docs/environment-configuration.md

このデプロイメントの接続設定方法と未解決項目

docs/architecture.md

アーキテクチャ、リクエストフロー、セキュリティ境界、RBAC、監査、エラー処理

docs/testing-scenarios.md

期待される結果を含む完全なテスト計画

docs/deployment-checklist.md

本番稼働前チェックリストとハードニングのバックログ

docs/conversation-flows.md

10 の実践例と拒否フロー

prompts/system_prompt.md

チャットボットのシステムプロンプト

sql/

読み取り専用ユーザー、権限、監査スキーマ

mcp-clients/

Cursor および Claude Desktop の設定

本番稼働前の確認事項

この実装は、4 つの点で意図的に簡略化されています。完全なリストは docs/deployment-checklist.md を参照してください。主な項目:

  • ROLE_BINDING_MODE=env を設定する。.env.example のデフォルトは開発用です。

  • HTTP トランスポートを認証ゲートウェイの背後に置く。組み込みの HTTP サーバーには認証がありません。

  • 本番用のシークレット管理を使用する。Compose の環境変数は docker inspect で読めます。

  • 監査ログを WORM ストレージに送る。付属の audit_log テーブルは読み取り専用ユーザーからは隠蔽されていますが、本番では専用の保存先が必要です。

ライセンス

参照実装として MIT ライセンスで提供しています。


Oracle および Java は Oracle Corporation の登録商標です。その他の名称は各社の商標である場合があります。

Related MCP Connectors

Related MCP Servers