Bridge your existing Module Federation remotes to AI-native interactive UIs via the MCP Apps standard.
- β Fully compliant with MCP Apps standard
- β Dynamic tool registration from configuration
- β CORS proxy for CDN resources
- β Protocol-relative URL handling
- β CSP configuration support
- β AI-friendly Skills for configuration management
mcp-apps-demo.mp4
The MCP Apps standard lets AI hosts (Claude, VS Code, Goose, etc.) render interactive UI components inside conversations. But it raises a practical question: where does the UI come from?
The standard approach requires an MCP Server to provide a self-contained HTML resource β React, component code, and styles all bundled together. This means:
- UI components must be extracted from your existing project and rebuilt with a separate bundling pipeline
- Each MCP tool needs its own build artifact
- Updating a component requires rebuilding and redeploying the MCP Server's static assets
- Shared dependencies like React are duplicated across every tool's bundle
Module Federation solves all of this by flipping the model.
Instead of bundling UI into the MCP Server, the server holds a configuration file (mcp_apps.json) that points to your existing MF remotes. The UI lives where it already belongs β in your frontend deployment pipeline.
| Standard MCP Apps | This project | |
|---|---|---|
| UI source | Self-contained HTML bundle inside MCP Server | Existing MF remote, loaded dynamically from CDN |
| Adding a new tool | Extract component β create new build β redeploy server | Add one entry to mcp_apps.json |
| Updating UI | Rebuild bundle β redeploy server | Deploy new version to CDN, bump version in config |
| Shared dependencies | Duplicated per tool bundle | Shared across remotes via MF shared scope |
| Granularity | One bundle per tool | Any exposes entry β a button, a form, or an entire page |
In short: MF provides the UI delivery infrastructure that MCP Apps needs, without the overhead of maintaining a parallel build system for AI interfaces.
βββββββββββββββββββ
β Claude AI β
ββββββββββ¬βββββββββ
β MCP Protocol
βΌ
βββββββββββββββββββββββ
β MF MCP Server β
β - Load config β
β - Register tools β
β - Generate β
β ui://mf/<slug> β
β resource URIs β
ββββββββββ¬βββββββββββββ
β Returns resource URI (ui://mf/<slug>)
β Host fetches HTML for that URI
βΌ
ββββββββββββββββββββββββ
β mf_render_container β (rendered as iframe)
β - Load MF remote β
β from CDN β
β - Render component β
β with tool input β
ββββββββββββββββββββββββ
- Node.js 22+
- Claude Desktop (or any MCP host that supports the MCP Apps spec)
@module-federation/mcp-apps |
MCP Apps spec (@modelcontextprotocol/ext-apps) |
MCP SDK (@modelcontextprotocol/sdk) |
Module Federation (@module-federation/enhanced) |
Tested Claude Desktop |
|---|---|---|---|---|
0.0.x |
^1.1.2 |
^1.27.1 |
^2.0.1 |
0.9.x (macOS) |
The MCP Apps spec version this package implements is 1.1.x (Streamable HTTP +
text/html;profile=mcp-appresource MIME type). Hosts that do not support the MCP Apps spec still receive plain-text tool responses β the UI is simply not rendered.
The repo includes a ready-to-run Module Federation provider with a Deploy Wizard demo.
cd module-federation-examples/basic
pnpm install
pnpm run dev
# Runs on http://localhost:8080Then register the MCP server with Claude Desktop β edit ~/Library/Application Support/Claude/claude_desktop_config.json:
Option 1: Using npx (recommended)
{
"mcpServers": {
"module-federation": {
"command": "npx",
"args": [
"-y",
"@module-federation/mcp-apps@latest",
"--config",
"/absolute/path/to/module-federation-mcp/module-federation-examples/basic/mcp_apps.json",
"--stdio"
]
}
}
}nvm users: Claude Desktop does not inherit your shell's PATH, so
npxmay resolve to the wrong Node version (e.g. an old v16). Use the full path tonpxand pin PATH viaenv:which npx # e.g. /Users/you/.nvm/versions/node/v22.21.1/bin/npx{ "mcpServers": { "module-federation": { "command": "/Users/you/.nvm/versions/node/v22.21.1/bin/npx", "args": [ "-y", "@module-federation/mcp-apps@latest", "--config", "/absolute/path/to/module-federation-mcp/module-federation-examples/basic/mcp_apps.json", "--stdio" ], "env": { "PATH": "/Users/you/.nvm/versions/node/v22.21.1/bin:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin" } } } }
Option 2: Run from a local build
# In the module-federation-mcp directory
pnpm install && pnpm run build{
"mcpServers": {
"module-federation": {
"command": "/absolute/path/to/node",
"args": [
"/absolute/path/to/module-federation-mcp/dist/index.js",
"--config",
"/absolute/path/to/module-federation-mcp/module-federation-examples/basic/mcp_apps.json",
"--stdio"
]
}
}
}Replace /absolute/path/to/... with the actual absolute path on your machine. Restart Claude Desktop, then type:
Start a deployment
Claude will open the Deploy Wizard β a 3-step interactive UI running inside the chat.
Create a config file for your project (see Configuration Reference below), or use the AI Skill to generate it automatically.
Use the included Skill to set up your configuration. The skill will automatically detect if your project is a Module Federation project and parse the configuration:
For Module Federation Projects:
You: Set up MCP for my MF project
AI: β
Detected module-federation.config.ts
π¦ Found package: @scope/your-package
π§ Found 3 exposed components
[Asks for: version, CDN URL, locale]
[Automatically generates tools from exposes]
Supported Config Files:
module-federation.config.tsrspack.config.js/webpack.config.js(with ModuleFederationPlugin)
For Non-MF Projects:
You: Add MF tools to MCP
AI: βΉοΈ Not a Module Federation project
[Asks for: package name, version, CDN URL, components manually]
Or manually create mcp_apps.json:
{
"remotes": [
{
"name": "@scope/package",
"version": "1.0.0",
"baseUrl": "https://cdn.example.com/path",
"locale": "en",
"csp": {
"connectDomains": ["cdn.example.com"],
"resourceDomains": ["cdn.example.com"]
}
}
],
"tools": [
{
"name": "my_tool",
"title": "My Tool",
"description": "Tool description",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
},
"remote": "@scope/package",
"module": "./ComponentName",
"exportName": "default"
}
]
}Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
Option 1: Using npx (recommended)
{
"mcpServers": {
"module-federation": {
"command": "npx",
"args": [
"-y",
"@module-federation/mcp-apps@latest",
"--config",
"/absolute/path/to/mcp_apps.json",
"--stdio"
]
}
}
}nvm users: Claude Desktop does not inherit your shell's PATH, so
npxmay resolve to the wrong Node version (e.g. an old v16). Use the full path tonpxand pin PATH viaenv:which npx # e.g. /Users/you/.nvm/versions/node/v22.21.1/bin/npx{ "mcpServers": { "module-federation": { "command": "/Users/you/.nvm/versions/node/v22.21.1/bin/npx", "args": [ "-y", "@module-federation/mcp-apps@latest", "--config", "/absolute/path/to/mcp_apps.json", "--stdio" ], "env": { "PATH": "/Users/you/.nvm/versions/node/v22.21.1/bin:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin" } } } }
Option 2: Run from a local build
# In the module-federation-mcp directory
pnpm install && pnpm run build{
"mcpServers": {
"module-federation": {
"command": "/absolute/path/to/node",
"args": [
"/absolute/path/to/module-federation-mcp/dist/index.js",
"--config",
"/absolute/path/to/mcp_apps.json",
"--stdio"
]
}
}
}Your tools are now available!
This repo includes an AI Skill that automatically generates mcp_apps.json for your project. The skill works with any AI coding tool β Claude, Cursor, GitHub Copilot, Windsurf, Cline, etc.
Point your AI assistant at skill/generate-mcp-apps-config.md. The skill will:
- Auto-detect your MF config (
module-federation.config.ts,rspack.config.js,webpack.config.js) - Parse
nameandexposesto generate tool entries automatically - Ask for CDN URL, version, and locale
- Create a complete, validated
mcp_apps.json
Claude (Projects or chat)
Upload the entire skill/ directory to your Claude Project, or paste into chat:
Use the instructions in skill/generate-mcp-apps-config.md to generate mcp_apps.json for my project.
Cursor / Windsurf / Cline
Add skill/generate-mcp-apps-config.md as context in the chat, then:
Follow skill/generate-mcp-apps-config.md to generate mcp_apps.json
GitHub Copilot
Attach the file via #file:skill/generate-mcp-apps-config.md in Copilot Chat, then ask it to generate the config.
Any other AI tool
The skill is plain Markdown β paste it directly into any chat or custom instruction field.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | β | Package name |
version |
string | β | Package version |
baseUrl |
string | β | CDN base URL |
locale |
string | β | Locale (default: 'en') |
csp |
object | β | CSP configuration |
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | β | Tool identifier |
title |
string | β | Display name |
description |
string | β | Tool description |
inputSchema |
object | β | JSON Schema for input |
remote |
string | β | Remote name |
module |
string | β | Module Federation path |
exportName |
string | β | Export name (default: 'default') |
Already configured above. Tools will appear in Claude after restart.
# Install dependencies
npm install
# Build
npm run build
# Development with watch mode
npm run dev
# Type check
npm run typecheck- Configuration Loading: Server loads
mcp_apps.jsondefining remotes and tools - Tool Registration: Each tool is registered with MCP protocol
- Resource Generation: Server generates bundled HTML with MF runtime
- Component Loading: When tool is called:
- MCP host renders the HTML resource
- Module Federation loads remote component from CDN
- CORS proxy handles cross-origin requests
- Component renders with tool input as props
If you see "Server disconnected" immediately after starting Claude Desktop, the most common cause with nvm is that Claude launches the MCP server with the wrong Node.js version.
Check the logs to confirm:
cat ~/Library/Logs/Claude/mcp-server-module-federation.logIf you see a TypeError from @hono/node-server or a warning about an unsupported Node version, follow the nvm users note in the Option 1 config above to use the full path to npx and pin PATH via env.
- Check configuration file path is absolute
- Validate
mcp_apps.jsonsyntax - Restart Claude Desktop
- Check logs:
~/Library/Logs/Claude/mcp-server-module-federation.log
- Verify CDN URL is accessible
- Check
csp.connectDomainsincludes CDN domain - Verify module path matches Module Federation expose
- Check browser console in Claude DevTools
Validate manually:
// Check remote exists
const remote = config.remotes.find(r => r.name === tool.remote);
if (!remote) {
console.error('Remote not found');
}See mcp_apps.example.json for a complete example configuration.
The server also supports HTTP mode for agent frameworks that run the MCP client server-side and render UI in a browser. See docs/integration-guide.md for a detailed integration walkthrough.
MIT