Boilerplate
Boilerplate (apps/boilerplate/) is the starter template for integrating webmcp-auto-ui into a SvelteKit project. It shows how to register custom widgets via createWebMcpServer, connect to remote MCP servers, and drive an AI agent to automatically generate interfaces. This is the recommended starting point for any new project.
What you see when you open the app
Section titled “What you see when you open the app”When you open the Boilerplate, you’ll see a clean interface with a toolbar at the top. On the left, the title “Boilerplate Tricoteuses” in monospace. On the right, the MCP connection status (with connected servers and tool count), a Nano-RAG checkbox, an LLM model selector, and a light/dark theme toggle.
Below that, an input field lets you enter an MCP server URL with a “Connect” button. The app auto-connects to the Tricoteuses server (mcp.code4code.eu/mcp) on startup.
Below that, a row of buttons lets you enable/disable local WebMCP servers (Tricoteuses and AutoUI), each showing how many widgets they expose.
In the center, an empty state greets you with three suggestion buttons: “Fiche depute”, “Scrutin”, and “Amendement”. When the agent generates widgets, they appear in a responsive 2-column grid.
At the bottom, an input bar lets you ask questions in natural language, and an AgentProgress indicator shows elapsed time, tool call count, and the last tool used.
Architecture
Section titled “Architecture”graph TD subgraph Frontend Page["+page.svelte<br/>Chat + Widgets + Config"] Widgets["lib/widgets/<br/>3 Svelte components"] Register["register.ts<br/>createWebMcpServer"] end
subgraph "Custom Widgets" FD["FicheDepute.svelte<br/>Photo, group, votes"] RS["ResultatScrutin.svelte<br/>For/against bar"] AM["Amendement.svelte<br/>Article, motives, outcome"] end
subgraph Packages Agent["@webmcp-auto-ui/agent<br/>runAgentLoop, RemoteLLMProvider"] Core["@webmcp-auto-ui/core<br/>createWebMcpServer,<br/>McpMultiClient"] SDK["@webmcp-auto-ui/sdk<br/>canvas store"] UI["@webmcp-auto-ui/ui<br/>LLMSelector, McpStatus,<br/>AgentProgress, WidgetRenderer"] end
subgraph Backend Proxy["api/chat/+server.ts<br/>LLM Proxy"] end
Register --> FD Register --> RS Register --> AM Page --> Register Page --> Agent Page --> Core Page --> SDK Page --> UI Agent --> ProxyTech stack
Section titled “Tech stack”| Component | Detail |
|---|---|
| Framework | SvelteKit + Svelte 5 |
| Styles | TailwindCSS 3.4 |
| Icons | lucide-svelte |
| LLM provider | RemoteLLMProvider (remote LLM via proxy) |
| MCP | McpMultiClient (multi-server) |
| Custom widgets | 3 Svelte components via createWebMcpServer |
| RAG | ContextRAG (experimental) |
| Adapter | @sveltejs/adapter-node |
Packages used:
@webmcp-auto-ui/core:createWebMcpServer,McpMultiClient@webmcp-auto-ui/agent:runAgentLoop,RemoteLLMProvider,buildSystemPrompt,fromMcpTools,autoui,buildDiscoveryCache,ContextRAG@webmcp-auto-ui/sdk:canvasstore@webmcp-auto-ui/ui:LLMSelector,McpStatus,AgentProgress,WidgetRenderer,getTheme
Getting started
Section titled “Getting started”| Environment | Port | Command |
|---|---|---|
| Dev | 5179 | npm -w apps/boilerplate run dev |
| Production | 3011 | node index.js (via systemd) |
npm -w apps/boilerplate run dev# Available at http://localhost:5179Features
Section titled “Features”3 Tricoteuses widgets
Section titled “3 Tricoteuses widgets”Widgets are registered in src/lib/widgets/register.ts via createWebMcpServer. Each widget is defined by a YAML frontmatter (name, description, JSON schema) and a Svelte component:
- FicheDepute (
fiche-depute): complete profile of a French National Assembly deputy with photo, political group (color), constituency, mandate dates, participation rate, and vote breakdown (for/against/abstention) - ResultatScrutin (
resultat-scrutin): vote result with title, number, date, proportional for/against/abstention bar, voter count, “Adopted” or “Rejected” badge - Amendement (
amendement): parliamentary amendment with number, targeted article, author, group, explanatory statement, and outcome (adopted, rejected, withdrawn, unsupported)
Multi-MCP AI agent
Section titled “Multi-MCP AI agent”The agent uses a layered architecture:
- MCP layers: one layer per connected remote MCP server, with tools converted via
fromMcpTools - WebMCP layers: one layer per enabled local WebMCP server (Tricoteuses, AutoUI)
Layers are reactively recomputed on every connection change.
Pre-filled suggestions
Section titled “Pre-filled suggestions”Three buttons trigger sample queries that demonstrate widget capabilities:
- “Show me Jean-Luc Melenchon’s profile with his voting stats”
- “Display the vote result on pension reform”
- “Show an adopted amendment on article 7 of the finance bill”
Automatic LLM optimization
Section titled “Automatic LLM optimization”Optimization options (sanitize, flatten, truncate, compress) automatically adjust via $effect when the LLM model changes. Small models (Gemma, local) get flattened schemas and truncated results to fit their context window.
Configuration
Section titled “Configuration”| Variable | Description | Default |
|---|---|---|
LLM_API_KEY | Remote LLM provider API key (server-side .env) | required |
mcpUrl | Default MCP server URL | https://mcp.code4code.eu/mcp |
Code walkthrough
Section titled “Code walkthrough”src/lib/widgets/register.ts
Section titled “src/lib/widgets/register.ts”The key file in the Boilerplate. It creates a WebMCP server named tricoteuses-widgets with createWebMcpServer, then registers each widget via registerWidget(). Each registration takes a YAML frontmatter (complete JSON Schema) and a Svelte component.
export const tricoteusesServer = createWebMcpServer('tricoteuses-widgets', { description: 'French parliamentary widgets...',});
tricoteusesServer.registerWidget(`---widget: fiche-deputedescription: Deputy profile...schema: type: object required: [nom, prenom, groupe] properties: nom: { type: string } ...---Displays a deputy profile...`, FicheDepute);src/routes/+page.svelte
Section titled “src/routes/+page.svelte”The main component. It manages:
- MCP connection via
McpMultiClient(with auto-connect on mount) - Reactive layer construction (
$derived) - Agent loop with
onWidget,onClear,onText,onToolCallcallbacks - Widget display via
WidgetRendererin a responsive grid - Toggleable local WebMCP servers
src/routes/api/chat/+server.ts
Section titled “src/routes/api/chat/+server.ts”Server-side proxy identical to Flex: uses llmProxy from the agent package.
Using as a template
Section titled “Using as a template”From the monorepo
Section titled “From the monorepo”cp -r apps/boilerplate apps/my-appModify:
package.json: change the name (@webmcp-auto-ui/my-app) and port in the dev scriptsrc/lib/widgets/register.ts: replace the 3 widgets with your own+page.svelte: adapt the UI, suggestions, and title
From an external project
Section titled “From an external project”npx degit jeanbaptiste/webmcp-auto-ui/apps/boilerplate my-appcd my-appnpm installnpm run devCreating a new widget
Section titled “Creating a new widget”- Create a Svelte component in
src/lib/widgets/ - Register it in
register.tswith a YAML frontmatter defining the schema - The local WebMCP server automatically exposes the widget to the LLM
Deployment
Section titled “Deployment”| Server path | /opt/webmcp-demos/boilerplate/ (root) |
|---|---|
| systemd service | webmcp-boilerplate |
| ExecStart | node index.js |
./scripts/deploy.sh boilerplate- Live demo
- Core package —
createWebMcpServer - Agent package —
runAgentLoop - Flex (full app) — for all advanced features