公式の`create-mcp-app` スキルを使ってMCP AppをClaude Codeで作ってみた

公式の`create-mcp-app` スキルを使ってMCP AppをClaude Codeで作ってみた

2026.03.17

リテールアプリ共創部のるおんです。

以前、MCP Appsの概要と仕組み、公式サンプル map-server の内部構造を解説する記事を書きました。

https://dev.classmethod.jp/articles/mcp-apps-introduction-overview/

前回は「MCP Appsとは何か」を理解するための記事でしたが、今回は実際に create-mcp-app スキルを使ってMCP AppをClaude Codeを使って作ってみた 記事です。

Claude Codeにスキルをインストールし、「ポモドーロタイマーを作って」と指示するだけで、MCP Appのプロジェクト一式が生成され、Claudeの会話内でインタラクティブなタイマーUIが動作するところまでを試してみました。

実際に作られたポモドーロタイマーMCP Apps

スクリーンショット 2026-03-17 21.52.28

MCP Appsのおさらい

前回の記事の要点をおさらいします。

MCP Apps は、通常のMCPツール定義に _meta.ui フィールドを追加するだけで、テキストを返す関数をインタラクティブなWebアプリに変える 仕組みです。

通常の MCP ツール MCP Apps ツール
結果の表示 テキストのみ テキスト + ifrzame 内の UI
ユーザー操作 不可(結果を読むだけ) ボタン、フォーム等で操作可能
通信 ツール呼び出し → 結果で終了 表示後も 双方向通信が継続

詳しくは前回の記事をご参照ください。

create-mcp-app スキルとは

create-mcp-app は、MCP Apps の公式リポジトリ ext-apps で提供されている AIコーディングエージェント向けのスキル です。

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

スキルとは、AIエージェントに専門的な知識やワークフローを教えるための命令セットです。create-mcp-app スキルをインストールすると、AIエージェントがMCP Appのプロジェクト構成、ベストプラクティス、APIの使い方を理解した上で、コードを生成してくれます。

つまり、「ポモドーロタイマーのMCP Appを作って」と自然言語で指示するだけで、サーバー・UI・設定ファイルの一式を自動生成 してくれるということです。

スキルのインストール

Claude Codeを使用している場合、以下のコマンドでスキルを直接インストールできます。

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

インストールが完了したら、/reload-plugins でプラグインをリロードします。

/reload-plugins

これだけで準備完了です。

MCP Appを作ってみる

スキルがインストールされた状態で、Claude Codeに以下のように指示しました。

これを使っていい感じのMCP Appsを作ってみてください

すると、Claude Codeが create-mcp-app スキルを認識し、参考コードのクローン、プロジェクト構造の生成、依存関係のインストール、ビルドまでを一気に実行してくれました。

スクリーンショット 2026-03-17 21.47.12

今回は ポモドーロタイマー のMCP Appが生成されました。

生成されたプロジェクト構成

mcp-pomodoro-app/
├── server.ts        ← MCPサーバー(バックエンド)
├── main.ts          ← エントリーポイント(stdio / HTTP 切り替え)
├── mcp-app.html     ← UIのHTMLシェル
├── src/
│   ├── mcp-app.tsx      ← React App(フロントエンド・iframe内)
│   ├── global.css       ← グローバルスタイル(ホストテーマ対応)
│   ├── mcp-app.module.css ← コンポーネントスタイル
│   └── vite-env.d.ts
├── package.json
├── tsconfig.json
├── vite.config.ts
└── .gitignore

前回の記事で解説した通り、MCP Appsの開発は 通常のWebアプリ開発と同じ構造 です。バックエンド(server.ts)とフロントエンド(src/mcp-app.tsx)に分かれています。

サーバー側:server.ts

サーバー側では、start-pomodoro というMCP Appsツールを登録しています。

server.ts
registerAppTool(server,
  "start-pomodoro",
  {
    title: "Pomodoro Timer",
    description: "Start an interactive Pomodoro timer.",
    inputSchema: {
      type: "object",
      properties: {
        workMinutes: z.number().min(1).max(120).default(25),
        breakMinutes: z.number().min(1).max(60).default(5),
        task: z.string().default("Focus Time"),
      },
    },
+   _meta: { ui: { resourceUri } },
  },
  async ({ workMinutes, breakMinutes, task }) => {
    const config = {
      workMinutes: workMinutes ?? 25,
      breakMinutes: breakMinutes ?? 5,
      task: task ?? "Focus Time",
      startedAt: new Date().toISOString(),
    };
    return {
      content: [{ type: "text", text: JSON.stringify(config) }],
    };
  },
);

ポイントは _meta: { ui: { resourceUri } } です。このフィールドがあることで、ホストはツール結果をテキストとしてだけでなく、インタラクティブなUIとしてもレンダリング します。

ツールのパラメータとして workMinutes(作業時間)、breakMinutes(休憩時間)、task(タスク名)を受け取ります。これにより、Claudeに「25分の作業と5分の休憩でポモドーロを開始して」と指示すると、AIがパラメータを解釈してツールを呼び出してくれます。

App側:src/mcp-app.tsx

App側(iframe内で動くフロントエンド)では、React + useApp フックを使ってホストとの通信を行います。

src/mcp-app.tsx
import { useApp } from "@modelcontextprotocol/ext-apps/react";

function PomodoroApp() {
  const [config, setConfig] = useState<PomodoroConfig>({
    workMinutes: 25, breakMinutes: 5, task: "Focus Time",
  });

  const { app, error } = useApp({
    appInfo: { name: "Pomodoro Timer", version: "1.0.0" },
    capabilities: {},
    onAppCreated: (app) => {
+     app.ontoolresult = async (result) => {
+       setConfig(parseConfig(result));
+     };
      app.onhostcontextchanged = (params) => {
        setHostContext((prev) => ({ ...prev, ...params }));
      };
    },
  });

  // ...
}
  • useApp() フックでAppインスタンスを作成し、ホストとの接続を確立
  • app.ontoolresult でホストから転送されたツール結果(作業時間、休憩時間などの設定)を受け取る
  • app.onhostcontextchanged でホストのテーマ変更(ダーク/ライトモード)に対応

タイマーのセッションが完了すると、app.sendMessage() でホスト(Claude)に完了を通知します。

src/mcp-app.tsx
app.sendMessage({
  role: "user",
  content: [{
    type: "text",
    text: `Pomodoro session completed: "${config.task}" (${config.workMinutes} min)`,
  }],
}).catch(console.error);

これにより、ポモドーロ完了後にClaudeが「お疲れさまでした!次のタスクは何にしますか?」のように応答できるようになります。App内でのユーザー操作がAIの理解を更新する というのが、MCP Appsの面白いところですね。

UIの特徴

生成されたポモドーロタイマーは以下の機能を備えています。

  • 円形プログレスバー:SVGで描画された残り時間の視覚的な表示
  • 作業/休憩モード:作業(赤)と休憩(緑)を自動で切り替え
  • 操作ボタン:開始/一時停止、リセット、スキップ
  • セッションカウンター:完了したポモドーロをドットで表示(4セッション)
  • ダーク/ライトモード対応:ホストのテーマに自動適応

Claudeでテストしてみた

ローカルサーバーの起動

まず、ビルドしてサーバーを起動します。

bash
npm install && npm run build && npm run serve

デフォルトで http://localhost:3001/mcp でMCPサーバーが起動します。

cloudflaredでトンネルを作成

Claude(Web版/Desktop版)からローカルサーバーにアクセスするには、インターネットに公開する必要があります。cloudflared を使ってトンネルを作成します。

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

実行すると、https://random-name.trycloudflare.com のようなURLが生成されます。

Claudeにカスタムコネクターを追加

  1. claude.ai または Claude Desktop を開く
  2. プロフィールアイコンをクリック → SettingsConnectors
  3. Add custom connector をクリック
  4. URLに https://生成されたURL/mcp を入力
  5. 保存

スクリーンショット 2026-03-17 21.53.44

動かしてみる

Claudeに「ポモドーロタイマーを開始して」と入力すると、start-pomodoro ツールが呼び出され、会話内にインタラクティブなタイマーUIが表示されました。

スクリーンショット 2026-03-17 21.51.57

スクリーンショット 2026-03-17 21.52.28

タイマーの開始/一時停止、モードの切り替え、セッションカウントなど、すべての操作がClaude内で完結します。テキストで「25分経過しました」と返されるのではなく、操作可能なタイマーそのもの が会話に埋め込まれるのが新鮮ですね。

create-mcp-app スキルを使ってみた感想

良かった点

  • プロジェクト構成を考えなくていい:Viteの設定、vite-plugin-singlefile によるバンドル、TypeScript設定など、MCP Apps特有の構成を自動で生成してくれる
  • ベストプラクティスが反映される:ハンドラーの登録順序(connect() の前に登録)、テキストフォールバックの提供、ホストテーマへの対応など、スキルに組み込まれた知識が自動的に反映される
  • テスト環境もセットアップしてくれるcloudflared によるトンネル作成やbasic-hostの起動など、テスト環境の構築まで案内してくれる

注意点

  • スキルはあくまでAIエージェントへの「知識の注入」であり、生成されるコードの品質はAIの能力に依存する
  • 複雑なMCP App(ネットワークリクエスト、CSP設定、バイナリリソースなど)を作る場合は、公式のパターンドキュメントも併せて確認するのがおすすめ

おわりに

今回は、create-mcp-app スキルを使ってMCP Appを実際に作ってみました。

前回の記事でMCP Appsの仕組みを理解した上で、スキルを使って実際にアプリを構築してみると、MCP Appsの開発体験は通常のWebアプリ開発と変わらない ことが実感できました。サーバー側でツールとリソースを登録し、クライアント側でUIを構築する。この構造はバックエンド/フロントエンドの分離そのものです。

create-mcp-app スキルのおかげで、MCP Apps特有のセットアップ(Vite設定、シングルファイルバンドル、ホストとの通信設定など)に悩むことなく、作りたいものの実装に集中 できました。

MCP Appsは現在も活発に開発が進んでいる仕組みです。「AIチャットの中にインタラクティブなUIを埋め込む」というコンセプトに興味がある方は、ぜひスキルをインストールして試してみてください。

以上、どなたかの参考になれば幸いです。

参考

https://modelcontextprotocol.io/extensions/apps

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

https://github.com/modelcontextprotocol/ext-apps

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

この記事をシェアする

FacebookHatena blogX

関連記事