MCP AppsでAskUserQuestionライクな質問UIを実装する

MCP AppsでAskUserQuestionライクな質問UIを実装する

2026.01.29

はじめに

生成AIやAIエージェントによってUIを生成するGenerative UIという考え方がCopilotKitやAI SDKなどに実装されました。動的に生成して返すというより、コンポーネントを用意し、そこにAIがデータを流し込む形が一般的な気がします。本記事もその内容です。このメリットはAIチャットボットと従来のWebの良さのハイブリッドという体験で、人間がプロンプトを書かなくてよいというメリットがあります。

今回はClaude Codeでよく使われるAskUserQuestionをMCP Appsに取り込んでUIとしてユーザーに返してみようと思います。

AskUserQuestionは、実行中にユーザーへ質問を表示し、選択肢から回答を収集するツールです。Claude Codeを使っていると以下のような画面を見たことがある方も多いと思います。プロンプトを書かずに方針を決められるので便利です。今後よりAIが賢くなることを考えると、AIに要点を整理してもらい、聞いてもらう機会は増えると思っています。
CleanShot 2026-01-29 at 09.28.18

MCP Appsは、Model Context Protocol(MCP)を拡張し、AIチャットの中に「直接操作できるインタラクティブな画面(UI)」を埋め込むための仕組みです。標準化された通信規格MCPでGenerative UIができます。

https://modelcontextprotocol.io/docs/extensions/apps

公式のサンプルだとカラーピッカーの例が紹介されています。
CleanShot 2026-01-29 at 02.40.54

すでにこのような体験は Generative UIで可能です。MCP Appsだとクライアントを選ばないので汎用性が高いというメリットがあります。ただWebのLLMチャットアプリ(HTMLをレンダリングできるMCPクライアント)がMCP及びMCP Appsに対応しているか確認が必要です。現状MCP Appsをサポートしているクライアントは公式の引用より以下となります。

https://modelcontextprotocol.io/docs/extensions/apps

  • Claude (Web版)
  • Claude Desktop
  • Visual Studio Code (Insiders版)
  • Goose
  • Postman
  • MCPJam

動作、設定方法

はじめに

ソースは以下のリポジトリです。

https://github.com/shuntaka9576/mcp-ask-user/blob/main/apps/ask-user
https://www.npmjs.com/package/mcp-ask-user/v/1.0.0

動作の様子は以下の通りです。

https://youtu.be/Oe7nG4IIzpc

新規でネイティブアプリを開発したいです。AskUserQuestionを使って質問してください。 というプロンプトに対して、対話形式でいくつかの質問がUIとして返されます。

※ loading部分は4倍速にしています。

画像でも補足します。

CleanShot 2026-01-29 at 09.48.28@2x

Submitを押すと、選択した内容がホストに送信され、チャット入力欄に挿入されます。ただし、AIへの送信(確定)はユーザーが手動で行う必要があります。(上記の画像は送信済みですが、これは私が手動で送信したためです)
CleanShot 2026-01-29 at 09.53.14@2x

設定方法

npm install -g mcp-ask-user
# or
pnpm install -g mcp-ask-user

Claude Desktopの設定は以下を参照してください

https://github.com/shuntaka9576/mcp-ask-user/blob/main/apps/ask-user/README.md

自分の環境ではnixやmiseなど特殊な設定が多いので、フルパスにしたり、nodeのパス設定を入れないと動きませんでした。動作しなかった際に参考にしてください。
https://github.com/shuntaka9576/dotfiles/blob/d79cd20c203bc082301b583ab9a9f6be51b2df76/home-manager/programs/mcp/mcp-general.jsonnet#L1-L15

MCP Apps構築

Tips

基本的に公式手順のGetting startedに載っているSkillを導入するとよいです。

https://modelcontextprotocol.io/docs/extensions/apps

今回はUI側とサーバー側に分けて実装しています。UI側はツール経由で配信するHTMLを作り、Server側はツール定義(UI側のリソース紐付け)とstdio及びStreamableHTTPのインタフェース提供部分を担っています。

UI側

UI側のビルドとサーバー側のビルドでそれぞれビルドした成果物をdistに格納しています。

vite-plugin-singlefile で CSS/JS を HTML に埋め込んで、単一の dist/mcp-app.html を生成しています。

INPUT=mcp-app.html vite build

サーバー側

ESM 形式で dist/server.mjs を生成しています

tsdown src/server.ts --format esm --out-dir dist --clean false

UI側でビルドした単一のHTMLを、resourceとして登録しています。

https://github.com/shuntaka9576/mcp-ask-user/blob/6ec7e90923bd8c06687f3616a3a3ac9cbcde6c46/apps/ask-user/src/server.ts#L69-L80

こちらでpublish前に両方ビルドします
https://github.com/shuntaka9576/mcp-ask-user/blob/6ec7e90923bd8c06687f3616a3a3ac9cbcde6c46/apps/ask-user/package.json#L27

先ほどUI側でビルドした内容を ui:// スキームとして定義します。ui://ask-user/mcp-app.html スキームと実体のファイル(dist/mcp-app.html)を紐付けします。
https://github.com/shuntaka9576/mcp-ask-user/blob/6ec7e90923bd8c06687f3616a3a3ac9cbcde6c46/apps/ask-user/src/server.ts#L23
https://github.com/shuntaka9576/mcp-ask-user/blob/6ec7e90923bd8c06687f3616a3a3ac9cbcde6c46/apps/ask-user/src/server.ts#L69-L80

そしてツール側の _meta.ui.resourceUri でこのリソースURI (ui://ask-user/mcp-app.html) を参照しています。
https://github.com/shuntaka9576/mcp-ask-user/blob/6ec7e90923bd8c06687f3616a3a3ac9cbcde6c46/apps/ask-user/src/server.ts#L42-L67

これにより、ツール呼び出し時にクライアントがどのUIリソースを表示すべきか分かります。

AIからこのツールが以下のような形で呼び出されます。multiSelect=true の部分は複数選択が可能になります。このスキーマ設計も大切ですね。

Claudeからツール呼び出しログ
{
  "questions": [
    {
      "header": "プラットフォーム",
      "options": [
        {
          "label": "iOS",
          "description": "iPhone/iPad向けアプリ"
        },
        {
          "label": "Android",
          "description": "Androidスマートフォン/タブレット向け"
        },
        {
          "label": "両方",
          "description": "iOS・Android両対応のクロスプラットフォーム"
        }
      ],
      "question": "どのプラットフォーム向けのアプリを開発したいですか?",
      "multiSelect": true
    },
    {
      "header": "アプリ種類",
      "options": [
        {
          "label": "ビジネス/業務効率化",
          "description": "タスク管理、CRM、社内ツールなど"
        },
        {
          "label": "SNS/コミュニケーション",
          "description": "チャット、マッチング、コミュニティなど"
        },
        {
          "label": "Eコマース",
          "description": "ショッピング、決済、予約など"
        },
        {
          "label": "その他",
          "description": "ゲーム、教育、ヘルスケアなど"
        }
      ],
      "question": "どのような種類のアプリを作りたいですか?"
    },
    {
      "header": "経験レベル",
      "options": [
        {
          "label": "初心者",
          "description": "プログラミング経験が少ない"
        },
        {
          "label": "中級者",
          "description": "Web開発経験あり、モバイルは初めて"
        },
        {
          "label": "上級者",
          "description": "モバイルアプリ開発経験あり"
        }
      ],
      "question": "開発経験はどの程度ありますか?"
    },
    {
      "header": "優先事項",
      "options": [
        {
          "label": "開発スピード",
          "description": "早くリリースしたい"
        },
        {
          "label": "パフォーマンス",
          "description": "高速で滑らかな動作"
        },
        {
          "label": "コスト削減",
          "description": "開発・運用コストを抑えたい"
        },
        {
          "label": "学習機会",
          "description": "技術を深く学びたい"
        }
      ],
      "question": "優先したいことは何ですか?"
    }
  ]
}

MCP配布

--stdio でローカル MCP として、デフォルト(HTTP)はリモート MCP として動作します。ローカル MCP にも対応したのは、リモートだと mcp-remote を被せたりネットワークポートを塞ぐ必要があるためです。ポートは被らないようにしていますが、ローカルの方が手軽で設定しやすいと思っています。

さいごに

MCP AppsでClaude CodeのAskUserQuestionを再現してみました。AIチャットボットで便利になったけれどプロンプトを打つのが面倒だなーというケースへのソリューションとして良いと思います。

MCP Appsに対応したHTMLをレンダリングできるMCPクライアントが増えて欲しいところですね...(切実

この記事をシェアする

FacebookHatena blogX

関連記事