2025年11月28日金曜日

ORDSで実行するMCPサーバーをMLE/JavaScriptで記述する

先日の記事「ORDSのRESTサービスをClaude Desktopのカスタムコネクタとして登録して呼び出す」で、ORDSにMCPサーバーを実装しました。今回はPL/SQLの代わりにMLE/JavaScriptでMCPサーバーを実装してみます。

Oracle REST Data ServicesのProduct ManagerであるPeter O'Brienさんの、以下のブログ記事を参考に実装しています。

Implement an MCP Server with ORDS and MLE JavaScript
https://peterobrien.blog/2025/08/16/implement-an-mcp-server-with-ords-and-mle-javascript/

作成するリモートMCPサーバーはPL/SQLの実装と同じく、ツールとして任意のSELECT文を実行するrun_sqlとスキーマ情報を取得するget_schemaを含みます。

PL/SQLでの実装では、ツールを画面で定義したり、ORDSのRESTサービスとツールの紐付けを画面上でできるようにAPEXアプリを作成していました。MLE/JavaScriptによる実装は、Peter O'Brienさんの記事を参考にして、すべてをスクリプトで実装しています。

元記事にあるtools/list、tools/callの処理は、ツールであるrun_sqlおよびget_schemaが含まれるように書き直しています。

PL/SQLでは実装していた、ヘッダーMcp-Session-Idを使ったセッション管理については省略しています。そのためDELETEハンドラはありません。


今回はAutonomous AI DatabaseのSQL Developer Webより実装します。PL/SQLのときと同様にリモートMCPサーバーには認証による保護がかけられません。対応としてORDSのRESTサービスの事前認証済リクエストを活用してみます。

Autonomous AI DatabaseのSQL Developer Web(Database Actions)に接続し、管理者ユーザーのADMINにてサインインします。


RESTサービスを実装するデータベース・ユーザーを作成します。

管理データベース・ユーザーを開きます。


ユーザーの作成をクリックします。


作成するユーザー名は任意です。本記事ではMCPSERVERとしました。パスワードを設定します。

REST、GraphQL、MongoDB APIおよびWebアクセスオンにし、Webアクセス拡張機能承認が必要オフにします。REST別名は小文字のmcpserverとします。このREST別名はリモートMCPサーバーのURLに含まれます。

以上でユーザーの作成を実行します。


データベース・ユーザーMCPSERVERが作成されます。


本記事ではRESTハンドラをMLE/JavaScriptで記述します。そのため、作成したデータベース・ユーザーMCPSERVERに、MLE/JavaScriptを実行する権限を与えます。

開発SQLワークシートを開き、以下の2行のコマンドを実行します。

GRANT EXECUTE ON JAVASCRIPT TO MCPSERVER;
GRANT EXECUTE DYNAMIC MLE TO MCPSERVER;


以上で管理者ユーザーADMINの作業は完了です。

ADMINをサインアウトして、SQL Developer WebにユーザーMCPSERVERでサインインしなおします。


開発SQLワークシートを開き、RESTサービス(MCPサーバー)を実装したコードを貼り付けて実行します。


開発RESTを開きます。コードを実行したことで、Module、Template、Handlerが作成されていることが確認できます。


この状態で、リモートMCPサーバーを保護なしで呼び出すことができます。

権限による保護を適用します。

セキュリティ権限を開きます。


権限の作成をクリックします。


ラベルsamplejs MCP server access名前oracle.mcp.samplejs説明MCPサーバーsamplejsの保護と記述します。


ロールタブを開き、RESTful Servicesを選択します。


保護されたモジュールを開き、samplejsを選択します。

以上で権限を作成します。


権限oracle.mcp.samplejsが作成されました。これでリモートMCPサーバーであるRESTサービスは、認証しないと呼び出せない状態になりました。


ユーザー認証は実装できないので、代わりに事前承認済リクエストを作成します。

モジュールを開きます。

作成済みのモジュールsamplejsの3点メニューより、テンプレートを開きます。


モジュールsamplejsに含まれるテンプレートmcpの3点メニューより、ハンドラを開きます。


テンプレートmcpに含まれるPOSTハンドラの3点メニューより、事前承認済リクエストから事前承認済リクエストの作成を実行します。


トークンの有効期限(秒)を調整し、作成をクリックします。


事前承認済リクエストが作成されます。

使用するのはURLだけなので、URLコピーします。OKをクリックしてダイアログを閉じます。


以上で作業は完了です。

Claude Desktopにカスタムコネクタを追加します。リモートMCPサーバーURLに、上記でコピーした事前承認済リクエストを指定します。

コネクタの設定画面を開き、カスタムコネクタの追加をクリックします。


コネクタの名前samplejsとします。リモートMCPサーバーURL事前承認済リクエストを設定します。

追加をクリックします。


ダイアログが再度開いたら、キャンセルをクリックして閉じます。


カスタムコネクタとしてsamplejsが追加されます。設定をクリックして確認します。


設定を開くと、ツールとしてget_schemarun_sqlが認識されていることが確認できます。


Claude Desktopで新規チャットを開始し、ツールsamplejsの動作を確認します。

「samplejsから確認できるデータを教えて。」

今までの手順通りに作業をしていると、スキーマMCPSERVERはほぼ空です。なので、実装したツールを呼び出して出来ることも少ないのですが、ツール自体が動作することは確認できます。


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

2025年11月27日木曜日

ORDSのRESTサービスをClaude Desktopのカスタムコネクタとして登録して呼び出す

Oracle REST Data Servicesで作成したRESTサービスを、Claude Desktopにカスタムコネクタとして追加して呼び出します。実際には、リモートMCPサーバーに見えるようにORDSのRESTサービスを作成します。とりあえずRESTサービスを呼び出せることは確認できましたが、Oracle REST Data Servicesには、Claude Desktopがカスタムコネクタに要求しているOAuth2.1 + PKCE Authorization Codeフローは実装されていません。

以下の記事で作成したORDSのRESTサービスを、Claude Desktopのカスタムコネクタとして登録します。

Oracle REST Data ServicesのRESTサービスとしてStreamable HTTPを話すMCP Serverを実装してみる

詳しい作業内容は元記事を参照していただくとして、本記事ではClaude Desktopのカスタムコネクタとして追加して、データベースに問い合わせるまでを実施します。


カスタムコネクタとして追加するリモートMCPサーバーは、DNSでホスト名が参照でき、かつ、HTTPSで通信する必要があります。そのため、今回の作業はAlways FreeのAutonomous AI Databaseで行います。

Autonomous AI DatabaseにAPEXのワークスペースとしてAPEXDEVが作成済みとします。

以下のAPEXアプリケーションをワークスペースにインポートします。
https://github.com/ujnak/apexapps/blob/master/exports/chat-with-generative-ai-hc-242.zip

アプリケーション・ビルダーよりインポートを実行します。


インポートするファイルとしてchat-with-generative-ai-hc-242.zipを選択します。ファイル・タイプアプリケーション、ページまたはコンポーネントのエクスポートです。

へ進みます。


アプリケーションのインストールを実行します。


アプリケーションがインストールされると、サポートするオブジェクトのインストールの確認を求めれらます。

サポートするオブジェクトとして、表OPENAI_TOOLSとファンクションget_schemarun_sqlが作成され、属性などの定義情報が表に挿入されます。これらの定義情報を、リモートMCPサーバーで流用します。

サポートするオブジェクトのインストールをクリックします。


APEXアプリケーションと、それをサポートするオブジェクトがインストールされました。


インストールされたアプリケーションを実行し、ナビゲーション・メニューのToolsを開きます。

MCPサーバーのツールにあたる設定として、run_sqlget_schemaが登録済みです。run_sqlおよびget_schemaは、PL/SQLのファンクションとして実装されています。この2つのツールはCountriesという名前のTool Setとしてまとめられています。


次にリモートMCPサーバーの実装をサポート・スクリプトとして含む、以下のAPEXアプリケーションをインポートします。作業手順は、先ほどのchat-with-generative-ai-hc-242.zipと同じです。
https://github.com/ujnak/apexapps/blob/master/exports/mcp_handler.zip

APEXアプリケーションがインストールされると、パッケージMCP_HTTP_SERVER_PKGMCP_SAMPLEが作成されます。またORDSのRESTサービスとしてsampleseverが作成されます。

インストールされたAPEXアプリケーションを実行します。

作成をクリックし、ORDSのRESTサービスとMCPサーバーの実装を紐付けます。


今回は、APEXアプリケーションをインポートしたときに作成されたORDS RESTサービスsampleserverと、MCPサーバーの実装MCP_SAMPLEを使います。

Ords Url/ords/[ワークスペース名]/sampleserverを指定します。ワークスペース名はアプリケーションをインポートしたワークスペース名を、小文字で指定します。Apex App IDはデフォルトで、このアプリケーション自身のアプリケーションIDになります。変更は不要です。Apex Page IDのこのAPEXアプリケーションのホーム・ページのIDになります。変更は不要です。これらはAPEXセッションを開始する際に使用します。

Package NameMCP_SAMPLEを指定します。このパッケージにMCPサーバーに必要なinitialize、tools/list、tools/callなどに対応した処理が、プロシージャとして実装されています。

Log Level4Tool SetCountriesを選択します。Tool SetのCountriesにはget_schemaおよびrun_sqlがツールとして含まれています。

以上で作成をクリックします。


/ords/apexdev/sampleserverとパッケージMCP_SAMPLEの紐付けができました。


作成済みのORDS RESTサービスの保護を解除します。

ORDS RESTサービスのsampleserverは、インポート時に権限oracle.example.mcpによって保護されるように構成しています。

Claude Desktopからカスタムコネクタとして呼び出すために、保護を解除しなければなりません。

SQLワークショップRESTfulサービスを開き、権限oracle.example.mcpを選択します。

保護されたモジュールからsampleserverを除外します。


変更の適用をクリックします。


Oracle REST Data Servicesの認証を解除すると、APEXワークスペース・スキーマがユーザーになるようにコードを書いています。そのため、同名のAPEXユーザーを作成します。

ワークスペースの管理ユーザーとグループの管理を開きます。


ユーザーの作成をクリックします。


ユーザー名はAPEXのワークスペース・スキーマの名前にします。それ以外の必須項目である、電子メール・アドレスパスワードを設定します。

ユーザーの作成をクリックします。

以上でユーザーの作成をクリックします。


ユーザーが作成されました。


以上でClaude Desktopにカスタムコネクタとして登録する準備は完了です。

RESTfulサービスのモジュールsampleserverに含まれるテンプレートmcpを選択し、完全なURLをコピーします。このURLがリモートMCPサーバーURLとして指定する値になります。


Claude Desktopの設定コネクタを開きます。

カスタムコネクタを追加をクリックします。


カスタムコネクタを追加のダイアログが開きます。

名前My Custom ConnectorリモートMCPサーバーURLには、テンプレートmcp完全なURLをペーストします。

追加をクリックします。


なぜかまたダイアログが開きます。これは、キャンセルします。


My Custom Connectorが追加されています。設定を開いて確認します。


設定を開くと、ツールとしてget_schemaおよびrun_sqlが認識されていることが確認できます。


以上でOracle REST Data Servicesで作成したRESTサービスを、Claude Desktopのカスタムコネクタとして設定することができました。

サンプル・データセットをインストールすると、記事の先頭にあるGIF動画の問い合わせを実行できます。


ユーザー認証の実装はできていないため実用的とは言えないですが、何かの役には立つと思います。

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

2025年11月26日水曜日

LeafletのQuick Start GuideをAPEXアプリケーションに実装してみる

2Dのマップ表示の用途で人気の高いLeafletによるマップを、Oracle APEXのアプリケーションに組み込んでみます。組み込む機能はLeafletのQuick Start Guideで紹介されている、以下を対象とします。
  • ラスタタイルの表示(国土地理院タイルを使用します)
  • マーカーの表示/非表示、およびポップアップの表示/非表示
  • サークルの表示/非表示、およびポップアップの表示/非表示
  • ポリゴンの表示/非表示、およびポップアップの表示/非表示
  • スタンドアロンのポップアップ表示/非表示
  • マップ上のクリックによるポップアップの表示
上記を実装したAPEXアプリケーションは、以下のように動作します。渋谷のスクランブル交差点を中心に地図を表示し、マーカー、サークルおよびポリゴン(道玄坂)などを表示しています。


Leaflet Quick Start Guideに沿って、APEXアプリケーションの組み込みを実施します。

空のアプリケーションを作成します。名前Leafletとします。


APEXアプリケーションが作成されます。今回はデフォルトで作成されるホーム・ページに、すべての機能を実装します。


ページ・デザイナホーム・ページを開きます。

ホーム・ページに、Quick Start GuideのPreparing your pageに記載されている設定を加えます。

Oracle APEXには、ページにロードするJavaScriptファイルを指定するプロパティとして、JavaScriptファイルURLCSSファイルを指定するプロパティとして、CSSファイルURLがあります。

LeafletのQuick Start Guideでは、ロードするCSSファイルおよびJavaScriptファイルに属性integritycrossoriginの指定が含まれています。これらは、APEXのプロパティでは設定できません。また、必ずCSSファイルをJavaScriptファイルの前にロードするように指示されています。こちらについては、ページ・プロパティのCSSファイルURL(link要素)は、必ずJavaScriptファイルURL(script要素)よりも先にHTMLとして出力されます。

integritycrossoriginの設定を残すために、ページ・プロパティHTMLヘッダーに、Quick Start Guideに記載されている内容をそのまま転記します。
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
 <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""></script>
CSSインラインでマップの高さを指定します。Quick Start Guideでは180pxとなっていますが、それよりも高い640pxを設定します。

#map { height: 640px; }


Leafletを初期化するdiv要素を含むリージョンを作成します。

識別名前Mapタイプ静的コンテンツソースHTMLコードに以下を記述します。

<div id="map"></div>


以上で、Preparing your pageに記載されている内容をホーム・ページに設定できました。

Leafletの初期化から、マーカーの表示/非表示、サークルの表示/非表示など、JavaScriptによる実装はすべて、静的アプリケーション・ファイルに記述します。以下のファイルを、静的アプリケーション・ファイルとして保存します。名前はapp.jsとします。



LeafletのQuick Start Guideでは、マーカー、サークルおよびポリゴンを表示するコードは紹介されていますが、それを非表示にするコードはありません。上記のapp.jsには、非表示にするコードも追加しています。

マーカーなどの表示/非表示はAPEXアクションとして定義し、ページ上のボタンとカスタム属性data-actionによって紐付けています。

ページ・ロード時に静的アプケーション・ファイルapp.jsがロードされるように、ページ・プロパティJavaScriptファイルURLに以下を設定します。

#APP_FILES#app#MIN#.js


静的アプリケーション・ファイルに記述したAPEXアクションを呼び出すボタンを、ページ上に作成します。

ボタンを一列で配置するために、静的コンテンツのリージョンを作成します。外観テンプレートButtons Containerを選択します。


APEXアクションを呼び出すボタンを作成します。

ボタンの詳細カスタム属性に記述するdata-actionで、APEXアクションに紐付けます。

data-action="TOGGLE_MARKER"

ボタンのクリックでページの送信などが動作しないように、動作アクション動的アクションで定義を設定します。

識別ラベルは、data-actionで紐づけられたAPEXアクションのlabel属性の値に置き換わります。そのため、ページでの設定値は画面に表示されません。


同様にTOGGLE_CIRCLETOGGLE_POLYGONTOGGLE_MARKER_POPUPTOGGLE_CIRCLE_POPUPTOGGLE_POLYGON_POPUPTOGGLE_STANALONE_POPUPのボタンを作成します。

これらのボタンは、TOGGLE_MARKERと横一列に並べるため、レイアウト新規行の開始オフにします。それ以外はdata-actionに、それぞれに紐づけるAPEXアクション名を設定します。


以上でAPEXアプリケーションは完成です。アプリケーションを実行すると、記事の先頭にあるGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/leaflet-quick-start-on-apex.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。