MCPはモデルが道具と対話するためのプロトコルとして始まった。モデルがサーバーに何があるかを訊き、道具を呼び、結果を受け取る。人はその対話の外にいて、画面が必要になれば文字で戻ってきた。
道具が増えるにつれ文字では足りなくなった。表を見せなければならず、地図を出さなければならず、ボタンを押さなければならなかった。窓が必要になったのだ。
ここで分かれる。窓は一種類ではない。
窓 ① — モデルが人に見せる窓
2025年11月、MCP-UIコミュニティとOpenAIのApps SDKが同じ必要をそれぞれ解いていた。その二つが合わさって MCP Apps(SEP-1865)になり、MCP初の公式拡張としてFinalに到達した。
構造はこうだ。
- サーバーが
ui://スキームでUIリソースを あらかじめ宣言する - 道具がメタデータでそのリソースを参照する
- 道具が呼ばれると ホストが サンドボックスiframe にHTMLを描画する
- iframeとホストが双方向でやりとりする
- UIが道具を呼ぶときは利用者の同意を取る
よく設計された仕様だ。事前宣言のおかげでホストが先に受け取ってキャッシュし、セキュリティ検討ができる。iframeサンドボックスで信頼できないサーバーのUIを隔離する。HTMLだけを扱うと決めたのも明確だ — どこでも動き、セキュリティモデルが単純で、画面を取れる。
この窓の持ち主はモデルだ。 対話の途中で道具が呼ばれ、その結果が画面として現れる。対話の表現力が広がった。

窓 ② — 人が装置を直接さわる窓
ところが、こういう場面がある。
船の操舵室。エンジン状態、燃料、バラスト、発電機。機関長はコンソールで直接さわる。船長はタブレットで計器を見る。甲板の船員は携帯でアラームだけを受ける。同じ設備、違う画面、違う権限。
ここにモデルはいない。あればよい — 「3番発電機の温度が15分上がり続けています」と先に言ってくれるほうがよい。しかし なくても船は進む。 機関長は計器を見て弁を握る。
特装車の制御盤も、農機の作業機操作も、工場設備の運転盤も同じだ。人が機械を直接扱う窓である。道具呼び出しの結果物ではなく、操作面そのものだ。
この窓はMCPが元々狙った席ではなかった。だがMCPはすでにその材料を持っている — 装置が自分の機能を道具として出し、状態をリソースとして出し、変化を知らせる。足りないのは画面だ。
なぜ窓①で窓②をつくれないのか
優劣の問題ではなく 設計前提の問題だ。四つともMCP Appsの仕様に書かれている。
第一に、HTMLとiframeが要件だ。 描画対象がHTMLで、サンドボックス化は任意ではなく必須である。数十KBのRAMのマイコンにHTMLエンジンはない。iframeもない。装置が自分のLCDに画面を描かねばならない状況で、この要件は越えられない壁になる。
第二に、道具が呼ばれてUIが出る。 ループが モデル → 道具 → UI → 利用者 だ。モデルを外せば窓が開かない。 一方、操舵室のコンソールは船に電源が入れば点いていなければならない。
第三に、チャネルという軸がない。 「同じ設備を操舵室では制御権で、携帯では閲覧だけで」— この区別を表す席がない。窓を開けるホストがひとつだからだ。
第四に、脅威モデルが逆を向いている。 MCP Appsが防ぐのは「信頼できないサーバーが自分のチャットクライアントに悪意あるUIを送ること」だ。装置制御が防ぐべきは「誰がこの機械を操作してよいのか」である。前者は利用者を守り、後者は機械と人の安全を守る。
二つの窓は競合しない
MCP Appsはモデルが人に見せる窓であり、装置の制御面は人が機械を直接扱う窓だ。前者はモデルを外せば消え、後者はモデルがなくても回る。
そして二つの窓は 同じ画面に一緒にいられる。 モデルが異常の兆しを話しながら推移グラフを出し(窓①)、その隣で機関長が直接弁を操作する(窓②)。
設計者が言ったのもその絵だ — モデルが対話する窓口を、人も一緒に対話できる窓にしたのであり、一緒に見ながらやることもできる、と。
ここまでが第二の軸
第一の軸は事業の層で ビジネスの持ち主を問い、第二の軸はプロトコルの層で 窓の持ち主を問うた。層が違うので二つの答えが互いを削らない。
次の一編からは画面だ。窓②が実際にどうつくられるのか — 装置が自分の画面を渡すとはどういうことかを、机の上のボード二枚で確認する。
makemind.dev 「探索」— MCP Appsについての記述はすべてその仕様書で確認したものだ。