Skip to content
Automation
Skill

/single-file-bundling

Configure Vite with vite-plugin-singlefile for mandatory single-file HTML bundling of MCP Apps. All assets (JS, CSS, images, fonts) must be inlined into a single HTML file for sandboxed iframe compatibility.

From plugin
babysitter
1.9k200 skills3 agents21 commands1 MCP

Claude Code

$ npx -y skills add a5c-ai/babysitter --skill single-file-bundling --agent claude-code

SKILL.md

single-file-bundling.SKILL.md
name: single-file-bundling
description: Configure Vite with vite-plugin-singlefile for mandatory single-file HTML bundling of MCP Apps. All assets (JS, CSS, images, fonts) must be inlined into a single HTML file for sandboxed iframe compatibility.
allowed-tools: Read, Write, Edit, Bash
graph:
  domains: [domain:software-engineering]
  specializations: [specialization:ai-agents-conversational]
  skillAreas: [skill-area:mcp-server-implementation, skill-area:mcp-tool-design]
  roles: [role:backend-engineer, role:fullstack-engineer]
  workflows: [workflow:feature-development]

single-file-bundling

Configure Vite with vite-plugin-singlefile to produce a single self-contained HTML file for MCP Apps running in sandboxed iframes.

Overview

MCP Apps run in sandboxed iframes with no same-origin server. This means:

  • **No relative asset URLs** -- `<script src="./main.js">` will not resolve
  • **No CSS file imports** -- `<link href="./styles.css">` will not load
  • **No image/font paths** -- relative paths to assets will fail
  • The **entire UI must be a single HTML file** with all JS, CSS, images, and fonts inlined

`vite-plugin-singlefile` handles this by inlining all assets into one HTML file during the Vite build. This is **mandatory** for MCP Apps -- without it, the app will show a blank iframe.

Capabilities

Vite Configuration

  • Configure Vite with `vite-plugin-singlefile`
  • Set correct `base`, `build.outDir`, and entry point
  • Handle framework-specific Vite plugins (React, Vue, Svelte, Preact, Solid)

Single HTML File Output

  • All JavaScript inlined as `<script>` tags
  • All CSS inlined as `<style>` tags
  • All images converted to data URIs
  • All fonts converted to base64

Two-Phase Build Setup

  • Phase 1: Vite bundles UI into `dist/mcp-app.html`
  • Phase 2: TypeScript compiles server into `dist/server.js`
  • Combined build script orchestrates both phases

Hybrid Build Pipelines

  • Add MCP build alongside existing standalone build
  • Separate Vite configs for MCP and standalone if needed
  • Separate HTML entry points (`mcp-app.html` vs `index.html`)

Usage

Basic Vite Configuration

// vite.config.ts
import { defineConfig } from 'vite';
import { viteSingleFile } from 'vite-plugin-singlefile';

export default defineConfig({
  plugins: [viteSingleFile()],
  build: {
    outDir: 'dist',
    // Entry point for the MCP App UI
    rollupOptions: {
      input: 'mcp-app.html',
    },
  },
});

React Vite Configuration

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { viteSingleFile } from 'vite-plugin-singlefile';

export default defineConfig({
  plugins: [react(), viteSingleFile()],
  build: {
    outDir: 'dist',
    rollupOptions: {
      input: 'mcp-app.html',
    },
  },
});

Vue Vite Configuration

// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteSingleFile } from 'vite-plugin-singlefile';

export default defineConfig({
  plugins: [vue(), viteSingleFile()],
  build: {
    outDir: 'dist',
    rollupOptions: {
      input: 'mcp-app.html',
    },
  },
});

Svelte Vite Configuration

// vite.config.ts
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { viteSingleFile } from 'vite-plugin-singlefile';

export default defineConfig({
  plugins: [svelte(), viteSingleFile()],
  build: {
    outDir: 'dist',
    rollupOptions: {
      input: 'mcp-app.html',
    },
  },
});

HTML Entry Point

<!-- mcp-app.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My MCP App</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.ts"></script>
</body>
</html>

For React (`.tsx` entry):

<!-- mcp-app.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>My MCP App</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.tsx"></script>
</body>
</html>

Package.json Build Scripts

{
  "scripts": {
    "build:ui": "vite build",
    "build:server": "tsc --project tsconfig.server.json",
    "build": "npm run build:ui && npm run build:server",
    "dev": "concurrently \"vite\" \"tsx watch src/server.ts\"",
    "serve": "tsx src/server.ts"
  }
}

Server Reading the Bundled HTML

import fs from 'fs';
import path from 'path';
import { registerAppResource, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps';

// Read the single-file bundle produced by Vite
const bundledHtml = fs.readFileSync(
  path.join(__dirname, '../dist/mcp-app.html'),
  'utf-8'
);

registerAppResource(server, {
  uri: 'app:///my-app',
  name: 'My App',
  mimeType: RESOURCE_MIME_TYPE,
  async read() {
    return {
      contents: [{
        uri: 'app:///my-app',
        mimeType: RESOURCE_MIME_TYPE,
        text: bundledHtml,
      }],
    };
  },
});

Hybrid Build Pipeline (MCP + Standalone)

When converting a web app that already has its own build:

// vite.config.mcp.ts -- MCP-specific build config
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { viteSingleFile } from 'vite-plugin-singlefile';

export default defineConfig({
  plugins: [react(), viteSingleFile()],
  build: {
    outDir: 'dist/mcp',
    rollupOptions: {
      input: 'mcp-app.html',  // Separate entry from index.html
    },
  },
});
{
  "scripts": {
    "build:standalone": "vite build",
    "build:mcp:ui": "vite build --config vite.config.mcp.ts",
    "build:mcp:server": "tsc --project tsconfig.server.json",
    "build:mcp": "npm run build:mcp:ui && npm run build:mcp:server",
    "build:all": "npm run build
Read more
@a5c-ai
Ships withbabysitter

Enforce obedience on agentic workforces. Manage extremely complex workflows through deterministic, hallucination-free self-orchestration.

1.9k200 skills3 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.9k
Star history of a5c-ai/babysitter on GitHub, a chart by star-history.com

Other skills on babysitter.

babysit-babysitter-issues

babysit-babysitter-iss…

This skill should be used when the user asks to "babysit issues", "work on assigned issues", "check a5c-agent issues", "process…

@a5c-ai@a5c-aiInstall Skill
catalog-babysitter-users

catalog-babysitter-use…

Discover public GitHub repositories that import defineTask from @a5c-ai/babysitter-sdk and maintain a deduplicated catalog of…

@a5c-ai@a5c-aiInstall Skill
fix-failing-pipelines

fix-failing-pipelines

This skill should be used when the user asks to "fix pipelines", "fix CI", "check staging pipelines", "fix failing workflows",…

@a5c-ai@a5c-aiInstall Skill
process-builder

process-builder

Scaffold new babysitter process definitions following SDK patterns, proper structure, and best practices. Guides the 3-phase…

@a5c-ai@a5c-aiInstall Skill

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n10d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about single-file-bundling.

Which coding agents can use single-file-bundling?
single-file-bundling installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.