Serveur AWS MCP et Widgets
Introduction
NOTE
Cet article est la suite directe de mon travail sur les Applications MCP et l'UI Générative. Je vous recommande vivement de le lire au préalable pour comprendre les concepts de base de l'ajout de couches d'interface utilisateur (UI) aux serveurs MCP !
AWS a récemment publié son serveur MCP officiel. Il est doté de capacités impressionnantes : des outils pour exécuter du code et des commandes, ainsi que l'accès à la documentation officielle d'AWS. Il s'agit cependant d'un serveur MCP classique. Il ne fournit aucune interface utilisateur via ses endpoints, et puisqu'il ne renvoie aucun en-tête CORS, il ne peut pas être appelé directement depuis un navigateur.
Dans mon précédent PoC GenUI, j'ai exploré exactement cette lacune : ajouter la génération d'interface utilisateur (UI) par-dessus un serveur MCP, de sorte que les résultats des outils puissent être rendus sous forme d'interfaces pratiques. Ce PoC fonctionnait bien, mais uniquement avec des serveurs fictifs que j'avais créés et hébergés pour l'occasion.
Cette fois, je voulais un vrai serveur MCP, et le serveur AWS MCP a attiré mon attention pour une raison simple : l'exécution du code se produit à l'intérieur du serveur managé lui-même, et c'est gratuit pour l'instant. L'exécution de l'outil MCP ne coûte rien ; vous ne payez que pour les ressources AWS sous-jacentes que vos appels consomment. Comme auparavant, cela a été construit avec l'IA : j'ai continué à "vibe coder" sur le PoC précédent.
L'objectif est resté le même : enrichir un vrai serveur avec des capacités d'UI, en rendant des résultats proches de ce que produisent les applications MCP (MCP Apps), comme je l'ai fait avec le serveur de marché dans le PoC précédent.
Vous pouvez tester le PoC en direct ici : genui.iheb.pro.
Prérequis
- Une clé API d'IA agentique.
- Un principal AWS : un rôle ou un utilisateur IAM avec la politique gérée
AWSMCPSignInOAuthAccessPolicyattachée.
WARNING
Cet outil peut exécuter, via MCP, toute action que le principal est autorisé à effectuer. Commencez avec des politiques en lecture seule et adaptez-les à votre cas d'usage, en n'ajoutant des actions ciblées sur des ressources spécifiques que lorsque cela est nécessaire. Privilégiez les rôles : ils sont plus rapides à contrôler et à révoquer.
Pour l'accès aux données en plus de la politique gérée, une déclaration en lecture seule comme celle-ci est un bon point de départ. Assurez-vous de restreindre les champs Resource à vos ARN spécifiques au lieu d'utiliser des jokers * en production :
Accès aux données en lecture seule
- La dernière version de l'AWS CLI, authentifiée avec le principal ci-dessus. La version 2.35.19 ou plus récente est requise. Une fois authentifié, exécutez :
Générer un jeton d'accès
Cette commande génère un jeton d'accès OAuth 2.1. Normalement, un bouton de connexion gère cela automatiquement, mais comme la solution est hébergée sur le web, la génération du jeton reste manuelle pour l'instant. Le jeton dure une heure. Pour les besoins du PoC, le rafraîchissement n'est pas implémenté : l'agent vous notifiera lorsque le jeton expirera, et vous en générerez simplement un nouveau.

Utilisation
Je voulais que le PoC respecte un principe : tout ce qui est accessible au principal AWS devrait au moins pouvoir recevoir une réponse dans le chat, et être dessiné sous forme de widget dans les meilleurs cas.
Une fois l'accès configuré, à la fois pour votre fournisseur d'IA préféré et pour votre principal AWS, le chat offre des capacités basées sur les autorisations accordées. Soyez très prudent avec ces permissions.
J'ai sollicité l'agent pour interagir avec plusieurs services : Athena, DynamoDB et S3. À travers le serveur MCP, l'agent a orchestré des exécutions à distance et a généré des widgets affichant les résultats. Il intègre un bouton d'actualisation permettant de récupérer et comparer les informations, puis de mettre à jour le contenu du widget en place.

Il peut également comparer des données provenant de différents services. L'agent orchestre cela de lui-même.

La génération de widgets est personnalisable, en titre et en forme. Vous itérez dans le prompt jusqu'à atteindre le résultat souhaité, puis vous épinglez le widget au tableau (board).

Un agent d'IA peut naturellement faire des erreurs. Les réponses d'erreur et les indications MCP redirigent l'agent pour qu'il réessaie et accomplisse le prompt. J'ai été confronté à des dépassements de délai (timeouts) avec l'agent Kimi Code, et lui dire simplement de continuer a fonctionné pour moi. Le modèle peut également se corriger pendant la génération. Une fois qu'un widget est épinglé, il reste sur le tableau, mais il n'est pas figé : vous pouvez toujours le mettre à jour via le prompt, le rafraîchir par rapport à sa source, ou le détacher (unpin).
C'est pourquoi le serveur MCP seul n'est pas suffisant. Même lorsqu'une documentation est fournie, guider le cheminement de l'agent optimise son exécution et réduit les coûts. Des directives explicites aident à adapter le comportement de l'agent au résultat souhaité et au style d'orchestration.

Les profils d'UI sont la première version de cette idée : ils font de l'outil un fournisseur composé d'un serveur MCP plus un ensemble d'instructions. Pour l'instant, les instructions sont basiques, mais elles évolueront dans leur format et leur description dans les prochaines versions.
Sous le Capot
Les captures d'écran montrent à quoi cela ressemble, mais voici un bref aperçu de son fonctionnement. La génération d'UI repose sur quelques composants clés :
- Registre de Widgets : Un dictionnaire central associant les noms d'outils à des composants React/Astro spécifiques.
- Frontière Validée par Zod : Avant le rendu, la sortie de l'agent est validée par rapport à des schémas Zod stricts pour s'assurer que le widget reçoit exactement les props attendus.
- Profils d'UI : Ces profils associent la connexion au serveur MCP à un ensemble d'instructions système (ex: "toujours renvoyer un graphique à barres pour les métriques").
- Réconciliation d'État : Lorsque vous cliquez sur le bouton d'actualisation, l'UI envoie une requête en arrière-plan au serveur, compare les nouvelles données avec les anciennes, et met à jour l'état du widget sur place sans ré-afficher tout l'historique du chat.
Coût et Latence
Bien que l'exécution MCP elle-même soit gratuite, vous payez toujours pour les ressources AWS et les tokens LLM. Voici une estimation approximative de ce que coûte une interaction typique dans ce PoC :
| Métrique | Exemple de Coût / Temps |
|---|---|
| Tokens par Widget | ~800 à 1 500 tokens (selon la complexité du prompt) |
| Coût de Ressource AWS | Tarifs standard AWS (ex: 5,00 $ par To pour Athena). Les petites requêtes du PoC coûtent des fractions de centime. |
| Temps de Réponse | 3 à 8 secondes (raisonnement de l'agent + exécution AWS + rendu) |
Les Défis
Pour utiliser le serveur AWS MCP dans mon PoC, ce dernier a dû résoudre deux défis.
CORS
Le serveur AWS MCP est conçu pour être utilisé localement par des agents. Puisque mon agent s'exécute dans le navigateur, il a besoin d'en-têtes CORS pour communiquer directement. Cependant, le serveur ne renvoie pas d'en-têtes CORS ni n'expose de méthode OPTIONS, ce qui pousse le navigateur à bloquer toute requête "cross-origin" par défaut.
En utilisant les capacités côté serveur de Next.js, les appels sont déclenchés depuis les serveurs de Vercel à la place. Le navigateur n'envoie des requêtes qu'à lui-même : un proxy les achemine côté serveur via /api/mcp/aws pour le trafic MCP et /api/oauth/aws/ pour les endpoints OAuth.
Authentification
Il s'agit d'un serveur public exposant les capacités des services AWS, il nécessite donc naturellement une authentification par rapport à un principal AWS. De nombreuses méthodes existent, mais je voulais la plus simple : pas d'identifiants permanents, et pas de maux de tête lorsque les autorisations doivent être révoquées. AWS a récemment ajouté la prise en charge d'OAuth 2.1 à son serveur MCP, via AWS Sign-In, et un agent peut l'utiliser pour s'authentifier en tant que principal AWS actif. J'ai trouvé l'approche grâce à une recherche approfondie assistée par l'IA et cet excellent tutoriel de Satoru Ishikawa sur DevelopersIO.
WARNING
Note de Sécurité : Dans ce PoC hébergé, vous collez un jeton OAuth AWS actif dans une application web. Ce jeton transite par mon proxy backend Vercel pour atteindre AWS. Pour cette raison, veuillez utiliser uniquement un compte bac à sable (sandbox) jetable ou strictement limité.
Je voulais reproduire ce flux de travail exact, et j'ai réussi localement.
Une fois déployé, cependant, l'enregistrement de client dynamique a immédiatement rejeté mon domaine dans l'URI de redirection. Il n'accepte que localhost ou 127.0.0.1. J'avais ignoré ce détail, et mon agent IA aussi. Un bon rappel de l'importance des connaissances approfondies, même lorsqu'on utilise l'IA efficacement.

Aussi décevant que cela puisse être, ce n'est pas un point bloquant pour le moment. L'authentification reste sur le même protocole OAuth 2.1 avec un défi PKCE ; seul le jeton est généré localement via la commande CLI montrée dans les prérequis, puis collé dans l'application. Je suis assez confiant qu'une solution côté serveur plus propre pourra être trouvée ultérieurement.
Pour implémenter cet accès au serveur, mon assistant de codage a nettoyé les bugs signalés et a préparé le terrain pour le proxy CORS et le module OAuth. Une exigence externe vient d'AWS lui-même : la politique gérée AWSMCPSignInOAuthAccessPolicy doit être attachée au principal qui se connecte, sinon la page d'autorisation échoue avant toute invite de connexion.
Limites et La suite
Ce PoC démontre avec succès la faisabilité : vous pouvez greffer une couche d'UI similaire aux Applications MCP sur un serveur MCP managé tiers que vous ne contrôlez pas.
Cependant, il est important d'être honnête quant à ses limites actuelles. C'est une démonstration de faisabilité, pas nécessairement d'utilité pour le moment. Bien que les petites agrégations et les tableaux de 9 lignes s'affichent magnifiquement, le système n'a pas été testé sur des volumes de données massifs et réalistes. Il reste également à voir si une couche de widgets complexe bat systématiquement le simple fait de demander à l'IA de générer un simple tableau Markdown.
À l'horizon : résoudre le copier-coller manuel du jeton avec un bouton de connexion unique fluide, et ajouter d'autres véritables fournisseurs MCP. Les deux enrichiraient le PoC, nous permettant de croiser les réponses entre différents fournisseurs et de construire les affichages les plus pratiques au-dessus des résultats.
En fin de compte, ce projet prouve que la thèse fondamentale de la composabilité peut fonctionner ; il ne prouve pas encore qu'il fonctionne suffisamment bien pour en dépendre dans le cadre d'une utilisation quotidienne en production. Mais c'est une excellente première étape vers une UI générative propulsée par une infrastructure réelle.