create-mcp-use-app 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/templates/api/README.md +224 -0
- package/dist/templates/api/package.json +24 -0
- package/dist/templates/api/src/server.ts +229 -0
- package/dist/templates/api/tsconfig.json +20 -0
- package/dist/templates/basic/README.md +64 -0
- package/dist/templates/basic/package.json +23 -0
- package/dist/templates/basic/src/server.ts +67 -0
- package/dist/templates/basic/tsconfig.json +20 -0
- package/dist/templates/filesystem/README.md +139 -0
- package/dist/templates/filesystem/package.json +23 -0
- package/dist/templates/filesystem/src/server.ts +155 -0
- package/dist/templates/filesystem/tsconfig.json +20 -0
- package/dist/templates/ui/README.md +454 -0
- package/dist/templates/ui/package-lock.json +2870 -0
- package/dist/templates/ui/package.json +45 -0
- package/dist/templates/ui/resources/data-visualization.tsx +475 -0
- package/dist/templates/ui/resources/kanban-board.tsx +306 -0
- package/dist/templates/ui/resources/todo-list.tsx +408 -0
- package/dist/templates/ui/src/server.ts +153 -0
- package/dist/templates/ui/tsconfig.json +20 -0
- package/package.json +63 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# UI MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP server with React UI widgets created with `create-mcp-app` that provides interactive web components for MCP clients.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **🎨 React Components**: Interactive UI widgets built with React
|
|
8
|
+
- **🔥 Hot Reloading**: Development server with instant updates
|
|
9
|
+
- **📦 Production Builds**: Optimized bundles for production
|
|
10
|
+
- **🌐 Web Endpoints**: Serve widgets at `/mcp-use/widgets/{widget-name}`
|
|
11
|
+
- **🛠️ Development Tools**: Full TypeScript support and modern tooling
|
|
12
|
+
|
|
13
|
+
## Getting Started
|
|
14
|
+
|
|
15
|
+
### Development
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Install dependencies
|
|
19
|
+
npm install
|
|
20
|
+
|
|
21
|
+
# Start development server with hot reloading
|
|
22
|
+
npm run dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This will start:
|
|
26
|
+
|
|
27
|
+
- MCP server on port 3000
|
|
28
|
+
- Vite dev server on port 3001 with hot reloading
|
|
29
|
+
|
|
30
|
+
### Production
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Build the server and UI components
|
|
34
|
+
npm run build
|
|
35
|
+
|
|
36
|
+
# Run the built server
|
|
37
|
+
npm start
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Available Widgets
|
|
41
|
+
|
|
42
|
+
### 1. Kanban Board (`/mcp-use/widgets/kanban-board`)
|
|
43
|
+
|
|
44
|
+
Interactive Kanban board for task management.
|
|
45
|
+
|
|
46
|
+
**Features:**
|
|
47
|
+
|
|
48
|
+
- Drag and drop tasks between columns
|
|
49
|
+
- Add/remove tasks
|
|
50
|
+
- Priority levels and assignees
|
|
51
|
+
- Real-time updates
|
|
52
|
+
|
|
53
|
+
**Usage:**
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
mcp.tool({
|
|
57
|
+
name: 'show-kanban',
|
|
58
|
+
inputs: [{ name: 'tasks', type: 'string', required: true }],
|
|
59
|
+
fn: async ({ tasks }) => {
|
|
60
|
+
// Display Kanban board with tasks
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. Todo List (`/mcp-use/widgets/todo-list`)
|
|
66
|
+
|
|
67
|
+
Interactive todo list with filtering and sorting.
|
|
68
|
+
|
|
69
|
+
**Features:**
|
|
70
|
+
|
|
71
|
+
- Add/complete/delete todos
|
|
72
|
+
- Filter by status (all/active/completed)
|
|
73
|
+
- Sort by priority, due date, or creation time
|
|
74
|
+
- Progress tracking
|
|
75
|
+
- Categories and due dates
|
|
76
|
+
|
|
77
|
+
**Usage:**
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
mcp.tool({
|
|
81
|
+
name: 'show-todo-list',
|
|
82
|
+
inputs: [{ name: 'todos', type: 'string', required: true }],
|
|
83
|
+
fn: async ({ todos }) => {
|
|
84
|
+
// Display todo list with todos
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 3. Data Visualization (`/mcp-use/widgets/data-visualization`)
|
|
90
|
+
|
|
91
|
+
Interactive charts and data visualization.
|
|
92
|
+
|
|
93
|
+
**Features:**
|
|
94
|
+
|
|
95
|
+
- Bar charts, line charts, and pie charts
|
|
96
|
+
- Add/remove data points
|
|
97
|
+
- Interactive legends
|
|
98
|
+
- Data table view
|
|
99
|
+
- Multiple chart types
|
|
100
|
+
|
|
101
|
+
**Usage:**
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
mcp.tool({
|
|
105
|
+
name: 'show-data-viz',
|
|
106
|
+
inputs: [
|
|
107
|
+
{ name: 'data', type: 'string', required: true },
|
|
108
|
+
{ name: 'chartType', type: 'string', required: false }
|
|
109
|
+
],
|
|
110
|
+
fn: async ({ data, chartType }) => {
|
|
111
|
+
// Display data visualization
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Development Workflow
|
|
117
|
+
|
|
118
|
+
### 1. Create a New Widget
|
|
119
|
+
|
|
120
|
+
1. **Create the React component:**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Create resources/my-widget.tsx
|
|
124
|
+
touch resources/my-widget.tsx
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
2. **Create the HTML entry point:**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Create resources/my-widget.html
|
|
131
|
+
touch resources/my-widget.html
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
3. **Add to Vite config:**
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// vite.config.ts
|
|
138
|
+
rollupOptions: {
|
|
139
|
+
input: {
|
|
140
|
+
'my-widget': resolve(__dirname, 'resources/my-widget.html')
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
4. **Add MCP resource:**
|
|
146
|
+
```typescript
|
|
147
|
+
// src/server.ts
|
|
148
|
+
mcp.resource({
|
|
149
|
+
uri: 'ui://widget/my-widget',
|
|
150
|
+
name: 'My Widget',
|
|
151
|
+
mimeType: 'text/html+skybridge',
|
|
152
|
+
fn: async () => {
|
|
153
|
+
const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/my-widget`
|
|
154
|
+
return `<div id="my-widget-root"></div><script type="module" src="${widgetUrl}"></script>`
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 2. Development with Hot Reloading
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Start development
|
|
163
|
+
npm run dev
|
|
164
|
+
|
|
165
|
+
# Visit your widget
|
|
166
|
+
open http://localhost:3001/my-widget.html
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Changes to your React components will automatically reload!
|
|
170
|
+
|
|
171
|
+
### 3. Widget Development Best Practices
|
|
172
|
+
|
|
173
|
+
#### Component Structure
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import React, { useState, useEffect } from 'react'
|
|
177
|
+
import { createRoot } from 'react-dom/client'
|
|
178
|
+
|
|
179
|
+
interface MyWidgetProps {
|
|
180
|
+
initialData?: any
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const MyWidget: React.FC<MyWidgetProps> = ({ initialData = [] }) => {
|
|
184
|
+
const [data, setData] = useState(initialData)
|
|
185
|
+
|
|
186
|
+
// Load data from URL parameters
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
189
|
+
const dataParam = urlParams.get('data')
|
|
190
|
+
|
|
191
|
+
if (dataParam) {
|
|
192
|
+
try {
|
|
193
|
+
const parsedData = JSON.parse(decodeURIComponent(dataParam))
|
|
194
|
+
setData(parsedData)
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error('Error parsing data:', error)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}, [])
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div>
|
|
203
|
+
{/* Your widget content */}
|
|
204
|
+
</div>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Render the component
|
|
209
|
+
const container = document.getElementById('my-widget-root')
|
|
210
|
+
if (container) {
|
|
211
|
+
const root = createRoot(container)
|
|
212
|
+
root.render(<MyWidget />)
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Styling Guidelines
|
|
217
|
+
|
|
218
|
+
- Use inline styles for simplicity
|
|
219
|
+
- Follow the existing design system
|
|
220
|
+
- Ensure responsive design
|
|
221
|
+
- Use consistent color palette
|
|
222
|
+
|
|
223
|
+
#### Data Handling
|
|
224
|
+
|
|
225
|
+
- Accept data via URL parameters
|
|
226
|
+
- Provide sensible defaults
|
|
227
|
+
- Handle errors gracefully
|
|
228
|
+
- Use TypeScript for type safety
|
|
229
|
+
|
|
230
|
+
### 4. Production Deployment
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Build everything
|
|
234
|
+
npm run build
|
|
235
|
+
|
|
236
|
+
# The built files will be in dist/
|
|
237
|
+
# - dist/server.js (MCP server)
|
|
238
|
+
# - dist/resources/ (UI widgets)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Project Structure
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
my-ui-server/
|
|
245
|
+
├── src/
|
|
246
|
+
│ └── server.ts # MCP server with UI endpoints
|
|
247
|
+
├── resources/ # React components and HTML entry points
|
|
248
|
+
│ ├── kanban-board.html
|
|
249
|
+
│ ├── kanban-board.tsx
|
|
250
|
+
│ ├── todo-list.html
|
|
251
|
+
│ ├── todo-list.tsx
|
|
252
|
+
│ ├── data-visualization.html
|
|
253
|
+
│ └── data-visualization.tsx
|
|
254
|
+
├── dist/ # Built files
|
|
255
|
+
│ ├── server.js
|
|
256
|
+
│ └── resources/
|
|
257
|
+
├── package.json
|
|
258
|
+
├── tsconfig.json
|
|
259
|
+
├── vite.config.ts
|
|
260
|
+
└── README.md
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## API Reference
|
|
264
|
+
|
|
265
|
+
### MCP Resources
|
|
266
|
+
|
|
267
|
+
All UI widgets are available as MCP resources:
|
|
268
|
+
|
|
269
|
+
- `ui://status` - Server status and available widgets
|
|
270
|
+
- `ui://widget/kanban-board` - Kanban board widget
|
|
271
|
+
- `ui://widget/todo-list` - Todo list widget
|
|
272
|
+
- `ui://widget/data-visualization` - Data visualization widget
|
|
273
|
+
|
|
274
|
+
### MCP Tools
|
|
275
|
+
|
|
276
|
+
- `show-kanban` - Display Kanban board with tasks
|
|
277
|
+
- `show-todo-list` - Display todo list with items
|
|
278
|
+
- `show-data-viz` - Display data visualization
|
|
279
|
+
|
|
280
|
+
### MCP Prompts
|
|
281
|
+
|
|
282
|
+
- `ui-development` - Generate UI development guidance
|
|
283
|
+
|
|
284
|
+
## Customization
|
|
285
|
+
|
|
286
|
+
### Adding New Dependencies
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Add React libraries
|
|
290
|
+
npm install @types/react-router-dom react-router-dom
|
|
291
|
+
|
|
292
|
+
# Add UI libraries
|
|
293
|
+
npm install @mui/material @emotion/react @emotion/styled
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Environment Variables
|
|
297
|
+
|
|
298
|
+
Create a `.env` file:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Server configuration
|
|
302
|
+
PORT=3000
|
|
303
|
+
NODE_ENV=development
|
|
304
|
+
|
|
305
|
+
# UI configuration
|
|
306
|
+
VITE_API_URL=http://localhost:3000
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Custom Build Configuration
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// vite.config.ts
|
|
313
|
+
export default defineConfig({
|
|
314
|
+
plugins: [react()],
|
|
315
|
+
build: {
|
|
316
|
+
rollupOptions: {
|
|
317
|
+
input: {
|
|
318
|
+
'my-custom-widget': resolve(__dirname, 'resources/my-custom-widget.html')
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
})
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Troubleshooting
|
|
326
|
+
|
|
327
|
+
### Common Issues
|
|
328
|
+
|
|
329
|
+
1. **"Cannot find module" errors**
|
|
330
|
+
|
|
331
|
+
- Make sure all dependencies are installed: `npm install`
|
|
332
|
+
- Check that TypeScript paths are correct
|
|
333
|
+
|
|
334
|
+
2. **Hot reloading not working**
|
|
335
|
+
|
|
336
|
+
- Ensure Vite dev server is running on port 3001
|
|
337
|
+
- Check that the widget HTML file exists
|
|
338
|
+
|
|
339
|
+
3. **Widget not loading**
|
|
340
|
+
|
|
341
|
+
- Verify the widget is added to vite.config.ts
|
|
342
|
+
- Check that the MCP resource is properly configured
|
|
343
|
+
|
|
344
|
+
4. **Build errors**
|
|
345
|
+
- Run `npm run build` to see detailed error messages
|
|
346
|
+
- Check that all imports are correct
|
|
347
|
+
|
|
348
|
+
### Development Tips
|
|
349
|
+
|
|
350
|
+
- Use browser dev tools to debug React components
|
|
351
|
+
- Check the Network tab for failed requests
|
|
352
|
+
- Use React DevTools browser extension
|
|
353
|
+
- Monitor console for errors
|
|
354
|
+
|
|
355
|
+
## Learn More
|
|
356
|
+
|
|
357
|
+
- [React Documentation](https://react.dev/)
|
|
358
|
+
- [Vite Documentation](https://vitejs.dev/)
|
|
359
|
+
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
360
|
+
- [mcp-use Documentation](https://docs.mcp-use.io)
|
|
361
|
+
|
|
362
|
+
## Examples
|
|
363
|
+
|
|
364
|
+
### Simple Counter Widget
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
// resources/counter.tsx
|
|
368
|
+
import React, { useState } from 'react'
|
|
369
|
+
import { createRoot } from 'react-dom/client'
|
|
370
|
+
|
|
371
|
+
const Counter: React.FC = () => {
|
|
372
|
+
const [count, setCount] = useState(0)
|
|
373
|
+
|
|
374
|
+
return (
|
|
375
|
+
<div style={{ padding: '20px', textAlign: 'center' }}>
|
|
376
|
+
<h1>Counter: {count}</h1>
|
|
377
|
+
<button onClick={() => setCount(count + 1)}>
|
|
378
|
+
Increment
|
|
379
|
+
</button>
|
|
380
|
+
<button onClick={() => setCount(count - 1)}>
|
|
381
|
+
Decrement
|
|
382
|
+
</button>
|
|
383
|
+
</div>
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const container = document.getElementById('counter-root')
|
|
388
|
+
if (container) {
|
|
389
|
+
const root = createRoot(container)
|
|
390
|
+
root.render(<Counter />)
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Data Table Widget
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// resources/data-table.tsx
|
|
398
|
+
import React, { useState, useEffect } from 'react'
|
|
399
|
+
import { createRoot } from 'react-dom/client'
|
|
400
|
+
|
|
401
|
+
interface TableData {
|
|
402
|
+
id: string
|
|
403
|
+
name: string
|
|
404
|
+
value: number
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const DataTable: React.FC = () => {
|
|
408
|
+
const [data, setData] = useState<TableData[]>([])
|
|
409
|
+
|
|
410
|
+
useEffect(() => {
|
|
411
|
+
// Load data from URL or use defaults
|
|
412
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
413
|
+
const dataParam = urlParams.get('data')
|
|
414
|
+
|
|
415
|
+
if (dataParam) {
|
|
416
|
+
try {
|
|
417
|
+
setData(JSON.parse(decodeURIComponent(dataParam)))
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.error('Error parsing data:', error)
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}, [])
|
|
423
|
+
|
|
424
|
+
return (
|
|
425
|
+
<div style={{ padding: '20px' }}>
|
|
426
|
+
<h1>Data Table</h1>
|
|
427
|
+
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
|
428
|
+
<thead>
|
|
429
|
+
<tr>
|
|
430
|
+
<th>Name</th>
|
|
431
|
+
<th>Value</th>
|
|
432
|
+
</tr>
|
|
433
|
+
</thead>
|
|
434
|
+
<tbody>
|
|
435
|
+
{data.map(row => (
|
|
436
|
+
<tr key={row.id}>
|
|
437
|
+
<td>{row.name}</td>
|
|
438
|
+
<td>{row.value}</td>
|
|
439
|
+
</tr>
|
|
440
|
+
))}
|
|
441
|
+
</tbody>
|
|
442
|
+
</table>
|
|
443
|
+
</div>
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const container = document.getElementById('data-table-root')
|
|
448
|
+
if (container) {
|
|
449
|
+
const root = createRoot(container)
|
|
450
|
+
root.render(<DataTable />)
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Happy coding! 🚀
|