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.
@@ -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! 🚀