create-mcp-use-app 0.4.4-canary.0 → 0.4.4
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.js +18 -8
- package/dist/templates/{apps_sdk → apps-sdk-demo}/README.md +1 -1
- package/dist/templates/{apps_sdk → apps-sdk-demo}/src/widgets.ts +0 -27
- package/dist/templates/starter/README.md +557 -0
- package/dist/templates/{ui → starter}/package.json +9 -4
- package/dist/templates/starter/src/remoteDom/index.ts +93 -0
- package/dist/templates/starter/src/server.ts +195 -0
- package/dist/templates/{uiresource → starter}/tsconfig.json +1 -0
- package/package.json +1 -1
- package/dist/templates/ui/README.md +0 -449
- package/dist/templates/ui/src/server.ts +0 -67
- /package/dist/templates/{apps_sdk → apps-sdk-demo}/index.ts +0 -0
- /package/dist/templates/{apps_sdk → apps-sdk-demo}/package.json +0 -0
- /package/dist/templates/{apps_sdk → apps-sdk-demo}/src/server.ts +0 -0
- /package/dist/templates/{apps_sdk → apps-sdk-demo}/tsconfig.json +0 -0
- /package/dist/templates/{ui → starter}/index.ts +0 -0
- /package/dist/templates/{ui → starter}/resources/kanban-board.tsx +0 -0
- /package/dist/templates/{uiresource → ui-resource}/README.md +0 -0
- /package/dist/templates/{uiresource → ui-resource}/index.ts +0 -0
- /package/dist/templates/{uiresource → ui-resource}/package.json +0 -0
- /package/dist/templates/{uiresource → ui-resource}/resources/kanban-board.tsx +0 -0
- /package/dist/templates/{uiresource → ui-resource}/src/server.ts +0 -0
- /package/dist/templates/{ui → ui-resource}/tsconfig.json +0 -0
package/dist/index.js
CHANGED
|
@@ -303,8 +303,9 @@ async function copyTemplate(projectPath, template, versions, isDevelopment = fal
|
|
|
303
303
|
} else {
|
|
304
304
|
console.log("No templates directory found");
|
|
305
305
|
}
|
|
306
|
-
console.log('\u{1F4A1} Tip: Use "
|
|
307
|
-
console.log('\u{1F4A1} Tip: Use "
|
|
306
|
+
console.log('\u{1F4A1} Tip: Use "starter" template for a comprehensive MCP server with all features');
|
|
307
|
+
console.log('\u{1F4A1} Tip: Use "ui-resource" template for a MCP server with mcp-ui resources');
|
|
308
|
+
console.log('\u{1F4A1} Tip: Use "apps-sdk-demo" template for a MCP server with OpenAI Apps SDK integration');
|
|
308
309
|
process.exit(1);
|
|
309
310
|
}
|
|
310
311
|
copyDirectoryWithProcessing(templatePath, projectPath, versions, isDevelopment, useCanary);
|
|
@@ -359,12 +360,21 @@ async function promptForProjectName() {
|
|
|
359
360
|
}
|
|
360
361
|
async function promptForTemplate() {
|
|
361
362
|
const templatesDir = join(__dirname, "templates");
|
|
362
|
-
const availableTemplates =
|
|
363
|
-
const templateDescriptions = {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
363
|
+
const availableTemplates = readdirSync(templatesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
|
|
364
|
+
const templateDescriptions = {};
|
|
365
|
+
for (const template2 of availableTemplates) {
|
|
366
|
+
const packageJsonPath = join(templatesDir, template2, "package.json");
|
|
367
|
+
if (existsSync(packageJsonPath)) {
|
|
368
|
+
try {
|
|
369
|
+
const packageJson2 = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
370
|
+
templateDescriptions[template2] = packageJson2.description || "MCP server template";
|
|
371
|
+
} catch (error) {
|
|
372
|
+
templateDescriptions[template2] = "MCP server template";
|
|
373
|
+
}
|
|
374
|
+
} else {
|
|
375
|
+
templateDescriptions[template2] = "MCP server template";
|
|
376
|
+
}
|
|
377
|
+
}
|
|
368
378
|
const { template } = await inquirer.prompt([
|
|
369
379
|
{
|
|
370
380
|
type: "list",
|
|
@@ -151,30 +151,3 @@ export function getPizzazWidgetsSummary() {
|
|
|
151
151
|
}))
|
|
152
152
|
}
|
|
153
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,557 @@
|
|
|
1
|
+
# MCP Starter Server
|
|
2
|
+
|
|
3
|
+
A comprehensive MCP server template with examples of tools, resources, prompts, and all UIResource types.
|
|
4
|
+
|
|
5
|
+
> 📚 **[View Full Documentation](https://docs.mcp-use.com/typescript/getting-started/quickstart)** - Complete guides, API references, and tutorials
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **🛠️ Tools**: Regular MCP tools and API integrations
|
|
10
|
+
- **📦 Resources**: Static and dynamic resources
|
|
11
|
+
- **📝 Prompts**: Reusable prompt templates
|
|
12
|
+
- **🎨 UIResources**: Three types of interactive widgets
|
|
13
|
+
- External URL (React iframe widgets)
|
|
14
|
+
- Remote DOM (MCP-UI components)
|
|
15
|
+
- Apps SDK (OpenAI ChatGPT compatible)
|
|
16
|
+
- **🔥 Hot Reload**: Development server with auto-reload
|
|
17
|
+
- **🔍 Inspector UI**: Built-in testing interface
|
|
18
|
+
- **✅ TypeScript**: Full type safety
|
|
19
|
+
|
|
20
|
+
## What's Included
|
|
21
|
+
|
|
22
|
+
This starter template demonstrates all major MCP features:
|
|
23
|
+
|
|
24
|
+
### 1. Traditional Tools
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
server.tool({
|
|
28
|
+
name: 'greet',
|
|
29
|
+
description: 'Greet someone by name',
|
|
30
|
+
inputs: [{ name: 'name', type: 'string', required: true }],
|
|
31
|
+
cb: async ({ name }) => {
|
|
32
|
+
return { content: [{ type: 'text', text: `Hello, ${name}!` }] }
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Resources
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
server.resource({
|
|
41
|
+
name: 'config',
|
|
42
|
+
uri: 'config://settings',
|
|
43
|
+
mimeType: 'application/json',
|
|
44
|
+
readCallback: async () => ({
|
|
45
|
+
/* ... */
|
|
46
|
+
}),
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Prompts
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
server.prompt({
|
|
54
|
+
name: 'review-code',
|
|
55
|
+
description: 'Review code for best practices',
|
|
56
|
+
args: [{ name: 'code', type: 'string', required: true }],
|
|
57
|
+
cb: async ({ code }) => {
|
|
58
|
+
/* ... */
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 4. UIResources (3 Types)
|
|
64
|
+
|
|
65
|
+
#### A. External URL (Iframe Widget)
|
|
66
|
+
|
|
67
|
+
React components served from your filesystem:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
server.uiResource({
|
|
71
|
+
type: 'externalUrl',
|
|
72
|
+
name: 'kanban-board',
|
|
73
|
+
widget: 'kanban-board',
|
|
74
|
+
title: 'Kanban Board',
|
|
75
|
+
props: {
|
|
76
|
+
/* ... */
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### B. Remote DOM (MCP-UI Components)
|
|
82
|
+
|
|
83
|
+
Lightweight widgets using MCP-UI React components:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
server.uiResource({
|
|
87
|
+
type: 'remoteDom',
|
|
88
|
+
name: 'quick-poll',
|
|
89
|
+
script: `/* Remote DOM script */`,
|
|
90
|
+
framework: 'react',
|
|
91
|
+
props: {
|
|
92
|
+
/* ... */
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### C. Apps SDK (ChatGPT Compatible)
|
|
98
|
+
|
|
99
|
+
OpenAI Apps SDK widgets for ChatGPT integration:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
server.uiResource({
|
|
103
|
+
type: 'appsSdk',
|
|
104
|
+
name: 'pizzaz-map-apps-sdk',
|
|
105
|
+
htmlTemplate: `<div id="pizzaz-root"></div>`,
|
|
106
|
+
appsSdkMetadata: {
|
|
107
|
+
/* OpenAI metadata */
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Getting Started
|
|
113
|
+
|
|
114
|
+
### Installation
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Install dependencies
|
|
118
|
+
npm install
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Start development server with hot reloading
|
|
125
|
+
npm run dev
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This starts:
|
|
129
|
+
|
|
130
|
+
- MCP server on port 3000
|
|
131
|
+
- Widget serving at `/mcp-use/widgets/*`
|
|
132
|
+
- Inspector UI at `/inspector`
|
|
133
|
+
|
|
134
|
+
### Production
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Build the server and widgets
|
|
138
|
+
npm run build
|
|
139
|
+
|
|
140
|
+
# Run the built server
|
|
141
|
+
npm start
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Project Structure
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
starter/
|
|
148
|
+
├── src/
|
|
149
|
+
│ ├── server.ts # Main server configuration
|
|
150
|
+
│ └── remoteDom/ # Remote DOM scripts
|
|
151
|
+
│ └── index.ts # Quick poll script
|
|
152
|
+
├── resources/ # React widget components (root level!)
|
|
153
|
+
│ └── kanban-board.tsx
|
|
154
|
+
├── index.ts # Entry point
|
|
155
|
+
├── package.json
|
|
156
|
+
├── tsconfig.json
|
|
157
|
+
└── README.md
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Available Tools
|
|
161
|
+
|
|
162
|
+
### `greet`
|
|
163
|
+
|
|
164
|
+
Simple greeting tool demonstrating basic tool structure.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
await client.callTool('greet', { name: 'Alice' })
|
|
168
|
+
// Returns: "Hello, Alice! Welcome to MCP."
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `fetch-weather`
|
|
172
|
+
|
|
173
|
+
Demonstrates async operations and external API calls.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await client.callTool('fetch-weather', { city: 'London' })
|
|
177
|
+
// Returns: Weather information from wttr.in
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `ui_kanban-board`
|
|
181
|
+
|
|
182
|
+
Interactive Kanban board widget (External URL).
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
await client.callTool('ui_kanban-board', {
|
|
186
|
+
initialTasks: [{ id: '1', title: 'Task 1' /* ... */ }],
|
|
187
|
+
theme: 'dark',
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `ui_quick-poll`
|
|
192
|
+
|
|
193
|
+
Quick polling widget (Remote DOM).
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
await client.callTool('ui_quick-poll', {
|
|
197
|
+
question: 'Favorite framework?',
|
|
198
|
+
options: ['React', 'Vue', 'Svelte'],
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### `ui_pizzaz-map-apps-sdk`
|
|
203
|
+
|
|
204
|
+
Pizza location map (Apps SDK).
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
await client.callTool('ui_pizzaz-map-apps-sdk', {
|
|
208
|
+
pizzaTopping: 'pepperoni',
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Available Resources
|
|
213
|
+
|
|
214
|
+
### `config://settings`
|
|
215
|
+
|
|
216
|
+
Server configuration resource.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
await client.readResource('config://settings')
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### `ui://widget/kanban-board`
|
|
223
|
+
|
|
224
|
+
Static Kanban board widget with defaults.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
await client.readResource('ui://widget/kanban-board')
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### `ui://widget/quick-poll`
|
|
231
|
+
|
|
232
|
+
Static quick poll widget with defaults.
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
await client.readResource('ui://widget/quick-poll')
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### `ui://widget/pizzaz-map-apps-sdk`
|
|
239
|
+
|
|
240
|
+
Static pizza map widget.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
await client.readResource('ui://widget/pizzaz-map-apps-sdk')
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Available Prompts
|
|
247
|
+
|
|
248
|
+
### `review-code`
|
|
249
|
+
|
|
250
|
+
Code review prompt template.
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
await client.getPrompt('review-code', { code: 'const x = 1;' })
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Customization Guide
|
|
257
|
+
|
|
258
|
+
### Adding New Tools
|
|
259
|
+
|
|
260
|
+
1. Add to `src/server.ts`:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
server.tool({
|
|
264
|
+
name: 'my-tool',
|
|
265
|
+
description: 'My custom tool',
|
|
266
|
+
inputs: [{ name: 'param', type: 'string', required: true }],
|
|
267
|
+
cb: async ({ param }) => {
|
|
268
|
+
// Your logic here
|
|
269
|
+
return {
|
|
270
|
+
content: [{ type: 'text', text: `Result: ${param}` }],
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
})
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Adding New React Widgets
|
|
277
|
+
|
|
278
|
+
1. Create widget in `resources/my-widget.tsx` (at root level):
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
import React from 'react'
|
|
282
|
+
import { createRoot } from 'react-dom/client'
|
|
283
|
+
|
|
284
|
+
const MyWidget: React.FC = () => {
|
|
285
|
+
return <div>My Widget</div>
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const container = document.getElementById('widget-root')
|
|
289
|
+
if (container) {
|
|
290
|
+
createRoot(container).render(<MyWidget />)
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
2. Register in `src/server.ts`:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
server.uiResource({
|
|
298
|
+
type: 'externalUrl',
|
|
299
|
+
name: 'my-widget',
|
|
300
|
+
widget: 'my-widget',
|
|
301
|
+
title: 'My Widget',
|
|
302
|
+
description: 'My custom widget',
|
|
303
|
+
})
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Adding Remote DOM Widgets
|
|
307
|
+
|
|
308
|
+
1. Create script in `src/remoteDom/my-script.ts`:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
export const myScript = `
|
|
312
|
+
const container = document.createElement('ui-stack');
|
|
313
|
+
container.setAttribute('direction', 'column');
|
|
314
|
+
|
|
315
|
+
const text = document.createElement('ui-text');
|
|
316
|
+
text.textContent = 'Hello from Remote DOM!';
|
|
317
|
+
container.appendChild(text);
|
|
318
|
+
|
|
319
|
+
root.appendChild(container);
|
|
320
|
+
`
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
2. Register in `src/server.ts`:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { myScript } from './remoteDom/my-script'
|
|
327
|
+
|
|
328
|
+
server.uiResource({
|
|
329
|
+
type: 'remoteDom',
|
|
330
|
+
name: 'my-remote-widget',
|
|
331
|
+
script: myScript,
|
|
332
|
+
framework: 'react',
|
|
333
|
+
encoding: 'text',
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Adding Resources
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
server.resource({
|
|
341
|
+
name: 'my-resource',
|
|
342
|
+
uri: 'custom://my-data',
|
|
343
|
+
mimeType: 'application/json',
|
|
344
|
+
description: 'My custom resource',
|
|
345
|
+
readCallback: async () => ({
|
|
346
|
+
contents: [
|
|
347
|
+
{
|
|
348
|
+
uri: 'custom://my-data',
|
|
349
|
+
mimeType: 'application/json',
|
|
350
|
+
text: JSON.stringify({ data: 'value' }),
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
}),
|
|
354
|
+
})
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Adding Prompts
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
server.prompt({
|
|
361
|
+
name: 'my-prompt',
|
|
362
|
+
description: 'My custom prompt',
|
|
363
|
+
args: [{ name: 'input', type: 'string', required: true }],
|
|
364
|
+
cb: async ({ input }) => ({
|
|
365
|
+
content: [
|
|
366
|
+
{
|
|
367
|
+
type: 'text',
|
|
368
|
+
text: `Process this input: ${input}`,
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
}),
|
|
372
|
+
})
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Testing Your Server
|
|
376
|
+
|
|
377
|
+
### Using the Inspector UI
|
|
378
|
+
|
|
379
|
+
1. Start the server: `npm run dev`
|
|
380
|
+
2. Open: `http://localhost:3000/inspector`
|
|
381
|
+
3. Test tools, resources, and prompts interactively
|
|
382
|
+
|
|
383
|
+
### Direct Browser Access
|
|
384
|
+
|
|
385
|
+
For External URL widgets:
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
http://localhost:3000/mcp-use/widgets/kanban-board
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Via MCP Client
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
import { createMCPClient } from 'mcp-use/client'
|
|
395
|
+
|
|
396
|
+
const client = createMCPClient({
|
|
397
|
+
serverUrl: 'http://localhost:3000/mcp',
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
await client.connect()
|
|
401
|
+
|
|
402
|
+
// Test tools
|
|
403
|
+
const result = await client.callTool('greet', { name: 'World' })
|
|
404
|
+
|
|
405
|
+
// Test resources
|
|
406
|
+
const config = await client.readResource('config://settings')
|
|
407
|
+
|
|
408
|
+
// Test prompts
|
|
409
|
+
const prompt = await client.getPrompt('review-code', { code: '...' })
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## UIResource Types Comparison
|
|
413
|
+
|
|
414
|
+
| Type | Use Case | Complexity | Features |
|
|
415
|
+
| ---------------- | ------------------- | ---------- | --------------------------------- |
|
|
416
|
+
| **External URL** | Complex React apps | High | Full React, npm packages, routing |
|
|
417
|
+
| **Remote DOM** | Lightweight widgets | Low | MCP-UI components only |
|
|
418
|
+
| **Apps SDK** | ChatGPT integration | Medium | OpenAI ecosystem compatibility |
|
|
419
|
+
|
|
420
|
+
### When to Use Each
|
|
421
|
+
|
|
422
|
+
- **External URL**: Complex interactive UIs (dashboards, forms, games)
|
|
423
|
+
- **Remote DOM**: Simple widgets (buttons, cards, polls)
|
|
424
|
+
- **Apps SDK**: ChatGPT-specific integrations
|
|
425
|
+
|
|
426
|
+
## Environment Variables
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
PORT=3000 # Server port (default: 3000)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Build Output
|
|
433
|
+
|
|
434
|
+
After running `npm run build`:
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
dist/
|
|
438
|
+
├── index.js # Entry point
|
|
439
|
+
├── src/
|
|
440
|
+
│ ├── server.js # Compiled server
|
|
441
|
+
│ └── remoteDom/
|
|
442
|
+
│ └── index.js
|
|
443
|
+
└── resources/
|
|
444
|
+
└── mcp-use/
|
|
445
|
+
└── widgets/
|
|
446
|
+
└── kanban-board/
|
|
447
|
+
└── index.html
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## Troubleshooting
|
|
451
|
+
|
|
452
|
+
### Widget Not Loading
|
|
453
|
+
|
|
454
|
+
- Ensure `tsconfig.json` has `"jsx": "react-jsx"`
|
|
455
|
+
- Check `src/resources/` contains your widget file
|
|
456
|
+
- Verify widget is built in `dist/resources/mcp-use/widgets/`
|
|
457
|
+
- Check browser console for errors
|
|
458
|
+
|
|
459
|
+
### Props Not Passed to Widget
|
|
460
|
+
|
|
461
|
+
- Widgets receive props as URL query parameters
|
|
462
|
+
- Parse them in `useEffect` with `URLSearchParams`
|
|
463
|
+
- Complex objects are JSON-stringified
|
|
464
|
+
|
|
465
|
+
### Build Errors
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
# Clean build
|
|
469
|
+
rm -rf dist node_modules
|
|
470
|
+
npm install
|
|
471
|
+
npm run build
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Port Already in Use
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
# Change port
|
|
478
|
+
PORT=3001 npm run dev
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## Examples
|
|
482
|
+
|
|
483
|
+
### Complete Weather Widget
|
|
484
|
+
|
|
485
|
+
1. **Create widget** (`resources/weather.tsx`):
|
|
486
|
+
|
|
487
|
+
```tsx
|
|
488
|
+
import React, { useEffect, useState } from 'react'
|
|
489
|
+
import { createRoot } from 'react-dom/client'
|
|
490
|
+
|
|
491
|
+
const Weather: React.FC = () => {
|
|
492
|
+
const [city, setCity] = useState('London')
|
|
493
|
+
const [weather, setWeather] = useState(null)
|
|
494
|
+
|
|
495
|
+
useEffect(() => {
|
|
496
|
+
const params = new URLSearchParams(window.location.search)
|
|
497
|
+
const cityParam = params.get('city')
|
|
498
|
+
if (cityParam) setCity(cityParam)
|
|
499
|
+
}, [])
|
|
500
|
+
|
|
501
|
+
useEffect(() => {
|
|
502
|
+
fetch(`https://wttr.in/${city}?format=j1`)
|
|
503
|
+
.then((r) => r.json())
|
|
504
|
+
.then(setWeather)
|
|
505
|
+
}, [city])
|
|
506
|
+
|
|
507
|
+
if (!weather) return <div>Loading...</div>
|
|
508
|
+
|
|
509
|
+
return (
|
|
510
|
+
<div style={{ padding: 20 }}>
|
|
511
|
+
<h1>Weather in {city}</h1>
|
|
512
|
+
<p>{weather.current_condition[0].temp_C}°C</p>
|
|
513
|
+
</div>
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const container = document.getElementById('widget-root')
|
|
518
|
+
if (container) createRoot(container).render(<Weather />)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
2. **Register** (`src/server.ts`):
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
server.uiResource({
|
|
525
|
+
type: 'externalUrl',
|
|
526
|
+
name: 'weather-widget',
|
|
527
|
+
widget: 'weather',
|
|
528
|
+
title: 'Weather Widget',
|
|
529
|
+
props: {
|
|
530
|
+
city: { type: 'string', default: 'London' },
|
|
531
|
+
},
|
|
532
|
+
})
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
3. **Use**:
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
await client.callTool('ui_weather-widget', { city: 'Paris' })
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Learn More
|
|
542
|
+
|
|
543
|
+
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
544
|
+
- [MCP-UI Documentation](https://github.com/idosal/mcp-ui)
|
|
545
|
+
- [mcp-use Documentation](https://github.com/pyroprompt/mcp-use)
|
|
546
|
+
- [React Documentation](https://react.dev/)
|
|
547
|
+
- [OpenAI Apps SDK](https://platform.openai.com/docs/apps)
|
|
548
|
+
|
|
549
|
+
## License
|
|
550
|
+
|
|
551
|
+
MIT
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
> 📚 **[View Full Documentation](https://docs.mcp-use.com/typescript/getting-started/quickstart)** - For more guides and advanced features
|
|
556
|
+
|
|
557
|
+
Happy building! 🚀
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "mcp-use-server
|
|
2
|
+
"name": "mcp-use-starter-server",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"version": "1.0.0",
|
|
5
|
-
"description": "MCP server
|
|
5
|
+
"description": "MCP server with starter tools and resources",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"mcp",
|
|
10
10
|
"server",
|
|
11
|
+
"starter",
|
|
12
|
+
"tools",
|
|
13
|
+
"resources",
|
|
14
|
+
"prompts",
|
|
15
|
+
"uiresource",
|
|
11
16
|
"ui",
|
|
12
17
|
"react",
|
|
13
18
|
"widgets",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
19
|
+
"mcp-ui",
|
|
20
|
+
"apps-sdk"
|
|
16
21
|
],
|
|
17
22
|
"main": "dist/index.js",
|
|
18
23
|
"scripts": {
|