2026年9月8日火曜日

MCP Toolbox for DatabasesをOracle IAMでOIDC認証する

先日の記事「GoogleのMCP Toolbox for DatabasesをOracle Databaseで使用してみる」にて構成したOracle Databaseに接続するMCP Toolbox for Databasesに、OpenID Connectによる認証を実装します。IdPにはOracle IAMを使用します。

MCP Toolbox for DatabaseでのOpenID Connectの設定については、以下で説明されています。

Documentation / Configuration / Authentication / Generic OIDC Auth
Generic OIDC Auth

MCPとしての認証は2. MCP Authorizationに記載があります。ドキュメントに記載されている設定例は以下です。
kind: authService
name: my-generic-auth
type: generic
audience: ${YOUR_TOKEN_AUDIENCE}
authorizationServer: https://your-idp.example.com
mcpEnabled: true
scopesRequired:
  - read
  - write
kind, name, type, mcpEnabled(これはtrueにする)は、MCP Toolboxとしての設定です。IdP側(今回はOracle IAM)から入手する必要がある設定値はaudienceauthorizationServerscopesRequiredになります。

MCP Toolboxとしては、authorizationServerの値はアクセス・トークンのiss(Issuer)の値と一致し、かつ、/.well-known/openid-configurationを加えることでOIDCのDiscovery URLとなることを期待しているようです。そのDiscovery URLより取得できるドキュメントに含まれる属性jwks_uriより、JWTの署名検証用の公開鍵を取得します。

Oracle IAMが発行するトークンのデフォルトの発行者(Issuer - issの値)はhttps://identity.oraclecloud.com/です。この発行者に/.well-known/openid-configurationをつけてもOIDC Discovery URLにはならないため、Oracle IAM側の発行者は変更する必要があります。

audienceはOracle IAMのドメインに作成した統合アプリケーションプライマリ・オーディエンスとして設定した値になります。プライマリ・オーディエンスを設定するには、統合アプリケーションにリソース・サーバーを構成する必要があります。

Oracle IAMではクライアントから提示されたスコープにより、リソース・サーバーが選択されます。そのため、リソース・サーバーにスコープを設定し、そのスコープがユーザー認証時にサーバーに送信されるように接続元のクライアント(今回はMCP Inspector)を構成する必要があります。リソース・サーバーに構成されたスコープは、MCP ToolboxのscopesRequiredに含めます。

MCP Toolboxに設定する値は、上記のように決まります。

以下より、Oracle IAMのドメインでの設定を行います。作業には費用がかからないドメイン・タイプFreeの、Defaultドメインを使用します。

Oracle Cloudのコンソールから、アイデンティティとセキュリティドメインを開きます。

ドメインDefaultを開きます。


ドメインURLをコピーします。このURLに/.well-known/openid-configurationを付けるとOIDC Discovery URLとなります。この値がMCP ToolboxのauthorizationServerの値の元になります。MCP ToolboxはauthorizationServerの値がIssuerの値であることを期待しているため、このドメインURL発行者とする必要があります。ドメインURLの末尾のポート番号:443があると発行者として設定できないため、発行者として登録するURLから:443を削除します。

結果としてMCP ToolboxのauthorizationServerとして設定する値は、ドメインURLから末尾の:443を除いたURLになります。


発行者を上記のドメインURLに変更します。

セキュリティ・タブを選択し、Oauth設定 - デフォルトのトークン発行ポリシーOAuth設定の編集を開きます。


デフォルトのトークン発行ポリシー発行者ドメインURL(ポート番号無し)を設定します。

変更の保存をクリックします。


デフォルトのトークン発行ポリシー発行者が更新されたことを確認します。


統合アプリケーションを作成します。

統合アプリケーション・タブを開き、アプリケーションの追加をクリックします。


アプリケーションのタイプとして機密アプリケーションを選択します。

ワークフローの起動をクリックします。


作成する機密アプリケーションの名前MCP Hotelsとします。説明は何でもよいのですが、Search for a hotelと記述しています。認証と認可権限付与を認可として実施オンにします。

以上を設定して送信します。


統合アプリケーションMCP Hotelsが作成されます。


OAuth構成・タブを選択し、OAuth構成の編集をクリックします。リソース・サーバー構成クライアント構成の双方を実施します。


クライアント構成はリソース・サーバーの構成を参照するため、リソース・サーバー構成を先に実施します。

このアプリケーションをリソース・サーバーとして今すぐ構成します、を選択します。選択すると、設定画面が表示されます。

必須ではありませんが、トークン・リフレッシュの許可オンにします。

プライマリ・オーディエンスはMCP Toolbox for Databasesの構成に依存します。今回はローカルホストでデフォルトのポート番号である5000番で接続を待ち受けるように構成しているため、プライマリ・オーディエンスは以下になります。最後にスラッシュをつけます。

http://localhost:5000/

これはMCP Toolboxのaudienceとして設定する値になります。また、MCP Toolboxの起動オプションの--toolbox-urlとして指定する値でもあります。

スコープの追加オンにし、スコープとしてmcphotelsを追加します。

ここで設定したスコープmcphotelsは、MCP ToolboxのscopesRequiredに含めます

リソース・サーバーを構成したところで、一旦送信します。


追加したスコープmcphotelsは、表示名MCP Hotels説明Search for a hotel.としています。


先ほどと同様にOAuth構成の編集を開き、今度はクライアント構成を実施します。

このアプケーションをクライアントとして今すぐ構成します、を選択します。選択すると、設定画面が表示されます。

認可認可される権限付与タイプとして、クライアント資格証明(これはおそらく無くてもよい)、リフレッシュ・トークン(リソース・サーバーでリフレッシュ・トークンを構成し、クライアントからもリフレッシュ・トークンを要求する場合に必要)、認可コード(必須)をチェックします。

HTTPS以外のURLを許可オンにし、今回クライアントとして使用するMCP InspectorのリダイレクトURLとして、以下の4つを設定します。

http://localhost:6274/oauth/callback
http://localhost:6274/oauth/callback/debug
http://127.0.0.1:6274/oauth/callback
http://127.0.0.1:6274/oauth/callback/debug

Claude CodeやOpenAI Codexから呼び出す場合は、それぞれのアプリケーションで決められているリダイレクトURLを追加します。

ページの下に移動し、リソースの追加をオンにします。

スコープの追加をクリックし、スコープとして統合アプリケーションMCP Hotelshttp://localhost:5000/mcphotels(リソース・サーバーのプライマリ・オーディエンスhttp://localhost:5000/とスコープmcphotelsが連結)を追加します。

以上で送信します。


リソースの追加を行う画面です。

統合アプリケーションMCP Hotelsより範囲(スコープのこと)の選択にある、スコープhttp://localhost:5000/mcphotelsにチェックを入れます。


ここで選択したスコープhttp://localhost:5000/mcphotelsは、MCP InspectorのOAuth設定のスコープに含めます

以上で統合アプリケーションMCP Hotelsの構成は完了です。

OAuth構成よりクライアントIDクライアント・シークレットを取得します。

これらの値は、MCP InspectorのOAuth SettingsClient IDClient Secretとして設定します。


作成した統合アプリケーションMCP Hotelsアクティブ化します。


ユーザー・タブを開き、この統合アプリケーションで認証できるユーザーを割り当てます。

ユーザーの割当てをクリックします。


今回の作業を行なっているユーザーを割り当てます。


作成した統合アプリケーションで認証できるユーザーが割り当てられました。


以上で、Oracle IAMでの作業は完了です。

先日の記事で作成したtools.yamlに以下を追記します。OIDC認証の設定oracle-iam-authに加え、アクセス・トークンのsubクレームの値を表示するツールshow_sub_claimを定義しています。

ツールshow_sub_claimの第1パラメータとしてuser_idを設定しています。この値はauthServicesで設定しているoracle-iam-auth、つまりOracle IAMによるOIDC認証で得られたアクセス・トークンのsubの値になります。この値はSELECT文のバインド変数:1に割り当てられます。user_idはパラメータとして定義しているため、MCP Inspectorからツールを呼び出す際に値の入力を求められます。値を入力してもアクセス・トークンのsubの値で置き換えられますが、requiredfalseを設定(デフォルトはtrueなので、必ず値が必要)することにより、user_idを入力しなくてもツールを実行できるようにしています。
---
kind: authService
name: oracle-iam-auth
type: generic
authorizationServer: [発行者として設定したドメインURL(ポート番号無し)]
audience: http://localhost:5000/
mcpEnabled: true
scopesRequired:
  - openid
  - mcphotels
---
# show sub claim in access token
kind: tool
name: show_sub_claim
type: oracle-sql
source: my-oracle-instance
statement: |
  SELECT :1 sub from dual
description: |
  Show sub claim value in the access token
parameters:
  - name: user_id 
    type: string
    required: false
    description: Auto-populated from token
    authServices:
      - name: oracle-iam-auth
        field: sub
authRequired:
  - oracle-iam-auth
MCP Toolboxを実行する際に--toolbox-urlとしてaudience(resource)を指定します。

./toolbox --config tools.yaml --toolbox-url http://localhost:5000/

mcp-toolbox % ./toolbox --config tools.yaml --toolbox-url http://localhost:5000/

2026-09-08T13:20:06.905274+09:00 INFO "Starting MCP Toolbox for Databases version 1.10.0+binary.darwin.arm64.21f972f" 

2026-09-08T13:20:06.983898+09:00 INFO "Initialized 1 sources: my-oracle-instance" 

2026-09-08T13:20:08.061104+09:00 INFO "Initialized 1 authServices: orcle-iam-auth" 

2026-09-08T13:20:08.061141+09:00 INFO "Initialized 0 embeddingModels: " 

2026-09-08T13:20:08.06143+09:00 INFO "Initialized 4 tools: show_sub_claim, execute_sql, list_all_hotels, list_hotels_in_the_location" 

2026-09-08T13:20:08.061451+09:00 INFO "Initialized 0 prompts: " 

2026-09-08T13:20:08.061472+09:00 INFO "Initialized 1 groups: default" 

2026-09-08T13:20:08.061722+09:00 WARN "wildcard (*) allows any website to access the primitives. This creates a security risk regardless of whether you are in a production or local development environment. Recommended to use --allowed-origins with specific local addresses." 

2026-09-08T13:20:08.061774+09:00 WARN "wildcard (*) hosts allow any domain to access this resource, making it vulnerable to DNS rebinding attacks regardless of whether you are in a production or local development environment. For improved security, use the --allowed-hosts flag to specify trusted domains." 

2026-09-08T13:20:08.062055+09:00 INFO "Server ready to serve!" 



MCP Inspectorに登録済みのMCP ToolboxのServer Settingsを開きます。


OAuth SettingsClient IDClient SecretScopesを設定します。Scopesに設定する値は以下です。指定するスコープにプライマリ・オーディエンスを含めます。

openid http://localhost:5000/mcphotels


以上で設定はすべて完了です。

動作確認を実施します。

MCP InspectorよりMCP ToolboxのMCPサーバーに接続します。


Oracle CloudのIdentity Domainへのサインインが求められます。


Authenticatorを使ったユーザー認証が行われサインインが完了すると、アプリケーションMCP Hotelsへのアクセス許可が要求されます。

アクセスを許可すると、MCP Toolboxへの接続が完了します。


Toolsタブを開き、ツールshow_sub_claimを選択します。

パラメータuser_idには値を設定できますが、user_idの値はアクセス・トークンのsubの値に置き換えられるため、設定する意味はありません。

user_idには値を設定せずExecute Toolを実行します。


ツールの実行結果として、SUBにサインインに使用したメール・アドレスが返されます。


ツールoracle-sqlに設定するSELECT文にOIDCで認証したユーザー名を渡せるため、ツールの検索範囲をユーザーごとに制限することができます。

今回の記事は以上になります。

2026年9月7日月曜日

GoogleのMCP Toolbox for DatabasesをOracle Databaseで使用してみる

GoogleのMCP Toolbox for DatabaseがMCPの2026-07-28を実装したので、Oracle Databaseに接続して使用してみました。

Introduction

オープン・ソースのSDKがOracle Databaseをサポートしていることは少ない印象があるのですが、MCP ToolboxではOracle Databaseを使うことができます。

Oracle using MCP
Oracle Source

利用できるツールはoracle-execute-sql(任意のSQLの実行)、oracle-sql(事前に定義したSQLの実行)の2種類です。ドキュメントには他のツールもありますが、これはoracle-sqlツールにSELECT文を事前定義したツールのようです。

できるだけ時間をかけずに動作確認ができる手順で作業をします。

接続先のOracle Databaseとして手元のMacでコンテナとして動作している、Oracle AI Database 26ai Freeを使用します。接続先はlocalhost:1521/freepdb1になります。接続先となるデータベース・ユーザーはあらかじめ作成しておきます。

動作確認をするクライアントとしてMCP Inspectorを使います。バージョンがv2に上がって、UIが大幅に変更されています。

MCP Inspectorを使用する手順は、Getting StartedのQuickstart(MCP)に記載されています。

Quickstart(MCP)

Quickstart(MCP)のStep 1: Set up your databaseでセットアップするデータベースはpostgresです。今回の接続先はOracle Databaseを想定しているため、以下のスクリプトを実行します。
CREATE TABLE hotels (
  id            NUMBER PRIMARY KEY,
  name          VARCHAR2(80) NOT NULL,
  location      VARCHAR2(80) NOT NULL,
  price_tier    VARCHAR2(80) NOT NULL,
  checkin_date  DATE NOT NULL,
  checkout_date DATE NOT NULL,
  booked        NUMBER NOT NULL CHECK (booked IN (0, 1))
);

alter session set nls_date_format = 'YYYY-MM-DD';

INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-22', '2024-04-20', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-24', '2024-04-05', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-23', '2024-04-01', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-27', '2024-04-02', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-24', '2024-04-09', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', 0);
INSERT INTO hotels(id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES (10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', 0);

commit;
exit;
MCP Toolboxのバイナリをダウンロードします。リリースのページを開き、適切なOS/Architectureのリンクから、バイナリをダウンロードします。私の環境はApple SiliconのmacOSなので、darwin/arm64のバイナリをダウンロードしています。MCP Toolboxは頻繁にアップデートされているようなので、最新のリリースを選択します。2026年9月7日の時点ではv1.10.0でした。



最初はPrebuiltのツールを使用します。Oracle向けのPrebuiltツールを使用する設定については、以下に記載されています。

Prebuilt Configs / Oracle

ダウンロードしたバイナリtoolboxに実行フラグを立てます。

chmod +x toolbox

mcp-toolbox % chmod +x toolbox 

mcp-toolbox % 


MCP ToolboxのPrebuilt構成が必要とする環境変数を設定します。Prebuilt構成を使用する場合、tools.yamlといった構成ファイルは不要です。

export ORACLE_CONNECTION_STRING="ホスト名:ポート番号/サービス名"
export ORACLE_USERNAME="データベース・ユーザー"
export ORACLE_PASSWORD="パスワード"
ORACLE_USE_OCI=false


ORACLE_USE_OCIをtrueにする場合、Oracle Instant Clientが必要です。今回はローカルのコンテナで実行しているOracle AI Database 26ai Freeを接続先とするため、ORACLE_USE_OCIをfalseとしています。Autonomous AI Databaseの場合はtrueにする必要があるでしょう。

mcp-toolbox % export ORACLE_CONNECTION_STRING="localhost:1521/freepdb1"

mcp-toolbox % export ORACLE_USERNAME="apexdev"

mcp-toolbox % export ORACLE_PASSWORD="パスワード"

mcp-toolbox % ORACLE_USE_OCI=false

mcp-toolbox % 


MCP ToolboxをOracleのPrebuilt構成で実行します。

./toolbox --prebuilt oracledb

Server ready to serve!と表示されれば、MCPサーバーとして接続できる状態です。

mcp-toolbox % ./toolbox --prebuilt oracledb                            

2026-09-07T14:24:21.940256+09:00 INFO "Starting MCP Toolbox for Databases version 1.10.0+binary.darwin.arm64.21f972f" 

2026-09-07T14:24:21.942172+09:00 INFO "Using prebuilt tool configurations for: oracledb" 

2026-09-07T14:24:21.942183+09:00 WARN "These prebuilt configs are intended for 'build-time' use cases, where agents are helping trusted developers build things. They are not secure enough for 'run time' use cases, where the agent will be talking to potentially untrusted developers." 

2026-09-07T14:24:22.016809+09:00 INFO "Initialized 1 sources: oracle-source" 

2026-09-07T14:24:22.016839+09:00 INFO "Initialized 0 authServices: " 

2026-09-07T14:24:22.016862+09:00 INFO "Initialized 0 embeddingModels: " 

2026-09-07T14:24:22.017076+09:00 INFO "Initialized 7 tools: list_top_sql_by_resource, list_tablespace_usage, list_invalid_objects, execute_sql, list_tables, list_active_sessions, get_query_plan" 

2026-09-07T14:24:22.017088+09:00 INFO "Initialized 0 prompts: " 

2026-09-07T14:24:22.017102+09:00 INFO "Initialized 2 groups: default, oracle_database_tools" 

2026-09-07T14:24:22.017493+09:00 WARN "wildcard (*) allows any website to access the primitives. This creates a security risk regardless of whether you are in a production or local development environment. Recommended to use --allowed-origins with specific local addresses." 

2026-09-07T14:24:22.017532+09:00 WARN "wildcard (*) hosts allow any domain to access this resource, making it vulnerable to DNS rebinding attacks regardless of whether you are in a production or local development environment. For improved security, use the --allowed-hosts flag to specify trusted domains." 

2026-09-07T14:24:22.017822+09:00 INFO "Server ready to serve!" 


MCP Inspectorを実行します。

npx @modelcontextprotocol/inspector

% npx @modelcontextprotocol/inspector


Starting MCP inspector...


MCP Inspector Web is up and running at:

   http://127.0.0.1:6274?MCP_INSPECTOR_API_TOKEN=26f426782a8a0ed97e6e2d79b1fd4941d91f06803defe71e92a0d77e22dbeb0e


   Sandbox (MCP Apps): http://127.0.0.1:6275/sandbox


   Auth token: 26f426782a8a0ed97e6e2d79b1fd4941d91f06803defe71e92a0d77e22dbeb0e


   Secrets: OS keychain


Opening browser...



ブラウザが起動し、MCP Inspectorの画面が開きます。

最初にAdd Serversから+ Add manuallyを実行します。現在実行中のMCP ToolboxをMCPサーバーとして登録します。


Server IDmcp-toolboxとします。Transportstreamable-httpを選択し、URLhttp://localhost:5000/mcpを設定します。MCP Toolboxはデフォルトで、リクエストをHTTPの5000番ポートで待ち受けます。


MCPサーバーmcp-toolboxが登録されます。Settingsを開きます。


新しいv2のMCP Inspectorは、MCPの2026-07-28を含むMCPの拡張機能に対応しています。


Advertise ExtensionsにはTasks(非同期実行)およびMCP Apps UIのサポートが含まれています。


OAuth SettingsEnterprise-managed authorizationが含まれています。


MCPサーバーに接続すると、クライアント/サーバー間のメッセージのやり取りが表示されます。


Connection Infoをクリックします。


Server Capabilitiesを見る範囲では、サポートされているのは実質的にToolsのみのようです。


Prebuilt構成として提供されているツールを確認します。Toolsタブを開きます。

execute_sqlは任意のSQLを実行するツールです。それ以外のget_query_plan、list_active_sessions、list_invalid_objects、list_tables、list_tablespace_usage、list_top_sql_by_resourceは受け付けるパラメータの有無はありますが、事前定義されたSQLを実行しているようです。


execute_sqlツールを選択し、sqlとしてselect * from hotelsを記述します。

Execute Toolをクリックし、sqlに与えたSELECT文を実行します。


表HOTELSの内容がJSONドキュメントとして返されます。


Prebuilt構成について、動作が確認できました。

Prebuilt構成で実質的に使用できるツールは、任意のSQLを実行するツールexecute_sqlのみです。それだけでは実用的ではないため、ツールを構成してみます。

任意のSQLを実行するツールとしてexecute_sqlは残し、その他に、すべてのホテルをリストするツールlist_all_hotelsと、指定したロケーションにあるホテルを、検索する上限を設定して返すツールlist_hotels_in_the_lcoationを作成します。

tools.yamlとして以下を記述します。Oracle Databaseの接続先、ユーザー名やパスワードは、Prebuilt構成の際に設定した環境変数を利用します。
kind: source
name: my-oracle-instance
type: oracle
connectionString: ${ORACLE_CONNECTION_STRING}
user: ${ORACLE_USERNAME}
password: ${ORACLE_PASSWORD}
---
# Execute arbitrary SQL.
kind: tool
name: execute_sql
type: oracle-execute-sql
source: my-oracle-instance
description: Use this tool to execute sql statement.
---
# List All hotels.
kind: tool
name: list_all_hotels
type: oracle-sql
source: my-oracle-instance
statement: |
  SELECT * FROM hotels
description: |
  Use this tools to list all hotels.
---
# List hotels located in specific location.
kind: tool
name: list_hotels_in_the_location
type: oracle-sql
source: my-oracle-instance
statement: |
  SELECT * FROM hotels WHERE location = :1
  FETCH FIRST :2 ROWS ONLY
description: |
  List hotels located in specified location. 
  Return the specified number of hotels.
  Example: 
  {{
      "location": "Basel",
      "limit": 10
  }}
parameters:
  - name: location
    type: string
    description: location of the hotel
  - name: limit
    type: integer
    description: number of the hotels to be returned
作成したtools.yamlを構成ファイルとして指定し、toolboxを実行します。

./toolbox --config tools.yaml

mcp-toolbox % ./toolbox --config tools.yaml

2026-09-07T15:34:36.871842+09:00 INFO "Starting MCP Toolbox for Databases version 1.10.0+binary.darwin.arm64.21f972f" 

2026-09-07T15:34:36.926093+09:00 INFO "Initialized 1 sources: my-oracle-instance" 

2026-09-07T15:34:36.926127+09:00 INFO "Initialized 0 authServices: " 

2026-09-07T15:34:36.926146+09:00 INFO "Initialized 0 embeddingModels: " 

2026-09-07T15:34:36.926185+09:00 INFO "Initialized 3 tools: execute_sql, list_all_hotels, list_hotels_in_the_location" 

2026-09-07T15:34:36.926192+09:00 INFO "Initialized 0 prompts: " 

2026-09-07T15:34:36.926206+09:00 INFO "Initialized 1 groups: default" 

2026-09-07T15:34:36.926224+09:00 WARN "wildcard (*) allows any website to access the primitives. This creates a security risk regardless of whether you are in a production or local development environment. Recommended to use --allowed-origins with specific local addresses." 

2026-09-07T15:34:36.926339+09:00 WARN "wildcard (*) hosts allow any domain to access this resource, making it vulnerable to DNS rebinding attacks regardless of whether you are in a production or local development environment. For improved security, use the --allowed-hosts flag to specify trusted domains." 

2026-09-07T15:34:36.926503+09:00 INFO "Server ready to serve!" 



MCP Inspectorからツール一覧を確認します。

tools.yamlに設定したツールexecute_sqllist_all_hotelslist_hotels_in_the_locationの3つが現れていることが確認できます。


ツールlist_hotels_in_the_locationを選択すると、パラメータとして設定したlimitlocationの入力を要求されます。それぞれ、3Baselと入力し、Execute Toolを実行します。


locationがBaselのホテルが3つリストされます。


Oracle Corporationからは、ツール開発部門より3種類のMCPサーバーが提供されています。

Oracle MCP Servers

また、それとは別にAutonomous AI Database向けのMCPサーバーが提供されています。

Autonomous AI Database MCP Server
https://www.oracle.com/autonomous-database/mcp-server/

ユースケースによっては、オープンソースのMCPサーバーも検討する価値はあるでしょう。例えば、オンプレミスのOracle Database向けのMCPサーバーはSQLclかORDSで実装することになりますが、現状では両方ともカスタム・ツールの実装をサポートしていません。また、Oracle Databaseの他にもデータ・ソースがあり、それらを同様にOIDC認証したい場合など、認証はMCP Toolboxが行うためデータ・ソースごとの設定は不要になります。確認していませんが、OIDC認証で受け取るIDトークンのsubの値をSQLの引数として渡すこともできるようなので、データの検索範囲も認証されたユーザーに応じて制限できそうです。

2026年9月4日金曜日

Oracle Databaseの問合せ結果変更通知(QRCN)の動作を確認する

Oracle Backend for Firebaseではサーバー側で発生した変更をクライアントに通知する際に、Oracle Databaseの機能のひとつである連続問合せ通知(CQN - Continuous Query Notification)を使用しています。

データベース開発ガイド, リリース26
20 連続問合せ通知(CQN)の使用

通知の種類には、オブジェクト変更通知(OCN - Object Change Notification)と問合せ結果変更通知(Query Result Change Notification)の2種類があります。表に保存されているデータを対象とした場合、データの新規作成、変更、削除を正確に捉えるにはトリガーを使います。ただし、トリガーを作成するとデータを操作するトランザクションに影響を与えます。連続問合せ通知は、登録したオブジェクトまたは問い合わせ結果の変更がコミットされたときに通知が行われます。PL/SQLによる実装では、登録したコールバック・プロシージャが通知として呼び出されます。トリガーとは異なり、データを変更したトランザクションの外でコールバック・プロシージャの処理が行われるため、通知を登録しても元のトランザクションに影響を与えません。

問合せ結果変更通知トリガーの違いを説明します。

問合せ結果変更通知には、通知を発生させたトランザクションのトランザクションIDと、変更された行のROWIDが含まれます。問合せ結果変更通知では、以下の状況が発生しえます。
  1. 表EMPの列SALの値を3000から4000に変更し、コミットします。
  2. 上記のトランザクションIDと変更された行のROWIDを含んだデータが、通知として呼び出されたPL/SQLのコールバック・プロシージャに渡されます。
  3. コールバック・プロシージャ内で表EMPの列SALの値を、渡されたROWIDを条件として検索できます。しかし、列SALの値は4000であるとは限りません。
  4. 上記1と3の間に、列SALの値が更新されている可能性があります。
  5. 通知が発生した時点での列SALの値を求めるには、渡されたトランザクションIDを条件としてFlashback Queryを実行して求める必要があります。そこまでする必要があるなら、トリガーを使ったほうが簡単でしょう。
従って、問合せ結果変更通知は名前の通り、データが変更されたことを通知するために使用します。変更された時点でのデータが重要な場合は、トリガーを使用します。

連続問合せ通知(CQN - Continuous Query Notification)はOracle Database 11gからある機能のようですが、まったく聞いたことありませんでした。そのため、APEXアプリケーションを作成して簡単な動作確認をしてみました。

結論を先にいうと、Oracle AI Database 26ai Free 23.26.3.0では不具合があり、動作確認以上のことはできませんでした。

テストに使用したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/APEXlang-exports/tree/main/continuous-query-notification-test

以下のサイトを使うと、APEXにインポート可能なZIPファイルとしてダウンロードできます。
https://download-directory.github.io/

APEXアプリケーションをインポートする前に、APEXのワークスペース・スキーマで連続問合せ通知を使用するための権限を与えます。

GRANT CHANGE NOTIFICATION TO <スキーマ名>;
GRANT EXECUTE ON DBMS_CQ_NOTIFICATION TO <スキーマ名>;


DBAユーザーで実行します。

SQL> GRANT CHANGE NOTIFICATION TO apexdev;


Grantが正常に実行されました。


SQL> GRANT EXECUTE ON DBMS_CQ_NOTIFICATION TO apexdev;


Grantが正常に実行されました。


SQL> 


動作確認に、APEXのサンプル・データセットのEMP/DEPTを使用します。このデータセットに含まれる表EMPに問合せ結果変更通知を設定します。

サンプル・データセットEMP/DEPTを、あらかじめAPEXワークスペースにインストールしておきます。

以上で準備は完了です。ダウンロードしたAPEXアプリケーションを、APEXワークスペースにインポートします。サポート・オブジェクトをインストールすると、アプリケーションが使用する表、パッケージおよびプロシージャが作成されます。

インポートされたアプリケーションには、以下の機能が実装されています。

Employees - 表EMPを編集します。問合せ結果変更通知を発生させるために使用します。
Definitions - 問合せ結果変更通知の登録と削除を行います。
Notifications - 発生した通知を確認します。
Official Example - 公式ドキュメントにある表NFEVENTS、NFQUERIES、NFTABLECHANGES、NFROWCHANGESに保存されたデータを一覧します。


最初にDefinitionsのページをより、問合せ結果変更通知を設定します。

設定の際に呼び出されるコードは以下です。

Ownerに指定した従業員の給与と手当の変更が通知の対象になります。


OwnerSCOTTを指定した場合、検知対象のSELECT文として、以下の2行が登録されます。

SELECT APEXDEV.EMP.SAL FROM APEXDEV.EMP WHERE APEXDEV.EMP.ENAME = 'SCOTT'
SELECT APEXDEV.EMP.COMM FROM APEXDEV.EMP WHERE APEXDEV.EMP.ENAME = 'SCOTT'

それぞれ異なるQueryIDが割り振られます。通知として呼び出されるPL/SQLのコールバック・プロシージャにQueryIDも渡されるため、QueryIDから変更されたのが列SALなのか列COMMなのかが判別できます。


従業員SCOTTを変更通知の対象としています。

ナビゲーション・メニューよりEmployeesを開き、従業員SCOTTの給与と手当を更新します。


通知の際に呼び出されるPL/SQLプロシージャTCQ_CALLBACKのコードは以下です。


ナビゲーション・メニューNotificationsを開き、コールバック内で生成した通知メッセージを一覧します。

今回の操作で生成されたメッセージは以下です。列SALおよびCOMMは1つのトランザクションで更新していますが、問合せ結果変更通知として設定したSELECT文は2行なので、通知も2行になります。メッセージにCurrent value is ...と記述していますが、これは通知が参照した値であって、通知の元となったトランザクションで変更された値とは限りません。

SAL query result changed. Current value is 4000.
COMM query result changed. Current value is 200.


ここまでは、問合せ結果変更通知としての動作を確認できます。

この状態から問合せ結果変更通知を追加しようとすると、エラーが発生することがあります。


OpenAI Codexに以下を指示して、障害解析をしてもらいました。


Codexから色々と解析した結果が報告されましたが、最終的にORA-7445が発生しているのでオラクルの不具合だろう、との結論が返されました。

実際に行われた確認作業が分からなかったので、Codexに確認しました。正解といっていいでしょう。


adrciについても、指示通りに実行すると以下の結果が得られました。

adrci> show incident -mode detail -p "incident_id=21599"


ADR Home = /opt/oracle/diag/rdbms/free/FREE:

*************************************************************************


**********************************************************

INCIDENT INFO RECORD 1

**********************************************************

   INCIDENT_ID                   21599

   STATUS                        ready

   CREATE_TIME                   2026-09-04 04:38:50.580000 +00:00

   PROBLEM_ID                    2

   CLOSE_TIME                    <NULL>

   FLOOD_CONTROLLED              none

   ERROR_FACILITY                ORA

   ERROR_NUMBER                  7445

   ERROR_ARG1                    ktcn_is_safe_plsql

   ERROR_ARG2                    SIGSEGV

   ERROR_ARG3                    ADDR:0xFD33BC7E9918

   ERROR_ARG4                    PC:0x2B75020

   ERROR_ARG5                    Address not mapped to object

   ERROR_ARG6                    <NULL>

   ERROR_ARG7                    <NULL>

   ERROR_ARG8                    <NULL>

   ERROR_ARG9                    <NULL>

   ERROR_ARG10                   <NULL>

   ERROR_ARG11                   <NULL>

   ERROR_ARG12                   <NULL>

   SIGNALLING_COMPONENT          Transactions

   SIGNALLING_SUBCOMPONENT       <NULL>

   SUSPECT_COMPONENT             <NULL>

   SUSPECT_SUBCOMPONENT          <NULL>

   ECID                          <NULL>

   IMPACTS                       0

   CON_UID                       3461734982

   PROBLEM_KEY                   ORA 7445 [ktcn_is_safe_plsql]

   FIRST_INCIDENT                12071

   FIRSTINC_TIME                 2026-09-04 01:52:57.428000 +00:00

   LAST_INCIDENT                 21599

   LASTINC_TIME                  2026-09-04 04:38:50.580000 +00:00

   IMPACT1                       0

   IMPACT2                       0

   IMPACT3                       0

   IMPACT4                       0

   KEY_NAME                      PdbName

   KEY_VALUE                     FREEPDB1

   KEY_NAME                      Client ProcId

   KEY_VALUE                     oracle@5f1c1e0baa79 (TNS V1-V3).56677_247037836460048

   KEY_NAME                      SID

   KEY_VALUE                     72.31772

   KEY_NAME                      ECID

   KEY_VALUE                     G6pjTKaG1v3V07ocxodqlg.17

   KEY_NAME                      Service

   KEY_VALUE                     freepdb1

   KEY_NAME                      Module

   KEY_VALUE                     APEXDEV/APEX:APP 100:5

   KEY_NAME                      PQ

   KEY_VALUE                     (16777219, 1788496729)

   KEY_NAME                      Action

   KEY_VALUE                     Processes - point: AFTER_SUBMIT,

   KEY_NAME                      ProcId

   KEY_VALUE                     96.5

   OWNER_ID                      1

   INCIDENT_FILE                 /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_56677_1.trc

   OWNER_ID                      1

   INCIDENT_FILE                 /opt/oracle/diag/rdbms/free/FREE/incident/incdir_21599/FREE_ora_56677_i21599.trc

1 row fetched


adrci> 


現在のAIは、適切なツール連携と必要な権限があれば、Oracle Databaseで発生したバグのトリアージに必要な情報を能動的に収集し、分析を進めることができるようです。

問合せ結果変更通知の不具合については残念でしたが、Oracle Databaseの障害調査でAI(OpenAI Codex)が使えるのが分かったことは収穫でした。

今回の記事は以上になります。