create-mcp-use-app 2.0.0-beta.0 → 2.0.0-beta.10
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/README.md +74 -47
- package/dist/index.js +70 -96
- package/dist/templates/blank/README.md +3 -1
- package/dist/templates/blank/mcp-env.d.ts +10 -0
- package/dist/templates/blank/package.json +16 -8
- package/dist/templates/blank/tsconfig.json +14 -14
- package/dist/templates/mcp-apps/README.md +3 -1
- package/dist/templates/mcp-apps/index.ts +98 -24
- package/dist/templates/mcp-apps/mcp-env.d.ts +10 -0
- package/dist/templates/mcp-apps/package.json +17 -15
- package/dist/templates/mcp-apps/public/logo-mcp-use.svg +8 -0
- package/dist/templates/mcp-apps/tsconfig.json +9 -3
- package/dist/templates/mcp-apps/views/my-view/MeshGradient.tsx +299 -0
- package/dist/templates/mcp-apps/views/my-view/Tooltip.tsx +75 -0
- package/dist/templates/mcp-apps/views/my-view/icons.tsx +142 -0
- package/dist/templates/mcp-apps/views/my-view/view.css +5 -0
- package/dist/templates/mcp-apps/views/my-view/view.tsx +396 -0
- package/dist/templates/{starter → mcp-server}/README.md +4 -2
- package/dist/templates/{starter → mcp-server}/index.ts +1 -19
- package/dist/templates/mcp-server/mcp-env.d.ts +10 -0
- package/dist/templates/mcp-server/package.json +37 -0
- package/dist/templates/mcp-server/tsconfig.json +24 -0
- package/package.json +3 -3
- package/dist/templates/blank/public/favicon.ico +0 -0
- package/dist/templates/mcp-apps/public/favicon.ico +0 -0
- package/dist/templates/mcp-apps/public/fruits/apple.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/apricot.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/avocado.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/banana.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/blueberry.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/cherries.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/coconut.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/grapes.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/lemon.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/mango.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/orange.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/pear.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/pineapple.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/plum.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/strawberry.png +0 -0
- package/dist/templates/mcp-apps/public/fruits/watermelon.png +0 -0
- package/dist/templates/mcp-apps/resources/product-search-result/view.tsx +0 -26
- package/dist/templates/mcp-apps/src/register.d.ts +0 -7
- package/dist/templates/starter/package.json +0 -32
- package/dist/templates/starter/public/favicon.ico +0 -0
- package/dist/templates/starter/tsconfig.json +0 -24
- /package/dist/templates/{starter → mcp-server}/gitignore +0 -0
- /package/dist/templates/{starter → mcp-server}/public/icon.svg +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
export function ExpandIcon() {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
width="14"
|
|
5
|
+
height="14"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
fill="none"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
strokeWidth="2"
|
|
10
|
+
aria-hidden
|
|
11
|
+
>
|
|
12
|
+
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function PipIcon() {
|
|
18
|
+
return (
|
|
19
|
+
<svg
|
|
20
|
+
width="14"
|
|
21
|
+
height="14"
|
|
22
|
+
viewBox="0 0 24 24"
|
|
23
|
+
fill="none"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
strokeWidth="2"
|
|
26
|
+
aria-hidden
|
|
27
|
+
>
|
|
28
|
+
<rect x="2" y="4" width="20" height="14" rx="2" />
|
|
29
|
+
<rect x="13" y="11" width="7" height="5" rx="1" fill="currentColor" />
|
|
30
|
+
</svg>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function CloseIcon() {
|
|
35
|
+
return (
|
|
36
|
+
<svg
|
|
37
|
+
width="14"
|
|
38
|
+
height="14"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
fill="none"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
strokeWidth="2"
|
|
43
|
+
aria-hidden
|
|
44
|
+
>
|
|
45
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
46
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
47
|
+
</svg>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function SunIcon() {
|
|
52
|
+
return (
|
|
53
|
+
<svg
|
|
54
|
+
width="14"
|
|
55
|
+
height="14"
|
|
56
|
+
viewBox="0 0 24 24"
|
|
57
|
+
fill="none"
|
|
58
|
+
stroke="currentColor"
|
|
59
|
+
strokeWidth="2"
|
|
60
|
+
strokeLinecap="round"
|
|
61
|
+
strokeLinejoin="round"
|
|
62
|
+
aria-hidden
|
|
63
|
+
>
|
|
64
|
+
<circle cx="12" cy="12" r="4" />
|
|
65
|
+
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
|
|
66
|
+
</svg>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function MoonIcon() {
|
|
71
|
+
return (
|
|
72
|
+
<svg
|
|
73
|
+
width="14"
|
|
74
|
+
height="14"
|
|
75
|
+
viewBox="0 0 24 24"
|
|
76
|
+
fill="none"
|
|
77
|
+
stroke="currentColor"
|
|
78
|
+
strokeWidth="2"
|
|
79
|
+
strokeLinecap="round"
|
|
80
|
+
strokeLinejoin="round"
|
|
81
|
+
aria-hidden
|
|
82
|
+
>
|
|
83
|
+
<path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" />
|
|
84
|
+
</svg>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function SmartphoneIcon() {
|
|
89
|
+
return (
|
|
90
|
+
<svg
|
|
91
|
+
width="14"
|
|
92
|
+
height="14"
|
|
93
|
+
viewBox="0 0 24 24"
|
|
94
|
+
fill="none"
|
|
95
|
+
stroke="currentColor"
|
|
96
|
+
strokeWidth="2"
|
|
97
|
+
strokeLinecap="round"
|
|
98
|
+
strokeLinejoin="round"
|
|
99
|
+
aria-hidden
|
|
100
|
+
>
|
|
101
|
+
<rect width="14" height="20" x="5" y="2" rx="2" ry="2" />
|
|
102
|
+
<path d="M12 18h.01" />
|
|
103
|
+
</svg>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function MonitorIcon() {
|
|
108
|
+
return (
|
|
109
|
+
<svg
|
|
110
|
+
width="14"
|
|
111
|
+
height="14"
|
|
112
|
+
viewBox="0 0 24 24"
|
|
113
|
+
fill="none"
|
|
114
|
+
stroke="currentColor"
|
|
115
|
+
strokeWidth="2"
|
|
116
|
+
strokeLinecap="round"
|
|
117
|
+
strokeLinejoin="round"
|
|
118
|
+
aria-hidden
|
|
119
|
+
>
|
|
120
|
+
<rect width="20" height="14" x="2" y="3" rx="2" />
|
|
121
|
+
<path d="M8 21h8M12 17v4" />
|
|
122
|
+
</svg>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function ExternalLinkIcon() {
|
|
127
|
+
return (
|
|
128
|
+
<svg
|
|
129
|
+
width="12"
|
|
130
|
+
height="12"
|
|
131
|
+
viewBox="0 0 24 24"
|
|
132
|
+
fill="none"
|
|
133
|
+
stroke="currentColor"
|
|
134
|
+
strokeWidth="2"
|
|
135
|
+
aria-hidden
|
|
136
|
+
>
|
|
137
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
138
|
+
<polyline points="15 3 21 3 21 9" />
|
|
139
|
+
<line x1="10" y1="14" x2="21" y2="3" />
|
|
140
|
+
</svg>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/** MCP App starter view — edit this file to build your UI. */
|
|
2
|
+
import {
|
|
3
|
+
Image,
|
|
4
|
+
ModelContext,
|
|
5
|
+
ThemeProvider,
|
|
6
|
+
useCallTool,
|
|
7
|
+
useDisplayMode,
|
|
8
|
+
useHostContext,
|
|
9
|
+
useOpenExternal,
|
|
10
|
+
useSendFollowUp,
|
|
11
|
+
useToolContext,
|
|
12
|
+
useViewTheme,
|
|
13
|
+
useViewTool,
|
|
14
|
+
} from "mcp-use/react";
|
|
15
|
+
import { useState } from "react";
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
CloseIcon,
|
|
20
|
+
ExpandIcon,
|
|
21
|
+
ExternalLinkIcon,
|
|
22
|
+
MonitorIcon,
|
|
23
|
+
MoonIcon,
|
|
24
|
+
PipIcon,
|
|
25
|
+
SmartphoneIcon,
|
|
26
|
+
SunIcon,
|
|
27
|
+
} from "./icons.js";
|
|
28
|
+
import { HeroMeshOrb } from "./MeshGradient.js";
|
|
29
|
+
import { Tooltip } from "./Tooltip.js";
|
|
30
|
+
import "./view.css";
|
|
31
|
+
|
|
32
|
+
export default function McpApp() {
|
|
33
|
+
// useToolContext — tool lifecycle (pending / error / result)
|
|
34
|
+
const view = useToolContext<"show-app">();
|
|
35
|
+
// useHostContext — locale, timezone, platform, capabilities
|
|
36
|
+
const { hostCapabilities, platform, displayMode, locale, timeZone } =
|
|
37
|
+
useHostContext();
|
|
38
|
+
const theme = useViewTheme();
|
|
39
|
+
// useDisplayMode — request pip / fullscreen / inline
|
|
40
|
+
const { availableDisplayModes, requestDisplayMode } = useDisplayMode();
|
|
41
|
+
// useOpenExternal — open URLs via the host
|
|
42
|
+
const openExternal = useOpenExternal();
|
|
43
|
+
// useSendFollowUp — send a prompt back to the host
|
|
44
|
+
const sendFollowUp = useSendFollowUp();
|
|
45
|
+
// useCallTool — invoke server tools from the view
|
|
46
|
+
const sayHello = useCallTool("say-hello");
|
|
47
|
+
|
|
48
|
+
const [count, setCount] = useState(0);
|
|
49
|
+
const [highlighted, setHighlighted] = useState(false);
|
|
50
|
+
|
|
51
|
+
// useViewTool — register a tool callable from the host
|
|
52
|
+
useViewTool(
|
|
53
|
+
{
|
|
54
|
+
name: "set-counter",
|
|
55
|
+
description: "Set the counter displayed in the MCP App card",
|
|
56
|
+
inputSchema: z.object({
|
|
57
|
+
value: z.number().int().min(0).describe("Counter value to display"),
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
async ({ value }) => {
|
|
61
|
+
setCount(value);
|
|
62
|
+
setHighlighted(true);
|
|
63
|
+
window.setTimeout(() => setHighlighted(false), 1200);
|
|
64
|
+
return { content: [{ type: "text", text: `Counter set to ${value}` }] };
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const isMobile = platform === "mobile";
|
|
69
|
+
const isFullscreen = displayMode === "fullscreen";
|
|
70
|
+
const isPip = displayMode === "pip";
|
|
71
|
+
const pending = view.status === "pending";
|
|
72
|
+
const canOpenExternal = hostCapabilities?.openLinks !== undefined;
|
|
73
|
+
const canSendFollowUp = hostCapabilities?.message !== undefined;
|
|
74
|
+
const callResult = sayHello.data?.structuredContent?.greeting;
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<ThemeProvider>
|
|
78
|
+
<div
|
|
79
|
+
data-card-shell
|
|
80
|
+
className={
|
|
81
|
+
isFullscreen
|
|
82
|
+
? "relative flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden rounded-none border-0 bg-white dark:bg-black"
|
|
83
|
+
: `relative overflow-hidden rounded-3xl border border-zinc-200 bg-white dark:border-white/10 dark:bg-black${
|
|
84
|
+
!pending && highlighted
|
|
85
|
+
? " ring-2 ring-blue-500 ring-offset-2 dark:ring-offset-black"
|
|
86
|
+
: ""
|
|
87
|
+
}`
|
|
88
|
+
}
|
|
89
|
+
>
|
|
90
|
+
{!isMobile && <HeroMeshOrb />}
|
|
91
|
+
{!isFullscreen && (
|
|
92
|
+
<div className="absolute inset-x-4 top-4 z-20 flex items-center justify-between">
|
|
93
|
+
<div className="flex items-center gap-2">
|
|
94
|
+
<Tooltip label={`MCP Host sending: Theme: ${theme}`} multiline>
|
|
95
|
+
<span
|
|
96
|
+
className="inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium tracking-wide text-neutral-500 dark:text-neutral-400"
|
|
97
|
+
aria-label={`Theme: ${theme}`}
|
|
98
|
+
>
|
|
99
|
+
{theme === "dark" ? <MoonIcon /> : <SunIcon />}
|
|
100
|
+
</span>
|
|
101
|
+
</Tooltip>
|
|
102
|
+
<Tooltip
|
|
103
|
+
label={`MCP Host sending: Platform: ${isMobile ? "mobile" : "web"}`}
|
|
104
|
+
multiline
|
|
105
|
+
>
|
|
106
|
+
<span
|
|
107
|
+
className="inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium tracking-wide text-neutral-500 dark:text-neutral-400"
|
|
108
|
+
aria-label={`Platform: ${isMobile ? "mobile" : "web"}`}
|
|
109
|
+
>
|
|
110
|
+
{isMobile ? <SmartphoneIcon /> : <MonitorIcon />}
|
|
111
|
+
</span>
|
|
112
|
+
</Tooltip>
|
|
113
|
+
<Tooltip label={`MCP Host sending: Locale: ${locale}`} multiline>
|
|
114
|
+
<span className="inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium tracking-wide text-neutral-500 dark:text-neutral-400">
|
|
115
|
+
{locale}
|
|
116
|
+
</span>
|
|
117
|
+
</Tooltip>
|
|
118
|
+
<Tooltip
|
|
119
|
+
label={`MCP Host sending: Timezone: ${timeZone}`}
|
|
120
|
+
multiline
|
|
121
|
+
>
|
|
122
|
+
<span className="inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium tracking-wide text-neutral-500 dark:text-neutral-400">
|
|
123
|
+
{timeZone.split("/").pop()?.replace(/_/g, " ") ?? timeZone}
|
|
124
|
+
</span>
|
|
125
|
+
</Tooltip>
|
|
126
|
+
</div>
|
|
127
|
+
<div className="flex items-center gap-2">
|
|
128
|
+
{!isFullscreen && !isPip && (
|
|
129
|
+
<>
|
|
130
|
+
{availableDisplayModes.includes("pip") && (
|
|
131
|
+
<Tooltip
|
|
132
|
+
label="MCP Apps display mode: picture-in-picture"
|
|
133
|
+
multiline
|
|
134
|
+
>
|
|
135
|
+
<button
|
|
136
|
+
type="button"
|
|
137
|
+
className="cursor-pointer rounded-full border border-neutral-300 p-2 text-neutral-900 transition-colors hover:bg-neutral-100 dark:border-neutral-600 dark:text-neutral-100 dark:hover:bg-neutral-800"
|
|
138
|
+
aria-label="Picture-in-picture"
|
|
139
|
+
onClick={() => void requestDisplayMode({ mode: "pip" })}
|
|
140
|
+
>
|
|
141
|
+
<PipIcon />
|
|
142
|
+
</button>
|
|
143
|
+
</Tooltip>
|
|
144
|
+
)}
|
|
145
|
+
{availableDisplayModes.includes("fullscreen") && (
|
|
146
|
+
<Tooltip
|
|
147
|
+
label="MCP Apps display mode: fullscreen"
|
|
148
|
+
multiline
|
|
149
|
+
>
|
|
150
|
+
<button
|
|
151
|
+
type="button"
|
|
152
|
+
className="cursor-pointer rounded-full border border-neutral-300 p-2 text-neutral-900 transition-colors hover:bg-neutral-100 dark:border-neutral-600 dark:text-neutral-100 dark:hover:bg-neutral-800"
|
|
153
|
+
aria-label="Fullscreen"
|
|
154
|
+
onClick={() =>
|
|
155
|
+
void requestDisplayMode({ mode: "fullscreen" })
|
|
156
|
+
}
|
|
157
|
+
>
|
|
158
|
+
<ExpandIcon />
|
|
159
|
+
</button>
|
|
160
|
+
</Tooltip>
|
|
161
|
+
)}
|
|
162
|
+
</>
|
|
163
|
+
)}
|
|
164
|
+
{(isFullscreen || isPip) && (
|
|
165
|
+
<Tooltip
|
|
166
|
+
label="MCP Apps display mode: return to inline"
|
|
167
|
+
multiline
|
|
168
|
+
>
|
|
169
|
+
<button
|
|
170
|
+
type="button"
|
|
171
|
+
className="cursor-pointer rounded-full border border-neutral-300 p-2 text-neutral-900 transition-colors hover:bg-neutral-100 dark:border-neutral-600 dark:text-neutral-100 dark:hover:bg-neutral-800"
|
|
172
|
+
aria-label="Exit"
|
|
173
|
+
onClick={() => void requestDisplayMode({ mode: "inline" })}
|
|
174
|
+
>
|
|
175
|
+
<CloseIcon />
|
|
176
|
+
</button>
|
|
177
|
+
</Tooltip>
|
|
178
|
+
)}
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
)}
|
|
182
|
+
{!isMobile && (
|
|
183
|
+
<button
|
|
184
|
+
type="button"
|
|
185
|
+
className="absolute bottom-6 left-1/2 z-20 flex -translate-x-1/2 cursor-pointer flex-col items-center gap-1 border-0 bg-transparent p-0 text-neutral-900 transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50"
|
|
186
|
+
disabled={!canOpenExternal}
|
|
187
|
+
title="mcp-use on GitHub"
|
|
188
|
+
onClick={() =>
|
|
189
|
+
void openExternal({ url: "https://github.com/mcp-use/mcp-use" })
|
|
190
|
+
}
|
|
191
|
+
>
|
|
192
|
+
<span className="text-[10px] font-medium tracking-wide uppercase">
|
|
193
|
+
Built with
|
|
194
|
+
</span>
|
|
195
|
+
<Image
|
|
196
|
+
src="/logo-mcp-use.svg"
|
|
197
|
+
alt="mcp-use"
|
|
198
|
+
className="h-[1.4rem] w-auto max-w-[115px] object-contain"
|
|
199
|
+
/>
|
|
200
|
+
</button>
|
|
201
|
+
)}
|
|
202
|
+
<div
|
|
203
|
+
className={`relative z-10 flex flex-col items-center text-center ${
|
|
204
|
+
isFullscreen
|
|
205
|
+
? "min-h-0 flex-1 justify-center overflow-y-auto px-6 py-8"
|
|
206
|
+
: isMobile
|
|
207
|
+
? "px-6 py-10"
|
|
208
|
+
: "min-h-[400px] px-8 py-8 pb-16 sm:min-h-[440px] sm:px-10 sm:py-10 sm:pb-16"
|
|
209
|
+
}`}
|
|
210
|
+
>
|
|
211
|
+
{view.status === "error" ? (
|
|
212
|
+
<>
|
|
213
|
+
<h1 className="m-0 text-2xl font-semibold tracking-tight text-neutral-900 dark:text-neutral-100">
|
|
214
|
+
Failed to load MCP App
|
|
215
|
+
</h1>
|
|
216
|
+
<p className="mt-4 mb-0 text-sm text-neutral-600 dark:text-neutral-400">
|
|
217
|
+
{view.error.message}
|
|
218
|
+
</p>
|
|
219
|
+
</>
|
|
220
|
+
) : (
|
|
221
|
+
<>
|
|
222
|
+
{/* ModelContext — push state the host model can read */}
|
|
223
|
+
{!pending && (
|
|
224
|
+
<ModelContext content={`MCP App counter: ${count}`} />
|
|
225
|
+
)}
|
|
226
|
+
<div
|
|
227
|
+
className={`relative z-10 mb-0 flex flex-col items-center gap-3 ${isMobile ? "mt-10" : "mt-3"}`}
|
|
228
|
+
>
|
|
229
|
+
{pending ? (
|
|
230
|
+
<span
|
|
231
|
+
aria-hidden
|
|
232
|
+
className="inline-block h-7 w-[4.75rem] animate-pulse rounded-full bg-zinc-200 dark:bg-zinc-800"
|
|
233
|
+
/>
|
|
234
|
+
) : (
|
|
235
|
+
<button
|
|
236
|
+
type="button"
|
|
237
|
+
className="inline-flex cursor-pointer items-center gap-1 rounded-full border border-neutral-300 bg-transparent px-3 py-1 text-xs font-medium text-neutral-600 transition-colors hover:bg-neutral-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-600 dark:text-neutral-300 dark:hover:bg-neutral-800"
|
|
238
|
+
disabled={!canOpenExternal}
|
|
239
|
+
onClick={() =>
|
|
240
|
+
void openExternal({
|
|
241
|
+
url: "https://mcp-use.com/docs/typescript",
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
>
|
|
245
|
+
Docs
|
|
246
|
+
<ExternalLinkIcon />
|
|
247
|
+
</button>
|
|
248
|
+
)}
|
|
249
|
+
<h1
|
|
250
|
+
className={`hero-title relative z-10 mx-auto mb-0 max-w-md text-center font-medium leading-tight text-neutral-900 dark:text-neutral-100 ${
|
|
251
|
+
isMobile ? "text-2xl" : "text-4xl sm:text-5xl"
|
|
252
|
+
}`}
|
|
253
|
+
>
|
|
254
|
+
{pending ? (
|
|
255
|
+
<span className="inline-block animate-pulse rounded-sm text-transparent select-none bg-zinc-200 dark:bg-zinc-800">
|
|
256
|
+
{view.toolInput?.appName?.trim() || "MCP App"}
|
|
257
|
+
</span>
|
|
258
|
+
) : (
|
|
259
|
+
view.toolInput?.appName?.trim() || "MCP App"
|
|
260
|
+
)}
|
|
261
|
+
</h1>
|
|
262
|
+
</div>
|
|
263
|
+
<p
|
|
264
|
+
className={`relative z-10 mx-auto mt-4 mb-6 max-w-md text-center leading-relaxed text-neutral-600 dark:text-neutral-400 ${isMobile ? "text-sm" : "text-base"}`}
|
|
265
|
+
>
|
|
266
|
+
{pending ? (
|
|
267
|
+
<span className="inline-block animate-pulse rounded-sm text-transparent select-none bg-zinc-200 dark:bg-zinc-800">
|
|
268
|
+
Get started by editing{" "}
|
|
269
|
+
<code className="inline-flex align-middle rounded-md bg-zinc-100 px-1.5 py-0.5 font-mono text-[13px] leading-none text-transparent dark:bg-zinc-800">
|
|
270
|
+
views/my-view/view.tsx
|
|
271
|
+
</code>
|
|
272
|
+
</span>
|
|
273
|
+
) : (
|
|
274
|
+
<>
|
|
275
|
+
Get started by editing{" "}
|
|
276
|
+
<code className="inline-flex align-middle rounded-md bg-zinc-100 px-1.5 py-0.5 font-mono text-[13px] leading-none text-neutral-700 dark:bg-zinc-800 dark:text-neutral-200">
|
|
277
|
+
views/my-view/view.tsx
|
|
278
|
+
</code>
|
|
279
|
+
</>
|
|
280
|
+
)}
|
|
281
|
+
</p>
|
|
282
|
+
<div
|
|
283
|
+
className={`relative z-10 flex w-full flex-wrap items-center justify-center ${isMobile ? "gap-1.5" : "gap-2"}`}
|
|
284
|
+
>
|
|
285
|
+
<Tooltip
|
|
286
|
+
label="Widget state: updates UI and Model Context for the host"
|
|
287
|
+
multiline
|
|
288
|
+
>
|
|
289
|
+
<button
|
|
290
|
+
type="button"
|
|
291
|
+
disabled={pending}
|
|
292
|
+
aria-hidden={pending}
|
|
293
|
+
tabIndex={pending ? -1 : 0}
|
|
294
|
+
className={`inline-flex cursor-pointer items-center gap-1.5 rounded-full bg-black font-normal text-white transition-colors hover:bg-black/90 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-white dark:text-black dark:hover:bg-white/90 ${
|
|
295
|
+
isMobile ? "px-3 py-1.5 text-xs" : "px-4 py-2 text-sm"
|
|
296
|
+
} ${pending ? "animate-pulse opacity-70" : ""}`}
|
|
297
|
+
onClick={() => setCount((c) => c + 1)}
|
|
298
|
+
>
|
|
299
|
+
<span className={pending ? "text-transparent" : undefined}>
|
|
300
|
+
Update State
|
|
301
|
+
</span>
|
|
302
|
+
<span
|
|
303
|
+
className={`rounded-full border tabular-nums ${
|
|
304
|
+
isMobile
|
|
305
|
+
? "px-1 py-0.5 text-[10px]"
|
|
306
|
+
: "px-1.5 py-0.5 text-xs"
|
|
307
|
+
} border-white/35 dark:border-black/25 ${pending ? "text-transparent" : ""}`}
|
|
308
|
+
>
|
|
309
|
+
{count}
|
|
310
|
+
</span>
|
|
311
|
+
</button>
|
|
312
|
+
</Tooltip>
|
|
313
|
+
<Tooltip
|
|
314
|
+
label="In-app tool calls: invoke MCP tools from the view"
|
|
315
|
+
multiline
|
|
316
|
+
>
|
|
317
|
+
<button
|
|
318
|
+
type="button"
|
|
319
|
+
disabled={pending || sayHello.isPending}
|
|
320
|
+
aria-hidden={pending}
|
|
321
|
+
tabIndex={pending ? -1 : 0}
|
|
322
|
+
className={`inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-neutral-300 bg-transparent font-normal text-neutral-900 transition-colors hover:bg-neutral-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-600 dark:text-neutral-100 dark:hover:bg-neutral-800 ${
|
|
323
|
+
isMobile ? "px-3 py-1.5 text-xs" : "px-4 py-2 text-sm"
|
|
324
|
+
} ${pending ? "animate-pulse opacity-70" : ""}`}
|
|
325
|
+
onClick={() => void sayHello.callTool({ name: "mcp-use" })}
|
|
326
|
+
>
|
|
327
|
+
<span className={pending ? "text-transparent" : undefined}>
|
|
328
|
+
{sayHello.isPending ? "Saying…" : "Say Hello"}
|
|
329
|
+
</span>
|
|
330
|
+
</button>
|
|
331
|
+
</Tooltip>
|
|
332
|
+
<Tooltip
|
|
333
|
+
label="Follow-up messages: send a prompt back to the MCP host"
|
|
334
|
+
multiline
|
|
335
|
+
>
|
|
336
|
+
<button
|
|
337
|
+
type="button"
|
|
338
|
+
disabled={pending || !canSendFollowUp}
|
|
339
|
+
aria-hidden={pending}
|
|
340
|
+
tabIndex={pending ? -1 : 0}
|
|
341
|
+
className={`inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-neutral-300 bg-transparent font-normal text-neutral-900 transition-colors hover:bg-neutral-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-600 dark:text-neutral-100 dark:hover:bg-neutral-800 ${
|
|
342
|
+
isMobile ? "px-3 py-1.5 text-xs" : "px-4 py-2 text-sm"
|
|
343
|
+
} ${pending ? "animate-pulse opacity-70" : ""}`}
|
|
344
|
+
onClick={() =>
|
|
345
|
+
void sendFollowUp({
|
|
346
|
+
prompt:
|
|
347
|
+
"Tell me more about MCP Apps and views in mcp-use",
|
|
348
|
+
}).catch(() => {})
|
|
349
|
+
}
|
|
350
|
+
>
|
|
351
|
+
<span className={pending ? "text-transparent" : undefined}>
|
|
352
|
+
Send Followup
|
|
353
|
+
</span>
|
|
354
|
+
</button>
|
|
355
|
+
</Tooltip>
|
|
356
|
+
</div>
|
|
357
|
+
{!pending && callResult !== undefined && (
|
|
358
|
+
<p className="mx-auto mt-4 mb-0 text-center text-sm text-neutral-600 dark:text-neutral-400">
|
|
359
|
+
Tool Response: {callResult}
|
|
360
|
+
</p>
|
|
361
|
+
)}
|
|
362
|
+
{!pending && sayHello.error !== undefined && (
|
|
363
|
+
<p className="mt-4 mb-0 text-sm text-red-500" role="alert">
|
|
364
|
+
{sayHello.error.message}
|
|
365
|
+
</p>
|
|
366
|
+
)}
|
|
367
|
+
</>
|
|
368
|
+
)}
|
|
369
|
+
</div>
|
|
370
|
+
{isMobile && !isFullscreen && (
|
|
371
|
+
<div className="relative w-full">
|
|
372
|
+
<HeroMeshOrb flow />
|
|
373
|
+
<button
|
|
374
|
+
type="button"
|
|
375
|
+
className="absolute bottom-3 left-1/2 z-20 flex -translate-x-1/2 cursor-pointer flex-col items-center gap-1 border-0 bg-transparent p-0 text-neutral-900 transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50"
|
|
376
|
+
disabled={!canOpenExternal}
|
|
377
|
+
title="mcp-use on GitHub"
|
|
378
|
+
onClick={() =>
|
|
379
|
+
void openExternal({ url: "https://github.com/mcp-use/mcp-use" })
|
|
380
|
+
}
|
|
381
|
+
>
|
|
382
|
+
<span className="text-[10px] font-medium tracking-wide uppercase">
|
|
383
|
+
Built with
|
|
384
|
+
</span>
|
|
385
|
+
<Image
|
|
386
|
+
src="/logo-mcp-use.svg"
|
|
387
|
+
alt="mcp-use"
|
|
388
|
+
className="h-[1.15rem] w-auto max-w-[98px] object-contain"
|
|
389
|
+
/>
|
|
390
|
+
</button>
|
|
391
|
+
</div>
|
|
392
|
+
)}
|
|
393
|
+
</div>
|
|
394
|
+
</ThemeProvider>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
@@ -11,9 +11,11 @@ npm install
|
|
|
11
11
|
npm run dev
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
Open [http://localhost:3000/inspector](http://localhost:3000/inspector) with your browser to test your server.
|
|
14
|
+
Open [http://localhost:3000/mcp/inspector](http://localhost:3000/mcp/inspector) with your browser to test your server.
|
|
15
15
|
|
|
16
|
-
You can start building by editing the entry file. Add tools
|
|
16
|
+
You can start building by editing the entry file. Add tools and prompts — the server auto-reloads as you edit.
|
|
17
|
+
|
|
18
|
+
Run `npm run typecheck` to refresh MCP view types and check the project with its local TypeScript compiler.
|
|
17
19
|
|
|
18
20
|
## Learn More
|
|
19
21
|
|
|
@@ -8,7 +8,7 @@ const server = new MCPServer({
|
|
|
8
8
|
description: "An MCP server built with mcp-use",
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
server.tool(
|
|
11
|
+
export const fetchWeather = server.tool(
|
|
12
12
|
{
|
|
13
13
|
name: "fetch-weather",
|
|
14
14
|
description: "Return demo weather for a city",
|
|
@@ -29,24 +29,6 @@ server.tool(
|
|
|
29
29
|
}
|
|
30
30
|
);
|
|
31
31
|
|
|
32
|
-
server.resource(
|
|
33
|
-
{
|
|
34
|
-
name: "settings",
|
|
35
|
-
uri: "config://settings",
|
|
36
|
-
description: "Example application settings",
|
|
37
|
-
mimeType: "application/json",
|
|
38
|
-
},
|
|
39
|
-
async (uri) => ({
|
|
40
|
-
contents: [
|
|
41
|
-
{
|
|
42
|
-
uri: uri.href,
|
|
43
|
-
mimeType: "application/json",
|
|
44
|
-
text: JSON.stringify({ theme: "dark", language: "en" }),
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
})
|
|
48
|
-
);
|
|
49
|
-
|
|
50
32
|
server.prompt(
|
|
51
33
|
{
|
|
52
34
|
name: "review-code",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-use server",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=22.22.2"
|
|
6
|
+
},
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"description": "an mcp-use server",
|
|
9
|
+
"author": "mcp-use",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/mcp-use/mcp-use",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mcp",
|
|
14
|
+
"mcp-server",
|
|
15
|
+
"chatgpt plugins",
|
|
16
|
+
"claude connector",
|
|
17
|
+
"mcp-app",
|
|
18
|
+
"mcp-use",
|
|
19
|
+
"manufact"
|
|
20
|
+
],
|
|
21
|
+
"main": "dist/index.js",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "mcp-use build",
|
|
24
|
+
"dev": "mcp-use dev",
|
|
25
|
+
"start": "mcp-use start",
|
|
26
|
+
"deploy": "mcp-use deploy",
|
|
27
|
+
"typecheck": "mcp-use typecheck"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"mcp-use": "workspace:*",
|
|
31
|
+
"zod": "^4.4.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.20.0",
|
|
35
|
+
"typescript": "^7.0.2"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
"lib": ["ES2024", "DOM", "DOM.Iterable"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"noUncheckedSideEffectImports": false
|
|
14
|
+
},
|
|
15
|
+
"include": [
|
|
16
|
+
"index.ts",
|
|
17
|
+
"mcp-env.d.ts",
|
|
18
|
+
"src/**/*",
|
|
19
|
+
"views/**/*",
|
|
20
|
+
"server.ts",
|
|
21
|
+
".mcp-use/**/*.d.ts"
|
|
22
|
+
],
|
|
23
|
+
"exclude": ["node_modules", "dist"]
|
|
24
|
+
}
|