2025年8月15日金曜日

SQLclのMCPサーバーのデータベース接続にTOKEN_AUTH=AZURE_INTERACTIVEの設定を使用する

本記事では、SQLclのMCPサーバーからデータベースに接続する際に、Entra IDとの対話型のユーザー認証を行うように構成します(TOKEN_AUTH=AZURE_INTERACTIVE)。

Claude Desktopでは以下のように、MCPサーバーがデータベースに接続するときにブラウがが開いて、ユーザー認証を要求します。


記事「SQLclのMCPサーバーのデータベース接続をMicrosoft Entra IDのOAuth2で認証する」に沿って、Autonomous DatabaseとしてSALESADB、Entra IDにアプリケーションとしてSALESADBが作成されていることを前提とします。

Microsoft Entra IDの設定


Albert Balbekovさんの以下の記事に沿った作業を実施します。

Azure AD (Entra ID) Tokens: 1. Entra ID App Registrations
Register Client in Entra ID


クライアントとなるアプリケーションを作成します。

アプリの登録を開き、新規作成を実行します。


作成するアプリケーションの名前SALESADB-CLIとします。サポートされているアカウントの種類この組織ディレクトリのみに含まれるアカウント (既定のディレクトリ のみ - シングル テナント)を選択します。

リダイレクトURIのタイプとしてパブリック クライアント/ネィティブ(モバイルとデスクトップ)を選択し、リダイレクトURIとしてhttp://localhostを設定します。

以上でアプリケーションを登録します。


アプリケーションSALESADB-CLIが作成されます。

後で参照するため、アプリケーション(クライアント)IDをコピーして保存します。その後に、リダイレクトURIの設定を開き、パブリッククライアントフローの設定を確認します。


設定を開きます。


設定を開くとパブリッククライアントフローを許可するという設定があります。デフォルトでは無効になっています。

この設定を有効に切り替えます。


変更した設定を保存したいのですが、保存ボタンが見つかりません

仕方がないので、To switch to the old experience, please click hereのリンクをクリックし、以前の設定画面に変更します。

詳細設定パブリッククライアントフローを許可する次のモバイルとデスクトップのフローを有効にするはいに変更します。

以上で保存をクリックします。


アプリの登録に戻り、データベースSALESADBに紐づけられているアプリケーションSALESADBを開きます。


APIの公開を開き、クライアントアプリケーションの追加を実行します。


クライアントID
に先ほどコピーしたアプリケーションSALESADB-CLIアプリケーション(クライアント)IDを設定します。

承認済みのスコープチェックし、アプリケーションの追加をクリックします。


承認済みのクライアント・アプリケーションとしてSALESADB-CLIが追加されます。


以上でEntra IDの設定は完了です。


SQLclの構成



データベースへ接続するツールとしてSQLclを使用します。sqlcl-latest.zipには、Entra IDによる認証に使用するライブラリが含まれていません。

テスト用にSQCclを展開し、Azure認証プロバイダのライブラリを追加します。

作業ディレクトリにsqlcl-latest.zipおよびデータベースSALESADBへの接続に使用するウォレットWallet_SALESADB.zipを置いておきます。

ls 

azure % ls

sqlcl-latest.zip Wallet_SALESADB.zip

azure % 


sqlcl-latest.zipを展開し、環境変数PATHを更新します。

unzip sqlcl-latest.zip
export PATH=$PWD/sqlcl/bin:$PATH


azure % unzip sqlcl-latest.zip 

Archive:  sqlcl-latest.zip

   creating: sqlcl

   creating: sqlcl/bin

   creating: sqlcl/lib

   creating: sqlcl/lib/ext

  inflating: sqlcl/NOTICES.txt       

  inflating: sqlcl/LICENSE.txt       

  inflating: sqlcl/THIRD-PARTY-LICENSES.txt  

  inflating: sqlcl/25.2.2.199.0918   

  inflating: sqlcl/bin/version.txt   

  inflating: sqlcl/bin/dependencies.txt  


[中略]


  inflating: sqlcl/lib/oci-java-sdk-common.jar  

  inflating: sqlcl/lib/orajsoda.jar  

  inflating: sqlcl/lib/quartz.jar    

  inflating: sqlcl/lib/javassist.jar  

azure % export PATH=$PWD/sqlcl/bin:$PATH

azure % 


以下の内容のファイルをpom.xmlとして作成します。


oracle-provider-azureと従属するライブラリを、ディレクトリtarget/dependency以下に一括ダウンロードします。

mvn dependency:copy-dependencies

azure % mvn dependency:copy-dependencies

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called

WARNING: sun.misc.Unsafe::staticFieldBase has been called by com.google.inject.internal.aop.HiddenClassDefiner (file:/opt/homebrew/Cellar/maven/3.9.11/libexec/lib/guice-5.1.0-classes.jar)

WARNING: Please consider reporting this to the maintainers of class com.google.inject.internal.aop.HiddenClassDefiner

WARNING: sun.misc.Unsafe::staticFieldBase will be removed in a future release

[INFO] Scanning for projects...

[INFO] 

[INFO] ---------------------< local:sqlcl-azure-provider >---------------------

[INFO] Building sqlcl-azure-provider 1.0

[INFO]   from pom.xml

[INFO] --------------------------------[ jar ]---------------------------------

[INFO] 

[INFO] --- dependency:3.7.0:copy-dependencies (default-cli) @ sqlcl-azure-provider ---

[INFO] com.oracle.database.jdbc:ojdbc-provider-azure:jar:1.0.6 already exists in destination.

[INFO] com.oracle.database.jdbc:ojdbc-provider-common:jar:1.0.6 already exists in destination.

[INFO] com.oracle.database.jdbc:ojdbc8:jar:23.8.0.25.04 already exists in destination.

[INFO] com.oracle.database.security:oraclepki:jar:23.8.0.25.04 already exists in destination.


[中略]


[INFO] net.java.dev.jna:jna:jar:5.13.0 already exists in destination.

[INFO] net.java.dev.jna:jna-platform:jar:5.13.0 already exists in destination.

[INFO] com.azure:azure-data-appconfiguration:jar:1.8.0 already exists in destination.

[INFO] com.azure:azure-security-keyvault-secrets:jar:4.9.4 already exists in destination.

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:  0.403 s

[INFO] Finished at: 2025-08-15T15:03:40+09:00

[INFO] ------------------------------------------------------------------------

azure % 


ディレクトリtarget/dependencyの内容を確認します。

ls target/dependency

azure % ls target/dependency 

accessors-smart-2.5.2.jar

asm-9.7.1.jar

azure-core-1.55.3.jar

azure-core-http-netty-1.15.11.jar

azure-data-appconfiguration-1.8.0.jar

azure-identity-1.16.1.jar

azure-json-1.5.0.jar

azure-security-keyvault-secrets-4.9.4.jar

azure-xml-1.2.0.jar

content-type-2.3.jar

jackson-annotations-2.17.2.jar

jackson-core-2.17.2.jar

jackson-databind-2.17.2.jar

jackson-datatype-jsr310-2.17.2.jar

jcip-annotations-1.0-1.jar

jna-5.13.0.jar

jna-platform-5.13.0.jar

json-smart-2.5.2.jar

lang-tag-1.7.jar

msal4j-1.20.1.jar

msal4j-persistence-extension-1.3.0.jar

netty-buffer-4.1.118.Final.jar

netty-codec-4.1.118.Final.jar

netty-codec-dns-4.1.112.Final.jar

netty-codec-http-4.1.118.Final.jar

netty-codec-http2-4.1.118.Final.jar

netty-codec-socks-4.1.118.Final.jar

netty-common-4.1.118.Final.jar

netty-handler-4.1.118.Final.jar

netty-handler-proxy-4.1.118.Final.jar

netty-resolver-4.1.118.Final.jar

netty-resolver-dns-4.1.112.Final.jar

netty-resolver-dns-classes-macos-4.1.112.Final.jar

netty-resolver-dns-native-macos-4.1.112.Final-osx-x86_64.jar

netty-tcnative-boringssl-static-2.0.70.Final-linux-aarch_64.jar

netty-tcnative-boringssl-static-2.0.70.Final-linux-x86_64.jar

netty-tcnative-boringssl-static-2.0.70.Final-osx-aarch_64.jar

netty-tcnative-boringssl-static-2.0.70.Final-osx-x86_64.jar

netty-tcnative-boringssl-static-2.0.70.Final-windows-x86_64.jar

netty-tcnative-boringssl-static-2.0.70.Final.jar

netty-tcnative-classes-2.0.70.Final.jar

netty-transport-4.1.118.Final.jar

netty-transport-classes-epoll-4.1.118.Final.jar

netty-transport-classes-kqueue-4.1.118.Final.jar

netty-transport-native-epoll-4.1.118.Final-linux-x86_64.jar

netty-transport-native-kqueue-4.1.118.Final-osx-x86_64.jar

netty-transport-native-unix-common-4.1.118.Final.jar

nimbus-jose-jwt-10.0.1.jar

oauth2-oidc-sdk-11.23.jar

ojdbc-provider-azure-1.0.6.jar

ojdbc-provider-common-1.0.6.jar

ojdbc8-23.8.0.25.04.jar

oraclepki-23.8.0.25.04.jar

reactive-streams-1.0.4.jar

reactor-core-3.4.41.jar

reactor-netty-core-1.0.48.jar

reactor-netty-http-1.0.48.jar

slf4j-api-1.7.36.jar

azure % 


これらのライブラリを./sqlcl/lib/ext/以下にコピーします。

cp -i ./target/dependency/* ./sqlcl/lib/ext

azure % cp -i ./target/dependency/* ./sqlcl/lib/ext

azure % 


SQLclの構成は以上で完了です。


TOKEN_AUTH=AZURE_DEVICE_CODEでの接続



tnsnames.oraの記述を更新するため、Wallet_SALESADB.zipを解凍します。

unzip -d tns_admin Wallet_SALESADB.zip

azure % unzip -d tns_admin Wallet_SALESADB.zip 

Archive:  Wallet_SALESADB.zip

  inflating: tns_admin/ewallet.pem   

  inflating: tns_admin/README        

  inflating: tns_admin/cwallet.sso   

  inflating: tns_admin/tnsnames.ora  

  inflating: tns_admin/truststore.jks  

  inflating: tns_admin/ojdbc.properties  

  inflating: tns_admin/sqlnet.ora    

  inflating: tns_admin/ewallet.p12   

  inflating: tns_admin/keystore.jks  

azure %


展開したディレクトリを環境変数TNS_ADMINに設定します。

export TNS_ADMIN=$PWD/tns_admin

azure % export TNS_ADMIN=$PWD/tns_admin

% 


今までの設定でデータベースに接続できるか確認するため、管理者ユーザーADMINSALESADBに接続します。

sql admin@salesadb_low

azure % sql admin@salesadb_low



SQLcl: 金 8月 15 15:13:56 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


パスワード (**********?) **************

Last Successful login time: 金 8月  15 2025 15:14:02 +09:00


接続先:

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems

Version 23.9.0.25.08


SQL> exit

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems

Version 23.9.0.25.08から切断されました

azure %


データベースSALESADBに接続できました。

TOKEN_AUTH=AZURE_DEVICE_CODEを指定する際に必要なTENANT_IDCLIENT_IDAZURE_DB_APP_ID_URIの値を、Entra IDの画面から取得します。

アプリケーションSALESADB概要を開き、アプリケーションIDのURIの値をコピーします。この値をAZURE_DB_APP_ID_URIとして設定します。


アプリケーションSALESADB-CLI概要を開き、アプリケーション(クライアント)IDの値をコピーします。この値をCLIENT_IDとして設定します。次にディレクトリ(テナント)IDの値をコピーします。この値をTENANT_IDとして設定します。


tns_admin/tnsnames.oraTOKEN_AUTHTENANT_IDCLIENT_IDAZURE_DB_APP_ID_URIの指定を加えた、以下のようなエントリSALESADB_AZCODEを追加します。
salesadb_azcode = (
    description = (retry_count=20)(retry_delay=3)
    (address = (protocol=tcps)(port=1522)(host=adb.ca-toronto-1.oraclecloud.com))
    (connect_data = (service_name=g____________f_salesadb_low.adb.oraclecloud.com))
    (security = (ssl_server_dn_match=yes)(TOKEN_AUTH=AZURE_DEVICE_CODE)
               (TENANT_ID=3940511e-****-****-****-01b080952758)
               (CLIENT_ID=0133b47d-****-****-****-2a5dcacd41a0)
               (AZURE_DB_APP_ID_URI=api://c276626e-****-****-****-a87ff322acb6))
)
追加したTNS名SALESADB_AZCODEを使って、データベースSALESADBに接続します。

sql /@salesadb_azcode

azure % sql /@salesadb_azcode    



SQLcl: 金 8月 15 15:35:50 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code NW2ALBJQ8 to authenticate.



ブラウザでhttps://microsoft.com/deviceloginを開き、表示されているコードを入力します。

次へ進みます。


Entra IDに登録されたユーザーでサインインします。以下のスクリーンショットは、すでにサインインしているため、サインイン済みのユーザーを選択しています。


アプリケーションSALESADB-CLIにサインインします。

続行をクリックします。


アプリケーションSALESADB-CLIにサインインできました。


SCLclでは、データベースへの接続が完了しています。

azure % sql /@salesadb_azcode    



SQLcl: 金 8月 15 15:35:50 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code NW2ALBJQ8 to authenticate.

接続先:

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems

Version 23.9.0.25.08


SQL> 


以下のSELECT文を実行し、接続ユーザーを確認します。
select
    sys_context('userenv','session_user') as session_user,
    sys_context('userenv','current_user') as current_user,
    sys_context('userenv','authenticated_identity') as azure_user
from dual;

SQL> select

  2      sys_context('userenv','session_user') as session_user,

  3      sys_context('userenv','current_user') as current_user,

  4      sys_context('userenv','authenticated_identity') as azure_user

  5* from dual;


SESSION_USER    CURRENT_USER    AZURE_USER                                                    

_______________ _______________ _____________________________________________________________ 

MCPUSER         MCPUSER         yu__._______outlook.com_EXT_@_______soutlook.onmicrosoft.com    


SQL> exit

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems

Version 23.9.0.25.08から切断されました

azure % 


システム・コンテキストUSERENVAUTHENTICATED_IDENTITYに、Entra IDでのupnの値が設定されていることが確認できます。

以上で、TOKEN_AUTH=AZURE_DEVICE_CODEでの認証を確認できました。


TOKEN_AUTH=AZURE_INTERACTIVEでの接続



tns_admin/tnsnames.oraにエントリSALESADB_AZCODETOKEN_AUTHAZURE_INTERACTIVEに変更したエントリSALESADB_AZINTを作成します。
salesadb_azint = (
    description = (retry_count=20)(retry_delay=3)
    (address = (protocol=tcps)(port=1522)(host=adb.ca-toronto-1.oraclecloud.com))
    (connect_data = (service_name=g____________f_salesadb_low.adb.oraclecloud.com))
    (security = (ssl_server_dn_match=yes)(TOKEN_AUTH=AZURE_INTERACTIVE)
               (TENANT_ID=3940511e-****-****-****-01b080952758)
               (CLIENT_ID=0133b47d-****-****-****-2a5dcacd41a0)
               (AZURE_DB_APP_ID_URI=api://c276626e-****-****-****-a87ff322acb6))
)

追加したTNS名SALESADB_AZINTを使って、データベースSALESADBに接続します。

sql /@salesadb_azint

azure % sql /@salesadb_azint



SQLcl: 金 8月 15 15:58:45 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.



ブラウザが起動してユーザーのサインインを求められるところまでは進むのですが、そこから先に進めません。


AZURE_DEVICE_CODEではユーザー認証できるため、Entra IDおよびデータベースの設定に不備はないはずです。

調べたところ、AZURE_INTERACTIVEでブラウザが開かれた時のURLは以下で始まります。

https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?scope=openid+

このorganizationsの指定が曖昧なため、サインインに失敗する模様です。organizationsの部分を、URLを直接編集してテナントIDに置き換えます。

置き換えた後にEnterを入力してページを更新します。


ページの表示は変わりませんが、URLは変更されています。先ほどのEnterの入力時は、HTTPのGETリクエストが発行されてページが更新されています。

今度はユーザーを選択し、変更したURLにPOSTリクエストを発行します。これがユーザー認証のリクエストになります。


Authentication complete. You can close the browser and return to the application.と表示されます。


SQLclを確認すると、データベースへの接続が確立されています。

AZURE_DEVICE_CODEのときと同様のSELECT文を実行し、AUTHENTICATED_IDENTITYを確認します。

Entra IDのユーザーで認証されていることが確認できます。

SQL> select

  2      sys_context('userenv','session_user') as session_user,

  3      sys_context('userenv','current_user') as current_user,

  4      sys_context('userenv','authenticated_identity') as azure_user

  5* from dual;


SESSION_USER    CURRENT_USER    AZURE_USER                                                    

_______________ _______________ _____________________________________________________________ 

MCPUSER         MCPUSER         yuji.________outlook.com_EXT_@_________kksoutlook.onmicrosoft.com    


SQL> 


あまり実用的でないワークアラウンドですが、かろうじてTOKEN_AUTH=AZURE_INTERACTIVEでの接続が確認できました。


MCPサーバーの確認



TOKEN_AUTH=AZURE_INTERACTIVEでの接続を、MCPサーバーで使用できるように保存します。

保存する名前はsalesadb-azとします。

conn -save salesadb-az -savepwd /@salesadb_azint

azure % sql /nolog          



SQLcl: 金 8月 15 17:38:11 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


SQL> conn -save salesadb-az -savepwd /@salesadb_azint

名前: salesadb-az

接続文字列: salesadb_azint

ユーザー: 

パスワード: 未保存

接続しました.

SQL> exit

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems

Version 23.9.0.25.08から切断されました

azure % 


connmgr listを実行し、接続salesadb-azが保存されていることを確認します。

azure % sql /nolog



SQLcl: 金 8月 15 17:42:44 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


SQL> connmgr list

.

├── adb-free-23ai-freepdb1-wksp_apexdev

├── local-23ai-freepdb1-sys

├── local-23ai-freepdb1-wskp_apexdev

├── mydb

└── salesadb-az

SQL> exit

azure % 


環境変数TNS_ADMINが必ず設定され、また、このディレクトリに配置したSQLclが実行されるように、以下のスクリプトを作成します。
#!/bin/sh

WD=/Users/xxxxxxxxxx/Documents/azure
export TNS_ADMIN=$WD/tns_admin
$WD/sqlcl/bin/sql -mcp
WDに設定するディレクトリは、それぞれの環境に合わせて変更します。作成したスクリプトに、実行権限を付与します。

chmod 755 sql-mcp.sh

azure % chmod 755 sql-mcp.sh 

azure % 


Claude DesktopにMCPサーバーとして登録します。実行するcommandとして、先ほど作成したsql-mcp.shをフルパスで記述します。
{
  "mcpServers": {
    "sqlcl": {
      "command": "/Users/xxxxxxxxx/Documents/azure/sql-mcp.sh"
    }
  }
}
Claude DesktopでMCPサーバーsqlclを有効にして、salesadb-azに接続します。

ユーザー認証が必要なときは、ブラウザが開きます。前の章で紹介したURLのorganizationsテナントIDに変更すると、ユーザー認証に成功します。

ユーザー認証に成功すると、Claude Desktopからデータベースにアクセスできるようになります。


きちんと使用するにはあと少し足りませんが、データベース・ユーザーではなくEntra IDに個人として登録したユーザーによって、オラクル・データベースにアクセスできるようになりました。

Oracle Databaseには仮想プライベート・データベースやReal Application Securityといった、認識した個人ごとにデータベースへのアクセスを制限する機能があります。また、Unified Auditingでは監査レコードにAUTHENTICATED_IDENTITYの値を記録することもできます。

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