npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@fractal-mcp/mcp

v0.11.4

Published

Fractal MCP server components and utilities

Readme

@fractal-mcp/mcp

Express server utilities and MCP server implementation for hosting Fractal MCP (Model Context Protocol) servers over HTTP with authentication, component tools, and session management.

Installation

npm install @fractal-mcp/mcp

Overview

The @fractal-mcp/mcp package provides a complete solution for hosting MCP servers with Fractal-specific enhancements. It includes:

  • FractalMCPServer - Enhanced MCP server with component tool support
  • Express Integration - HTTP transport with authentication and session management
  • Component Tools - Tools that return React components alongside data
  • JWT Authentication - Secure authentication using Fractal's auth service
  • Session Management - Automatic session handling for MCP clients

Quick Start

Basic MCP Server

import { FractalMCPServer, startExpressServer } from '@fractal-mcp/mcp';

// Create a Fractal MCP server
const server = new FractalMCPServer({
  name: 'my-fractal-server',
  version: '1.0.0'
});

// Add a simple tool
server.tool({
  name: 'greet',
  description: 'Greet a user',
        inputSchema: {
    name: { type: 'string' }
  },
  handler: async ({ name }) => {
    return `Hello, ${name}!`;
  }
});

// Start the server
startExpressServer(server, 3000);
console.log('Server running at http://localhost:3000/mcp');

Component Tool Example

import { FractalMCPServer, startExpressServer } from '@fractal-mcp/mcp';

const server = new FractalMCPServer({
  name: 'component-server',
  version: '1.0.0'
});

// Add a component tool
server.componentTool({
  name: 'weather-widget',
  description: 'Display weather information',
  inputSchema: {
    location: { type: 'string' },
    units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
  },
  componentPath: './components/WeatherWidget.tsx',
  handler: async ({ location, units }) => {
    // Fetch weather data
    const weatherData = await fetchWeather(location, units);
    return weatherData;
  }
});

startExpressServer(server, 3000);

API Reference

FractalMCPServer

Enhanced MCP server with support for regular tools and component tools.

Constructor

new FractalMCPServer(options: { name: string; version: string })

Parameters:

  • options.name: string - Server name identifier
  • options.version: string - Server version

Example:

const server = new FractalMCPServer({
  name: 'my-server',
  version: '2.1.0'
});

tool(toolDefinition)

Register a standard MCP tool.

Parameters:

interface FractalTool {
  name: string;                    // Tool identifier
  description: string | undefined; // Human-readable description
  inputSchema: z.ZodRawShape;     // Zod schema for input validation
  outputSchema?: z.ZodRawShape;   // Optional output schema
  handler: (args: any, extra: RequestHandlerExtra) => any; // Tool implementation
}

Example:

server.tool({
  name: 'calculate',
  description: 'Perform mathematical calculations',
  inputSchema: {
    operation: { type: 'string', enum: ['add', 'subtract', 'multiply', 'divide'] },
    a: { type: 'number' },
    b: { type: 'number' }
  },
  outputSchema: {
    result: { type: 'number' },
    operation: { type: 'string' }
  },
  handler: async ({ operation, a, b }) => {
    let result: number;
    switch (operation) {
      case 'add': result = a + b; break;
      case 'subtract': result = a - b; break;
      case 'multiply': result = a * b; break;
      case 'divide': result = a / b; break;
      default: throw new Error('Invalid operation');
    }
    return { result, operation };
  }
});

componentTool(toolDefinition)

Register a component tool that returns both data and a React component.

Parameters:

type FractalComponentTool<TInput, TData> = 
  | FractalStaticComponentTool<TInput, TData>
  | FractalDynamicComponentTool<TInput, TData>;

Static Component Tool:

interface FractalStaticComponentTool<TInput, TData> {
  name: string;
  description: string;
  inputSchema: z.ZodRawShape;
  outputSchema?: z.ZodRawShape;
  price?: number;                 // Optional pricing information
  
  // Component specification (choose one):
  componentPath: string;          // Path to unbundled React component
  componentBundlePath: string;    // Path to bundled component directory
  componentBundleHtmlPath: string; // Path to complete HTML file
  
  handler: (args: TInput, extra: RequestHandlerExtra) => Promise<TData>;
}

Dynamic Component Tool:

interface FractalDynamicComponentTool<TInput, TData> {
  name: string;
  description: string;
  inputSchema: z.ZodRawShape;
  outputSchema?: z.ZodRawShape;
  price?: number;
  
  componentHandler: (args: TInput, extra: RequestHandlerExtra) => Promise<WithComponentBundle<TData>>;
}

Static Component Tool Example:

server.componentTool({
  name: 'user-profile',
  description: 'Display user profile information',
  inputSchema: {
    userId: { type: 'string' }
  },
  componentPath: './components/UserProfile.tsx',
  price: 0.01, // Optional pricing
  handler: async ({ userId }) => {
    const user = await getUserById(userId);
    return {
      id: user.id,
      name: user.name,
      email: user.email,
      avatar: user.avatar
    };
  }
});

Dynamic Component Tool Example:

server.componentTool({
  name: 'dynamic-chart',
  description: 'Generate charts based on data type',
  inputSchema: {
    dataType: { type: 'string', enum: ['bar', 'line', 'pie'] },
    data: { type: 'array' }
  },
  componentHandler: async ({ dataType, data }) => {
    // Generate different components based on data type
    let componentPath: string;
    switch (dataType) {
      case 'bar': componentPath = './components/BarChart.tsx'; break;
      case 'line': componentPath = './components/LineChart.tsx'; break;
      case 'pie': componentPath = './components/PieChart.tsx'; break;
    }
    
    // Bundle the component dynamically
    const bundle = await getComponentBundle({ componentPath });
    
    return {
      data: { chartData: data, type: dataType },
      component: bundle
    };
  }
});

connect(transport)

Connect the server to a transport layer.

Parameters:

  • transport: Transport - MCP transport instance

Returns: Promise<void>

introspect()

Get detailed information about all registered tools.

Returns: Promise<IntrospectionResult>

interface IntrospectionResult {
  tools: Array<{
    name: string;
    description: string | undefined;
    inputSchema: any;
    outputSchema: any;
  }>;
  componentTools: Array<{
    name: string;
    description: string;
    inputSchema: any;
    outputSchema: any;
  }>;
}

Example:

const info = await server.introspect();
console.log(`Server has ${info.tools.length} regular tools`);
console.log(`Server has ${info.componentTools.length} component tools`);

Express Server Functions

startExpressServer(mcpServer, port?)

Start a complete Express server with authentication, CORS, and MCP handling.

Parameters:

  • mcpServer: IMcpConnectable - MCP server instance
  • port?: number - Port to listen on (default: 3000)

Returns: void

Features:

  • JWT authentication via Authorization header
  • CORS middleware for cross-origin requests
  • Session management with mcp-session-id header
  • Health check endpoint at /health
  • Hello endpoint at /hello for testing authentication

Example:

import { FractalMCPServer, startExpressServer } from '@fractal-mcp/mcp';

const server = new FractalMCPServer({ name: 'my-server', version: '1.0.0' });

// Add tools...

startExpressServer(server, 3000);
// Server available at:
// - http://localhost:3000/mcp (MCP endpoint)
// - http://localhost:3000/health (health check)
// - http://localhost:3000/hello (auth test)

makeExpressApp(app, mcpServer)

Create MCP routes on an existing Express app (for custom setups).

Parameters:

  • app: express.Express - Existing Express application
  • mcpServer: IMcpConnectable - MCP server instance

Returns: express.Express - The same app with MCP routes added

Example:

import express from 'express';
import { makeExpressApp, FractalMCPServer } from '@fractal-mcp/mcp';

const app = express();
const server = new FractalMCPServer({ name: 'custom', version: '1.0.0' });

// Add custom middleware
app.use('/api', myApiRoutes);

// Add MCP functionality
makeExpressApp(app, server);

app.listen(3000);

defaultCorsMiddleware

Default CORS middleware for cross-origin requests.

Type: (req: Request, res: Response, next: NextFunction) => void

Example:

import express from 'express';
import { defaultCorsMiddleware } from '@fractal-mcp/mcp';

const app = express();
app.use(defaultCorsMiddleware);

Component Tool Utilities

registerComponentTool(server, componentTool)

Register a component tool with an MCP server (used internally by FractalMCPServer).

Parameters:

  • server: McpServer - Standard MCP server instance
  • componentTool: FractalComponentTool<any, any> - Component tool definition

Example:

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { registerComponentTool } from '@fractal-mcp/mcp';

const server = new McpServer({ name: 'test', version: '1.0.0' });

registerComponentTool(server, {
  name: 'my-component',
  description: 'Test component',
  inputSchema: { message: { type: 'string' } },
  componentPath: './TestComponent.tsx',
  handler: async ({ message }) => ({ message })
});

getComponentBundle(componentTool)

Extract component bundle information from a component tool.

Parameters:

  • componentTool: FractalComponentTool<any, any> - Component tool definition

Returns: Promise<FractalComponentToolBundle | undefined>

type FractalComponentToolBundle = 
  | { html: string }
  | { jsPath: string; cssPath?: string };

Authentication

JWT Authentication

The server automatically validates JWT tokens from the Authorization header:

// Client request headers
{
  "Authorization": "Bearer <jwt-token>",
  "Content-Type": "application/json"
}

Token Requirements:

  • Algorithm: RS256
  • Issuer: "fractal-auth"
  • Audience: "fractal"
  • Valid signature from Fractal's JWKS endpoint

Authentication Flow:

  1. Client sends request with JWT in Authorization header
  2. Server fetches public key from https://auth.fractalmcp.com/.well-known/jwks.json
  3. Server verifies token signature and claims
  4. On success, request proceeds with req.auth containing decoded payload
  5. On failure, returns 401 with error details

Testing Authentication

# Test the hello endpoint
curl -H "Authorization: Bearer <your-jwt>" http://localhost:3000/hello

# Expected response:
{
  "message": "Hello, user!",
  "user": { /* decoded JWT payload */ }
}

Session Management

Session Headers

  • mcp-session-id - Session identifier for maintaining client state
  • Sessions are automatically created on first initialize request
  • Subsequent requests with same session ID reuse the connection

Session Flow

  1. Initialize: Client sends initialize request without session ID
  2. Session Created: Server creates new session and returns session ID
  3. Subsequent Requests: Client includes session ID in all future requests
  4. Session Reuse: Server routes requests to existing session transport

Component Tool Development

Component Structure

Components receive data through window.__FRACTAL_DATA__:

// WeatherWidget.tsx
import React from 'react';

interface WeatherData {
  location: string;
  temperature: number;
  conditions: string;
}

export default function WeatherWidget() {
  const data = (window as any).__FRACTAL_DATA__ as WeatherData;
  
  return (
    <div className="weather-widget">
      <h2>Weather in {data.location}</h2>
      <p>{data.temperature}°F - {data.conditions}</p>
    </div>
  );
}

Component Tool Types

Static Components:

  • Component is known at registration time
  • Data is generated by the handler
  • Component path specified in tool definition

Dynamic Components:

  • Component is determined at runtime
  • Both data and component returned by handler
  • More flexible but requires runtime bundling

Bundling Options

Development (componentPath):

{
  componentPath: './components/MyWidget.tsx'
  // Automatically bundles on each request
  // Good for development, not recommended for production
}

Production (componentBundlePath):

{
  componentBundlePath: './dist/my-widget'
  // Expects pre-bundled Component.jsx and index.css
  // Recommended for production
}

Custom HTML (componentBundleHtmlPath):

{
  componentBundleHtmlPath: './dist/widget.html'
  // Complete HTML file with embedded component
  // Maximum control over output
}

Error Handling

Tool Errors

server.tool({
  name: 'risky-operation',
  description: 'An operation that might fail',
  inputSchema: { data: { type: 'string' } },
  handler: async ({ data }) => {
    try {
      return await performRiskyOperation(data);
    } catch (error) {
      throw new Error(`Operation failed: ${error.message}`);
    }
  }
});

Component Tool Errors

server.componentTool({
  name: 'error-prone-widget',
  description: 'Widget that handles errors gracefully',
  inputSchema: { userId: { type: 'string' } },
  componentPath: './components/UserWidget.tsx',
  handler: async ({ userId }) => {
    try {
      const user = await fetchUser(userId);
      return user;
    } catch (error) {
      // Component will receive error in data
      throw new Error(`Failed to load user: ${error.message}`);
    }
  }
});

Authentication Errors

// 401 Unauthorized responses
{
  "error": "missing_token"
}

{
  "error": "invalid_token",
  "details": "Token has expired"
}

Production Deployment

Environment Variables

# Optional: Override JWKS URL for custom auth
JWKS_URL=https://your-auth-service.com/.well-known/jwks.json

# Optional: Custom port
PORT=3000

Pre-bundling Components

# Bundle components before deployment
npx @fractal-mcp/cli bundle -e ./components/Widget.tsx -d ./dist/widget

# Use bundled components in production
server.componentTool({
  name: 'my-widget',
  componentBundlePath: './dist/widget',
  // ... rest of configuration
});

Health Monitoring

# Health check endpoint
curl http://localhost:3000/health
# Response: {"status": "ok"}

# Use for load balancer health checks

Scaling Considerations

  • Each session maintains its own transport
  • Memory usage scales with concurrent sessions
  • Consider session cleanup for long-running servers
  • Use process managers (PM2, Docker) for production

Integration Examples

With Fractal Client

// Server setup
import { FractalMCPServer, startExpressServer } from '@fractal-mcp/mcp';

const server = new FractalMCPServer({ name: 'api-server', version: '1.0.0' });

server.componentTool({
  name: 'data-table',
  description: 'Display data in a table',
  inputSchema: { query: { type: 'string' } },
  componentPath: './components/DataTable.tsx',
  handler: async ({ query }) => {
    const results = await database.query(query);
    return { results, query };
  }
});

startExpressServer(server, 3001);

// Client usage
import { FractalSDK } from '@fractal-mcp/client';

const client = new FractalSDK({ apiKey: 'your-key' });
await client.connect();

const result = await client.executeTool('data-table', {
  query: 'SELECT * FROM users LIMIT 10'
});

// result contains both data and rendered component

Custom Express Setup

import express from 'express';
import { makeExpressApp, FractalMCPServer, defaultCorsMiddleware } from '@fractal-mcp/mcp';

const app = express();
const server = new FractalMCPServer({ name: 'custom', version: '1.0.0' });

// Custom middleware
app.use(express.json({ limit: '10mb' }));
app.use(defaultCorsMiddleware);

// Custom routes
app.get('/status', (req, res) => {
  res.json({ status: 'running', timestamp: Date.now() });
});

// Add MCP functionality
makeExpressApp(app, server);

// Custom error handling
app.use((error, req, res, next) => {
  console.error('Server error:', error);
  res.status(500).json({ error: 'Internal server error' });
});

app.listen(3000);

Dependencies

  • @fractal-mcp/bundle - Component bundling utilities
  • @modelcontextprotocol/sdk - MCP protocol implementation
  • express - HTTP server framework
  • jsonwebtoken - JWT token verification
  • jwk-to-pem - JWK to PEM conversion for RSA keys

Requirements

  • Node.js 18+
  • Valid Fractal JWT tokens for authentication
  • React components for component tools