
Guia mostra como testar acessibilidade de apps MCP renderizados no cliente
Por que a acessibilidade em MCP Apps importa
MCP Apps permitem que um servidor MCP envie uma interface real - botões, formulários, cartões - que renderiza dentro do cliente de IA, em vez de depender do agente para decidir o que apresentar. Harris Schneiderman, da Deque Systems, alerta que isso cria risco de excluir pessoas desde o início: se o widget for inacessível, todos os controles existem apenas ali, e uma descrição em texto não substitui as funções. O comportamento dos clientes varia - em testes, o Claude Desktop descreveu resultados junto ao widget, enquanto outros clientes suprimem o texto - e o desenvolvedor não controla o que o usuário recebe. O guia oficial de testes do MCP Apps cobre apenas testes funcionais, e a especificação não menciona contraste, teclado, leitor de tela ou foco; uma issue no GitHub de fevereiro de 2026 já pedia que a especificação oferecesse ganchos para acessibilidade.
Por que testar é diferente de apps web
Dois problemas separam o teste de MCP Apps do teste web tradicional. Primeiro, não é possível forçar um agente real a mostrar todos os estados do app: estados como carregamento sem dados, cancelamento e teardown são acionados pela pessoa ou pelo cliente, não pelos dados. Segundo, o app renderiza dentro de um iframe sandboxed e cross-origin em uma página que o desenvolvedor não controla. O MCP Inspector é uma opção para renderizar o app como um cliente de produção, e o Axe DevTools consegue enxergar dentro do frame - mas o caminho do frame varia por cliente e quebra quando o cliente muda sua marcação.
O harness de servidor de desenvolvimento local
Um servidor de desenvolvimento local resolve os dois problemas. A recomendação é:
- Servir exatamente o mesmo artefato que o servidor MCP serve, importando o mesmo HTML do mesmo módulo do manipulador de recurso ui:// - copiar ou criar variante leva a testar uma interface que os usuários nunca recebem.
- Escrever um host stub de menos de 100 linhas de código, que responde a ui/initialize, envia tool input e tool result, e responde a ui/open-link, sem dependências. O app não distingue o harness de um cliente real.
- Nunca renderizar interface no harness, para que varreduras de acessibilidade não atribuam problemas do próprio ambiente de teste ao app.
- Tornar cada estado endereçável por URL, usando parâmetros para selecionar fixtures, gerando uma lista de URLs que ferramentas automatizadas e pessoas podem consumir.
Estados, dados e temas a cobrir
O teste deve percorrer a sequência de mensagens e cobrir: conectando, aguardando dados, entrada em streaming, sucesso, vazio, erro, cancelado, teardown e mudança de contexto. Isso deve ser cruzado com um eixo de dados (mínimo, muitos itens e dados patológicos, como strings longas sem quebra, texto da direita para a esquerda e campos opcionais ausentes) e com temas claro e escuro. Contra cada URL, recomenda-se rodar regras automatizadas mais regras avançadas em largura realista de coluna de chat, seguidas de Intelligent Guided Tests - usando as mesmas ferramentas já empregadas em acessibilidade web.
Erros comuns específicos de MCP Apps
- Estrutura de documentos: começar títulos em h1, já que o app é um documento próprio dentro do iframe; não pular níveis; dar um título descritivo à página, complementar ao h1 (título descreve o app, h1 descreve o resultado); evitar o nome da ferramenta no h1, pois o cliente pode já usá-lo como rótulo do frame.
- Atalhos de teclado: verificar colisões com os atalhos do cliente, que podem prevalecer, e não assumir que teclas funcionam globalmente - nem que as teclas do usuário continuam funcionando com o foco no widget. O WCAG 2.1.4 exige que atalhos de tecla única possam ser desligados, remapeados ou ativos só com foco; remapear é a opção mais flexível.
- CSS e cores: usar tokens para os dois lados de um par de cores ou para nenhum; emparelhar dentro de famílias semânticas; definir cor em poucos lugares com herança e currentColor; garantir que cores de fallback funcionem nos dois sentidos; usar --color-ring-* para indicadores de foco e verificá-los contra a superfície do host.
- Safe area insets: não usar env(safe-area-inset-*) diretamente, pois resolve contra o viewport do iframe e retorna zeros sem significado; ler de hostContext.safeAreaInsets, aplicar a tudo que pinta na borda, compor com max() em vez de somar, reaplicar a cada atualização e tratar como aprimoramento progressivo com padrão zero. Isso importa principalmente em tela cheia e picture-in-picture.
- Movimento reduzido e outras media queries: prefers-reduced-motion, prefers-color-scheme, forced-colors e prefers-contrast se propagam sem tratamento especial.
Conclusão
Como MCP Apps ainda são novos, as abordagens estabelecidas agora tendem a permanecer à medida que o ecossistema cresce. Schneiderman defende agir nesta fase para não repetir os problemas de acessibilidade históricos da web, usando as ferramentas já existentes contra um alvo de teste estável.