create-mcp-use-app 0.3.4 → 0.4.0

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,180 @@
1
+ import type { AppsSdkUIResource } from 'mcp-use/server'
2
+
3
+ /**
4
+ * ════════════════════════════════════════════════════════════════════
5
+ * Pizzaz Widget Definitions
6
+ * ════════════════════════════════════════════════════════════════════
7
+ *
8
+ * OpenAI's pizzaz reference implementation demonstrating Apps SDK widgets.
9
+ * These widgets load external assets from OpenAI's CDN and use the
10
+ * text/html+skybridge MIME type for Apps SDK compatibility.
11
+ *
12
+ * Each widget demonstrates:
13
+ * - External resource loading (scripts and stylesheets)
14
+ * - Apps SDK metadata (CSP, tool invocation status, etc.)
15
+ * - Structured content injection via window.openai.toolOutput
16
+ */
17
+
18
+ export interface PizzazWidgetDefinition {
19
+ id: string
20
+ title: string
21
+ description: string
22
+ templateUri: string
23
+ invoking: string
24
+ invoked: string
25
+ html: string
26
+ responseText: string
27
+ }
28
+
29
+ export const pizzazWidgets: PizzazWidgetDefinition[] = [
30
+ {
31
+ id: 'pizza-map',
32
+ title: 'Show Pizza Map',
33
+ description: 'Interactive map widget for displaying pizza locations',
34
+ templateUri: 'ui://widget/pizza-map.html',
35
+ invoking: 'Hand-tossing a map',
36
+ invoked: 'Served a fresh map',
37
+ html: `
38
+ <div id="pizzaz-root"></div>
39
+ <link rel="stylesheet" href="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-0038.css">
40
+ <script type="module" src="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-0038.js"></script>
41
+ `.trim(),
42
+ responseText: 'Rendered a pizza map!'
43
+ },
44
+ {
45
+ id: 'pizza-carousel',
46
+ title: 'Show Pizza Carousel',
47
+ description: 'Carousel widget for browsing pizza options',
48
+ templateUri: 'ui://widget/pizza-carousel.html',
49
+ invoking: 'Carousel some spots',
50
+ invoked: 'Served a fresh carousel',
51
+ html: `
52
+ <div id="pizzaz-carousel-root"></div>
53
+ <link rel="stylesheet" href="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-carousel-0038.css">
54
+ <script type="module" src="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-carousel-0038.js"></script>
55
+ `.trim(),
56
+ responseText: 'Rendered a pizza carousel!'
57
+ },
58
+ {
59
+ id: 'pizza-albums',
60
+ title: 'Show Pizza Album',
61
+ description: 'Album-style gallery widget for pizza collections',
62
+ templateUri: 'ui://widget/pizza-albums.html',
63
+ invoking: 'Hand-tossing an album',
64
+ invoked: 'Served a fresh album',
65
+ html: `
66
+ <div id="pizzaz-albums-root"></div>
67
+ <link rel="stylesheet" href="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-albums-0038.css">
68
+ <script type="module" src="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-albums-0038.js"></script>
69
+ `.trim(),
70
+ responseText: 'Rendered a pizza album!'
71
+ },
72
+ {
73
+ id: 'pizza-list',
74
+ title: 'Show Pizza List',
75
+ description: 'List view widget for pizza items',
76
+ templateUri: 'ui://widget/pizza-list.html',
77
+ invoking: 'Hand-tossing a list',
78
+ invoked: 'Served a fresh list',
79
+ html: `
80
+ <div id="pizzaz-list-root"></div>
81
+ <link rel="stylesheet" href="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-list-0038.css">
82
+ <script type="module" src="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-list-0038.js"></script>
83
+ `.trim(),
84
+ responseText: 'Rendered a pizza list!'
85
+ },
86
+ {
87
+ id: 'pizza-video',
88
+ title: 'Show Pizza Video',
89
+ description: 'Video player widget for pizza content',
90
+ templateUri: 'ui://widget/pizza-video.html',
91
+ invoking: 'Hand-tossing a video',
92
+ invoked: 'Served a fresh video',
93
+ html: `
94
+ <div id="pizzaz-video-root"></div>
95
+ <link rel="stylesheet" href="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-video-0038.css">
96
+ <script type="module" src="https://persistent.oaistatic.com/ecosystem-built-assets/pizzaz-video-0038.js"></script>
97
+ `.trim(),
98
+ responseText: 'Rendered a pizza video!'
99
+ }
100
+ ]
101
+
102
+ /**
103
+ * Convert pizzaz widget definitions to mcp-use AppsSdkUIResource format
104
+ *
105
+ * This demonstrates using mcp-use's AppsSdkUIResource type which:
106
+ * - Automatically sets MIME type to text/html+skybridge
107
+ * - Supports Apps SDK metadata (CSP, widget description, etc.)
108
+ * - Injects structuredContent as window.openai.toolOutput
109
+ * - Works seamlessly with ChatGPT and other Apps SDK clients
110
+ */
111
+ export function getPizzazUIResources(): AppsSdkUIResource[] {
112
+ return pizzazWidgets.map(widget => ({
113
+ type: 'appsSdk',
114
+ name: widget.id,
115
+ title: widget.title,
116
+ description: widget.description,
117
+ htmlTemplate: widget.html,
118
+ size: ['800px', '600px'],
119
+ props: {
120
+ pizzaTopping: {
121
+ type: 'string',
122
+ description: 'Topping to mention when rendering the widget',
123
+ required: true
124
+ }
125
+ },
126
+ appsSdkMetadata: {
127
+ 'openai/widgetDescription': widget.description,
128
+ 'openai/toolInvocation/invoking': widget.invoking,
129
+ 'openai/toolInvocation/invoked': widget.invoked,
130
+ 'openai/widgetAccessible': true,
131
+ 'openai/resultCanProduceWidget': true,
132
+ 'openai/widgetCSP': {
133
+ connect_domains: [],
134
+ resource_domains: ['https://persistent.oaistatic.com']
135
+ }
136
+ }
137
+ } satisfies AppsSdkUIResource))
138
+ }
139
+
140
+ /**
141
+ * Get a summary of all pizzaz widgets for documentation
142
+ */
143
+ export function getPizzazWidgetsSummary() {
144
+ return pizzazWidgets.map(w => ({
145
+ id: w.id,
146
+ title: w.title,
147
+ description: w.description,
148
+ tool: `ui_${w.id}`,
149
+ resource: w.templateUri,
150
+ responseText: w.responseText
151
+ }))
152
+ }
153
+
154
+ /**
155
+ * Create widget metadata for a specific widget
156
+ */
157
+ export function widgetMeta(widget: PizzazWidgetDefinition) {
158
+ return {
159
+ 'openai/outputTemplate': widget.templateUri,
160
+ 'openai/toolInvocation/invoking': widget.invoking,
161
+ 'openai/toolInvocation/invoked': widget.invoked,
162
+ 'openai/widgetAccessible': true,
163
+ 'openai/resultCanProduceWidget': true
164
+ } as const
165
+ }
166
+
167
+ /**
168
+ * Get widget by ID
169
+ */
170
+ export function getWidgetById(id: string): PizzazWidgetDefinition | undefined {
171
+ return pizzazWidgets.find(w => w.id === id)
172
+ }
173
+
174
+ /**
175
+ * Get widget by template URI
176
+ */
177
+ export function getWidgetByUri(uri: string): PizzazWidgetDefinition | undefined {
178
+ return pizzazWidgets.find(w => w.templateUri === uri)
179
+ }
180
+
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "allowJs": true,
7
+ "strict": true,
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "outDir": "./dist",
11
+ "sourceMap": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "esModuleInterop": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "skipLibCheck": true
16
+ },
17
+ "include": ["index.ts", "src/**/*"],
18
+ "exclude": ["node_modules", "dist"]
19
+ }
20
+
@@ -56,9 +56,9 @@ Interactive Kanban board for task management.
56
56
  mcp.tool({
57
57
  name: 'show-kanban',
58
58
  inputs: [{ name: 'tasks', type: 'string', required: true }],
59
- fn: async ({ tasks }) => {
59
+ cb: async ({ tasks }) => {
60
60
  // Display Kanban board with tasks
61
- }
61
+ },
62
62
  })
63
63
  ```
64
64
 
@@ -80,9 +80,9 @@ Interactive todo list with filtering and sorting.
80
80
  mcp.tool({
81
81
  name: 'show-todo-list',
82
82
  inputs: [{ name: 'todos', type: 'string', required: true }],
83
- fn: async ({ todos }) => {
83
+ cb: async ({ todos }) => {
84
84
  // Display todo list with todos
85
- }
85
+ },
86
86
  })
87
87
  ```
88
88
 
@@ -105,11 +105,11 @@ mcp.tool({
105
105
  name: 'show-data-viz',
106
106
  inputs: [
107
107
  { name: 'data', type: 'string', required: true },
108
- { name: 'chartType', type: 'string', required: false }
108
+ { name: 'chartType', type: 'string', required: false },
109
109
  ],
110
- fn: async ({ data, chartType }) => {
110
+ cb: async ({ data, chartType }) => {
111
111
  // Display data visualization
112
- }
112
+ },
113
113
  })
114
114
  ```
115
115
 
@@ -149,10 +149,10 @@ mcp.tool({
149
149
  uri: 'ui://widget/my-widget',
150
150
  name: 'My Widget',
151
151
  mimeType: 'text/html+skybridge',
152
- fn: async () => {
152
+ readCallback: async () => {
153
153
  const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/my-widget`
154
154
  return `<div id="my-widget-root"></div><script type="module" src="${widgetUrl}"></script>`
155
- }
155
+ },
156
156
  })
157
157
  ```
158
158
 
@@ -198,11 +198,7 @@ const MyWidget: React.FC<MyWidgetProps> = ({ initialData = [] }) => {
198
198
  }
199
199
  }, [])
200
200
 
201
- return (
202
- <div>
203
- {/* Your widget content */}
204
- </div>
205
- )
201
+ return <div>{/* Your widget content */}</div>
206
202
  }
207
203
 
208
204
  // Render the component
@@ -235,7 +231,7 @@ npm run build
235
231
 
236
232
  # The built files will be in dist/
237
233
  # - dist/index.js (MCP server entry point)
238
- # - dist/src/server.js (MCP server implementation)
234
+ # - dist/src/server.js (MCP server implementation)
239
235
  # - dist/resources/ (Compiled TypeScript + UI widget bundles)
240
236
  ```
241
237
 
@@ -315,10 +311,13 @@ export default defineConfig({
315
311
  build: {
316
312
  rollupOptions: {
317
313
  input: {
318
- 'my-custom-widget': resolve(__dirname, 'resources/my-custom-widget.html')
319
- }
320
- }
321
- }
314
+ 'my-custom-widget': resolve(
315
+ __dirname,
316
+ 'resources/my-custom-widget.html'
317
+ ),
318
+ },
319
+ },
320
+ },
322
321
  })
323
322
  ```
324
323
 
@@ -374,12 +373,8 @@ const Counter: React.FC = () => {
374
373
  return (
375
374
  <div style={{ padding: '20px', textAlign: 'center' }}>
376
375
  <h1>Counter: {count}</h1>
377
- <button onClick={() => setCount(count + 1)}>
378
- Increment
379
- </button>
380
- <button onClick={() => setCount(count - 1)}>
381
- Decrement
382
- </button>
376
+ <button onClick={() => setCount(count + 1)}>Increment</button>
377
+ <button onClick={() => setCount(count - 1)}>Decrement</button>
383
378
  </div>
384
379
  )
385
380
  }
@@ -432,7 +427,7 @@ const DataTable: React.FC = () => {
432
427
  </tr>
433
428
  </thead>
434
429
  <tbody>
435
- {data.map(row => (
430
+ {data.map((row) => (
436
431
  <tr key={row.id}>
437
432
  <td>{row.name}</td>
438
433
  <td>{row.value}</td>
@@ -22,7 +22,7 @@ server.tool({
22
22
  required: true,
23
23
  },
24
24
  ],
25
- fn: async () => {
25
+ cb: async () => {
26
26
  const uiResource = createUIResource({
27
27
  uri: 'ui://widget/kanban-board',
28
28
  content: {
@@ -49,7 +49,7 @@ server.resource({
49
49
  audience: ['user', 'assistant'],
50
50
  priority: 0.7
51
51
  },
52
- fn: async () => {
52
+ readCallback: async () => {
53
53
  const widgetUrl = `http://localhost:${PORT}/mcp-use/widgets/kanban-board`
54
54
  return {
55
55
  contents: [{
@@ -17,8 +17,12 @@ The `uiResource` method is a powerful new addition that simplifies widget regist
17
17
 
18
18
  ```typescript
19
19
  // Old way: Manual registration of tool and resource
20
- server.tool({ /* tool config */ })
21
- server.resource({ /* resource config */ })
20
+ server.tool({
21
+ /* tool config */
22
+ })
23
+ server.resource({
24
+ /* resource config */
25
+ })
22
26
 
23
27
  // New way: Single method does both!
24
28
  server.uiResource({
@@ -27,12 +31,13 @@ server.uiResource({
27
31
  title: 'Kanban Board',
28
32
  props: {
29
33
  initialTasks: { type: 'array', required: false },
30
- theme: { type: 'string', default: 'light' }
31
- }
34
+ theme: { type: 'string', default: 'light' },
35
+ },
32
36
  })
33
37
  ```
34
38
 
35
39
  This automatically creates:
40
+
36
41
  - **Tool**: `ui_kanban-board` - Accepts parameters and returns UIResource
37
42
  - **Resource**: `ui://widget/kanban-board` - Static access with defaults
38
43
 
@@ -49,6 +54,7 @@ npm run dev
49
54
  ```
50
55
 
51
56
  This will start:
57
+
52
58
  - MCP server on port 3000
53
59
  - Widget serving at `/mcp-use/widgets/*`
54
60
  - Inspector UI at `/inspector`
@@ -72,7 +78,7 @@ import { createMCPServer } from 'mcp-use/server'
72
78
 
73
79
  const server = createMCPServer('my-server', {
74
80
  version: '1.0.0',
75
- description: 'Server with UIResource widgets'
81
+ description: 'Server with UIResource widgets',
76
82
  })
77
83
 
78
84
  // Register a widget - creates both tool and resource
@@ -80,7 +86,7 @@ server.uiResource({
80
86
  name: 'my-widget',
81
87
  widget: 'my-widget',
82
88
  title: 'My Widget',
83
- description: 'An interactive widget'
89
+ description: 'An interactive widget',
84
90
  })
85
91
 
86
92
  server.listen(3000)
@@ -98,24 +104,24 @@ server.uiResource({
98
104
  data: {
99
105
  type: 'array',
100
106
  description: 'Data points to display',
101
- required: true
107
+ required: true,
102
108
  },
103
109
  chartType: {
104
110
  type: 'string',
105
111
  description: 'Type of chart (line/bar/pie)',
106
- default: 'line'
112
+ default: 'line',
107
113
  },
108
114
  theme: {
109
115
  type: 'string',
110
116
  description: 'Visual theme',
111
- default: 'light'
112
- }
117
+ default: 'light',
118
+ },
113
119
  },
114
120
  size: ['800px', '400px'], // Preferred iframe size
115
121
  annotations: {
116
122
  audience: ['user', 'assistant'],
117
- priority: 0.8
118
- }
123
+ priority: 0.8,
124
+ },
119
125
  })
120
126
  ```
121
127
 
@@ -135,7 +141,7 @@ interface MyWidgetProps {
135
141
 
136
142
  const MyWidget: React.FC<MyWidgetProps> = ({
137
143
  initialData = [],
138
- theme = 'light'
144
+ theme = 'light',
139
145
  }) => {
140
146
  const [data, setData] = useState(initialData)
141
147
 
@@ -158,11 +164,7 @@ const MyWidget: React.FC<MyWidgetProps> = ({
158
164
  }
159
165
  }, [])
160
166
 
161
- return (
162
- <div className={`widget theme-${theme}`}>
163
- {/* Your widget UI */}
164
- </div>
165
- )
167
+ return <div className={`widget theme-${theme}`}>{/* Your widget UI */}</div>
166
168
  }
167
169
 
168
170
  // Mount the widget
@@ -185,34 +187,40 @@ server.uiResource({
185
187
  initialData: {
186
188
  type: 'array',
187
189
  description: 'Initial data for the widget',
188
- required: false
190
+ required: false,
189
191
  },
190
192
  theme: {
191
193
  type: 'string',
192
194
  description: 'Widget theme',
193
- default: 'light'
194
- }
195
+ default: 'light',
196
+ },
195
197
  },
196
- size: ['600px', '400px']
198
+ size: ['600px', '400px'],
197
199
  })
198
200
  ```
199
201
 
200
202
  ## How It Works
201
203
 
202
204
  ### Tool Registration
205
+
203
206
  When you call `uiResource`, it automatically creates a tool:
207
+
204
208
  - Name: `ui_[widget-name]`
205
209
  - Accepts all props as parameters
206
210
  - Returns both text description and UIResource object
207
211
 
208
212
  ### Resource Registration
213
+
209
214
  Also creates a resource:
215
+
210
216
  - URI: `ui://widget/[widget-name]`
211
217
  - Returns UIResource with default prop values
212
218
  - Discoverable by MCP clients
213
219
 
214
220
  ### Parameter Passing
221
+
215
222
  Tool parameters are automatically:
223
+
216
224
  1. Converted to URL query parameters
217
225
  2. Complex objects are JSON-stringified
218
226
  3. Passed to widget via iframe URL
@@ -228,21 +236,21 @@ const widgets = [
228
236
  widget: 'todo-list',
229
237
  title: 'Todo List',
230
238
  props: {
231
- items: { type: 'array', default: [] }
232
- }
239
+ items: { type: 'array', default: [] },
240
+ },
233
241
  },
234
242
  {
235
243
  name: 'calendar',
236
244
  widget: 'calendar',
237
245
  title: 'Calendar',
238
246
  props: {
239
- date: { type: 'string', required: false }
240
- }
241
- }
247
+ date: { type: 'string', required: false },
248
+ },
249
+ },
242
250
  ]
243
251
 
244
252
  // Register all widgets
245
- widgets.forEach(widget => server.uiResource(widget))
253
+ widgets.forEach((widget) => server.uiResource(widget))
246
254
  ```
247
255
 
248
256
  ### Mixed Registration
@@ -252,14 +260,16 @@ widgets.forEach(widget => server.uiResource(widget))
252
260
  server.uiResource({
253
261
  name: 'dashboard',
254
262
  widget: 'dashboard',
255
- title: 'Analytics Dashboard'
263
+ title: 'Analytics Dashboard',
256
264
  })
257
265
 
258
266
  // Traditional tool for actions
259
267
  server.tool({
260
268
  name: 'calculate',
261
269
  description: 'Perform calculations',
262
- fn: async (params) => { /* ... */ }
270
+ cb: async (params) => {
271
+ /* ... */
272
+ },
263
273
  })
264
274
 
265
275
  // Traditional resource for data
@@ -267,7 +277,9 @@ server.resource({
267
277
  name: 'config',
268
278
  uri: 'config://app',
269
279
  mimeType: 'application/json',
270
- fn: async () => { /* ... */ }
280
+ readCallback: async () => {
281
+ /* ... */
282
+ },
271
283
  })
272
284
  ```
273
285
 
@@ -289,6 +301,7 @@ server.resource({
289
301
  #### WidgetProps
290
302
 
291
303
  Each prop can have:
304
+
292
305
  - `type: 'string' | 'number' | 'boolean' | 'object' | 'array'`
293
306
  - `required?: boolean` - Whether the prop is required
294
307
  - `default?: any` - Default value if not provided
@@ -297,14 +310,17 @@ Each prop can have:
297
310
  ## Testing Your Widgets
298
311
 
299
312
  ### Via Inspector UI
313
+
300
314
  1. Start the server: `npm run dev`
301
315
  2. Open: `http://localhost:3000/inspector`
302
316
  3. Test tools and resources
303
317
 
304
318
  ### Direct Browser Access
319
+
305
320
  Visit: `http://localhost:3000/mcp-use/widgets/[widget-name]`
306
321
 
307
322
  ### Via MCP Client
323
+
308
324
  ```typescript
309
325
  // Call as tool
310
326
  const result = await client.callTool('ui_kanban-board', {
@@ -328,16 +344,19 @@ const resource = await client.readResource('ui://widget/kanban-board')
328
344
  ## Troubleshooting
329
345
 
330
346
  ### Widget Not Loading
347
+
331
348
  - Ensure widget exists in `dist/resources/mcp-use/widgets/`
332
349
  - Check server console for errors
333
350
  - Verify widget is registered with `uiResource()`
334
351
 
335
352
  ### Props Not Passed
353
+
336
354
  - Check URL parameters in browser DevTools
337
355
  - Ensure prop names match exactly
338
356
  - Complex objects must be JSON-stringified
339
357
 
340
358
  ### Type Errors
359
+
341
360
  - Import types: `import type { UIResourceDefinition } from 'mcp-use/server'`
342
361
  - Ensure mcp-use is updated to latest version
343
362
 
@@ -347,8 +366,8 @@ If you have existing code using separate tool/resource:
347
366
 
348
367
  ```typescript
349
368
  // Old pattern
350
- server.tool({ name: 'show-widget', /* ... */ })
351
- server.resource({ uri: 'ui://widget', /* ... */ })
369
+ server.tool({ name: 'show-widget' /* ... */ })
370
+ server.resource({ uri: 'ui://widget' /* ... */ })
352
371
 
353
372
  // New pattern - replace both with:
354
373
  server.uiResource({
@@ -361,6 +380,7 @@ server.uiResource({
361
380
  ## Future Enhancements
362
381
 
363
382
  Coming soon:
383
+
364
384
  - Automatic widget discovery from filesystem
365
385
  - Widget manifests (widget.json)
366
386
  - Prop extraction from TypeScript interfaces
@@ -373,4 +393,4 @@ Coming soon:
373
393
  - [mcp-use Documentation](https://github.com/pyroprompt/mcp-use)
374
394
  - [React Documentation](https://react.dev/)
375
395
 
376
- Happy widget building! 🚀
396
+ Happy widget building! 🚀
@@ -289,7 +289,7 @@ root.appendChild(container);
289
289
  server.tool({
290
290
  name: 'get-widget-info',
291
291
  description: 'Get information about available UI widgets',
292
- fn: async () => {
292
+ cb: async () => {
293
293
  const widgets = [
294
294
  {
295
295
  name: 'kanban-board',
@@ -321,10 +321,10 @@ server.tool({
321
321
  ` Resource: ${w.resource}\n` +
322
322
  (w.url ? ` Browser: ${w.url}\n` : '')
323
323
  ).join('\n')}\n` +
324
- `\nTypes Explained:\n` +
325
- `• externalUrl: Iframe widget from filesystem\n` +
326
- `• rawHtml: Direct HTML rendering\n` +
327
- `• remoteDom: React/Web Components scripting`
324
+ `\nTypes Explained:\n` +
325
+ `• externalUrl: Iframe widget from filesystem\n` +
326
+ `• rawHtml: Direct HTML rendering\n` +
327
+ `• remoteDom: React/Web Components scripting`
328
328
  }]
329
329
  }
330
330
  }
@@ -336,7 +336,7 @@ server.resource({
336
336
  title: 'Server Configuration',
337
337
  description: 'Current server configuration and status',
338
338
  mimeType: 'application/json',
339
- fn: async () => ({
339
+ readCallback: async () => ({
340
340
  contents: [{
341
341
  uri: 'config://server',
342
342
  mimeType: 'application/json',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mcp-use-app",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Create MCP-Use apps with one command",
6
6
  "author": "mcp-use, Inc.",
@@ -39,11 +39,14 @@
39
39
  "dependencies": {
40
40
  "commander": "^11.0.0",
41
41
  "chalk": "^5.3.0",
42
- "fs-extra": "^11.2.0"
42
+ "fs-extra": "^11.2.0",
43
+ "inquirer": "^9.3.8",
44
+ "ora": "^8.2.0"
43
45
  },
44
46
  "devDependencies": {
45
47
  "@types/node": "^20.0.0",
46
48
  "@types/fs-extra": "^11.0.4",
49
+ "@types/inquirer": "^9.0.9",
47
50
  "typescript": "^5.0.0",
48
51
  "vitest": "^1.0.0"
49
52
  },