Socket
Book a DemoInstallSign in
Socket

create-mcp-use-app

Package Overview
Dependencies
Maintainers
3
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

create-mcp-use-app

Create MCP-Use apps with one command

Source
npmnpm
Version
0.2.1
Version published
Weekly downloads
1.2K
146.89%
Maintainers
3
Weekly downloads
Β 
Created
Source

UI MCP Server

An MCP server with React UI widgets created with create-mcp-app that provides interactive web components for MCP clients.

Features

  • 🎨 React Components: Interactive UI widgets built with React
  • πŸ”₯ Hot Reloading: Development server with instant updates
  • πŸ“¦ Production Builds: Optimized bundles for production
  • 🌐 Web Endpoints: Serve widgets at /mcp-use/widgets/{widget-name}
  • πŸ› οΈ Development Tools: Full TypeScript support and modern tooling

Getting Started

Development

# Install dependencies
npm install

# Start development server with hot reloading
npm run dev

This will start:

  • MCP server on port 3000
  • Vite dev server on port 3001 with hot reloading

Production

# Build the server and UI components
npm run build

# Run the built server
npm start

Available Widgets

1. Kanban Board (/mcp-use/widgets/kanban-board)

Interactive Kanban board for task management.

Features:

  • Drag and drop tasks between columns
  • Add/remove tasks
  • Priority levels and assignees
  • Real-time updates

Usage:

mcp.tool({
  name: 'show-kanban',
  inputs: [{ name: 'tasks', type: 'string', required: true }],
  fn: async ({ tasks }) => {
    // Display Kanban board with tasks
  }
})

2. Todo List (/mcp-use/widgets/todo-list)

Interactive todo list with filtering and sorting.

Features:

  • Add/complete/delete todos
  • Filter by status (all/active/completed)
  • Sort by priority, due date, or creation time
  • Progress tracking
  • Categories and due dates

Usage:

mcp.tool({
  name: 'show-todo-list',
  inputs: [{ name: 'todos', type: 'string', required: true }],
  fn: async ({ todos }) => {
    // Display todo list with todos
  }
})

3. Data Visualization (/mcp-use/widgets/data-visualization)

Interactive charts and data visualization.

Features:

  • Bar charts, line charts, and pie charts
  • Add/remove data points
  • Interactive legends
  • Data table view
  • Multiple chart types

Usage:

mcp.tool({
  name: 'show-data-viz',
  inputs: [
    { name: 'data', type: 'string', required: true },
    { name: 'chartType', type: 'string', required: false }
  ],
  fn: async ({ data, chartType }) => {
    // Display data visualization
  }
})

Development Workflow

1. Create a New Widget

  • Create the React component:

    # Create resources/my-widget.tsx
    touch resources/my-widget.tsx
    
  • Create the HTML entry point:

    # Create resources/my-widget.html
    touch resources/my-widget.html
    
  • Add to Vite config:

    // vite.config.ts
    rollupOptions: {
      input: {
        'my-widget': resolve(__dirname, 'resources/my-widget.html')
      }
    }
    
  • Add MCP resource:

    // src/server.ts
    mcp.resource({
      uri: 'ui://widget/my-widget',
      name: 'My Widget',
      mimeType: 'text/html+skybridge',
      fn: async () => {
        const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/my-widget`
        return `<div id="my-widget-root"></div><script type="module" src="${widgetUrl}"></script>`
      }
    })
    

2. Development with Hot Reloading

# Start development
npm run dev

# Visit your widget
open http://localhost:3001/my-widget.html

Changes to your React components will automatically reload!

3. Widget Development Best Practices

Component Structure

import React, { useState, useEffect } from 'react'
import { createRoot } from 'react-dom/client'

interface MyWidgetProps {
  initialData?: any
}

const MyWidget: React.FC<MyWidgetProps> = ({ initialData = [] }) => {
  const [data, setData] = useState(initialData)

  // Load data from URL parameters
  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search)
    const dataParam = urlParams.get('data')

    if (dataParam) {
      try {
        const parsedData = JSON.parse(decodeURIComponent(dataParam))
        setData(parsedData)
      } catch (error) {
        console.error('Error parsing data:', error)
      }
    }
  }, [])

  return (
    <div>
      {/* Your widget content */}
    </div>
  )
}

// Render the component
const container = document.getElementById('my-widget-root')
if (container) {
  const root = createRoot(container)
  root.render(<MyWidget />)
}

Styling Guidelines

  • Use inline styles for simplicity
  • Follow the existing design system
  • Ensure responsive design
  • Use consistent color palette

Data Handling

  • Accept data via URL parameters
  • Provide sensible defaults
  • Handle errors gracefully
  • Use TypeScript for type safety

4. Production Deployment

# Build everything
npm run build

# The built files will be in dist/
# - dist/server.js (MCP server)
# - dist/resources/ (UI widgets)

Project Structure

my-ui-server/
β”œβ”€β”€ src/
β”‚   └── server.ts              # MCP server with UI endpoints
β”œβ”€β”€ resources/                 # React components and HTML entry points
β”‚   β”œβ”€β”€ kanban-board.html
β”‚   β”œβ”€β”€ kanban-board.tsx
β”‚   β”œβ”€β”€ todo-list.html
β”‚   β”œβ”€β”€ todo-list.tsx
β”‚   β”œβ”€β”€ data-visualization.html
β”‚   └── data-visualization.tsx
β”œβ”€β”€ dist/                      # Built files
β”‚   β”œβ”€β”€ server.js
β”‚   └── resources/
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ vite.config.ts
└── README.md

API Reference

MCP Resources

All UI widgets are available as MCP resources:

  • ui://status - Server status and available widgets
  • ui://widget/kanban-board - Kanban board widget
  • ui://widget/todo-list - Todo list widget
  • ui://widget/data-visualization - Data visualization widget

MCP Tools

  • show-kanban - Display Kanban board with tasks
  • show-todo-list - Display todo list with items
  • show-data-viz - Display data visualization

MCP Prompts

  • ui-development - Generate UI development guidance

Customization

Adding New Dependencies

# Add React libraries
npm install @types/react-router-dom react-router-dom

# Add UI libraries
npm install @mui/material @emotion/react @emotion/styled

Environment Variables

Create a .env file:

# Server configuration
PORT=3000
NODE_ENV=development

# UI configuration
VITE_API_URL=http://localhost:3000

Custom Build Configuration

// vite.config.ts
export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      input: {
        'my-custom-widget': resolve(__dirname, 'resources/my-custom-widget.html')
      }
    }
  }
})

Troubleshooting

Common Issues

  • "Cannot find module" errors

    • Make sure all dependencies are installed: npm install
    • Check that TypeScript paths are correct
  • Hot reloading not working

    • Ensure Vite dev server is running on port 3001
    • Check that the widget HTML file exists
  • Widget not loading

    • Verify the widget is added to vite.config.ts
    • Check that the MCP resource is properly configured
  • Build errors

    • Run npm run build to see detailed error messages
    • Check that all imports are correct

Development Tips

  • Use browser dev tools to debug React components
  • Check the Network tab for failed requests
  • Use React DevTools browser extension
  • Monitor console for errors

Learn More

  • React Documentation
  • Vite Documentation
  • MCP Documentation
  • mcp-use Documentation

Examples

Simple Counter Widget

// resources/counter.tsx
import React, { useState } from 'react'
import { createRoot } from 'react-dom/client'

const Counter: React.FC = () => {
  const [count, setCount] = useState(0)

  return (
    <div style={{ padding: '20px', textAlign: 'center' }}>
      <h1>Counter: {count}</h1>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
      <button onClick={() => setCount(count - 1)}>
        Decrement
      </button>
    </div>
  )
}

const container = document.getElementById('counter-root')
if (container) {
  const root = createRoot(container)
  root.render(<Counter />)
}

Data Table Widget

// resources/data-table.tsx
import React, { useState, useEffect } from 'react'
import { createRoot } from 'react-dom/client'

interface TableData {
  id: string
  name: string
  value: number
}

const DataTable: React.FC = () => {
  const [data, setData] = useState<TableData[]>([])

  useEffect(() => {
    // Load data from URL or use defaults
    const urlParams = new URLSearchParams(window.location.search)
    const dataParam = urlParams.get('data')

    if (dataParam) {
      try {
        setData(JSON.parse(decodeURIComponent(dataParam)))
      } catch (error) {
        console.error('Error parsing data:', error)
      }
    }
  }, [])

  return (
    <div style={{ padding: '20px' }}>
      <h1>Data Table</h1>
      <table style={{ width: '100%', borderCollapse: 'collapse' }}>
        <thead>
          <tr>
            <th>Name</th>
            <th>Value</th>
          </tr>
        </thead>
        <tbody>
          {data.map(row => (
            <tr key={row.id}>
              <td>{row.name}</td>
              <td>{row.value}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

const container = document.getElementById('data-table-root')
if (container) {
  const root = createRoot(container)
  root.render(<DataTable />)
}

Happy coding! πŸš€

Keywords

mcp

FAQs

Package last updated on 09 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts