2026年4月17日金曜日

OpenAI CodexからリモートMCPサーバー経由でOracle Databaseに問い合わせる

以下の手順で作成したリモートMCPサーバーsampleserverにOpenAI Codexから接続し、プラグインを作成してみます。Microsoft Entra IDによるユーザー認証を行なうように構成します。
最初にCodexにMCPサーバーを作成します。~/.codex/config.tomlを直接編集します。アプリから設定する場合は、設定MCPサーバーから作成します。


config.tomlに以下の記述を追加します。MCPサーバーはconnector_for_oracle_datababaseと命名します。
[mcp_servers.connector_for_oracle_database]
url = "https://OpenRestyが動作しているホスト名/ords/apexdev/sampleserver/mcp"
bearer_token_env_var = "ORACLE_MCP_TOKEN"
CodexではMCPサーバーを以下のように設定すると、OAuthによるユーザー認証ができるようです。(mcp_oauth_callback_urlをEntra IDのアプリにリダイレクトURIとして設定する必要あり)
[mcp_servers.connector_for_oracle_database]
url = "https://OpenRestyが動作しているホスト名/ords/apexdev/sampleserver/mcp"

# --- OAuth callback ---
mcp_oauth_callback_port = 8787
mcp_oauth_callback_url = "http://localhost:8787/callback"
MCPサーバーconnector_for_oracle_databaseをユーザー認証するため、codexコマンドを実行します。

codex mcp login connector_for_oracle_database

~ % codex mcp login connector_for_oracle_database

Error: Registration failed: Dynamic registration failed: Registration failed: Dynamic client registration not supported

~ % 


config.toml内でOAuthのクライアントIDを設定する方法がドキュメントから見つからないため、エラー・メッセージにあるようにDynamic Client Registrationが必須と思われます。Microsoft Entra IDはDCRに対応していないため、CodexとEntra IDの組み合わせでOAuth2によるユーザー認証はできないようです。

諦めてbearer_token_env_varを使うように設定します。環境変数ORACLE_MCP_TOKENにEntra IDが発行したアクセス・トークンを設定します。

az loginコマンドを実行し、Entra IDにサインインします。

az login --tenant "テナントID" --scope "アプリORDS MCPで公開しているスコープ"

ブラウザが立ち上がり、Entra IDに登録されているユーザーによるユーザー認証が求められます。


ブラウザでのユーザー認証が完了すると、Select a subscription and tenant (Type a number or Enter for no changes):と聞かれます。そのままEnterを入力し、az loginコマンドを完了します。

~ % az login --tenant "********-****-****-****-************" --scope "api://********-****-****-****-************/mcp:connect"

A web browser has been opened at https://login.microsoftonline.com/********-****-****-****-************/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.


Retrieving subscriptions for the selection...


[Tenant and subscription selection]


No     Subscription name     Subscription ID                       Tenant

-----  --------------------  ------------------------------------  ------------------------------------

[1] *  Azure subscription 1  ********-****-****-****-************  ********-****-****-****-************


The default is marked with an *; the default tenant is '********-****-****-****-************' and subscription is 'Azure subscription 1' (********-****-****-****-************).


Select a subscription and tenant (Type a number or Enter for no changes): 


Tenant: ********-****-****-****-************

Subscription: Azure subscription 1 (********-****-****-****-************)


[Announcements]

With the new Azure CLI login experience, you can select the subscription you want to use more easily. Learn more about it and its configuration at https://go.microsoft.com/fwlink/?linkid=2271236


If you encounter any problem, please open an issue at https://aka.ms/azclibug


[Warning] The login output has been updated. Please be aware that it no longer displays the full list of available subscriptions by default.


ynakakoshi@Ns-Macbook ~ % 


Entra IDへのサインインが完了したので、アクセス・トークンを取得し環境変数ORACLE_MCP_TOKENに設定します。

export ORACLE_MCP_TOKEN=$(az account get-access-token \
--scope "
アプリORDS MCPで公開しているスコープ" \
--query accessToken -o tsv)

~ % export ORACLE_MCP_TOKEN=$(az account get-access-token \

--scope "api://*********-****-****-****-********/mcp:connect" \

--query accessToken -o tsv)

~ % echo $ORACLE_MCP_TOKEN

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlUxc1g4W

[中略]

7jbOqbhJSQ1Dk-CoHPF_yJPJGO2OPJEUjhIBehPC-abRHHVPXeiRC

ZuDTRAvZzVrSAW97jSQ0PFmMQ

~ % 


以上でアクセス・トークンが環境変数ORACLE_MCP_TOKENに設定されました。アクセス・トークンの有効期間は通常1時間程度なので、az account get-access-tokenコマンドは定期的に発行する必要があります。

コマンドラインから(デスクトップ・アプリの)Codexを起動します。以下はmacOSでの作業です。

open -a Codex

Codexが起動します。

作成されたMCPサーバーを確認します。

サイド・メニューよりプラグインを選択し、管理するを開きます。


MCPを選択するとConnector For Oracle Databaseが作成されていることが確認できます。


新しいプロジェクトを追加して、作業を進めます。


販売分析というプロジェクトを作成し、作業を進めます。


Connector for Oracle Databaseに繋げられるかを確認します。

 「Connector for Oracle Databaseに接続して、接続ユーザーを確認して。」

ツールget_current_userが呼び出され、アクセス・トークンのsubの値が表示されます。MCPサーバーに接続できていることが確認できます。


Connector For Oracle Databaseを使用したプラグインを作成します。

サイド・メニューよりプラグインを開き、作成からプラグインを作成を実行します。


Plugin Createrにたいして、以下の文言を与えて実行します。

「SHスキーマに保存されている販売履歴より、典型的な分析ができるプラグインを作成してください。」


CodexがMCPサーバーのツールを呼び出し、プラグインを作成していきます。


たまにツール実行の許可やファイル操作の許可を求められます。


プラグインの作成が完了したら、プラグインをインストールします。

「作成されたプラグインをインストールして」


サイド・メニューよりプラグインを開きます。


Local Analytics Plugins(またはLocal Plugins)を選択し、プラグインSH Sales Analyticsをインストールします。


プラグインSH Sales Analystをインストールします。


プラグインがインストールされます。

プロジェクトのチャット画面に移り、インストールされたプラグインを呼び出します。


プラグインを使って、分析してもらいます。

「SHスキーマの月次売上推移と成長率を分析して」


色々とツールを呼び出して、最終的な回答まで進みます。


Microsoft Entra IDとの連携は残念な感じですが、プラグインやスキル次第で、Codexをコーディング以外の作業で使用することもできそうです。

MCP AppsのサンプルアプリCohort Heatmap Serverをデータベースで実行する

GitHubのリポジトリmodelcontextprotocol/ext-appsに含まれているCohort Heatmap Serverをデータベースでホストしてみます。作業はBudget Allocator Serverと同じですが、TypeScriptで記述されたserver.tsのPL/SQLへの変換は、すべてClaude Opus 4.7に実施してもらいました。

Claude DesktopのChatから呼び出しています。


Claude Codeでのセッション履歴はこちらから参照できます。このセッションでのコンテキストウィンドウの使用量は87.2kでした。生成されたファイルは、リポジトリmcp-appのexamples/cohort-heatmap-server以下に保存されています。今回もオリジナルのTypeScriptの実装を忠実に反映しているかどうかは確認していません。MCPアプリが動作すれば、それで良しとしています。

Claudeはデータベース・サーバーへの実装まで行なう勢いでしたが、それは遠慮して自分で作業することにしました。

これからはBudget Allocator Serverの実装と同じ作業を行います。

サーバーをインストールします。スクリプトはchs_install.sqlとして作成されています。

sql -cloudconfig Wallet_SALESADB.zip wksp_apexdev@salesadb_low
@mcp-app/examples/cohort-heatmap-server/chs_install.sql


mcp-salesadb % sql -cloudconfig Wallet_SALESADB.zip wksp_apexdev@salesadb_low


SQLcl: 金 4月 17 12:58:41 2026のリリース25.4 Production


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


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

接続先:

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.31.0.1.0


SQL> @mcp-app/examples/cohort-heatmap-server/chs_install.sql 


Table CHS_METRIC_PARAMSは作成されました。



Table CHS_DATASET_METAは作成されました。



Table CHS_PERIODSは作成されました。



Table CHS_COHORTSは作成されました。



Table CHS_COHORT_CELLSは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Procedure CHS_GENERATE_COHORT_DATAがコンパイルされました



Function CHS_GET_COHORT_DATA_RESPONSEがコンパイルされました



1行挿入しました。



1行挿入しました。



1行挿入しました。



コミットが完了しました。



PL/SQLプロシージャが正常に完了しました。



コミットが完了しました。


{"content":[{"type":"text","text":"Cohort Analysis: 12 cohorts, 12 periods\nAverage retention: 60.5%\nMetric: retention, Period: monthly"}],"structuredContent":{"cohorts":[{"cohortId":"2025-05","cohortLabel":"May 2025","originalUsers":3329,"cells":[{"cohortIndex":0,"periodIndex":0,"retention":1,"usersRetained":3329,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":1,"retention":0.831585,"usersRetained":2768,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":2,"retention":0.742468,"usersRetained":2472,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":3,"retention":0.692134,"usersRetained":2304,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":4,"retention":0.597086,"usersRetained":1988,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":5,"retention":0.506757,"usersRetained":1687,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":6,"retention":0.485,"usersRetained":1615,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":7,"retention":0.469762,"usersRetained":1564,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":8,"retention":0.41277,"usersRetained":1374,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":9,"retention":0.384362,"usersRetained":1280,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":10,"retention":0.309279,"usersRetained":1030,"usersOriginal":3329},{"cohortIndex":0,"periodIndex":11,"retention":0.307191,"usersRetained":1023,"usersOriginal":3329}]},{"cohortId":"2025-06","cohortLabel":"Jun 2025","originalUsers":3247,"cells":[{"cohortIndex":1,"periodIndex":0,"retention":1,"usersRetained":3247,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":1,"retention":0.809895,"usersRetained":2630,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":2,"retention":0.778759,"usersRetained":2529,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":3,"retention":0.63884,"usersRetained":2074,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":4,"retention":0.615927,"usersRetained":2000,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":5,"retention":0.530365,"usersRetained":1722,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":6,"retention":0.466432,"usersRetained":1515,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":7,"retention":0.458745,"usersRetained":1490,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":8,"retention":0.437283,"usersRetained":1420,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":9,"retention":0.337689,"usersRetained":1096,"usersOriginal":3247},{"cohortIndex":1,"periodIndex":10,"retention":0.327546,"usersRetained":1064,"usersOriginal":3247}]},{"cohortId":"2025-07","cohortLabel":"Jul 2025","originalUsers":4396,"cells":[{"cohortIndex":2,"periodIndex":0,"retention":1,"usersRetained":4396,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":1,"retention":0.82277,"usersRetained":3617,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":2,"retention":0.707806,"usersRetained":3112,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":3,"retention":0.675264,"usersRetained":2968,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":4,"retention":0.627578,"usersRetained":2759,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":5,"retention":0.515941,"usersRetained":2268,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":6,"retention":0.523848,"usersRetained":2303,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":7,"retention":0.443467,"usersRetained":1949,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":8,"retention":0.399864,"usersRetained":1758,"usersOriginal":4396},{"cohortIndex":2,"periodIndex":9,"retention":0.383536,"usersRetained":1686,"usersOriginal":4396}]},{"cohortId":"2025-08","cohortLabel":"Aug 2025","originalUsers":4340,"cells":[{"cohortIndex":3,"periodIndex":0,"retention":1,"usersRetained":4340,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":1,"retention":0.852336,"usersRetained":3699,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":2,"retention":0.755159,"usersRetained":3277,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":3,"retention":0.647924,"usersRetained":2812,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":4,"retention":0.614553,"usersRetained":2667,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":5,"retention":0.577885,"usersRetained":2508,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":6,"retention":0.471343,"usersRetained":2046,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":7,"retention":0.412234,"usersRetained":1789,"usersOriginal":4340},{"cohortIndex":3,"periodIndex":8,"retention":0.432234,"usersRetained":1876,"usersOriginal":4340}]},{"cohortId":"2025-09","cohortLabel":"Sep 2025","originalUsers":2176,"cells":[{"cohortIndex":4,"periodIndex":0,"retention":1,"usersRetained":2176,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":1,"retention":0.79756,"usersRetained":1735,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":2,"retention":0.780148,"usersRetained":1698,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":3,"retention":0.658383,"usersRetained":1433,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":4,"retention":0.62944,"usersRetained":1370,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":5,"retention":0.525048,"usersRetained":1143,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":6,"retention":0.471819,"usersRetained":1027,"usersOriginal":2176},{"cohortIndex":4,"periodIndex":7,"retention":0.415988,"usersRetained":905,"usersOriginal":2176}]},{"cohortId":"2025-10","cohortLabel":"Oct 2025","originalUsers":1495,"cells":[{"cohortIndex":5,"periodIndex":0,"retention":1,"usersRetained":1495,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":1,"retention":0.862656,"usersRetained":1290,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":2,"retention":0.726128,"usersRetained":1086,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":3,"retention":0.664703,"usersRetained":994,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":4,"retention":0.606737,"usersRetained":907,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":5,"retention":0.535005,"usersRetained":800,"usersOriginal":1495},{"cohortIndex":5,"periodIndex":6,"retention":0.47813,"usersRetained":715,"usersOriginal":1495}]},{"cohortId":"2025-11","cohortLabel":"Nov 2025","originalUsers":1730,"cells":[{"cohortIndex":6,"periodIndex":0,"retention":1,"usersRetained":1730,"usersOriginal":1730},{"cohortIndex":6,"periodIndex":1,"retention":0.808085,"usersRetained":1398,"usersOriginal":1730},{"cohortIndex":6,"periodIndex":2,"retention":0.733066,"usersRetained":1268,"usersOriginal":1730},{"cohortIndex":6,"periodIndex":3,"retention":0.678534,"usersRetained":1174,"usersOriginal":1730},{"cohortIndex":6,"periodIndex":4,"retention":0.601015,"usersRetained":1040,"usersOriginal":1730},{"cohortIndex":6,"periodIndex":5,"retention":0.545659,"usersRetained":944,"usersOriginal":1730}]},{"cohortId":"2025-12","cohortLabel":"Dec 2025","originalUsers":4664,"cells":[{"cohortIndex":7,"periodIndex":0,"retention":1,"usersRetained":4664,"usersOriginal":4664},{"cohortIndex":7,"periodIndex":1,"retention":0.797832,"usersRetained":3721,"usersOriginal":4664},{"cohortIndex":7,"periodIndex":2,"retention":0.71077,"usersRetained":3315,"usersOriginal":4664},{"cohortIndex":7,"periodIndex":3,"retention":0.692459,"usersRetained":3230,"usersOriginal":4664},{"cohortIndex":7,"periodIndex":4,"retention":0.604596,"usersRetained":2820,"usersOriginal":4664}]},{"cohortId":"2026-01","cohortLabel":"Jan 2026","originalUsers":4739,"cells":[{"cohortIndex":8,"periodIndex":0,"retention":1,"usersRetained":4739,"usersOriginal":4739},{"cohortIndex":8,"periodIndex":1,"retention":0.827283,"usersRetained":3920,"usersOriginal":4739},{"cohortIndex":8,"periodIndex":2,"retention":0.706674,"usersRetained":3349,"usersOriginal":4739},{"cohortIndex":8,"periodIndex":3,"retention":0.667728,"usersRetained":3164,"usersOriginal":4739}]},{"cohortId":"2026-02","cohortLabel":"Feb 2026","originalUsers":1062,"cells":[{"cohortIndex":9,"periodIndex":0,"retention":1,"usersRetained":1062,"usersOriginal":1062},{"cohortIndex":9,"periodIndex":1,"retention":0.812612,"usersRetained":863,"usersOriginal":1062},{"cohortIndex":9,"periodIndex":2,"retention":0.732734,"usersRetained":778,"usersOriginal":1062}]},{"cohortId":"2026-03","cohortLabel":"Mar 2026","originalUsers":4754,"cells":[{"cohortIndex":10,"periodIndex":0,"retention":1,"usersRetained":4754,"usersOriginal":4754},{"cohortIndex":10,"periodIndex":1,"retention":0.85056,"usersRetained":4044,"usersOriginal":4754}]},{"cohortId":"2026-04","cohortLabel":"Apr 2026","originalUsers":2566,"cells":[{"cohortIndex":11,"periodIndex":0,"retention":1,"usersRetained":2566,"usersOriginal":2566}]}],"periods":["M0","M1","M2","M3","M4","M5","M6","M7","M8","M9","M10","M11"],"periodLabels":["Month 0","Month 1","Month 2","Month 3","Month 4","Month 5","Month 6","Month 7","Month 8","Month 9","Month 10","Month 11"],"metric":"retention","periodType":"monthly","generatedAt":"2026-04-16T18:59:21.447Z"}}



PL/SQLプロシージャが正常に完了しました。


Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.31.0.1.0から切断されました

mcp-salesadb % 


リソースは以下の値で作成しています。

Uri: ui://get-cohort-data/mcp-app.html
Name: Cohort Heatmap
Description: cohort retention heatmap data showing customer retention over time by signup month


作成したリソースCohort Heatmapに登録するUIバンドルは、リポジトリext-appsに含まれるext-apps/examples/cohort-heatmap-server/dist/mcp-app.htmlです。


ツールとしてget-cohort-dataを作成します。

Code: get-cohort-data
Description: Returns cohort retention heatmap data showing customer retention over time by signup month
Input Schema: input_schema.json
Function Call: return chs_get_cohort_data_response(:parameters);
Tags: ext-apps
Resource Id: Cohort Heatmap
Output Schema: output_schema.json


以上で、データベースにMCPアプリCohort Heatmapを登録できました。

Budget Allocatorのときに作成したカスタムコネクタを一旦削除し、Sample MCP Appsとして再登録したのち、get-cohort-dataを呼び出した結果が、記事の先頭にあるGIF動画になります。

2026年4月16日木曜日

MCP AppsのサンプルアプリBudget Allocator Serverをデータベースで実行する

GitHubのリポジトリmodelcontextprotocol/ext-appsに含まれているBudget Allocator Serverをデータベースでホストしてみます。今回はClaude Desktopから呼び出せるように、Autonomous AI Databaseを使用します。Autonomous AI Databaseでの準備作業は、以下の記事で紹介しています。
Claude Desktopでは以下のように動作します。


Budget Allocator Serverのサーバーはserver.tsで実装されています。以下の方針で、データベースに実装し直しています。データベースで実行するスクリプトはClaude Sonnetに生成してもらいました。
  1. Zodによるスキーマ定義を切り出し、Oracle Database向けの表定義を生成させました。(スクリプト:bas_create_tables.sql
  2. サンプルデータを生成するファンクションseededRandomとgenerateHistoryを取り出し、PL/SQLで書き直してもらいました。(スクリプト:bas_generate_history.sql
  3. 表bas_budget_categories、bas_budget_analyticsへの初期データの投入を行なうINSERT文を生成させました。(スクリプト:bas_prepare_budget_categories.sqlbas_prepare_budget_analytics.sql
  4. 表bas_budget_config、bas_budget_preset_budgetsへの初期データの投入については、自分でINSERT文を書きました。(スクリプト:bas_prepare_budget_config.sql
  5. ツールが返す構造化出力を生成するファンクションbas_get_budget_data_responseを生成させました。(スクリプト:bas_get_budget_data_response.sql
本記事の目的はMCPアプリをデータベースでホストすることなので、PL/SQLで実装されたサーバーがTypeScriptの機能と完全に互換かどうかという点は確認していません。MCPアプリが動作すれば良しとしています。

CREATE TABLE文を生成する部分、INSERT文を生成するデータ準備部分、それとツール本体となるプロシージャを生成する部分に、作業を分けてコード生成させましたが、server.tsを丸投げしても良かったかもしれません。

これらを一括で実行するスクリプトbas_install.sqlを作成しています。リポジトリmcp-appにmcp-app/examples/budget-allocator-server/bas_install.sqlとして含まれているので、リモートMCPサーバーを実装しているスキーマに接続して実行します。

Autonomous AI Database向けの構築手順にそって作成した環境であれば、Autonomous AI Lakehouseの19cのデータベースがSALESADBとして作成され、APEXワークスペースのスキーマとしてWKSP_APEXDEVが作成されています。この環境を前提とすると、以下のコマンドでBuget Allocator Serverのサーバーを実装できます。

sql -cloudconfig Wallet_SALESADB.zip wksp_apexdev@salesadb_low
@mcp-app/examples/budget-allocator-server/bas_install.sql


データベースにサーバーが実装されたことを確認するために、スクリプト実行の最後にツール呼び出しのレスポンスを出力しています。

mcp-salesadb % sql -cloudconfig Wallet_SALESADB.zip wksp_apexdev@salesadb_low


SQLcl: 木 4月 16 12:39:12 2026のリリース25.4 Production


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


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

接続先:

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.31.0.1.0


SQL> @mcp-app/examples/budget-allocator-server/bas_install.sql 


Table BAS_BUDGET_CATEGORIESは作成されました。



Table BAS_BUDGET_CONFIGは作成されました。



Table BAS_BUDGET_CONFIG_PRESET_BUDGETSは作成されました。



Table BAS_HISTORICAL_MONTHSは作成されました。



Table BAS_HISTORICAL_MONTH_ALLOCATIONSは作成されました。



Table BAS_BUDGET_ANALYTICSは作成されました。



Table BAS_BUDGET_ANALYTICS_STAGESは作成されました。



Table BAS_STAGE_BENCHMARKSは作成されました。



Table BAS_STAGE_BENCHMARK_PERCENTILESは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Commentは作成されました。



Procedure BAS_GENERATE_HISTORYがコンパイルされました



Function BAS_GET_BUDGET_DATA_RESPONSEがコンパイルされました



1行挿入しました。



1行挿入しました。



1行挿入しました。



1行挿入しました。



1行挿入しました。



コミットが完了しました。



PL/SQLプロシージャが正常に完了しました。



PL/SQLプロシージャが正常に完了しました。



PL/SQLプロシージャが正常に完了しました。



コミットが完了しました。


{"config":{"categories":[{"id":"engineering","name":"Engineering","color":"#10b981","defaultPercent":35},{"id":"marketing","name":"Marketing","color":"#3b82f6","defaultPercent":25},{"id":"operations","name":"Operations","color":"#f59e0b","defaultPercent":15},{"id":"rd","name":"R&D","color":"#8b5cf6","defaultPercent":10},{"id":"sales","name":"Sales","color":"#ef4444","defaultPercent":15}],"presetBudgets":[50000,500000,250000,100000],"defaultBudget":100000,"currency":"USD","currencySymbol":"$"},"analytics":{"history":[{"month":"2024-05","allocations":{"engineering":35,"marketing":24.9,"operations":14.8,"rd":10.7,"sales":14.7}},{"month":"2024-06","allocations":{"engineering":33.4,"marketing":24.8,"operations":15.9,"rd":10.1,"sales":15.7}},{"month":"2024-07","allocations":{"engineering":33.9,"marketing":25.4,"operations":15.3,"rd":8.9,"sales":16.5}},{"month":"2024-08","allocations":{"engineering":34.1,"marketing":26.4,"operations":14.9,"rd":8.7,"sales":16}},{"month":"2024-09","allocations":{"engineering":35.6,"marketing":24.3,"operations":14.8,"rd":10.3,"sales":15}},{"month":"2024-10","allocations":{"engineering":33.1,"marketing":26,"operations":16.2,"rd":8.1,"sales":16.6}},{"month":"2024-11","allocations":{"engineering":33.6,"marketing":25.2,"operations":15.6,"rd":9.7,"sales":16}},{"month":"2024-12","allocations":{"engineering":34.5,"marketing":25.1,"operations":15.7,"rd":10,"sales":14.7}},{"month":"2025-01","allocations":{"engineering":33.1,"marketing":27.7,"operations":14.8,"rd":7.4,"sales":17}},{"month":"2025-02","allocations":{"engineering":34.4,"marketing":27.9,"operations":15,"rd":7.8,"sales":14.9}},{"month":"2025-03","allocations":{"engineering":33.1,"marketing":27.9,"operations":14.9,"rd":8.1,"sales":16}},{"month":"2025-04","allocations":{"engineering":34.6,"marketing":27,"operations":15.1,"rd":7.4,"sales":15.9}},{"month":"2025-05","allocations":{"engineering":34,"marketing":26.6,"operations":15.6,"rd":9.1,"sales":14.7}},{"month":"2025-06","allocations":{"engineering":32.2,"marketing":27.6,"operations":15.6,"rd":8.9,"sales":15.8}},{"month":"2025-07","allocations":{"engineering":33.5,"marketing":28.2,"operations":14.9,"rd":7.1,"sales":16.3}},{"month":"2025-08","allocations":{"engineering":34.2,"marketing":27.5,"operations":15.2,"rd":7.8,"sales":15.3}},{"month":"2025-09","allocations":{"engineering":32.7,"marketing":27.9,"operations":17.1,"rd":7.3,"sales":14.9}},{"month":"2025-10","allocations":{"engineering":33.3,"marketing":27.3,"operations":17.6,"rd":5.9,"sales":15.9}},{"month":"2025-11","allocations":{"engineering":33.7,"marketing":26.4,"operations":16.8,"rd":8,"sales":15}},{"month":"2025-12","allocations":{"engineering":32.3,"marketing":27.9,"operations":15,"rd":8,"sales":16.8}},{"month":"2026-01","allocations":{"engineering":33.5,"marketing":28,"operations":15.7,"rd":6.6,"sales":16.1}},{"month":"2026-02","allocations":{"engineering":31.4,"marketing":28.3,"operations":16.7,"rd":6.7,"sales":16.9}},{"month":"2026-03","allocations":{"engineering":32.4,"marketing":28.3,"operations":16.7,"rd":4.6,"sales":18}},{"month":"2026-04","allocations":{"engineering":32.8,"marketing":28.5,"operations":16,"rd":6.2,"sales":16.4}}],"benchmarks":[{"stage":"Seed","categoryBenchmarks":{"marketing":{"p25":15,"p50":20,"p75":25},"engineering":{"p25":40,"p50":47,"p75":55},"operations":{"p25":8,"p50":12,"p75":15},"sales":{"p25":10,"p50":15,"p75":20},"rd":{"p25":5,"p50":10,"p75":15}}},{"stage":"Series A","categoryBenchmarks":{"marketing":{"p25":20,"p50":25,"p75":30},"engineering":{"p25":35,"p50":40,"p75":45},"operations":{"p25":10,"p50":14,"p75":18},"sales":{"p25":15,"p50":20,"p75":25},"rd":{"p25":8,"p50":12,"p75":15}}},{"stage":"Series B","categoryBenchmarks":{"marketing":{"p25":22,"p50":27,"p75":32},"engineering":{"p25":30,"p50":35,"p75":40},"operations":{"p25":12,"p50":16,"p75":20},"sales":{"p25":18,"p50":23,"p75":28},"rd":{"p25":8,"p50":12,"p75":15}}},{"stage":"Growth","categoryBenchmarks":{"marketing":{"p25":25,"p50":30,"p75":35},"engineering":{"p25":25,"p50":30,"p75":35},"operations":{"p25":15,"p50":18,"p75":22},"sales":{"p25":20,"p50":25,"p75":30},"rd":{"p25":5,"p50":8,"p75":12}}}],"stages":["Seed","Series A","Series B","Growth"],"defaultStage":"Seed"}}



PL/SQLプロシージャが正常に完了しました。


Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Version 19.31.0.1.0から切断されました

mcp-salesadb %


サーバーの実装を削除するスクリプトbas_drop_all.sqlも用意しています。

以上でサーバー側の実装はできました。

APEXアプリケーションをインストールして、Budget AllocatorをMCPアプリとして登録します。

Autonomous AI DatabaseのAPEXに接続し、アプリケーション・ビルダーからインポートを実行します。


リポジトリmcp-appに含まれるMCP App Helperアプリmcp-app/app/mcp-app-helper.sqlをインポートします。

へ進みます。


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


アプリケーションがインストールされます。

アプリケーションの編集を開き、アプリケーションの名前別名を更新します。


アプリケーションの名前ext-apps別名ext-appsとします。


アプリケーションを実行します。

最初にHandlersを開き、リモートMCPサーバーのエンドポイントとなるORDS RESTサービスをインストールします。

作成をクリックします。


ORDSのRESTモジュール名はAPEXアプリの別名と同じにします。これはリモートMCPサーバーの実装上、必須になっています。

リモートMCPサーバーのエンドポイントURLは以下になります。

https://リバースプロキシのホスト/ords/ORDS別名/ext-apps/mcp

デフォルトの設定のまま、作成をクリックします。


ORDSのRESTモジュールとしてext-apps、テンプレートとしてmcp、そのテンプレートにPOSTハンドラとDELETEハンドラが作成されます。


Resourcesを開き、UIリソースとしてBudget Allocatorを作成します。

作成をクリックします。


以下の値でUIリソースBudget Allocator作成します。

Uri: ui://budget-allocator/mcp-app.html
Name: Budget Allocator
Description: Interactive Budget Allocator UI


作成したUIリソースBudget Allocatorに実際のアプリを登録します。Bundleを開きます。

Resource IDBudget Allocatorを選択し、bundle html fileにリポジトリext-appsに含まれるext-apps/examples/budget-allocator-server/dist/mcp-app.htmlを選択します。

Updateをクリックし、MCPアプリをデータベースにアップロードします。


Toolsを開き、ツールとしてget-budget-dataを作成します。

Code: get-budget-data
Description: Returns budget configuration with 24 months of historical allocations and industry benchmarks by company stage
Input Schema: {"$schema":"http://json-schema.org/draft-07/schema#","type":"object"}
Function Call: return bas_get_budget_data_response();
Tags: ext-apps
Resource Id: Budget Allocator

Output Schemaには、こちらの内容output_schema.jsonを記述します。

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


以上で、データベースにMCPアプリBudget Allocatorを登録できました。

Claude DesktopよりMCPアプリBudget Allocatorを呼び出してみます。

サイド・メニューよりCustomizeを開きます。


コネクタを開きます。


プラス()アイコンを開き、カスタムコネクタを追加を実行します。


コネクタの名前をBudget Allocator、URLにAutonomous AI Databaseへのリバース・プロキシを指すリモートMCPサーバーのエンドポイントURLを設定します。

追加をクリックします。


カスタムコネクタBudget Allocatorが追加されます。


動作を確認します。

新規チャットより「Budget Allocatorを呼び出して」と伝えます。実行の承認を求められ、実行を許可すると、MCPアプリのBudget Allocatorが表示されます。


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