create-mcp-use-app 0.6.0 → 0.7.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.
- package/dist/templates/apps-sdk/README.md +6 -4
- package/dist/templates/apps-sdk/resources/product-search-result/components/Accordion.tsx +2 -2
- package/dist/templates/apps-sdk/resources/product-search-result/components/AccordionItem.tsx +4 -6
- package/dist/templates/apps-sdk/resources/product-search-result/components/Carousel.tsx +1 -1
- package/dist/templates/apps-sdk/resources/product-search-result/components/CarouselItem.tsx +1 -1
- package/dist/templates/apps-sdk/resources/product-search-result/widget.tsx +4 -4
- package/dist/templates/apps-sdk/resources/styles.css +115 -0
- package/dist/templates/starter/resources/display-weather.tsx +3 -3
- package/package.json +1 -1
- package/dist/templates/starter/styles.css +0 -11
- /package/dist/templates/{apps-sdk → starter/resources}/styles.css +0 -0
|
@@ -79,13 +79,14 @@ All React components in the `resources/` folder are automatically registered as
|
|
|
79
79
|
|
|
80
80
|
```typescript
|
|
81
81
|
import { z } from 'zod';
|
|
82
|
+
import type { WidgetMetadata } from 'mcp-use/react';
|
|
82
83
|
|
|
83
84
|
const propSchema = z.object({
|
|
84
85
|
city: z.string().describe('The city name'),
|
|
85
86
|
temperature: z.number().describe('Temperature in Celsius'),
|
|
86
87
|
});
|
|
87
88
|
|
|
88
|
-
export const widgetMetadata = {
|
|
89
|
+
export const widgetMetadata: WidgetMetadata = {
|
|
89
90
|
description: 'My widget description',
|
|
90
91
|
inputs: propSchema,
|
|
91
92
|
};
|
|
@@ -135,6 +136,7 @@ Use Zod schemas to define widget inputs:
|
|
|
135
136
|
|
|
136
137
|
```typescript
|
|
137
138
|
import { z } from 'zod';
|
|
139
|
+
import type { WidgetMetadata } from 'mcp-use/react';
|
|
138
140
|
|
|
139
141
|
const propSchema = z.object({
|
|
140
142
|
name: z.string().describe('Person name'),
|
|
@@ -142,7 +144,7 @@ const propSchema = z.object({
|
|
|
142
144
|
email: z.string().email().describe('Email address'),
|
|
143
145
|
});
|
|
144
146
|
|
|
145
|
-
export const widgetMetadata = {
|
|
147
|
+
export const widgetMetadata: WidgetMetadata = {
|
|
146
148
|
description: 'Display user information',
|
|
147
149
|
inputs: propSchema,
|
|
148
150
|
};
|
|
@@ -285,13 +287,13 @@ await client.readResource('ui://widget/display-weather');
|
|
|
285
287
|
```tsx
|
|
286
288
|
import React from 'react';
|
|
287
289
|
import { z } from 'zod';
|
|
288
|
-
import { useWidget } from 'mcp-use/react';
|
|
290
|
+
import { useWidget, type WidgetMetadata } from 'mcp-use/react';
|
|
289
291
|
|
|
290
292
|
const propSchema = z.object({
|
|
291
293
|
message: z.string().describe('Message to display'),
|
|
292
294
|
});
|
|
293
295
|
|
|
294
|
-
export const widgetMetadata = {
|
|
296
|
+
export const widgetMetadata: WidgetMetadata = {
|
|
295
297
|
description: 'Display a message',
|
|
296
298
|
inputs: propSchema,
|
|
297
299
|
};
|
|
@@ -20,9 +20,9 @@ export const Accordion: React.FC<AccordionProps> = ({
|
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
return (
|
|
23
|
-
<div className="p-8 pt-4 border-t border-
|
|
23
|
+
<div className="p-8 pt-4 border-t border-subtle mt-4">
|
|
24
24
|
<h3 className="heading-lg mb-4">{title}</h3>
|
|
25
|
-
<div className="rounded-lg border border-
|
|
25
|
+
<div className="rounded-lg border border-default overflow-hidden">
|
|
26
26
|
{items.map((item, index) => (
|
|
27
27
|
<AccordionItem
|
|
28
28
|
key={index}
|
package/dist/templates/apps-sdk/resources/product-search-result/components/AccordionItem.tsx
CHANGED
|
@@ -9,16 +9,14 @@ export const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
|
9
9
|
onToggle,
|
|
10
10
|
}) => {
|
|
11
11
|
return (
|
|
12
|
-
<div className="border-b border-
|
|
12
|
+
<div className="border-b border-subtle last:border-b-0">
|
|
13
13
|
<button
|
|
14
14
|
type="button"
|
|
15
15
|
onClick={onToggle}
|
|
16
|
-
className="w-full flex items-center justify-between p-4 text-left hover:bg-
|
|
16
|
+
className="w-full flex items-center justify-between p-4 text-left hover:bg-primary-soft-hover transition-colors"
|
|
17
17
|
>
|
|
18
|
-
<span className="font-medium text-
|
|
19
|
-
|
|
20
|
-
</span>
|
|
21
|
-
<span className="text-xl text-gray-500 dark:text-gray-400 transition-transform duration-200">
|
|
18
|
+
<span className="font-medium text-default">{question}</span>
|
|
19
|
+
<span className="text-xl text-tertiary transition-transform duration-200">
|
|
22
20
|
{isOpen ? "−" : "+"}
|
|
23
21
|
</span>
|
|
24
22
|
</button>
|
|
@@ -46,7 +46,7 @@ export const Carousel: React.FC<CarouselProps> = ({ mcpUrl }) => {
|
|
|
46
46
|
</div>
|
|
47
47
|
) : error ? (
|
|
48
48
|
<div className="flex items-center justify-center p-8">
|
|
49
|
-
<p className="text-
|
|
49
|
+
<p className="text-danger">Failed to load fruits</p>
|
|
50
50
|
</div>
|
|
51
51
|
) : (
|
|
52
52
|
<Animate className="flex gap-4">
|
|
@@ -9,7 +9,7 @@ export interface CarouselItemProps {
|
|
|
9
9
|
export const CarouselItem: React.FC<CarouselItemProps> = ({ fruit, color }) => {
|
|
10
10
|
return (
|
|
11
11
|
<div
|
|
12
|
-
className={`carousel-item size-52 rounded-xl border border-
|
|
12
|
+
className={`carousel-item size-52 rounded-xl border border-subtle ${color}`}
|
|
13
13
|
>
|
|
14
14
|
<div className="carousel-item-bg">
|
|
15
15
|
<Image src={"/fruits/" + fruit + ".png"} alt={fruit} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AppsSDKUIProvider } from "@openai/apps-sdk-ui/components/AppsSDKUIProvider";
|
|
2
2
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
-
import { McpUseProvider, useWidget } from "mcp-use/react";
|
|
3
|
+
import { McpUseProvider, useWidget, type WidgetMetadata } from "mcp-use/react";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Link } from "react-router";
|
|
6
6
|
import { Accordion } from "./components/Accordion";
|
|
@@ -8,9 +8,9 @@ import { Carousel } from "./components/Carousel";
|
|
|
8
8
|
import { queryClient } from "./constants";
|
|
9
9
|
import type { ProductSearchResultProps } from "./types";
|
|
10
10
|
import { propSchema } from "./types";
|
|
11
|
-
import "
|
|
11
|
+
import "../styles.css";
|
|
12
12
|
|
|
13
|
-
export const widgetMetadata = {
|
|
13
|
+
export const widgetMetadata: WidgetMetadata = {
|
|
14
14
|
description:
|
|
15
15
|
"Display product search results with filtering, state management, and tool interactions",
|
|
16
16
|
inputs: propSchema,
|
|
@@ -32,7 +32,7 @@ const ProductSearchResult: React.FC = () => {
|
|
|
32
32
|
return (
|
|
33
33
|
<McpUseProvider debugger viewControls autoSize>
|
|
34
34
|
<AppsSDKUIProvider linkComponent={Link}>
|
|
35
|
-
<div className="relative bg-
|
|
35
|
+
<div className="relative bg-surface-elevated border border-default rounded-3xl">
|
|
36
36
|
<div className="p-8">
|
|
37
37
|
<h5 className="text-secondary mb-1">Apps SDK Template</h5>
|
|
38
38
|
<h2 className="heading-xl mb-3">Lovely Little Fruit Shop</h2>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "@openai/apps-sdk-ui/css";
|
|
3
|
+
|
|
4
|
+
/* Configure Tailwind v4 to scan for classes */
|
|
5
|
+
@source "../node_modules/@openai/apps-sdk-ui";
|
|
6
|
+
@source "./**/*.{ts,tsx,js,jsx,html}";
|
|
7
|
+
|
|
8
|
+
@theme {
|
|
9
|
+
/* Enable class-based dark mode */
|
|
10
|
+
--color-scheme: light dark;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@variant dark (&:where(.dark, .dark *));
|
|
14
|
+
|
|
15
|
+
/* Custom styles */
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
font-family:
|
|
19
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
|
|
20
|
+
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
|
21
|
+
-webkit-font-smoothing: antialiased;
|
|
22
|
+
-moz-osx-font-smoothing: grayscale;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
h1,
|
|
26
|
+
h2,
|
|
27
|
+
h3,
|
|
28
|
+
h4,
|
|
29
|
+
h5,
|
|
30
|
+
h6 {
|
|
31
|
+
@apply text-default;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
p {
|
|
35
|
+
@apply text-secondary;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
a {
|
|
39
|
+
@apply text-info;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Carousel scroll container with padding for blur effect */
|
|
43
|
+
.carousel-scroll-container {
|
|
44
|
+
padding-bottom: 2rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Hover effect styles for carousel items */
|
|
48
|
+
.carousel-item {
|
|
49
|
+
position: relative;
|
|
50
|
+
container-type: size;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
transition-property: translate, scale;
|
|
53
|
+
transition-duration: 0.12s;
|
|
54
|
+
transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
55
|
+
-webkit-tap-highlight-color: transparent;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
border-radius: 12px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.carousel-item:active {
|
|
61
|
+
translate: 0 1px;
|
|
62
|
+
scale: 0.99;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.carousel-item-content {
|
|
66
|
+
position: relative;
|
|
67
|
+
z-index: 2;
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 100%;
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.carousel-item-bg {
|
|
76
|
+
position: absolute;
|
|
77
|
+
inset: 0;
|
|
78
|
+
display: grid;
|
|
79
|
+
place-items: center;
|
|
80
|
+
transform: translateZ(0);
|
|
81
|
+
filter: blur(28px) saturate(5) brightness(1.3);
|
|
82
|
+
translate: calc(var(--pointer-x, -10) * 50cqi)
|
|
83
|
+
calc(var(--pointer-y, -10) * 50cqh);
|
|
84
|
+
scale: var(--icon-scale, 3.4);
|
|
85
|
+
opacity: var(--icon-opacity, 0.25);
|
|
86
|
+
will-change: transform, filter, opacity;
|
|
87
|
+
pointer-events: none;
|
|
88
|
+
z-index: 1;
|
|
89
|
+
transition:
|
|
90
|
+
opacity 0.26s ease-out,
|
|
91
|
+
scale 0.26s ease-out;
|
|
92
|
+
border-radius: inherit;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.carousel-item-bg img {
|
|
96
|
+
width: 100px;
|
|
97
|
+
user-select: none;
|
|
98
|
+
-webkit-user-drag: none;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.carousel-item::after {
|
|
102
|
+
content: "";
|
|
103
|
+
position: absolute;
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
inset: 0px;
|
|
106
|
+
border-radius: inherit;
|
|
107
|
+
border: 3px solid transparent;
|
|
108
|
+
backdrop-filter: blur(0px) saturate(4.2) brightness(2.5) contrast(2.5);
|
|
109
|
+
mask:
|
|
110
|
+
linear-gradient(#fff 0 100%) border-box,
|
|
111
|
+
linear-gradient(#fff 0 100%) padding-box;
|
|
112
|
+
mask-composite: exclude;
|
|
113
|
+
z-index: 3;
|
|
114
|
+
transform: translateZ(0);
|
|
115
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { useWidget } from "mcp-use/react";
|
|
4
|
-
import "
|
|
3
|
+
import { useWidget, type WidgetMetadata } from "mcp-use/react";
|
|
4
|
+
import "./styles.css";
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* Apps SDK widget
|
|
@@ -21,7 +21,7 @@ const propSchema = z.object({
|
|
|
21
21
|
.describe("The temperature in Celsius"),
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
export const widgetMetadata = {
|
|
24
|
+
export const widgetMetadata: WidgetMetadata = {
|
|
25
25
|
description: "Display weather for a city",
|
|
26
26
|
inputs: propSchema,
|
|
27
27
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
|
|
3
|
-
/* Custom styles */
|
|
4
|
-
body {
|
|
5
|
-
margin: 0;
|
|
6
|
-
font-family:
|
|
7
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
|
|
8
|
-
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
|
9
|
-
-webkit-font-smoothing: antialiased;
|
|
10
|
-
-moz-osx-font-smoothing: grayscale;
|
|
11
|
-
}
|
|
File without changes
|