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が表示されます。


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