Demarrer avec le boilerplate
Vous allez voir, en 10 minutes vous aurez une application fonctionnelle qui connecte un serveur MCP, interroge un LLM distant, et affiche des widgets generes automatiquement par l’IA. C’est le point de depart ideal pour tout projet webmcp-auto-ui.
Objectif
Section intitulée « Objectif »Installer le boilerplate, connecter un serveur MCP distant, et obtenir votre premier widget genere par l’agent IA dans le navigateur.
Prerequis
Section intitulée « Prerequis »- Node.js 18+ installe
- Une cle API LLM (e.g. Anthropic pour Claude, Google pour Gemini, OpenAI pour ChatGPT) — niveaux gratuits disponibles pour les premiers essais
- Un terminal et un editeur de code
- Aucune connaissance prealable de MCP n’est requise
Resultat final
Section intitulée « Resultat final »A la fin de ce tutoriel, vous aurez une app SvelteKit 5 complete avec :
- Un chat connecte a un LLM distant (e.g. Claude, Gemini, ChatGPT)
- Un serveur MCP distant connecte (donnees parlementaires francaises)
- Des widgets qui s’affichent automatiquement sur un canvas
- Un theme clair/sombre fonctionnel
graph LR U[Utilisateur] -->|question| Chat Chat -->|prompt| LLM[LLM distant] LLM -->|tool_call| MCP[Serveur MCP distant] MCP -->|donnees| LLM LLM -->|widget_display| Canvas[Canvas widgets] Canvas -->|rendu| UEtape 1 : Scaffolding
Section intitulée « Etape 1 : Scaffolding »On commence par cloner le boilerplate avec degit, qui telecharge le repertoire sans l’historique git :
npx degit jeanbaptiste/webmcp-auto-ui/apps/boilerplate my-appcd my-appnpm installCela installe une app SvelteKit 5 pre-cablee avec les 4 packages du monorepo :
| Package | Role |
|---|---|
@webmcp-auto-ui/core | Client MCP, serveur WebMCP, validation JSON Schema |
@webmcp-auto-ui/agent | Boucle agent, providers LLM, lazy loading |
@webmcp-auto-ui/sdk | Canvas store, encodage HyperSkill |
@webmcp-auto-ui/ui | Composants Svelte (LLMSelector, McpStatus, WidgetRenderer, etc.) |
Verification : apres npm install, verifiez que le repertoire node_modules/@webmcp-auto-ui contient les 4 sous-repertoires (core, agent, sdk, ui).
Etape 2 : Configurer le proxy API
Section intitulée « Etape 2 : Configurer le proxy API »Le navigateur ne peut pas appeler l’API du provider LLM directement (les cles API ne doivent jamais etre exposees cote client). Le boilerplate inclut un proxy serveur SvelteKit qui relaie les requetes.
Ouvrez le fichier src/routes/api/chat/+server.ts (deja present dans le boilerplate) :
import { env } from '$env/dynamic/private';import type { RequestHandler } from '@sveltejs/kit';import { llmProxy } from '@webmcp-auto-ui/agent/server';
export const POST: RequestHandler = async ({ request }) => { const body = await request.json() as Record<string, unknown>; const apiKey = (body.__apiKey as string | undefined) || env.LLM_API_KEY || ''; delete body.__apiKey; return llmProxy(body, apiKey, request.headers.get('X-Model'));};Voici ce qui se passe :
- Le proxy lit la cle API depuis les variables d’environnement serveur (jamais exposee au client)
llmProxyreformate le body et l’envoie a l’API du LLM distant- Le header
X-Modelpermet de changer de modele dynamiquement ('haiku','sonnet','opus')
Ajoutez votre cle API dans un fichier .env a la racine du projet :
LLM_API_KEY=sk-ant-...Verification : le fichier .env existe et contient LLM_API_KEY=sk-ant-... (votre vraie cle).
Etape 3 : Comprendre la connexion MCP
Section intitulée « Etape 3 : Comprendre la connexion MCP »Le boilerplate utilise McpMultiClient pour gerer une ou plusieurs connexions a des serveurs MCP distants. Un serveur MCP expose des outils (tools) que le LLM peut appeler pour recuperer des donnees.
import { McpMultiClient } from '@webmcp-auto-ui/core';
const multiClient = new McpMultiClient();await multiClient.addServer('https://mcp.code4code.eu/mcp');addServer effectue trois operations :
- Connexion au serveur via HTTP Streamable (JSON-RPC 2.0)
- Initialisation du protocole MCP (echange de capabilities)
- Recuperation de la liste des outils disponibles
Dans le boilerplate, la connexion est deja cablee dans le composant principal : un champ URL + un bouton “Connecter”. L’app se connecte automatiquement au chargement de la page.
sequenceDiagram participant App as App (navigateur) participant MCP as Serveur MCP App->>MCP: POST /mcp {initialize} MCP-->>App: {capabilities, serverInfo} App->>MCP: POST /mcp {tools/list} MCP-->>App: {tools: [...]} Note over App: Outils disponibles !Verification : lancez npm run dev, ouvrez http://localhost:5173, et verifiez que l’indicateur MCP en haut de page passe au vert.
Etape 4 : Comprendre le provider LLM
Section intitulée « Etape 4 : Comprendre le provider LLM »Le provider LLM est l’abstraction qui permet de communiquer avec differents modeles de langage. Le boilerplate utilise RemoteLLMProvider pour les modeles distants (toute API compatible OpenAI) :
import { RemoteLLMProvider } from '@webmcp-auto-ui/agent';
const provider = new RemoteLLMProvider({ proxyUrl: '/api/chat' });Le composant <LLMSelector> (dans la barre superieure) permet de changer de modele a chaud. Les alias disponibles sont :
| Alias | Modele reel | Cas d’usage |
|---|---|---|
haiku | Claude Haiku | Rapide, economique, ideal pour les tests |
sonnet | Claude Sonnet | Equilibre performance/cout |
opus | Claude Opus | Maximum de qualite |
Etape 5 : Lancer la boucle agent
Section intitulée « Etape 5 : Lancer la boucle agent »La boucle agent est le coeur du systeme. Elle orchestre les echanges entre le LLM, les outils MCP (donnees distantes) et les widgets WebMCP (affichage local).
Voici le code complet, tel qu’il apparait dans le boilerplate :
import { runAgentLoop, buildSystemPrompt, fromMcpTools, autoui } from '@webmcp-auto-ui/agent';import type { ToolLayer, McpLayer } from '@webmcp-auto-ui/agent';
// 1. Construire les layers (MCP distant + WebMCP local)const layers: ToolLayer[] = [];
// Layer MCP : chaque serveur connecte fournit ses outilsfor (const server of multiClient.listServers()) { const mcpLayer: McpLayer = { protocol: 'mcp', serverName: server.name, tools: fromMcpTools(server.tools), }; layers.push(mcpLayer);}
// Layer WebMCP : widgets natifs (stat, chart, table, map...)layers.push(autoui.layer());
// 2. Generer le system prompt adapte aux serveurs connectesconst systemPrompt = buildSystemPrompt(layers);
// 3. Lancer la boucleconst result = await runAgentLoop(userMessage, { provider, systemPrompt, layers, maxIterations: 10, maxTokens: 4096, callbacks: { onWidget: (type, data) => { // Le LLM a demande d'afficher un widget const id = 'b_' + Date.now().toString(36); blocks = [...blocks, { id, type, data }]; return { id }; }, onText: (text) => { ephemeralText = text; }, onToolCall: (call) => { console.log('Tool:', call.name); }, },});Le flux est le suivant :
sequenceDiagram participant User as Utilisateur participant AgentLoop as Agent Loop participant LLM as LLM distant participant MCP as Serveur MCP participant UI as Canvas
User->>AgentLoop: "Montre-moi la fiche de Melenchon" AgentLoop->>LLM: prompt + tools disponibles LLM->>AgentLoop: tool_call: search_recipes AgentLoop->>MCP: search_recipes MCP-->>AgentLoop: recette "fiche-depute" AgentLoop->>LLM: resultat + suite LLM->>AgentLoop: tool_call: get_recipe AgentLoop->>MCP: get_recipe MCP-->>AgentLoop: schema + instructions AgentLoop->>LLM: schema du widget LLM->>AgentLoop: tool_call: query_sql AgentLoop->>MCP: requete donnees MCP-->>AgentLoop: donnees JSON AgentLoop->>LLM: donnees LLM->>AgentLoop: tool_call: widget_display AgentLoop->>UI: affiche le widget UI-->>User: Widget rendu !Le buildSystemPrompt genere un prompt qui impose un workflow en 4 etapes au LLM :
- Decouverte : chercher les recettes disponibles
- Lecture : lire le schema et les instructions de la recette
- Execution : appeler les outils de donnees
- Affichage : appeler
widget_displayavec les bonnes donnees
Verification : tapez “Montre-moi la fiche de Jean-Luc Melenchon” dans le chat. Vous devriez voir l’indicateur de progression, puis un widget s’afficher.
Etape 6 : Afficher les widgets
Section intitulée « Etape 6 : Afficher les widgets »Le rendu des widgets se fait via <WidgetRenderer>. Ce composant resout automatiquement le composant Svelte correspondant au type du widget :
<script lang="ts"> import { WidgetRenderer } from '@webmcp-auto-ui/ui';</script>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> {#each blocks as block (block.id)} <WidgetRenderer id={block.id} type={block.type} data={block.data} {servers} /> {/each}</div>WidgetRenderer cherche le bon composant dans cet ordre :
- Les serveurs WebMCP custom (passes via la prop
servers) - Les widgets natifs
autoui(stat, chart, table, map, profile, timeline, etc.)
Si le type n’est reconnu par aucun serveur, un fallback JSON s’affiche pour le debug.
Etape 7 : Ajouter les composants UI
Section intitulée « Etape 7 : Ajouter les composants UI »Le boilerplate integre plusieurs composants UI pre-faits qui simplifient la construction de l’interface :
<script lang="ts"> import { LLMSelector, // Selecteur de modele (haiku/sonnet/opus) McpStatus, // Indicateur de connexion MCP AgentProgress, // Progression de la boucle agent WidgetRenderer, // Rendu des widgets getTheme, // Theme clair/sombre } from '@webmcp-auto-ui/ui';</script>
<!-- Barre superieure --><header class="flex items-center gap-3 px-4 border-b"> <McpStatus connecting={canvas.mcpConnecting} connected={canvas.mcpConnected} name={mcpName} servers={multiClient.listServers().map(s => ({ url: s.url, name: s.name, toolCount: s.tools.length }))} /> <LLMSelector /></header>
<!-- Progression agent (barre animee pendant la generation) --><AgentProgress active={canvas.generating} elapsed={chatTimer} toolCalls={chatToolCount} lastTool={chatLastTool}/>Chaque composant est autonome :
McpStatusaffiche un point vert/rouge avec le nom du serveur et le nombre d’outilsLLMSelectorexpose un dropdown pour choisir le modele LLMAgentProgressmontre une barre de progression avec le temps ecoule, le nombre d’appels d’outils, et le dernier outil appele
Etape 8 : Ajouter un widget custom
Section intitulée « Etape 8 : Ajouter un widget custom »Le boilerplate inclut 3 widgets custom (fiches deputes, scrutins, amendements) comme exemples. Pour creer les votres, il suffit de :
- Creer un serveur WebMCP local :
import { createWebMcpServer } from '@webmcp-auto-ui/core';import MonWidget from './widgets/MonWidget.svelte';import monWidgetRecipe from './recipes/mon-widget.md?raw';
const monServeur = createWebMcpServer('mon-app', { description: 'Widgets custom de mon application',});
// Enregistrer le widget avec sa recette (frontmatter + instructions)monServeur.registerWidget(monWidgetRecipe, MonWidget);- Ajouter le layer a la boucle agent :
layers.push(monServeur.layer());- Passer le serveur au WidgetRenderer :
<WidgetRenderer id={block.id} type={block.type} data={block.data} servers={[monServeur]}/>Le LLM decouvre automatiquement vos widgets via search_recipes et peut les utiliser dans ses reponses.
Verification : demandez au chat quelque chose en rapport avec votre widget. Le LLM devrait decouvrir la recette et afficher votre composant.
Lancer le serveur de developpement
Section intitulée « Lancer le serveur de developpement »npm run devL’app est accessible sur http://localhost:5173. L’app se connecte automatiquement au serveur MCP par defaut.
Verification finale : tapez une question dans le chat et verifiez que :
- L’indicateur de progression s’active
- Des appels d’outils s’affichent dans la console
- Un ou plusieurs widgets apparaissent sur le canvas
Structure du projet
Section intitulée « Structure du projet »my-app/ src/ routes/ +page.svelte # Page principale (chat + canvas) +layout.svelte # Layout racine (ThemeProvider) api/chat/+server.ts # Proxy API LLM distant lib/ widgets/ register.ts # Serveur WebMCP + enregistrement widgets MonWidget.svelte # Composant widget custom recipes/ mon-widget.md # Recette du widget (frontmatter + instructions) .env # LLM_API_KEY (jamais commite) package.json svelte.config.js vite.config.tsTroubleshooting
Section intitulée « Troubleshooting »| Probleme | Cause probable | Solution |
|---|---|---|
| ”Failed to fetch” dans le chat | Cle API manquante ou invalide | Verifiez .env et redemarrez le serveur de dev |
| MCP reste rouge | URL incorrecte ou serveur MCP down | Verifiez l’URL, testez avec curl -X POST <url> |
| Widgets ne s’affichent pas | Le LLM n’appelle pas widget_display | Verifiez que autoui.layer() est dans les layers |
| ”Module not found” au build | Packages pas installes | Relancez npm install |
Aller plus loin
Section intitulée « Aller plus loin »- Ajouter un second serveur MCP : appelez
multiClient.addServer('https://autre-serveur/mcp')pour combiner plusieurs sources de donnees - Personnaliser le theme : modifiez les tokens dans
ThemeProvider(voir Construire une demo themee) - Creer vos propres widgets : suivez le tutoriel Creer un widget custom
- Activer le Nano-RAG : cochez la case “Nano-RAG” pour compresser le contexte avec des embeddings locaux