2026年4月14日火曜日

MCP Appsのサンプルアプリbasic-server-vanillajsをデータベースで実行する

GitHubのリポジトリmodelcontextprotocol/ext-appsでは、 複数のMCPアプリの実装例が提供されています。このサンプルのうち、examples/basic-server-vanillajsをデータベースに実装し、MCP Inspectorから動作を確認します。

MCP Inspectorでは以下のように動作します。MCPアプリのbasic-server-vanillajsから呼び出されるツールは、サーバーの現在時刻を返すget-timeのみです。


MCP Appsはその仕組みより、MCPサーバーとのやり取りはWindow.postMessageを介したツール呼び出しに限定されます。そのため、MCPサーバーが何で実装されていても、ツール呼び出しの仕様が同じであればMCPアプリは変更せずに動作します。

今回はbasic-server-vanillajsから呼び出されるツールget-timeをOracle Databaseに実装し、basic-server-vanillajsをデータベースでMCP Appsとしてホストします。

以下の記事にそって作成した環境で、作業を実施します。
リモートMCPサーバーを実装するコードはリポジトリmcp-appにあります。basic-server-vanillajsを実装するにあたってコードを修正しているため、これからに作業には最新のコードが必要です。

作業はmacOSで実施しています。


ext-appsのbasic-server-vanillajsの実行



リポジトリext-appsをクローンし、ext-appsのexamplesを実行します。

git clone https://github.com/modelcontextprotocol/ext-apps
cd ext-apps

% git clone https://github.com/modelcontextprotocol/ext-apps

Cloning into 'ext-apps'...

remote: Enumerating objects: 24263, done.

remote: Counting objects: 100% (5297/5297), done.

remote: Compressing objects: 100% (1139/1139), done.

remote: Total 24263 (delta 4777), reused 4233 (delta 4152), pack-reused 18966 (from 3)

Receiving objects: 100% (24263/24263), 142.89 MiB | 15.78 MiB/s, done.

Resolving deltas: 100% (15369/15369), done.

% cd ext-apps

ext-apps % 


ext-appsに含まれているexamplesをインストールします。bunが無い、zodが無いといった依存性に関するエラーが発生しましたが、その都度ChatGPT(またはClaude)に聞いて解決しました。

npm install

ext-apps % npm install

npm warn deprecated whatwg-encoding@3.1.1: Use @exodus/bytes instead for a more spec-conformant and faster implementation


> @modelcontextprotocol/ext-apps@1.5.0 prepare

> npm run build && husky



> @modelcontextprotocol/ext-apps@1.5.0 build

> npm run generate:schemas && npm run sync:snippets && node scripts/run-bun.mjs build.bun.ts && node scripts/link-self.mjs



> @modelcontextprotocol/ext-apps@1.5.0 generate:schemas

> tsx scripts/generate-schemas.ts && prettier --write "src/generated/**/*"


🔧 Generating Zod schemas from spec.types.ts...


✅ Written: /Users/ynakakoshi/Documents/ext-apps/src/generated/schema.ts

✅ Written: /Users/ynakakoshi/Documents/ext-apps/src/generated/schema.test.ts

✅ Written: /Users/ynakakoshi/Documents/ext-apps/src/generated/schema.json


🎉 Schema generation complete!

src/generated/schema.json 49ms

src/generated/schema.test.ts 24ms

src/generated/schema.ts 26ms


> @modelcontextprotocol/ext-apps@1.5.0 sync:snippets

> bun scripts/sync-snippets.ts


🔧 Syncing code snippets from example files...


✅ No files needed modification


🎉 Snippet sync complete!


added 573 packages, and audited 622 packages in 8s


119 packages are looking for funding

  run `npm fund` for details


3 vulnerabilities (2 moderate, 1 high)


To address all issues, run:

  npm audit fix


Run `npm audit` for details.

ext-apps %


サンプルを実行します。

ポート番号がAPEXの環境とコンフリクトするようなので、APEXのコンテナは停止しておくのが無難です。

npm run start

出力メッセージの中間くらいに、Host serverのURLが表示されます。
デフォルトではhttp://localhost:8080になります。

ext-apps % npm run start


> @modelcontextprotocol/ext-apps@1.5.0 start

> npm run examples:dev



> @modelcontextprotocol/ext-apps@1.5.0 examples:dev

> NODE_ENV=development bun examples/run-all.ts dev


Running command: dev

Server examples: basic-server-preact:3101, basic-server-react:3102, basic-server-solid:3103, basic-server-svelte:3104, basic-server-vanillajs:3105, basic-server-vue:3106, budget-allocator-server:3107, cohort-heatmap-server:3108, customer-segmentation-server:3109, debug-server:3110, integration-server:3111, map-server:3112, pdf-server:3113, qr-server:3114, quickstart:3115, say-server:3116, scenario-modeler-server:3117, shadertoy-server:3118, sheet-music-server:3119, system-monitor-server:3120, threejs-server:3121, transcript-server:3122, video-resource-server:3123, wiki-explorer-server:3124


[basic-server-solid] 

[basic-server-solid] > @modelcontextprotocol/server-basic-solid@1.5.0 dev

[basic-server-solid] > cross-env NODE_ENV=development concurrently "npm run watch" "npm run serve"

[basic-server-solid] 

[map-server] 


[中略]


[cohort-heatmap-server] [1] 

[cohort-heatmap-server] [1] > @modelcontextprotocol/server-cohort-heatmap@1.5.0 serve:http

[cohort-heatmap-server] [1] > bun --watch main.ts

[cohort-heatmap-server] [1] 

[basic-host] [1] Host server:    http://localhost:8080

[basic-host] [1] Sandbox server: http://localhost:8081

[basic-host] [1] 

[basic-host] [1] Press Ctrl+C to stop

[basic-host] [1] 

[integration-server] [1] 

[integration-server] [1] > integration-server@1.5.0 serve:http

[integration-server] [1] > bun --watch main.ts

[integration-server] [1] 


[中略]


[threejs-server] [0] dist/mcp-app.html  10,374.90 kB │ gzip: 2,151.32 kB

[threejs-server] [0] built in 3070ms.

[pdf-server] [0] dist/mcp-app.html  10,436.10 kB │ gzip: 2,377.31 kB

[say-server] npm error Lifecycle script `dev` failed with error:

[say-server] npm error code 1

[say-server] npm error path /Users/ynakakoshi/Documents/ext-apps/examples/say-server

[say-server] npm error workspace @modelcontextprotocol/server-say@1.5.0

[say-server] npm error location /Users/ynakakoshi/Documents/ext-apps/examples/say-server

[say-server] npm error command failed

[say-server] npm error command sh -c uv run --index https://pypi.org/simple server.py

[pdf-server] [0] built in 3304ms.

[say-server] npm run --workspace examples/say-server dev exited with code 1


ブラウザよりサンプルを呼び出します。

http://localhost:8080

ServerBasic MCP App Server(Vanilla JS)を選択し、Call Toolをクリックします。呼び出せるツールはget-timeのみです。


ブラウザにMCPアプリが表示されます。

Get Server Timeをクリックすると、Server Timeが更新されます。


このMCPアプリbasic-server-vanillajsをデータベースでホストします。

これからはOracle APEXでの作業に移ります。Oracle APEXをホストしているデータベースやORDSを起動しておきます。

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


リポジトリ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は以下になります。

http://localhost:8181/ords/ORDS別名/ext-apps/mcp

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


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


システムの現在時刻を返すPL/SQLファンクションget_timeを作成します。

SQLコマンドより実行します。



ext-appsに含まれるget-timeは、テキスト出力と構造化出力の両方で現在時刻を返します。
{
  "content": [
    {
      "type": "text",
      "text": "2026-04-14T06:09:37.819Z"
    }
  ],
  "structuredContent": {
    "time": "2026-04-14T06:09:37.819Z"
  }
}
データベースでの実装ではテキスト出力と構造化出力を別々に出力する方法を実装していないため、テキスト出力もJSON形式で返すようになってしまっています。ツールにoutputSchema定義を含んでいると構造化出力を参照するので、テキスト出力がJSONでも問題なさそうです。

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

作成をクリックします。


ツールget-timeとして以下を設定し、作成します。

Code: get-time
Description: Returns the current server time as an ISO 8601 string.
Input Schema: {"$schema":"http://json-schema.org/draft-07/schema#","type":"object"}
Function Call: return get_time();
Tags: ext-apps
Output Schema:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "time": {
      "type": "string"
    }
  }
}
UIリソースとの紐付けは、UIリソースの作成後に実施します。


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

作成をクリックします。


Uriui://get-time/mcp-app.htmlNameGet TimeDescriptionReturns the current server time as an ISO 8601 string.とします。

以上でUIリソースを作成します。


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


Resource IDとしてGet Timeを選択し、bundle html fileにext-apps以下にあるexamples/basic-server-vanillajs/dist/mcp-app.htmlを選択します。

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


Toolsを開き、ツールget-timeにUIリソースGet Timeを紐付けます。


ツールget-timeを開き、Resource IdGet Timeを選択します。

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


以上で、データベースにMCPアプリbasic-server-vanillajsを登録できました。

MCP Inspectorを使って動作確認します。

npx -y @modelcontextprotocol/inspector

Transport TypeStreamable HTTPを選択し、URLにリモートMCPサーバーのエンドポイントとなるURLを指定します。

http://localhost:8181/ords/ORDS別名/ext-apps/mcp

ConnectボタンをクリックしてMCPサーバーに接続します。接続ができたら、Appsタブを開き、MCP Appsget-timeを選択します。


この後は、本記事の先頭のGIF動画のように動作します。

以上でMCPアプリのサンプルbasic-server-vanillajsをデータベースでホストすることができました。