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.server/bundled/
directory: Where your bundled components will be stored.
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.