MCP UI ou MCP Apps: diferenças, SDK e exemplos

O MCP UI começou como um SDK da comunidade para interfaces interativas de ferramentas, e o MCP Apps é a extensão oficial que padronizou a ideia em janeiro de 2026. Este artigo coloca os dois lado a lado: modelo de entrega, sandboxing, suporte nos hosts, pacotes do SDK e código executável para servidores, Views e hosts, além de orientações sobre qual escolher para um projeto novo.

MCP UI ou MCP Apps: diferenças, SDK e exemplos
Cristian Da Conceicao
Fundador do Picasso IA

Pergunte a dez desenvolvedores o que separa MCP UI de MCP Apps e você ouvirá dez respostas diferentes. O motivo é simples: os dois nomes descrevem um projeto da comunidade e o padrão oficial que surgiu dele, e muitas publicações os tratam como rivais. Se uma das suas ferramentas MCP deve renderizar um gráfico, um formulário ou um mapa em vez de um bloco de texto, você precisa saber qual pacote instalar, onde fica o HTML e quais hosts de fato vão exibi-lo. Esta comparação de MCP UI ou MCP Apps apresenta as diferenças, as peças do SDK de cada lado e código que você pode adaptar hoje.

💡 Resposta curta: MCP Apps é a extensão oficial do MCP que entrou no ar em 26 de janeiro de 2026. MCP-UI é o projeto de SDK anterior, que foi o pioneiro dessa ideia, e seus pacotes agora funcionam com o padrão MCP Apps. Trate-os como antecessor e sucessor, não como concorrentes.

O que cada um realmente é

MCP UI em termos simples

MCP-UI é um SDK para criar componentes de interface interativos para ferramentas do Model Context Protocol. Ele surgiu em 2025 e foi pioneiro na ideia de que um servidor MCP poderia responder com uma interface em tempo real, em vez de texto simples. Segundo a documentação do MCP-UI, o projeto influenciou diretamente a especificação do MCP Apps.

O conjunto de ferramentas se divide em duas partes:

  • @mcp-ui/server expõe createUIResource, que cria um recurso de UI a partir de uma string HTML ou de uma URL externa.
  • @mcp-ui/client expõe AppRenderer para renderizar a interface de uma ferramenta e AppFrame para HTML que você já buscou.

Também existem auxiliares de servidor para Ruby (mcp_ui_server) e Python (mcp-ui-server), uma vantagem real quando seu servidor MCP não é escrito em TypeScript. Em sua forma inicial, o MCP-UI oferecia vários tipos de conteúdo, incluindo HTML puro, URLs externas e Remote DOM, e a interface viajava dentro da resposta da ferramenta.

MCP Apps em termos simples

MCP Apps é a extensão oficial que permite a uma ferramenta devolver um componente interativo, como um painel, um formulário ou um fluxo de trabalho em várias etapas, renderizado dentro da conversa em um iframe em sandbox. O anúncio oficial a chama de primeira extensão oficial do MCP e diz que ela está pronta para produção.

Ela se apoia em dois primitivos comuns do MCP:

  1. Uma ferramenta que carrega metadados de UI no campo _meta.ui.resourceUri.
  2. Um recurso de UI servido pelo esquema ui://, contendo HTML e JavaScript empacotados.

O SDK fica em um único pacote npm, @modelcontextprotocol/ext-apps, com subcaminhos para hooks do React, incorporação no host e registro no servidor.

Mãos de desenvolvedor digitando em um notebook fino exibindo uma interface colorida de gráfico de barras, sobre uma mesa de madeira de cafeteria

Como os dois projetos se fundiram

Do experimento à extensão

Os mantenedores propuseram o MCP Apps em novembro de 2025, com base no trabalho do MCP-UI e nas ideias do SDK de Apps da OpenAI. Dois meses depois, em 26 de janeiro de 2026, a extensão entrou no ar. O anúncio deixa claro que o MCP-UI continua como projeto separado e que migrar para a extensão oficial é opcional.

Esse detalhe importa para quem tem código antigo. Nada obriga a reescrever amanhã, e os pacotes do MCP-UI agora apontam para registerAppTool e registerAppResource do padrão MCP Apps como o caminho para conectar ferramentas e recursos.

Por que um padrão importou

Antes da fusão, os experimentos de interface estavam atrelados a clientes individuais. Um painel projetado para um host não podia ser executado em outro sem código específico do cliente. Reunir as ideias do MCP-UI e do SDK de Apps em uma única extensão significa que um autor de servidor escreve uma interface e qualquer host compatível pode renderizá-la.

Para equipes que entregam servidores MCP a muitos clientes, esse é justamente o ponto: um build, muitos hosts, uma única história de segurança.

Duas colegas desenhando dois retângulos conectados com um marcador em um quadro branco, em um escritório luminoso

Diferenças que realmente importam

A tabela comparativa

AspectoMCP-UIMCP Apps
OrigemProjeto de SDK da comunidade, de 2025Extensão oficial do MCP, proposta em novembro de 2025, no ar em 26 de janeiro de 2026
PapelPioneiro em interface interativa sobre MCP e fornece auxiliaresEspecificação padrão mais um SDK de referência
Vínculo com a ferramentaO modelo original devolve a UI dentro da resposta da ferramenta_meta.ui.resourceUri aponta para um recurso ui://
Tipo MIMEtext/html;profile=mcp-app quando usado com o padrãotext/html;profile=mcp-app
Auxiliares de servidorcreateUIResource em @mcp-ui/serverregisterAppTool e registerAppResource em ext-apps/server
View e clienteAppRenderer e AppFrame em @mcp-ui/clientClasse App, mais app-bridge para hosts
LinguagensAuxiliares de servidor em TypeScript, Ruby e PythonSDK em TypeScript com hooks do React
StatusContinua como projeto separado, migração opcionalDescrito como pronto para produção

Leia a tabela como um mapa de camadas, não como um placar. O MCP Apps define o contrato, e o MCP-UI oferece conveniência sobre esse contrato.

Onde fica o HTML

A diferença estrutural mais importante é onde a interface fica. No MCP Apps, o servidor armazena a UI sob um URI ui:// e a ferramenta aponta para ele por meio de _meta.ui.resourceUri. O host busca esse recurso separadamente e o renderiza no seu próprio ritmo, então o HTML não é enfiado em cada resposta da ferramenta.

Os ganhos práticos:

  • Modelos que podem ser revisados. Um host pode ler o modelo antes de executá-lo.
  • Separação limpa. Os resultados da ferramenta continuam sendo dados, e o recurso continua sendo a interface.

Vista aérea de uma mesa de carvalho com esboços de wireframes a lápis, um notebook com uma interface de mapa e um tablet com um layout parecido

Segurança e sandboxing

Código interativo dentro de um chat é um risco, então o modelo de segurança é um recurso central. O anúncio lista quatro camadas:

  • Sandbox de iframe com permissões restritas
  • Modelos pré-declarados que os hosts podem revisar
  • Mensagens JSON-RPC auditáveis para cada troca entre a interface e o host
  • Consentimento opcional do usuário antes de uma chamada de ferramenta iniciada pela interface

Do lado do MCP-UI, AppRenderer recebe uma propriedade sandbox que aponta para uma página proxy separada, que o exemplo da documentação serve a partir da própria porta. HTML não confiável nunca compartilha uma página com o seu aplicativo host.

💡 Dica: O manipulador onOpenLink documentado verifica se uma URL começa com https:// ou http:// antes de chamar window.open. Adote esse hábito. Uma View é uma entrada não confiável, então filtre o que ela pede ao host para fazer.

Close macro de um terrário de vidro com pequenos blocos de madeira e um cadeado de latão, como uma caixa de areia

Hosts que renderizam Views

No lançamento, o anúncio citou Claude (web e desktop), Goose e Visual Studio Code Insiders, com o ChatGPT chegando na mesma semana. O repositório ext-apps agora lista ChatGPT, Claude, VS Code, Goose, Postman, MCPJam, o inspector do mcp-use e o Alpic Playground. JetBrains, AWS, Google DeepMind e Antigravity foram citados como empresas que estudam oferecer suporte.

Confira o status atual do host de destino antes de prometer uma data de lançamento. Essa lista muda rápido.

Apresentador em uma sala de reuniões com paredes de vidro, ao lado de uma tela mostrando um painel limpo enquanto colegas assistem

As peças do SDK com que você vai trabalhar

Duas famílias de pacotes fazem o trabalho, e elas se encaixam.

PacoteFinalidade
@modelcontextprotocol/ext-appsCriar Views interativas com a classe App
@modelcontextprotocol/ext-apps/reactHooks do React para Views
@modelcontextprotocol/ext-apps/app-bridgeIncorporar Views em um cliente de chat
@modelcontextprotocol/ext-apps/serverRegistrar ferramentas e recursos no seu servidor MCP
@mcp-ui/servercreateUIResource e auxiliares para Ruby e Python
@mcp-ui/clientAppRenderer e AppFrame para hosts

Desenvolvedor visto de costas em uma mesa em pé com três monitores exibindo editores de código em tons discretos

Lado do servidor com ext-apps

Para um servidor MCP, o comando de instalação do repositório fica assim:

npm install -S @modelcontextprotocol/ext-apps \
  @modelcontextprotocol/client@^2.0.0 \
  @modelcontextprotocol/server@^2.0.0 \
  @modelcontextprotocol/node@^2.0.0 \
  @modelcontextprotocol/express@^2.0.0 \
  zod@^4.2.0

O pacote do servidor oferece dois auxiliares, registerAppTool e registerAppResource, além da constante RESOURCE_MIME_TYPE. Um adiciona metadados de UI a uma ferramenta, e o outro serve o pacote HTML.

Lado da View com a classe App

A View é a página que roda dentro do iframe. Sua classe App conversa com o host por meio de um PostMessageTransport. Você cria o app, define manipuladores como ontoolresult e chama connect(). A partir daí, a View pode chamar ferramentas do servidor com callServerTool e enviar notas de volta ao modelo com updateModelContext.

Lado do host com AppRenderer

Se você constrói o próprio cliente de chat, AppRenderer de @mcp-ui/client é o componente de alto nível. Ele precisa de um client do MCP, um toolName, uma URL sandbox e o toolInput e os toolResult da chamada. Callbacks como onOpenLink e onMessage permitem que o host decida o que uma View pode fazer. AppFrame é a opção de nível mais baixo para HTML que você buscou por conta própria.

Exemplos de código funcionais

Uma ferramenta que devolve a hora

Este código de servidor segue o quickstart oficial. Uma ferramenta chamada get-time está vinculada a um recurso ui://, e o manipulador do recurso lê um arquivo HTML empacotado.

import { z } from "zod";
import fs from "node:fs/promises";
import path from "node:path";
import {
  registerAppResource,
  registerAppTool,
  RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";

const DIST_DIR = path.join(process.cwd(), "dist");
const resourceUri = "ui://get-time/mcp-app.html";

registerAppTool(
  server,
  "get-time",
  {
    title: "Get Time",
    description: "Returns the current server time.",
    inputSchema: z.object({}),
    _meta: { ui: { resourceUri } },
  },
  async () => {
    const time = new Date().toISOString();
    return { content: [{ type: "text", text: time }] };
  },
);

registerAppResource(
  server,
  resourceUri,
  resourceUri,
  { mimeType: RESOURCE_MIME_TYPE },
  async () => {
    const html = await fs.readFile(path.join(DIST_DIR, "mcp-app.html"), "utf-8");
    return {
      contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }],
    };
  },
);

Repare em como é pouco: uma ferramenta, um recurso e um campo de metadados que os liga.

A View que a chama

A View recebe o primeiro resultado por meio de ontoolresult e pode pedir ao servidor dados atualizados quando o usuário clicar em um botão.

import { App } from "@modelcontextprotocol/ext-apps";

const app = new App({ name: "Get Time App", version: "1.0.0" });
const serverTimeEl = document.getElementById("server-time")!;

const readTime = (result: { content?: Array<{ type: string; text?: string }> }) =>
  result.content?.find((c) => c.type === "text")?.text ?? "[ERROR]";

app.ontoolresult = (result) => {
  serverTimeEl.textContent = readTime(result);
};

document.getElementById("get-time-btn")!.addEventListener("click", async () => {
  const result = await app.callServerTool({ name: "get-time", arguments: {} });
  serverTimeEl.textContent = readTime(result);
});

app.connect();

Tablet e notebook lado a lado sobre uma mesa de madeira clara, mostrando layouts de painel quase idênticos

Empacotando a UI com createUIResource

Com o MCP-UI, createUIResource de @mcp-ui/server cria o objeto de recurso para você:

import { createUIResource } from "@mcp-ui/server";

const widgetUI = await createUIResource({
  uri: "ui://my-server/widget",
  content: { type: "rawHtml", htmlString: "<h1>Widget</h1>" },
  encoding: "text",
});

O formato de transmissão que ele produz é um recurso MCP comum com o tipo MIME padrão:

{
  type: "resource",
  resource: {
    uri: "ui://my-server/widget",
    mimeType: "text/html;profile=mcp-app",
    text: "<h1>Widget</h1>",
  },
}

Enviando contexto de volta ao modelo

Uma View não é um beco sem saída. Ela pode informar ao modelo o que o usuário acabou de fazer, para que a próxima resposta reflita o clique:

await app.updateModelContext({
  content: [{ type: "text", text: "User selected option B" }],
});

Essa única chamada é o que transforma um widget estático em parte da conversa.

Qual escolher

A resposta honesta é que a maioria dos projetos novos deve partir do padrão MCP Apps e tratar o MCP-UI como uma caixa de ferramentas ao lado dele.

Escolha o SDK do MCP Apps quando:

  • Você está começando um projeto novo em TypeScript e quer o caminho oficial e neutro em relação ao host.
  • Você quer uma única interface renderizada em vários hosts, como Claude, VS Code, Goose e ChatGPT.
  • Você quer os hooks do React, ou app-bridge para incorporar Views no seu próprio cliente de chat.
  • Sua ferramenta executa tarefas longas. A geração de imagens e vídeos é assíncrona: uma ferramenta inicia uma tarefa, e algo consulta até ela terminar. Uma View com barra de progresso e galeria de resultados vence um log de texto todas as vezes.

Mantenha os auxiliares do MCP-UI quando:

  • Seu servidor é escrito em Ruby ou Python e você quer mcp_ui_server ou mcp-ui-server.
  • Você já entrega saída createUIResource e ela é renderizada corretamente nos seus hosts.
  • Você quer AppRenderer como um renderizador pronto dentro de um cliente que você controla.

Uma breve lista de verificação para migração:

  1. Adicione _meta.ui.resourceUri a cada ferramenta que tenha uma interface.
  2. Sirva o HTML a partir de um recurso ui:// com o tipo MIME text/html;profile=mcp-app.
  3. Substitua as cargas de UI embutidas nas respostas das ferramentas por ponteiros de recurso.
  4. Mova a lógica da View para a classe App e leia os resultados em ontoolresult.
  5. Teste em pelo menos dois hosts antes de lançar.

Vista aérea de uma trilha de caminhada que se divide em duas em uma floresta outonal de bétulas, com um caminhante solitário na bifurcação

Como usar o Sonnet 5 no PicassoIA

As Views são em sua maioria HTML, CSS e uma camada fina de TypeScript, exatamente o tipo de trabalho que um modelo de programação faz bem. O Claude Sonnet 5 no Picasso IA foi feito para tarefas de programação em várias etapas e uso de ferramentas, lê capturas de tela e wireframes, e pode rascunhar uma primeira versão de um servidor, de uma View ou de um wrapper de host a partir de um pedido simples.

  1. Abra a página do modelo. Acesse a página do Claude Sonnet 5 no Picasso IA.
  2. Preencha o campo obrigatório. prompt é o único parâmetro obrigatório. Experimente: "Escreva uma ferramenta de servidor MCP em TypeScript chamada show-chart que registre um recurso ui://, mais uma View usando a classe App que renderize um gráfico de barras a partir do resultado da ferramenta."
  3. Defina o nível de esforço. O padrão é low, que desliga o pensamento para a resposta mais rápida. Aumente para high ou max quando a tarefa tocar em vários arquivos, como servidor, View e etapa de build juntos.
  4. Adicione um prompt de sistema. Fixe um papel uma vez, por exemplo: "Você escreve código MCP Apps com @modelcontextprotocol/ext-apps e nunca insere segredos no HTML." Ele então vale para toda a sessão.
  5. Anexe uma imagem, se tiver uma. O parâmetro opcional image aceita um wireframe ou uma captura de tela, reduzido pelo max_image_resolution para economizar tempo e dinheiro.
  6. Gere e revise. A saída pode ir até 8.192 tokens por padrão. Copie o código e teste em um host.
ParâmetroObrigatórioPadrãoUse para
promptSimNenhumO próprio pedido
effortNãolowQuanto o modelo pensa antes de responder
max_tokensNão8192Limitar o tamanho da saída
system_promptNãoVazioPapel e estilo de código
imageNãoNenhumUm wireframe ou captura de tela como contexto
max_image_resolutionNão0,5 megapixelReduzir a imagem antes de enviá-la

💡 Dica: Cole os trechos deste artigo no seu prompt como referência. Assim o modelo usa os nomes reais da API em vez de adivinhá-los.

Mulher em uma mesa de estúdio revisando uma folha de contato impressa com lupa, ao lado de um notebook com uma grade de galeria de imagens

Crie suas próprias imagens hoje

Toda MCP App acaba precisando de imagens: uma imagem de destaque para uma landing page, fotos de produtos para uma galeria de View, um clipe curto para uma demonstração. O Picasso IA reúne os modelos para tudo isso em um só lugar, então você pode testar ideias antes de conectar qualquer coisa a um servidor.

  • Comece com imagens fixas do Seedream 5 Pro, e dê ao prompt uma lente, uma direção de luz e uma textura para obter um resultado fotográfico.
  • Transforme o melhor quadro em movimento com o Seedance 2.0, que combina vídeo com áudio integrado.
  • Mantenha o lado do código avançando com o Claude Sonnet 5, usando os passos acima.

Escolha um prompt, gere uma imagem e veja até onde uma única ideia chega. Depois abra a coleção de modelos do Picasso IA e teste um segundo modelo com o mesmo prompt. A comparação sozinha vai mostrar o que cada um faz de melhor.

Compartilhe este artigo

Escolha seu idioma