From 0bc13de5c851d0a221f767dae1bc9059cbd1bef5 Mon Sep 17 00:00:00 2001
From: Enrico Toniato <2827496+tonxxd@users.noreply.github.com>
Date: Tue, 14 Oct 2025 15:12:42 +0200
Subject: [PATCH 1/3] fix: export server from mcp-use/server due to edge
runtime
---
INSPECTOR_INTEGRATION.md | 2 +-
.../src/templates/ui/src/server.ts | 2 +-
.../src/templates/ui/tsconfig.json | 2 +-
packages/inspector/src/server/middleware.ts | 2 +-
.../examples/server/simple/src/server.ts | 2 +-
packages/mcp-use/index.ts | 13 -
pnpm-lock.yaml | 58 +++
pnpm-workspace.yaml | 1 +
test_app/README.md | 454 ++++++++++++++++++
test_app/index.ts | 12 +
test_app/package.json | 45 ++
test_app/resources/kanban-board.tsx | 306 ++++++++++++
test_app/src/server.ts | 67 +++
test_app/tsconfig.json | 20 +
14 files changed, 968 insertions(+), 18 deletions(-)
create mode 100644 test_app/README.md
create mode 100644 test_app/index.ts
create mode 100644 test_app/package.json
create mode 100644 test_app/resources/kanban-board.tsx
create mode 100644 test_app/src/server.ts
create mode 100644 test_app/tsconfig.json
diff --git a/INSPECTOR_INTEGRATION.md b/INSPECTOR_INTEGRATION.md
index 4038f635..f1a7c336 100644
--- a/INSPECTOR_INTEGRATION.md
+++ b/INSPECTOR_INTEGRATION.md
@@ -33,7 +33,7 @@ The MCP Inspector is now automatically mounted at `/inspector` for all MCP serve
When developers create a new MCP server:
```typescript
-import { createMCPServer } from 'mcp-use'
+import { createMCPServer } from 'mcp-use/server'
const server = createMCPServer('my-server', {
version: '1.0.0',
diff --git a/packages/create-mcp-use-app/src/templates/ui/src/server.ts b/packages/create-mcp-use-app/src/templates/ui/src/server.ts
index 8a150b09..e33eb641 100644
--- a/packages/create-mcp-use-app/src/templates/ui/src/server.ts
+++ b/packages/create-mcp-use-app/src/templates/ui/src/server.ts
@@ -1,4 +1,4 @@
-import { createMCPServer } from 'mcp-use'
+import { createMCPServer } from 'mcp-use/server'
import { createUIResource } from '@mcp-ui/server';
// Create an MCP server (which is also an Express app)
diff --git a/packages/create-mcp-use-app/src/templates/ui/tsconfig.json b/packages/create-mcp-use-app/src/templates/ui/tsconfig.json
index 5a2c6947..cafb2cf5 100644
--- a/packages/create-mcp-use-app/src/templates/ui/tsconfig.json
+++ b/packages/create-mcp-use-app/src/templates/ui/tsconfig.json
@@ -3,7 +3,7 @@
"target": "ES2022",
"jsx": "react-jsx",
"module": "ESNext",
- "moduleResolution": "node",
+ "moduleResolution": "bundler",
"allowJs": true,
"strict": true,
"declaration": true,
diff --git a/packages/inspector/src/server/middleware.ts b/packages/inspector/src/server/middleware.ts
index 1f5cb86b..2fbe428d 100644
--- a/packages/inspector/src/server/middleware.ts
+++ b/packages/inspector/src/server/middleware.ts
@@ -13,7 +13,7 @@ import { checkClientFiles, getClientDistPath, getContentType, handleChatRequest
*
* @example
* ```typescript
- * import { createMCPServer } from 'mcp-use'
+ * import { createMCPServer } from 'mcp-use/server'
* import { mountInspector } from '@mcp-use/inspector'
*
* const server = createMCPServer('my-server')
diff --git a/packages/mcp-use/examples/server/simple/src/server.ts b/packages/mcp-use/examples/server/simple/src/server.ts
index 50c4bb67..10cc2be2 100644
--- a/packages/mcp-use/examples/server/simple/src/server.ts
+++ b/packages/mcp-use/examples/server/simple/src/server.ts
@@ -1,4 +1,4 @@
-import { createMCPServer } from 'mcp-use'
+import { createMCPServer } from 'mcp-use/server'
// Create an MCP server (which is also an Express app)
// The MCP Inspector is automatically mounted at /inspector
diff --git a/packages/mcp-use/index.ts b/packages/mcp-use/index.ts
index 3ec34719..b447e02d 100644
--- a/packages/mcp-use/index.ts
+++ b/packages/mcp-use/index.ts
@@ -20,19 +20,6 @@ export * from './src/managers/tools/index.js'
// Export observability utilities
export { type ObservabilityConfig, ObservabilityManager } from './src/observability/index.js'
-// Export server utilities
-export { createMCPServer } from './src/server/index.js'
-
-export type {
- InputDefinition,
- PromptDefinition,
- PromptHandler,
- ResourceDefinition,
- ResourceHandler,
- ServerConfig,
- ToolDefinition,
- ToolHandler,
-} from './src/server/types.js'
// Export telemetry utilities
export { setTelemetrySource, Telemetry } from './src/telemetry/index.js'
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 71b5735e..10c81d68 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -516,6 +516,64 @@ importers:
specifier: ^5.0.0
version: 5.9.3
+ test_app:
+ dependencies:
+ '@mcp-ui/server':
+ specifier: ^5.11.0
+ version: 5.11.0(patch_hash=5d24b4104a7d6d537b7de1dc183b27e42d9c1b3fde96a28dbeb722713ba85f11)
+ cors:
+ specifier: ^2.8.5
+ version: 2.8.5
+ express:
+ specifier: ^4.18.0
+ version: 4.21.2
+ mcp-use:
+ specifier: workspace:*
+ version: link:../packages/mcp-use
+ devDependencies:
+ '@mcp-use/cli':
+ specifier: workspace:*
+ version: link:../packages/cli
+ '@mcp-use/inspector':
+ specifier: workspace:*
+ version: link:../packages/inspector
+ '@types/cors':
+ specifier: ^2.8.0
+ version: 2.8.19
+ '@types/express':
+ specifier: ^4.17.0
+ version: 4.17.23
+ '@types/node':
+ specifier: ^20.0.0
+ version: 20.19.19
+ '@types/react':
+ specifier: ^18.0.0
+ version: 18.3.26
+ '@types/react-dom':
+ specifier: ^18.0.0
+ version: 18.3.7(@types/react@18.3.26)
+ concurrently:
+ specifier: ^8.0.0
+ version: 8.2.2
+ esbuild:
+ specifier: ^0.23.0
+ version: 0.23.1
+ globby:
+ specifier: ^14.0.2
+ version: 14.1.0
+ react:
+ specifier: ^19.2.0
+ version: 19.2.0
+ react-dom:
+ specifier: ^19.2.0
+ version: 19.2.0(react@19.2.0)
+ tsx:
+ specifier: ^4.0.0
+ version: 4.20.6
+ typescript:
+ specifier: ^5.0.0
+ version: 5.9.3
+
packages:
'@ai-sdk/provider-utils@2.2.8':
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 28363ba3..cd64b37d 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -3,3 +3,4 @@ packages:
- 'packages/mcp-use/examples/client/react'
- 'packages/mcp-use/examples/server/simple'
- 'packages/create-mcp-use-app/src/templates/ui'
+ - 'test_app'
diff --git a/test_app/README.md b/test_app/README.md
new file mode 100644
index 00000000..a6d31caa
--- /dev/null
+++ b/test_app/README.md
@@ -0,0 +1,454 @@
+# 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
+
+```bash
+# 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
+
+```bash
+# 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:**
+
+```typescript
+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:**
+
+```typescript
+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:**
+
+```typescript
+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
+
+1. **Create the React component:**
+
+ ```bash
+ # Create resources/my-widget.tsx
+ touch resources/my-widget.tsx
+ ```
+
+2. **Create the HTML entry point:**
+
+ ```bash
+ # Create resources/my-widget.html
+ touch resources/my-widget.html
+ ```
+
+3. **Add to Vite config:**
+
+ ```typescript
+ // vite.config.ts
+ rollupOptions: {
+ input: {
+ 'my-widget': resolve(__dirname, 'resources/my-widget.html')
+ }
+ }
+ ```
+
+4. **Add MCP resource:**
+ ```typescript
+ // 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 `
`
+ }
+ })
+ ```
+
+### 2. Development with Hot Reloading
+
+```bash
+# 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
+
+```typescript
+import React, { useState, useEffect } from 'react'
+import { createRoot } from 'react-dom/client'
+
+interface MyWidgetProps {
+ initialData?: any
+}
+
+const MyWidget: React.FC = ({ 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 (
+
+ {/* Your widget content */}
+
+ )
+}
+
+// Render the component
+const container = document.getElementById('my-widget-root')
+if (container) {
+ const root = createRoot(container)
+ root.render()
+}
+```
+
+#### 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
+
+```bash
+# Build everything
+npm run build
+
+# The built files will be in dist/
+# - dist/index.js (MCP server entry point)
+# - dist/src/server.js (MCP server implementation)
+# - dist/resources/ (Compiled TypeScript + UI widget bundles)
+```
+
+## Project Structure
+
+```
+my-ui-server/
+├── index.ts # Entry point (re-exports server)
+├── src/
+│ └── server.ts # MCP server with UI endpoints
+├── resources/ # React components (TSX widgets)
+│ ├── kanban-board.tsx
+│ ├── todo-list.tsx
+│ └── data-visualization.tsx
+├── dist/ # Built files
+│ ├── index.js # Entry point
+│ ├── src/
+│ │ └── server.js # Server implementation
+│ └── resources/ # TypeScript output + bundled widgets
+├── package.json
+├── tsconfig.json
+└── 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
+
+```bash
+# 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:
+
+```bash
+# Server configuration
+PORT=3000
+NODE_ENV=development
+
+# UI configuration
+VITE_API_URL=http://localhost:3000
+```
+
+### Custom Build Configuration
+
+```typescript
+// vite.config.ts
+export default defineConfig({
+ plugins: [react()],
+ build: {
+ rollupOptions: {
+ input: {
+ 'my-custom-widget': resolve(__dirname, 'resources/my-custom-widget.html')
+ }
+ }
+ }
+})
+```
+
+## Troubleshooting
+
+### Common Issues
+
+1. **"Cannot find module" errors**
+
+ - Make sure all dependencies are installed: `npm install`
+ - Check that TypeScript paths are correct
+
+2. **Hot reloading not working**
+
+ - Ensure Vite dev server is running on port 3001
+ - Check that the widget HTML file exists
+
+3. **Widget not loading**
+
+ - Verify the widget is added to vite.config.ts
+ - Check that the MCP resource is properly configured
+
+4. **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](https://react.dev/)
+- [Vite Documentation](https://vitejs.dev/)
+- [MCP Documentation](https://modelcontextprotocol.io)
+- [mcp-use Documentation](https://docs.mcp-use.io)
+
+## Examples
+
+### Simple Counter Widget
+
+```typescript
+// resources/counter.tsx
+import React, { useState } from 'react'
+import { createRoot } from 'react-dom/client'
+
+const Counter: React.FC = () => {
+ const [count, setCount] = useState(0)
+
+ return (
+
+
Counter: {count}
+
+
+
+ )
+}
+
+const container = document.getElementById('counter-root')
+if (container) {
+ const root = createRoot(container)
+ root.render()
+}
+```
+
+### Data Table Widget
+
+```typescript
+// 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([])
+
+ 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 (
+
+
Data Table
+
+
+
+ | Name |
+ Value |
+
+
+
+ {data.map(row => (
+
+ | {row.name} |
+ {row.value} |
+
+ ))}
+
+
+
+ )
+}
+
+const container = document.getElementById('data-table-root')
+if (container) {
+ const root = createRoot(container)
+ root.render()
+}
+```
+
+Happy coding! 🚀
diff --git a/test_app/index.ts b/test_app/index.ts
new file mode 100644
index 00000000..6f48dc04
--- /dev/null
+++ b/test_app/index.ts
@@ -0,0 +1,12 @@
+/**
+ * MCP Server Entry Point
+ *
+ * This file serves as the main entry point for the MCP server application.
+ * It re-exports all functionality from the server implementation, allowing
+ * the CLI and other tools to locate and start the server.
+ *
+ * The server is automatically started when this module is imported, making
+ * it suitable for both direct execution and programmatic usage.
+ */
+export * from './src/server.js'
+
diff --git a/test_app/package.json b/test_app/package.json
new file mode 100644
index 00000000..0fc2f058
--- /dev/null
+++ b/test_app/package.json
@@ -0,0 +1,45 @@
+{
+ "name": "test_app",
+ "type": "module",
+ "version": "1.0.0",
+ "description": "MCP server: test_app",
+ "author": "",
+ "license": "MIT",
+ "keywords": [
+ "mcp",
+ "server",
+ "ui",
+ "react",
+ "widgets",
+ "ai",
+ "tools"
+ ],
+ "main": "dist/index.js",
+ "scripts": {
+ "build": "mcp-use build",
+ "dev": "mcp-use dev",
+ "start": "mcp-use start"
+ },
+ "dependencies": {
+ "@mcp-ui/server": "^5.11.0",
+ "cors": "^2.8.5",
+ "express": "^4.18.0",
+ "mcp-use": "workspace:*"
+ },
+ "devDependencies": {
+ "@mcp-use/cli": "workspace:*",
+ "@mcp-use/inspector": "workspace:*",
+ "@types/cors": "^2.8.0",
+ "@types/express": "^4.17.0",
+ "@types/node": "^20.0.0",
+ "@types/react": "^18.0.0",
+ "@types/react-dom": "^18.0.0",
+ "concurrently": "^8.0.0",
+ "esbuild": "^0.23.0",
+ "globby": "^14.0.2",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0",
+ "tsx": "^4.0.0",
+ "typescript": "^5.0.0"
+ }
+}
\ No newline at end of file
diff --git a/test_app/resources/kanban-board.tsx b/test_app/resources/kanban-board.tsx
new file mode 100644
index 00000000..5a4454cb
--- /dev/null
+++ b/test_app/resources/kanban-board.tsx
@@ -0,0 +1,306 @@
+import React, { useEffect, useState } from 'react'
+import { createRoot } from 'react-dom/client'
+
+interface Task {
+ id: string
+ title: string
+ description: string
+ status: 'todo' | 'in-progress' | 'done'
+ priority: 'low' | 'medium' | 'high'
+ assignee?: string
+}
+
+interface KanbanBoardProps {
+ initialTasks?: Task[]
+}
+
+const KanbanBoard: React.FC = ({ initialTasks = [] }) => {
+ const [tasks, setTasks] = useState(initialTasks)
+ const [newTask, setNewTask] = useState({ title: '', description: '', priority: 'medium' as Task['priority'] })
+
+ // Load tasks from URL parameters or use defaults
+ useEffect(() => {
+ const urlParams = new URLSearchParams(window.location.search)
+ const tasksParam = urlParams.get('tasks')
+
+ if (tasksParam) {
+ try {
+ const parsedTasks = JSON.parse(decodeURIComponent(tasksParam))
+ setTasks(parsedTasks)
+ }
+ catch (error) {
+ console.error('Error parsing tasks from URL:', error)
+ }
+ }
+ else {
+ // Default tasks for demo
+ setTasks([
+ { id: '1', title: 'Design UI mockups', description: 'Create wireframes for the new dashboard', status: 'todo', priority: 'high', assignee: 'Alice' },
+ { id: '2', title: 'Implement authentication', description: 'Add login and registration functionality', status: 'in-progress', priority: 'high', assignee: 'Bob' },
+ { id: '3', title: 'Write documentation', description: 'Document the API endpoints', status: 'done', priority: 'medium', assignee: 'Charlie' },
+ { id: '4', title: 'Setup CI/CD', description: 'Configure automated testing and deployment', status: 'todo', priority: 'medium' },
+ { id: '5', title: 'Code review', description: 'Review pull requests from the team', status: 'in-progress', priority: 'low', assignee: 'David' },
+ ])
+ }
+ }, [])
+
+ const addTask = () => {
+ if (newTask.title.trim()) {
+ const task: Task = {
+ id: Date.now().toString(),
+ title: newTask.title,
+ description: newTask.description,
+ status: 'todo',
+ priority: newTask.priority,
+ }
+ setTasks([...tasks, task])
+ setNewTask({ title: '', description: '', priority: 'medium' })
+ }
+ }
+
+ const moveTask = (taskId: string, newStatus: Task['status']) => {
+ setTasks(tasks.map(task =>
+ task.id === taskId ? { ...task, status: newStatus } : task,
+ ))
+ }
+
+ const deleteTask = (taskId: string) => {
+ setTasks(tasks.filter(task => task.id !== taskId))
+ }
+
+ const getTasksByStatus = (status: Task['status']) => {
+ return tasks.filter(task => task.status === status)
+ }
+
+ const getPriorityColor = (priority: Task['priority']) => {
+ switch (priority) {
+ case 'high': return '#ff4757'
+ case 'medium': return '#ffa502'
+ case 'low': return '#2ed573'
+ default: return '#57606f'
+ }
+ }
+
+ const columns = [
+ { id: 'todo', title: 'To Do', color: '#57606f' },
+ { id: 'in-progress', title: 'In Progress', color: '#ffa502' },
+ { id: 'done', title: 'Done', color: '#2ed573' },
+ ] as const
+
+ return (
+
+
+
Kanban Board
+
+ {/* Add new task form */}
+
+
Add New Task
+
+ setNewTask({ ...newTask, title: e.target.value })}
+ style={{
+ padding: '8px 12px',
+ border: '1px solid #ddd',
+ borderRadius: '4px',
+ flex: '1',
+ minWidth: '200px',
+ }}
+ />
+ setNewTask({ ...newTask, description: e.target.value })}
+ style={{
+ padding: '8px 12px',
+ border: '1px solid #ddd',
+ borderRadius: '4px',
+ flex: '1',
+ minWidth: '200px',
+ }}
+ />
+
+
+
+
+
+
+ {/* Kanban columns */}
+
+ {columns.map(column => (
+
+
+ {column.title}
+
+ {getTasksByStatus(column.id).length}
+
+
+
+
+ {getTasksByStatus(column.id).map(task => (
+
{
+ e.dataTransfer.setData('text/plain', task.id)
+ }}
+ onDragOver={e => e.preventDefault()}
+ onDrop={(e) => {
+ e.preventDefault()
+ const taskId = e.dataTransfer.getData('text/plain')
+ if (taskId === task.id) {
+ // Move to next column
+ const currentIndex = columns.findIndex(col => col.id === column.id)
+ const nextColumn = columns[currentIndex + 1]
+ if (nextColumn) {
+ moveTask(taskId, nextColumn.id)
+ }
+ }
+ }}
+ >
+
+
{task.title}
+
+
+
+ {task.description && (
+
+ {task.description}
+
+ )}
+
+
+
+ {task.priority.toUpperCase()}
+
+
+ {task.assignee && (
+
+ {task.assignee}
+
+ )}
+
+
+ ))}
+
+ {getTasksByStatus(column.id).length === 0 && (
+
+ No tasks in this column
+
+ )}
+
+
+ ))}
+
+
+ )
+}
+
+// Mount the component
+const container = document.getElementById('widget-root')
+if (container) {
+ const root = createRoot(container)
+ root.render()
+}
diff --git a/test_app/src/server.ts b/test_app/src/server.ts
new file mode 100644
index 00000000..e33eb641
--- /dev/null
+++ b/test_app/src/server.ts
@@ -0,0 +1,67 @@
+import { createMCPServer } from 'mcp-use/server'
+import { createUIResource } from '@mcp-ui/server';
+
+// Create an MCP server (which is also an Express app)
+// The MCP Inspector is automatically mounted at /inspector
+const server = createMCPServer('ui-mcp-server', {
+ version: '1.0.0',
+ description: 'An MCP server with React UI widgets',
+})
+
+const PORT = process.env.PORT || 3000
+
+
+server.tool({
+ name: 'test-tool',
+ description: 'Test tool',
+ inputs: [
+ {
+ name: 'test',
+ type: 'string',
+ description: 'Test input',
+ required: true,
+ },
+ ],
+ fn: async () => {
+ const uiResource = createUIResource({
+ uri: 'ui://widget/kanban-board',
+ content: {
+ type: 'externalUrl',
+ iframeUrl: `http://localhost:${PORT}/mcp-use/widgets/kanban-board`
+ },
+ encoding: 'text',
+ })
+ return {
+ content: [uiResource]
+ }
+ },
+})
+
+
+// MCP Resource for Kanban Board widget
+server.resource({
+ name: 'Kanban Board Widget',
+ uri: 'ui://widget/kanban-board',
+ title: 'Kanban Board Widget',
+ mimeType: 'text/html+skybridge',
+ description: 'Interactive Kanban board widget',
+ annotations: {
+ audience: ['user', 'assistant'],
+ priority: 0.7
+ },
+ fn: async () => {
+ const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/kanban-board`
+ return {
+ contents: [{
+ uri: 'ui://widget/kanban-board',
+ mimeType: 'text/uri-list',
+ text: widgetUrl
+ }]
+ }
+ },
+})
+
+
+
+// Start the server (MCP endpoints auto-mounted at /mcp)
+server.listen(PORT)
diff --git a/test_app/tsconfig.json b/test_app/tsconfig.json
new file mode 100644
index 00000000..cafb2cf5
--- /dev/null
+++ b/test_app/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "jsx": "react-jsx",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowJs": true,
+ "strict": true,
+ "declaration": true,
+ "declarationMap": true,
+ "outDir": "./dist",
+ "sourceMap": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true
+ },
+ "include": ["index.ts", "src/**/*", "resources/**/*"],
+ "exclude": ["node_modules", "dist"]
+}
From a2ec48edbf9d3c6382314b3f570febb340b43305 Mon Sep 17 00:00:00 2001
From: Enrico Toniato <2827496+tonxxd@users.noreply.github.com>
Date: Tue, 14 Oct 2025 15:13:26 +0200
Subject: [PATCH 2/3] chore: update versions
---
packages/cli/CHANGELOG.md | 8 ++++++++
packages/cli/package.json | 2 +-
packages/create-mcp-use-app/CHANGELOG.md | 6 ++++++
packages/create-mcp-use-app/package.json | 2 +-
packages/inspector/CHANGELOG.md | 8 ++++++++
packages/inspector/package.json | 2 +-
packages/mcp-use/CHANGELOG.md | 8 ++++++++
packages/mcp-use/package.json | 4 ++--
8 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index 3c5bfda4..f56f4444 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,13 @@
# @mcp-use/cli
+## 2.1.7
+
+### Patch Changes
+
+- Updated dependencies
+ - @mcp-use/inspector@0.3.7
+ - mcp-use@1.0.3
+
## 2.1.6
### Patch Changes
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 440ba8e1..57ee2a5e 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@mcp-use/cli",
- "version": "2.1.6",
+ "version": "2.1.7",
"description": "Build tool for MCP UI widgets - bundles React components into standalone HTML pages for Model Context Protocol servers",
"author": "mcp-use, Inc.",
"license": "MIT",
diff --git a/packages/create-mcp-use-app/CHANGELOG.md b/packages/create-mcp-use-app/CHANGELOG.md
index 649f6c12..e1cd6b71 100644
--- a/packages/create-mcp-use-app/CHANGELOG.md
+++ b/packages/create-mcp-use-app/CHANGELOG.md
@@ -1,5 +1,11 @@
# create-mcp-use-app
+## 0.3.3
+
+### Patch Changes
+
+- fix: export server from mcp-use/server due to edge runtime
+
## 0.3.2
### Patch Changes
diff --git a/packages/create-mcp-use-app/package.json b/packages/create-mcp-use-app/package.json
index 9876718c..f7828082 100644
--- a/packages/create-mcp-use-app/package.json
+++ b/packages/create-mcp-use-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-mcp-use-app",
- "version": "0.3.2",
+ "version": "0.3.3",
"type": "module",
"description": "Create MCP-Use apps with one command",
"author": "mcp-use, Inc.",
diff --git a/packages/inspector/CHANGELOG.md b/packages/inspector/CHANGELOG.md
index 0e7493af..c93d6a57 100644
--- a/packages/inspector/CHANGELOG.md
+++ b/packages/inspector/CHANGELOG.md
@@ -1,5 +1,13 @@
# @mcp-use/inspector
+## 0.3.7
+
+### Patch Changes
+
+- fix: export server from mcp-use/server due to edge runtime
+- Updated dependencies
+ - mcp-use@1.0.3
+
## 0.3.6
### Patch Changes
diff --git a/packages/inspector/package.json b/packages/inspector/package.json
index bb37bbb9..c2c25957 100644
--- a/packages/inspector/package.json
+++ b/packages/inspector/package.json
@@ -1,7 +1,7 @@
{
"name": "@mcp-use/inspector",
"type": "module",
- "version": "0.3.6",
+ "version": "0.3.7",
"description": "MCP Inspector - A tool for inspecting and debugging MCP servers",
"author": "",
"license": "MIT",
diff --git a/packages/mcp-use/CHANGELOG.md b/packages/mcp-use/CHANGELOG.md
index 4014344e..99d6075c 100644
--- a/packages/mcp-use/CHANGELOG.md
+++ b/packages/mcp-use/CHANGELOG.md
@@ -1,5 +1,13 @@
# mcp-use
+## 1.0.3
+
+### Patch Changes
+
+- fix: export server from mcp-use/server due to edge runtime
+- Updated dependencies
+ - @mcp-use/inspector@0.3.7
+
## 1.0.2
### Patch Changes
diff --git a/packages/mcp-use/package.json b/packages/mcp-use/package.json
index a22b418b..36fb768c 100644
--- a/packages/mcp-use/package.json
+++ b/packages/mcp-use/package.json
@@ -1,7 +1,7 @@
{
"name": "mcp-use",
"type": "module",
- "version": "1.0.2",
+ "version": "1.0.3",
"packageManager": "pnpm@10.6.1",
"description": "Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents and Clients + MCP Servers with support for MCP-UI.",
"author": "mcp-use, Inc.",
@@ -88,7 +88,7 @@
"example:observability": "tsx examples/client/observability.ts"
},
"peerDependencies": {
- "@mcp-use/inspector": "^0.3.6",
+ "@mcp-use/inspector": "^0.3.7",
"cors": "^2.8.5",
"express": "^4.18.2",
"langfuse": "^3.32.0",
From 83e39f671c38e83a33a1111a73d7418ed3437d25 Mon Sep 17 00:00:00 2001
From: Enrico Toniato <2827496+tonxxd@users.noreply.github.com>
Date: Tue, 14 Oct 2025 15:18:23 +0200
Subject: [PATCH 3/3] chore: remove test app
---
.gitignore | 4 +-
test_app/README.md | 454 ----------------------------
test_app/index.ts | 12 -
test_app/package.json | 45 ---
test_app/resources/kanban-board.tsx | 306 -------------------
test_app/src/server.ts | 67 ----
test_app/tsconfig.json | 20 --
7 files changed, 3 insertions(+), 905 deletions(-)
delete mode 100644 test_app/README.md
delete mode 100644 test_app/index.ts
delete mode 100644 test_app/package.json
delete mode 100644 test_app/resources/kanban-board.tsx
delete mode 100644 test_app/src/server.ts
delete mode 100644 test_app/tsconfig.json
diff --git a/.gitignore b/.gitignore
index 3750d9b8..3ab3cf96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,4 +60,6 @@ conf.yaml
# Agents
.cursor
.cursorrules
-.claude
\ No newline at end of file
+.claude
+
+test_app
\ No newline at end of file
diff --git a/test_app/README.md b/test_app/README.md
deleted file mode 100644
index a6d31caa..00000000
--- a/test_app/README.md
+++ /dev/null
@@ -1,454 +0,0 @@
-# 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
-
-```bash
-# 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
-
-```bash
-# 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:**
-
-```typescript
-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:**
-
-```typescript
-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:**
-
-```typescript
-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
-
-1. **Create the React component:**
-
- ```bash
- # Create resources/my-widget.tsx
- touch resources/my-widget.tsx
- ```
-
-2. **Create the HTML entry point:**
-
- ```bash
- # Create resources/my-widget.html
- touch resources/my-widget.html
- ```
-
-3. **Add to Vite config:**
-
- ```typescript
- // vite.config.ts
- rollupOptions: {
- input: {
- 'my-widget': resolve(__dirname, 'resources/my-widget.html')
- }
- }
- ```
-
-4. **Add MCP resource:**
- ```typescript
- // 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 ``
- }
- })
- ```
-
-### 2. Development with Hot Reloading
-
-```bash
-# 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
-
-```typescript
-import React, { useState, useEffect } from 'react'
-import { createRoot } from 'react-dom/client'
-
-interface MyWidgetProps {
- initialData?: any
-}
-
-const MyWidget: React.FC = ({ 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 (
-
- {/* Your widget content */}
-
- )
-}
-
-// Render the component
-const container = document.getElementById('my-widget-root')
-if (container) {
- const root = createRoot(container)
- root.render()
-}
-```
-
-#### 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
-
-```bash
-# Build everything
-npm run build
-
-# The built files will be in dist/
-# - dist/index.js (MCP server entry point)
-# - dist/src/server.js (MCP server implementation)
-# - dist/resources/ (Compiled TypeScript + UI widget bundles)
-```
-
-## Project Structure
-
-```
-my-ui-server/
-├── index.ts # Entry point (re-exports server)
-├── src/
-│ └── server.ts # MCP server with UI endpoints
-├── resources/ # React components (TSX widgets)
-│ ├── kanban-board.tsx
-│ ├── todo-list.tsx
-│ └── data-visualization.tsx
-├── dist/ # Built files
-│ ├── index.js # Entry point
-│ ├── src/
-│ │ └── server.js # Server implementation
-│ └── resources/ # TypeScript output + bundled widgets
-├── package.json
-├── tsconfig.json
-└── 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
-
-```bash
-# 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:
-
-```bash
-# Server configuration
-PORT=3000
-NODE_ENV=development
-
-# UI configuration
-VITE_API_URL=http://localhost:3000
-```
-
-### Custom Build Configuration
-
-```typescript
-// vite.config.ts
-export default defineConfig({
- plugins: [react()],
- build: {
- rollupOptions: {
- input: {
- 'my-custom-widget': resolve(__dirname, 'resources/my-custom-widget.html')
- }
- }
- }
-})
-```
-
-## Troubleshooting
-
-### Common Issues
-
-1. **"Cannot find module" errors**
-
- - Make sure all dependencies are installed: `npm install`
- - Check that TypeScript paths are correct
-
-2. **Hot reloading not working**
-
- - Ensure Vite dev server is running on port 3001
- - Check that the widget HTML file exists
-
-3. **Widget not loading**
-
- - Verify the widget is added to vite.config.ts
- - Check that the MCP resource is properly configured
-
-4. **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](https://react.dev/)
-- [Vite Documentation](https://vitejs.dev/)
-- [MCP Documentation](https://modelcontextprotocol.io)
-- [mcp-use Documentation](https://docs.mcp-use.io)
-
-## Examples
-
-### Simple Counter Widget
-
-```typescript
-// resources/counter.tsx
-import React, { useState } from 'react'
-import { createRoot } from 'react-dom/client'
-
-const Counter: React.FC = () => {
- const [count, setCount] = useState(0)
-
- return (
-
-
Counter: {count}
-
-
-
- )
-}
-
-const container = document.getElementById('counter-root')
-if (container) {
- const root = createRoot(container)
- root.render()
-}
-```
-
-### Data Table Widget
-
-```typescript
-// 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([])
-
- 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 (
-
-
Data Table
-
-
-
- | Name |
- Value |
-
-
-
- {data.map(row => (
-
- | {row.name} |
- {row.value} |
-
- ))}
-
-
-
- )
-}
-
-const container = document.getElementById('data-table-root')
-if (container) {
- const root = createRoot(container)
- root.render()
-}
-```
-
-Happy coding! 🚀
diff --git a/test_app/index.ts b/test_app/index.ts
deleted file mode 100644
index 6f48dc04..00000000
--- a/test_app/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * MCP Server Entry Point
- *
- * This file serves as the main entry point for the MCP server application.
- * It re-exports all functionality from the server implementation, allowing
- * the CLI and other tools to locate and start the server.
- *
- * The server is automatically started when this module is imported, making
- * it suitable for both direct execution and programmatic usage.
- */
-export * from './src/server.js'
-
diff --git a/test_app/package.json b/test_app/package.json
deleted file mode 100644
index 0fc2f058..00000000
--- a/test_app/package.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "name": "test_app",
- "type": "module",
- "version": "1.0.0",
- "description": "MCP server: test_app",
- "author": "",
- "license": "MIT",
- "keywords": [
- "mcp",
- "server",
- "ui",
- "react",
- "widgets",
- "ai",
- "tools"
- ],
- "main": "dist/index.js",
- "scripts": {
- "build": "mcp-use build",
- "dev": "mcp-use dev",
- "start": "mcp-use start"
- },
- "dependencies": {
- "@mcp-ui/server": "^5.11.0",
- "cors": "^2.8.5",
- "express": "^4.18.0",
- "mcp-use": "workspace:*"
- },
- "devDependencies": {
- "@mcp-use/cli": "workspace:*",
- "@mcp-use/inspector": "workspace:*",
- "@types/cors": "^2.8.0",
- "@types/express": "^4.17.0",
- "@types/node": "^20.0.0",
- "@types/react": "^18.0.0",
- "@types/react-dom": "^18.0.0",
- "concurrently": "^8.0.0",
- "esbuild": "^0.23.0",
- "globby": "^14.0.2",
- "react": "^18.0.0",
- "react-dom": "^18.0.0",
- "tsx": "^4.0.0",
- "typescript": "^5.0.0"
- }
-}
\ No newline at end of file
diff --git a/test_app/resources/kanban-board.tsx b/test_app/resources/kanban-board.tsx
deleted file mode 100644
index 5a4454cb..00000000
--- a/test_app/resources/kanban-board.tsx
+++ /dev/null
@@ -1,306 +0,0 @@
-import React, { useEffect, useState } from 'react'
-import { createRoot } from 'react-dom/client'
-
-interface Task {
- id: string
- title: string
- description: string
- status: 'todo' | 'in-progress' | 'done'
- priority: 'low' | 'medium' | 'high'
- assignee?: string
-}
-
-interface KanbanBoardProps {
- initialTasks?: Task[]
-}
-
-const KanbanBoard: React.FC = ({ initialTasks = [] }) => {
- const [tasks, setTasks] = useState(initialTasks)
- const [newTask, setNewTask] = useState({ title: '', description: '', priority: 'medium' as Task['priority'] })
-
- // Load tasks from URL parameters or use defaults
- useEffect(() => {
- const urlParams = new URLSearchParams(window.location.search)
- const tasksParam = urlParams.get('tasks')
-
- if (tasksParam) {
- try {
- const parsedTasks = JSON.parse(decodeURIComponent(tasksParam))
- setTasks(parsedTasks)
- }
- catch (error) {
- console.error('Error parsing tasks from URL:', error)
- }
- }
- else {
- // Default tasks for demo
- setTasks([
- { id: '1', title: 'Design UI mockups', description: 'Create wireframes for the new dashboard', status: 'todo', priority: 'high', assignee: 'Alice' },
- { id: '2', title: 'Implement authentication', description: 'Add login and registration functionality', status: 'in-progress', priority: 'high', assignee: 'Bob' },
- { id: '3', title: 'Write documentation', description: 'Document the API endpoints', status: 'done', priority: 'medium', assignee: 'Charlie' },
- { id: '4', title: 'Setup CI/CD', description: 'Configure automated testing and deployment', status: 'todo', priority: 'medium' },
- { id: '5', title: 'Code review', description: 'Review pull requests from the team', status: 'in-progress', priority: 'low', assignee: 'David' },
- ])
- }
- }, [])
-
- const addTask = () => {
- if (newTask.title.trim()) {
- const task: Task = {
- id: Date.now().toString(),
- title: newTask.title,
- description: newTask.description,
- status: 'todo',
- priority: newTask.priority,
- }
- setTasks([...tasks, task])
- setNewTask({ title: '', description: '', priority: 'medium' })
- }
- }
-
- const moveTask = (taskId: string, newStatus: Task['status']) => {
- setTasks(tasks.map(task =>
- task.id === taskId ? { ...task, status: newStatus } : task,
- ))
- }
-
- const deleteTask = (taskId: string) => {
- setTasks(tasks.filter(task => task.id !== taskId))
- }
-
- const getTasksByStatus = (status: Task['status']) => {
- return tasks.filter(task => task.status === status)
- }
-
- const getPriorityColor = (priority: Task['priority']) => {
- switch (priority) {
- case 'high': return '#ff4757'
- case 'medium': return '#ffa502'
- case 'low': return '#2ed573'
- default: return '#57606f'
- }
- }
-
- const columns = [
- { id: 'todo', title: 'To Do', color: '#57606f' },
- { id: 'in-progress', title: 'In Progress', color: '#ffa502' },
- { id: 'done', title: 'Done', color: '#2ed573' },
- ] as const
-
- return (
-
-
-
Kanban Board
-
- {/* Add new task form */}
-
-
Add New Task
-
- setNewTask({ ...newTask, title: e.target.value })}
- style={{
- padding: '8px 12px',
- border: '1px solid #ddd',
- borderRadius: '4px',
- flex: '1',
- minWidth: '200px',
- }}
- />
- setNewTask({ ...newTask, description: e.target.value })}
- style={{
- padding: '8px 12px',
- border: '1px solid #ddd',
- borderRadius: '4px',
- flex: '1',
- minWidth: '200px',
- }}
- />
-
-
-
-
-
-
- {/* Kanban columns */}
-
- {columns.map(column => (
-
-
- {column.title}
-
- {getTasksByStatus(column.id).length}
-
-
-
-
- {getTasksByStatus(column.id).map(task => (
-
{
- e.dataTransfer.setData('text/plain', task.id)
- }}
- onDragOver={e => e.preventDefault()}
- onDrop={(e) => {
- e.preventDefault()
- const taskId = e.dataTransfer.getData('text/plain')
- if (taskId === task.id) {
- // Move to next column
- const currentIndex = columns.findIndex(col => col.id === column.id)
- const nextColumn = columns[currentIndex + 1]
- if (nextColumn) {
- moveTask(taskId, nextColumn.id)
- }
- }
- }}
- >
-
-
{task.title}
-
-
-
- {task.description && (
-
- {task.description}
-
- )}
-
-
-
- {task.priority.toUpperCase()}
-
-
- {task.assignee && (
-
- {task.assignee}
-
- )}
-
-
- ))}
-
- {getTasksByStatus(column.id).length === 0 && (
-
- No tasks in this column
-
- )}
-
-
- ))}
-
-
- )
-}
-
-// Mount the component
-const container = document.getElementById('widget-root')
-if (container) {
- const root = createRoot(container)
- root.render()
-}
diff --git a/test_app/src/server.ts b/test_app/src/server.ts
deleted file mode 100644
index e33eb641..00000000
--- a/test_app/src/server.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { createMCPServer } from 'mcp-use/server'
-import { createUIResource } from '@mcp-ui/server';
-
-// Create an MCP server (which is also an Express app)
-// The MCP Inspector is automatically mounted at /inspector
-const server = createMCPServer('ui-mcp-server', {
- version: '1.0.0',
- description: 'An MCP server with React UI widgets',
-})
-
-const PORT = process.env.PORT || 3000
-
-
-server.tool({
- name: 'test-tool',
- description: 'Test tool',
- inputs: [
- {
- name: 'test',
- type: 'string',
- description: 'Test input',
- required: true,
- },
- ],
- fn: async () => {
- const uiResource = createUIResource({
- uri: 'ui://widget/kanban-board',
- content: {
- type: 'externalUrl',
- iframeUrl: `http://localhost:${PORT}/mcp-use/widgets/kanban-board`
- },
- encoding: 'text',
- })
- return {
- content: [uiResource]
- }
- },
-})
-
-
-// MCP Resource for Kanban Board widget
-server.resource({
- name: 'Kanban Board Widget',
- uri: 'ui://widget/kanban-board',
- title: 'Kanban Board Widget',
- mimeType: 'text/html+skybridge',
- description: 'Interactive Kanban board widget',
- annotations: {
- audience: ['user', 'assistant'],
- priority: 0.7
- },
- fn: async () => {
- const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/kanban-board`
- return {
- contents: [{
- uri: 'ui://widget/kanban-board',
- mimeType: 'text/uri-list',
- text: widgetUrl
- }]
- }
- },
-})
-
-
-
-// Start the server (MCP endpoints auto-mounted at /mcp)
-server.listen(PORT)
diff --git a/test_app/tsconfig.json b/test_app/tsconfig.json
deleted file mode 100644
index cafb2cf5..00000000
--- a/test_app/tsconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2022",
- "jsx": "react-jsx",
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowJs": true,
- "strict": true,
- "declaration": true,
- "declarationMap": true,
- "outDir": "./dist",
- "sourceMap": true,
- "allowSyntheticDefaultImports": true,
- "esModuleInterop": true,
- "forceConsistentCasingInFileNames": true,
- "skipLibCheck": true
- },
- "include": ["index.ts", "src/**/*", "resources/**/*"],
- "exclude": ["node_modules", "dist"]
-}