Fractal Platform
Beta – v0 Fractal’s APIs and CLI commands may evolve before the first stable release. Expect non‑breaking improvements in minor updates and possible breaking changes in the next major version.
Fractal is an ecosystem of UI-enabled MCP servers that allows you to create interactive components that can be rendered in AI chat interfaces. It provides a centralized registry and discovery service for Model Context Protocol (MCP) servers and clients.
Why Fractal?
Capability | What it means | Why you care |
---|---|---|
UI-enabled MCP servers | Create interactive React components that render in AI chat interfaces. | Build rich, interactive experiences that AI assistants can display. |
Registry‑first architecture | A single source of truth for every deployed model or tool. | Zero hard‑coded URLs; swap implementations without redeploying clients. |
Pre-bundled components | Components are bundled and optimized for production deployment. | Fast loading times and optimized bundle sizes for better performance. |
Type safety with introspection | Generate TypeScript types from your running server schemas. | Full autocomplete and compile-time safety for your components. |
Pluggable authentication | API keys, OAuth2, or your custom bearer strategy. | Works in both public SaaS and private enterprise deployments. |
High‑level architecture
- Client SDK searches the registry to discover available tools and components.
- Agent calls one of the returned MCP tools.
- MCP Server responds with bundled component assets (JavaScript, CSS, etc).
- Fractal’s render library displays the interactive component in the chat interface.
Core concepts
Term | Definition |
---|---|
MCP Server SDK | Framework for building servers that register artifacts with Fractal. |
MCP Client SDK | Library for discovering and invoking artifact endpoints. |
Registry | Cloud service that stores metadata, schemas, and version history. |
Version negotiation | Registry selects the best compatible artifact version for the client’s requested range. |
Component Tool | A React component registered as an MCP tool that can be rendered in chat interfaces. |
useFractal Hook | React hook that provides data, error handling, and navigation for components. |
Component Bundling | Process of optimizing React components for production deployment. |
Available Packages
The fractal ecosystem includes these npm packages:
Core Packages
@fractal-mcp/mcp
- Main server framework withFractalMCPServer
andcomponentTool()
@fractal-mcp/composer
- React hooks includinguseFractal()
for components@fractal-mcp/bundle
- Component bundling utilities@fractal-mcp/cli
- Command-line tools for bundling and type generation
Integration Packages
@fractal-mcp/client
- Client SDK for connecting to fractal servers@fractal-mcp/render
- Component rendering utilities@fractal-mcp/vercel-connector
- Integration with Vercel AI SDK@fractal-mcp/generate
- Type generation from server schemas
Development Packages
@fractal-mcp/preview
- Development preview server@fractal-mcp/shared-ui
- Shared UI utilities and types
Quick Start Guide
There are two ways to get started with Fractal:
Option 1: CLI Tool (Recommended - 2 minutes)
The fastest way to get up and running:
# Create a new Fractal project
npx @fractal-mcp/cli create
# Follow the prompts to select:
# - Server framework (Express or Next.js)
# - React version
# - Include Tailwind CSS (recommended)
# Navigate to your project and start development
cd your-project-name
npm run dev
That’s it! Your server will be running and ready for development. Test your components at the Fractal Playground .
Option 2: Manual Setup (Learn the fundamentals)
If you want to understand how Fractal works under the hood, follow this step-by-step guide:
Project Structure
First, understand the anatomy of a Fractal project:
ui/
McpUiExample.tsx
index.css
server/
index.ts
bundled/
McpUiExample/
Component.jsx
index.css
ui/
directory: Where your React component code lives. You can import scripts, CSS files, or external libraries. The only constraint is that top-level components cannot accept props directly (use theuseFractal
hook instead).server/
directory: Where you define your tool behavior and wire them up to UI components.
Step 1: Set Up the UI Component
Create your component directory and install dependencies:
# Initialize and install UI dependencies
npm init
npm install @fractal-mcp/composer react@^19.0.0 react-dom@^19.0.0
npm install -D @types/react@^19.0.0 @types/react-dom@^19.0.0
Add these scripts to your ui/package.json
:
{
"scripts": {
"bundle-all": "npx @fractal-mcp/cli bundle-all -s ./ ../server/bundled"
}
}
Create ui/McpUiExample.tsx
:
import React from 'react';
import './index.css';
import { useFractal } from '@fractal-mcp/composer';
export default function McpUiExample() {
const { navigate, data, error } = useFractal<any>();
// Container classes for consistent styling
const containerClasses = "mcp-container";
if (error) {
return (
<div className={containerClasses}>
<div className="mcp-header">
<h2 className="mcp-title">Error</h2>
<div className="mcp-title-underline"></div>
</div>
<div className="mcp-content">
<div className="mcp-result-row">
<span className="mcp-label">Error:</span>
<span className="mcp-value" style={{ color: 'red' }}>{error.message}</span>
</div>
</div>
</div>
);
}
// No data state
if (!data) {
return (
<div className={containerClasses}>
<div className="mcp-header">
<h2 className="mcp-title">Number Squared</h2>
<div className="mcp-title-underline"></div>
</div>
<div className="mcp-content">
<div className="mcp-result-row">
<span className="mcp-label">Status:</span>
<span className="mcp-value">No data available</span>
</div>
</div>
</div>
);
}
// Extract data - assuming the MCP tool returns an object with num and result
const num = data.num || data.input || 0;
const result = data.result || data.output || num * num;
return (
<div className={containerClasses}>
<div className="mcp-header">
<h2 className="mcp-title">Number Squared</h2>
<div className="mcp-title-underline"></div>
</div>
<div className="mcp-content">
<div className="mcp-input-row">
<span className="mcp-label">Input:</span>
<span className="mcp-value mcp-input-value">{num}</span>
</div>
<div className="mcp-result-row">
<span className="mcp-label">Result:</span>
<span className="mcp-value mcp-result-value">{num} × {num} = {result}</span>
</div>
</div>
<div className="mcp-info-box">
<div className="mcp-info-dot"></div>
<p className="mcp-info-text">
This is an example MCP UI component that displays the result of squaring a number.
The component demonstrates clean styling and responsive design principles.
</p>
</div>
</div>
);
}
Create ui/index.css
:
body {
background-color: #f9fafb;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
margin: 0;
padding: 0;
}
.mcp-container {
max-width: 512px;
margin: 0 auto;
padding: 32px;
background-color: white;
border: 1px solid #e5e7eb;
border-radius: 12px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transition: box-shadow 0.3s ease;
}
.mcp-container:hover {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.mcp-header {
margin-bottom: 24px;
}
.mcp-title {
font-size: 30px;
font-weight: bold;
color: #1f2937;
margin: 0 0 8px 0;
}
.mcp-title-underline {
width: 64px;
height: 4px;
background: linear-gradient(to right, #3b82f6, #8b5cf6);
border-radius: 2px;
}
.mcp-content {
margin-bottom: 24px;
}
.mcp-input-row, .mcp-result-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
margin-bottom: 16px;
border-radius: 8px;
border-left: 4px solid;
}
.mcp-input-row {
background-color: #f9fafb;
border-left-color: #3b82f6;
}
.mcp-result-row {
background: linear-gradient(to right, #eff6ff, #f3e8ff);
border-left-color: #8b5cf6;
}
.mcp-label {
font-size: 18px;
font-weight: 500;
color: #374151;
}
.mcp-value {
font-size: 20px;
font-weight: bold;
}
.mcp-input-value {
color: #2563eb;
}
.mcp-result-value {
color: #7c3aed;
}
.mcp-info-box {
background: linear-gradient(to right, #eff6ff, #eef2ff);
padding: 16px;
border-radius: 8px;
border: 1px solid #dbeafe;
display: flex;
align-items: flex-start;
}
.mcp-info-dot {
width: 8px;
height: 8px;
background-color: #3b82f6;
border-radius: 50%;
margin-top: 8px;
margin-right: 12px;
flex-shrink: 0;
}
.mcp-info-text {
font-size: 14px;
color: #4b5563;
line-height: 1.6;
margin: 0;
}
Step 2: Set Up the Server
Navigate to your server directory and install dependencies:
# Initialize and install server dependencies
npm init
npm install @modelcontextprotocol/sdk express zod
npm install @fractal-mcp/mcp @fractal-mcp/mcp-express @fractal-mcp/composer
npm install -D @types/express@^4.17.0 @types/node@^20.0.0 typescript@^5.0.0
Add these scripts to your server/package.json
:
{
"scripts": {
"build": "tsc",
"dev": "npm run build && npm run start",
"start": "node dist/index.js"
}
}
Create server/index.ts
:
import express from 'express';
import { FractalMCPServer } from '@fractal-mcp/mcp';
import { makeExpressApp } from '@fractal-mcp/mcp-express';
import path from 'path';
import { z } from 'zod';
const app = express();
const port = process.env.PORT || 3000;
// Create and configure the MCP server
const server = new FractalMCPServer({
name: 'my-fractal-app-server',
version: '1.0.0'
});
// Example UI tool
// This is a tool that will return a UI component
// Note the presence of `componentBundlePath`, which points to one of your bundled component directories.
server.componentTool({
name: 'square_number_ui',
description: 'Displays a UI using MCP',
componentBundlePath: path.resolve('./bundled/McpUiExample'),
inputSchema: { num: z.number().describe("Number to square") },
price: 0,
handler: async ({ num }) => {
try {
return {
num: num,
result: num * num
};
} catch (error) {
console.error('Error in square_number_ui tool:', error);
throw error;
}
},
});
// Example MCP tool
// This tool doesn't return any UI components!
// Just data like a normal MCP tool.
server.tool({
name: "times_ten",
description: "Multiplies a number by ten",
inputSchema: {
num: z.number().describe("The number to multiply by ten")
},
handler: async ({ num }) => {
try {
return {
result: num * 10
};
} catch (error) {
console.error('Error in times_ten tool:', error);
throw error;
}
}
});
// Basic health check
app.get('/', (req, res) => {
res.json({
name: 'my-fractal-app-server',
status: 'running',
version: '1.0.0'
});
});
// Set up MCP routes with Express
makeExpressApp(app, server);
app.listen(port, () => {
console.log(`my-fractal-app server running on port ${port}`);
});
Create server/tsconfig.json
:
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"allowJs": true,
"strict": true,
"noEmit": false,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Step 3: Bundle and Run
-
Bundle your UI components:
cd ui && npm run bundle-all
-
Start your server:
cd server && npm run dev
That’s it! Your Fractal server is now running and ready for development.
Next steps
- Understand the lifecycle: Concepts
- Spin up a full example: Platform Quick Start
- Build your own server: Provider SDK v0
- Call an existing service: Consumer SDK v0
- FAQ & Support: FAQ
Happy fractalling! 🎉