bunbun

MCP Apps は(まだ)商機なし...でも作ってみた

2026-08-31

はじめに

こんにちは!2025年7月より Belong で Software Engineer として開発している bun(ブン)です。 以前私が執筆した AI Engineer World's Fair に関する記事 の中で MCP Apps について触れましたが、今回はその実態を調べてみて、作ってみて、使ってみた感想をまとめました。

正直な感想 (TL;DR)

いきなり感想です。 タイトルのとおりなんですが、MCP Apps はまだまだ発展途上で、現状では EC 文脈で「まだユーザーが積極的に使うものではない」ため商機を見出せない、というのが正直なところです。

AI Engineer のカンファレンスではなかなか期待感が高く発表されていて、AI チャットを介した Web 検索新時代の幕開け感があったのですが、2026年8月時点ではまだスタンダードにはなりそうにない、という感じです。 つらつらとなぜこの感想に至ったかを書きます。

そもそも MCP Apps って?

MCP Apps は、MCP (Model Context Protocol) の公式拡張仕様 (io.modelcontextprotocol/ui) で、MCP サーバーが「テキスト」ではなく「インタラクティブな HTML の UI」をチャットの中に直接描画できるようにするものです。 2025年11月に Anthropic と OpenAI が共同で提案し、2026年1月に正式な仕様 (2026-01-26) として公開されました。それまで別々に存在していた MCP-UI と OpenAI の Apps SDK を一本化したもの、と理解するとわかりやすいと思います。

仕組みはシンプルで、通常の MCP のツール定義に _meta.ui.resourceUri というフィールドを足し、そこで ui:// スキームのリソース (HTML) を指定するだけです。

server.registerTool(
  'search_products',
  {
    description: 'Search products in the store',
    inputSchema: { query: z.string() },
    _meta: { ui: { resourceUri: 'ui://my-shop/product-list.html' } },
  },
  async ({ query }) => ({
    content: [{ type: 'text', text: JSON.stringify(await search(query)) }],
  }),
)

LLM がこのツールを呼ぶと、ホスト (ChatGPT や Claude などのチャットアプリケーション) は次のように動きます。

  1. ツール定義に書かれた ui:// リソースをサーバーから取得する
  2. 取得した HTML をチャット内の sandbox 化された iframe に描画する
  3. iframe とホストは postMessage 越しの JSON-RPC (ui/initializetools/call など、MCP の方言のようなもの) で双方向にやりとりする

ポイントは 3 の双方向通信で、UI 側から MCP サーバーのツールを呼び直したり、ユーザーの操作結果を LLM のコンテキストに送り返したりできます。つまり「検索結果を商品カードで表示し、ユーザーがボタンを押したら購入フローに進む」といった、これまで Web サイトに遷移しないとできなかったことがチャットの中で完結する、というのがこの仕様の狙いです。iframe は親ページの DOM や Cookie にはアクセスできないので、ホスト側は第三者が作ったアプリを比較的安全に描画できます。

開発者向けには @modelcontextprotocol/ext-apps という SDK があり、React / Vue / Svelte などのスターターも公式で用意されています。UI 自体は普通の Web フロントエンドなので、フロントエンドエンジニアであれば学習コストはほとんどありません。

対応クライアントも 2026年8月時点で ChatGPT、Claude (Web / Desktop)、Cursor、Microsoft 365 Copilot などかなり広がっていて(公式の対応クライアント一覧)、主要なチャットアプリケーションで「表示できない」ということはもうほとんどありません。

なお、同じものでもホストごとに呼び名が違い、ChatGPT では Plugin (以前は Apps)、Claude では Connector (コネクタ) と呼ばれています。本記事では仕様名である MCP Apps で統一し、各ホストの画面や手順に言及するときだけそのホストの呼称を使います。

なぜまだユーザーが積極的に使えるものではないのか?

主要なチャットが対応済みなのに使われない、というのが今の MCP Apps の状況です。問題は仕様やホスト側の準備ではなく、ユーザーに届くまでの経路にあります。理由は以下の 3 つです。

  1. チャットが MCP Apps の存在を教えてくれない (発見されない)

    求人検索大手の Indeed が MCP Apps を開発しているのですが(そもそも彼らが MCP Apps に関する発表をしていたのでこの機能を知りました)、実際に彼らの MCP Apps を ChatGPT が紹介してくれるわけではありません。

    実際に Indeed でフロントエンドエンジニアの求人を探して というプロンプトを ChatGPT に投げても、Indeed の MCP Apps をインストールしていない場合は、それをサジェストすることもしてこないのでただ ChatGPT が自前で作ったリストを見せられるだけです。サービス名を名指ししているプロンプトですらこの挙動なので、ユーザーが Plugin の存在を事前に知っていることが前提になっています。

    これは実際致命的で、開発をしてもユーザーがそれに気づいてくれず使われないという元も子もない事態に陥ります。

  2. ユーザーが MCP Apps を手動でインストールする必要がある

    存在を知っていたとしても、ユーザーは自分でディレクトリから探してインストールする必要があります。勝手にインストールしないのはもちろん理解できますし、セキュリティ的にも正しいのですが、Web サイトなら URL を踏むだけで済むところに「探す → 権限を確認する → 接続する」というステップが挟まるのは、一般ユーザーにとってはまだまだハードルが高いです。

  3. 開発者側: 配布経路と審査がホストごとにバラバラ

    これは開発者側の話ですが、1 と 2 を乗り越えるための「ディレクトリに載せる」作業がホストごとに完全に別物です。ChatGPT では OpenAI Developer Platform から Plugins Directory (Codex と共通) に申請し、サーバーをホストしているドメインの所有確認と審査を通す必要があります。Claude では Claude.ai の組織設定にある申請ポータルから Connectors Directory に申請しますが、そもそも Team または Enterprise プランの組織が必要で、プライバシーポリシーやツールのアノテーション、レビュアー用のテストアカウントまで揃えて手動審査を受けます。MCP Apps の場合はさらに、ディレクトリ掲載用のスクリーンショット (PNG / 幅 1000px 以上 / 3〜5 枚) も必要です。

    仕様が統一されたのでコードは一度書けばどのホストでも動くのですが、ユーザーの目に触れる場所に置くにはホストの数だけ別々の申請と審査が必要、というのが現状です。開発そのものよりも、この配布の面倒さのほうが実際のハードルになりそうです。

現状のユースケース

AI チャットが MCP Apps を自動でインストールする、あるいはインストールなしで使えるようになる、ということはセキュリティの観点でほぼあり得ないです。 また、ChatGPT には Plugin Directory や Apps メニューといった「探せば見つかる」場所はすでにあるのですが、会話の文脈に応じて特定の Plugin (MCP Apps) を紹介してくれる機能がつくかどうかはまだ不明です。

それを考慮すると、現時点では以下のシナリオで MCP Apps に実際のユースケースがありそうです。

  • ユーザーに積極的に MCP Apps を使ってもらうための告知をできるプラットフォームがある
    • Indeed のように既に大量のユーザーを抱えていて、自社サイトやメールで「ChatGPT からも使えます」と告知できるサービスは、インストールのハードルをある程度自力で越えられます
  • 一度インストールすれば繰り返し使ってもらえるユースケースである
    • 求人検索、EC の再購入、予約、家計簿のような「日常的に何度も使う」サービスであれば、最初のインストールコストを払ってもらう価値があります。逆に一回きりの利用を想定したものは、インストールしてもらう前に離脱されます
  • 企業内で管理者が一括配布できる (B2B / 社内ツール)
    • Microsoft 365 Copilot や Claude のエンタープライズプランのように、管理者が組織全体にコネクタを配布できる環境であれば、エンドユーザーが自分でインストールする問題そのものが消えます。個人的には、コンシューマー向けよりも先にこちらで MCP Apps が普及していくのではないかと見ています
  • 開発者向けツールである
    • 対応クライアントに VS Code、Cursor、Postman などの開発者向けツールが多く含まれている通り、「MCP サーバーを自分で追加する」ことに抵抗のない開発者がターゲットであれば、インストールのハードルはほぼ問題になりません

ただ、EC 文脈ではまだ実用化は先かなと感じております。もちろん AI 技術の進歩は早いのですぐに状況が変わる可能性はありますが...

それでも試したい方用に (そしてそれでも作りたかった私用に)

今回机上の空論ばかりではなく一応手も動かそうと思い MCP Apps の作り方と ChatGPT での動かし方をチェックしました。それをこの場でシェアします。 MCP Apps の開発自体は AI があればかなり簡単です。

公式が Claude Code 向けに create-mcp-app というスキルを配布しているので、それを入れて「スマホを購入するボタンを表示する MCP App を作って」と頼めば一式生成してくれます。

/plugin marketplace add modelcontextprotocol/ext-apps
/plugin install mcp-apps@modelcontextprotocol-ext-apps

ただ、中身を理解するために最小構成を手で書いてみます。必要なのは MCP サーバー (ツール + UI リソース)iframe の中で動く HTML の 2 つだけです。

npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk express

まず UI です。今回は「購入ボタンが表示される」ことだけ確認したいので、ホストと通信しない静的な HTML にします。

<!-- mcp-app.html -->
<!DOCTYPE html>
<html lang="ja">
  <body>
    <p>iPhone 15 (中古 / 良品) ¥79,800</p>
    <button onclick="this.textContent = '購入しました (fake)'">購入する</button>
  </body>
</html>

次にサーバー側です。通常の MCP ツールに _meta.ui.resourceUri を足し、その ui:// リソースとして上の HTML を返すだけです。

// server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
import {
  registerAppTool,
  registerAppResource,
  RESOURCE_MIME_TYPE,
} from '@modelcontextprotocol/ext-apps/server'
import express from 'express'
import fs from 'node:fs/promises'

const server = new McpServer({ name: 'My Shop', version: '1.0.0' })
const resourceUri = 'ui://my-shop/mcp-app.html'

// 1. ツール: _meta.ui.resourceUri で UI を紐付ける
registerAppTool(
  server,
  'show_phone',
  {
    description: 'Show a phone with a purchase button',
    inputSchema: {},
    _meta: { ui: { resourceUri } },
  },
  async () => ({
    content: [{ type: 'text', text: 'iPhone 15 (中古 / 良品) ¥79,800' }],
  }),
)

// 2. UI リソース: HTML をそのまま返す
registerAppResource(
  server,
  resourceUri,
  resourceUri,
  { mimeType: RESOURCE_MIME_TYPE },
  async () => ({
    contents: [
      {
        uri: resourceUri,
        mimeType: RESOURCE_MIME_TYPE,
        text: await fs.readFile('mcp-app.html', 'utf-8'),
      },
    ],
  }),
)

// 3. Streamable HTTP で公開
const app = express()
app.use(express.json())
app.post('/mcp', async (req, res) => {
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined,
    enableJsonResponse: true,
  })
  res.on('close', () => transport.close())
  await server.connect(transport)
  await transport.handleRequest(req, res, req.body)
})
app.listen(3001)
npx tsx server.ts   # http://localhost:3001/mcp で待ち受け

ボタンを押した結果を LLM に返したり、UI からツールを呼び直したりしたい場合は @modelcontextprotocol/ext-appsApp クラスを使います (その場合は JS をバンドルする必要があります)。

ChatGPT はクラウド側から MCP サーバーにアクセスするので、localhost のままでは届きません。公式ガイドでも使われている cloudflared で URL 公開します。アカウント登録は不要で、npx で叩くだけで使えます (この場合は npm のコミュニティパッケージ経由で公式バイナリを取得します。気になる方は Homebrew などで公式の cloudflared をインストールしてください)。

npx cloudflared tunnel --url http://localhost:3001

表示された https://xxxx.trycloudflare.com/mcp を付けたものが MCP サーバーの URL です。ChatGPT に登録するときはこの /mcp 付きの URL を使います。

その後 ChatGPT にて、

  1. プロフィール画像をクリックし、設定ページにいく
  2. Plugins タブから Developer mode をオンにする
  3. Plugins タブに戻り、Browse plugins をクリックし New Plugin モーダルを開く
  4. プラス (+) ボタンをクリックし、先ほどの cloudflared の URL とその他必須項目を入力し、Create をクリックする

上記で MCP Apps をインストールし、すぐにチャット画面で動作確認ができます。

この状態で、「購入ボタンを表示して」と言えばすぐ出てくれる...かと思いきやそううまくはいかず、もはや誘導尋問かのようなプロンプトを投げてみると、無事にチャットの中で購入ボタンが表示されました。ホストはツールの description を見て呼ぶかどうかを判断するので、今回のように一行だけの説明では拾われにくいというのもありそうです。

ChatGPT 上で描画された購入ボタン

※ 右上の「CSP off」バッジは、この Plugin に CSP (Content Security Policy) が設定されていないことを示しています。今回は静的な HTML なので問題ありませんが、外部のスクリプトや API を使う場合はリソースの _meta.ui.csp で許可するオリジンを宣言する必要があります。

以上でデモは終了です。開発自体は大したことはありません。 ハードルが高そうに見えるのはアプリを作り審査を通すことですが、これはまだ実際にパブリッシュしたことがないので実際の難しさなどはまだ不明というのが正直なところです...

まとめ

開発自体は簡単で、MCP Apps は「チャットの中で Web UI を表示する」という新しい体験を提供してくれます。 しかし、現状ではユーザーに届くまでの経路が整っていないため、まだまだ商機はなさそうです。

ということで本日の評決はまだまだ微妙、という感じです。

ただ、様々な AI チャットプラットフォームがこの機能を積極的にサジェストしてくれる日が来てくれれば私たちのような EC のユースケースで活用される日も来るかもしれません。 そのため今後の MCP Apps の仕様変更や、ホスト側の対応の進展に注目していきたいと思います。

No table of contents available for this content