Skip to content

Commit b5bd887

Browse files
authored
feat: introduce UI5 Web Components for React MCP Server (#8418)
Closes #7925
1 parent 033be84 commit b5bd887

46 files changed

Lines changed: 5222 additions & 219 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Publish to MCP Registry
2+
3+
on:
4+
workflow_call:
5+
workflow_dispatch:
6+
inputs:
7+
dry_run:
8+
description: 'Run in dry-run mode (install and login only, no publishing)'
9+
required: false
10+
type: boolean
11+
12+
permissions:
13+
id-token: write
14+
contents: read
15+
16+
jobs:
17+
publish-mcp-registry:
18+
runs-on: ubuntu-latest
19+
defaults:
20+
run:
21+
working-directory: packages/mcp-server
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
25+
26+
- name: Install mcp-publisher
27+
run: |
28+
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
29+
30+
- name: Authenticate to MCP Registry
31+
run: ./mcp-publisher login github-oidc
32+
33+
- name: Publish server to MCP Registry
34+
if: ${{ inputs.dry_run != true }}
35+
run: ./mcp-publisher publish

.github/workflows/release.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,11 @@ jobs:
148148
const { default: addIssueComments } = await import('${{ github.workspace }}/.github/createIssueCommentsForRelease.mjs');
149149
150150
await addIssueComments({ github, context })
151+
152+
publish-mcp-registry:
153+
needs: ['build-and-release']
154+
if: ${{ github.event.inputs.snapshot == 'false' && github.event.inputs.prerelease == 'false' }}
155+
uses: './.github/workflows/publish-mcp-registry.yml'
156+
permissions:
157+
id-token: write
158+
contents: read

docs/ProjectTemplates.mdx

Lines changed: 49 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
import { Footer, LabelWithWrapping, ProjectTemplate, TableOfContent } from '@sb/components';
1+
import { Footer, ProjectTemplate, TableOfContent } from '@sb/components';
22
import NextLogo from '@sb/images/logo-nextjs.svg';
33
import ReactRouterLogo from '@sb/images/logo-react-router.svg';
44
import ViteLogo from '@sb/images/logo-vitejs.svg';
55
import { Meta } from '@storybook/addon-docs/blocks';
66
import { FlexBox, FlexBoxJustifyContent, FlexBoxWrap, Label } from '@ui5/webcomponents-react';
7+
import projectTemplates from './project-templates.json';
8+
9+
export const logos = {
10+
nextjs: NextLogo,
11+
vite: ViteLogo,
12+
'react-router': ReactRouterLogo,
13+
};
14+
15+
export const repoBase = 'https://github.com/UI5/webcomponents-react/tree/main/';
716

817
<Meta title="Project Templates & Examples" />
918

@@ -18,113 +27,52 @@ A curated list of minimal project templates and examples to get started using UI
1827
<br />
1928

2029
<FlexBox wrap={FlexBoxWrap.Wrap} style={{ width: '100%', gap: '1rem' }} justifyContent={FlexBoxJustifyContent.Start}>
21-
<ProjectTemplate
22-
title={'Next.js'}
23-
subtitle={'App Router'}
24-
logo={NextLogo}
25-
logoAttribution={'Next.js Logo. Original Source: https://vercel.com/design/brands#next-js'}
26-
href={'https://github.com/UI5/webcomponents-react/tree/main/templates/nextjs-app'}
27-
stackBlitzHref="https://stackblitz.com/github/UI5/webcomponents-react/tree/main/templates/nextjs-app"
28-
isTypeScript
29-
isTemplate
30-
/>
31-
<ProjectTemplate
32-
title={'Next.js'}
33-
subtitle={'Pages Router'}
34-
logo={NextLogo}
35-
logoAttribution={'Next.js Logo. Original Source: https://vercel.com/design/brands#next-js'}
36-
href={'https://github.com/UI5/webcomponents-react/tree/main/templates/nextjs-pages'}
37-
isTypeScript
38-
isTemplate
39-
/>
40-
<ProjectTemplate
41-
title={'Vite.js'}
42-
logo={ViteLogo}
43-
logoAttribution={'Vite.js Logo. Original Source: https://github.com/vitejs/vite/blob/main/docs/public/logo.svg '}
44-
href={'https://github.com/UI5/webcomponents-react/tree/main/templates/vite-ts'}
45-
isTypeScript
46-
isTemplate
47-
stackBlitzHref="https://stackblitz.com/github/UI5/webcomponents-react/tree/main/templates/vite-ts?file=src%2FApp.tsx"
48-
/>
30+
{projectTemplates
31+
.filter((t) => t.type === 'template')
32+
.map((t) => (
33+
<ProjectTemplate
34+
key={t.path}
35+
title={t.name}
36+
subtitle={t.variant}
37+
logo={logos[t.logo]}
38+
logoAttribution={t.logoAttribution}
39+
href={`${repoBase}${t.path}`}
40+
stackBlitzHref={t.stackBlitz}
41+
isTypeScript={t.typescript}
42+
isTemplate
43+
/>
44+
))}
4945
</FlexBox>
5046

5147
## Examples
5248

5349
<br />
5450

5551
<FlexBox wrap={FlexBoxWrap.Wrap} style={{ width: '100%', gap: '1rem' }} justifyContent={FlexBoxJustifyContent.Start}>
56-
<ProjectTemplate
57-
title={'Next.js'}
58-
subtitle={'App Router'}
59-
logo={NextLogo}
60-
logoAttribution={'Next.js Logo. Original Source: https://vercel.com/design/brands#next-js'}
61-
href={'https://github.com/UI5/webcomponents-react/tree/main/examples/nextjs-app'}
62-
stackBlitzHref="https://stackblitz.com/github/UI5/webcomponents-react/tree/main/examples/nextjs-app"
63-
isTypeScript
64-
>
65-
<ul>
66-
<li>
67-
<Label>Next.js Template using the App Router</Label>
68-
</li>
69-
<li>
70-
<Label>Data Fetching using React Server Components</Label>
71-
</li>
72-
</ul>
73-
</ProjectTemplate>
74-
<ProjectTemplate
75-
title={'Next.js'}
76-
subtitle={'Pages Router'}
77-
logo={NextLogo}
78-
logoAttribution={'Next.js Logo. Original Source: https://vercel.com/design/brands#next-js'}
79-
href={'https://github.com/UI5/webcomponents-react/tree/main/examples/nextjs-pages'}
80-
isTypeScript
81-
>
82-
<ul>
83-
<li>
84-
<Label>Next.js Template using the Pages Router</Label>
85-
</li>
86-
<li>
87-
<Label>API Routes</Label>
88-
</li>
89-
</ul>
90-
</ProjectTemplate>
91-
<ProjectTemplate
92-
title={'Vite.js'}
93-
logo={ViteLogo}
94-
logoAttribution={'Vite.js Logo. Original Source: https://github.com/vitejs/vite/blob/main/docs/public/logo.svg '}
95-
href={'https://github.com/UI5/webcomponents-react/tree/main/examples/vite-ts'}
96-
isTypeScript
97-
stackBlitzHref="https://stackblitz.com/github/UI5/webcomponents-react/tree/main/examples/vite-ts?file=src%2Fmain.tsx"
98-
>
99-
<ul>
100-
<li>
101-
<LabelWithWrapping>{`Routing and Data Fetching using the createBrowserRouter of React Router v7`}</LabelWithWrapping>
102-
</li>
103-
<li>
104-
<Label>Cypress Component & E2E Test setup</Label>
105-
</li>
106-
<li>
107-
<Label>Theming</Label>
108-
</li>
109-
</ul>
110-
</ProjectTemplate>
111-
<ProjectTemplate
112-
title={'React Router v7'}
113-
subtitle={'Previously: Remix Template'}
114-
logo={ReactRouterLogo}
115-
logoAttribution={'React Router Logo. Original Source: https://reactrouter.com'}
116-
href={'https://github.com/UI5/webcomponents-react/tree/main/examples/react-router-ts'}
117-
isTypeScript
118-
>
119-
<ul>
120-
<li>
121-
<Label>{`React Router v7 with server side rendering`}</Label>
122-
</li>
123-
<li>
124-
<Label>Theming</Label>
125-
</li>
126-
</ul>
127-
</ProjectTemplate>
52+
{projectTemplates
53+
.filter((t) => t.type === 'example')
54+
.map((t) => (
55+
<ProjectTemplate
56+
key={t.path}
57+
title={t.name}
58+
subtitle={t.variant}
59+
logo={logos[t.logo]}
60+
logoAttribution={t.logoAttribution}
61+
href={`${repoBase}${t.path}`}
62+
stackBlitzHref={t.stackBlitz}
63+
isTypeScript={t.typescript}
64+
>
65+
{t.features && (
66+
<ul>
67+
{t.features.map((f) => (
68+
<li key={f}>
69+
<Label>{f}</Label>
70+
</li>
71+
))}
72+
</ul>
73+
)}
74+
</ProjectTemplate>
75+
))}
12876
</FlexBox>
12977

13078
<Footer />

docs/project-templates.json

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
[
2+
{
3+
"name": "Next.js",
4+
"variant": "App Router",
5+
"framework": "nextjs",
6+
"type": "template",
7+
"path": "templates/nextjs-app",
8+
"typescript": true,
9+
"stackBlitz": "https://stackblitz.com/github/UI5/webcomponents-react/tree/main/templates/nextjs-app",
10+
"logo": "nextjs",
11+
"logoAttribution": "Next.js Logo. Original Source: https://vercel.com/design/brands#next-js"
12+
},
13+
{
14+
"name": "Next.js",
15+
"variant": "Pages Router",
16+
"framework": "nextjs",
17+
"type": "template",
18+
"path": "templates/nextjs-pages",
19+
"typescript": true,
20+
"logo": "nextjs",
21+
"logoAttribution": "Next.js Logo. Original Source: https://vercel.com/design/brands#next-js"
22+
},
23+
{
24+
"name": "Vite.js",
25+
"framework": "vite",
26+
"type": "template",
27+
"path": "templates/vite-ts",
28+
"typescript": true,
29+
"stackBlitz": "https://stackblitz.com/github/UI5/webcomponents-react/tree/main/templates/vite-ts?file=src%2FApp.tsx",
30+
"logo": "vite",
31+
"logoAttribution": "Vite.js Logo. Original Source: https://github.com/vitejs/vite/blob/main/docs/public/logo.svg"
32+
},
33+
{
34+
"name": "Next.js",
35+
"variant": "App Router",
36+
"framework": "nextjs",
37+
"type": "example",
38+
"path": "examples/nextjs-app",
39+
"typescript": true,
40+
"stackBlitz": "https://stackblitz.com/github/UI5/webcomponents-react/tree/main/examples/nextjs-app",
41+
"logo": "nextjs",
42+
"logoAttribution": "Next.js Logo. Original Source: https://vercel.com/design/brands#next-js",
43+
"features": ["Next.js Template using the App Router", "Data Fetching using React Server Components"]
44+
},
45+
{
46+
"name": "Next.js",
47+
"variant": "Pages Router",
48+
"framework": "nextjs",
49+
"type": "example",
50+
"path": "examples/nextjs-pages",
51+
"typescript": true,
52+
"logo": "nextjs",
53+
"logoAttribution": "Next.js Logo. Original Source: https://vercel.com/design/brands#next-js",
54+
"features": ["Next.js Template using the Pages Router", "API Routes"]
55+
},
56+
{
57+
"name": "Vite.js",
58+
"framework": "vite",
59+
"type": "example",
60+
"path": "examples/vite-ts",
61+
"typescript": true,
62+
"stackBlitz": "https://stackblitz.com/github/UI5/webcomponents-react/tree/main/examples/vite-ts?file=src%2Fmain.tsx",
63+
"logo": "vite",
64+
"logoAttribution": "Vite.js Logo. Original Source: https://github.com/vitejs/vite/blob/main/docs/public/logo.svg",
65+
"features": [
66+
"Routing and Data Fetching using the createBrowserRouter of React Router v7",
67+
"Cypress Component & E2E Test setup",
68+
"Theming"
69+
]
70+
},
71+
{
72+
"name": "React Router v7",
73+
"variant": "Previously: Remix Template",
74+
"framework": "react-router",
75+
"type": "example",
76+
"path": "examples/react-router-ts",
77+
"typescript": true,
78+
"logo": "react-router",
79+
"logoAttribution": "React Router Logo. Original Source: https://reactrouter.com",
80+
"features": ["React Router v7 with server side rendering", "Theming"]
81+
}
82+
]

eslint.config.mjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const ignorePatterns = {
2020
'packages/compat/dist',
2121
'packages/main/dist',
2222
'packages/main/wrappers',
23+
'packages/mcp-server/dist',
24+
'packages/mcp-server/scripts',
2325
'packages/main/src/i18n/i18n-defaults.ts',
2426
'packages/main/src/generated',
2527
'packages/cypress-commands/dist',
@@ -60,7 +62,7 @@ const config = tseslint.config(
6062

6163
parserOptions: {
6264
projectService: {
63-
allowDefaultProject: ['packages/*/postcss.config.mjs'],
65+
allowDefaultProject: ['packages/*/postcss.config.mjs', 'packages/*/ava.config.js'],
6466
// eslint-disable-next-line camelcase
6567
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING: 1000,
6668
},
@@ -253,7 +255,7 @@ const config = tseslint.config(
253255
},
254256

255257
{
256-
files: ['packages/cli/**/*', 'scripts/**/*', '.github/**/*', 'config/**/*'],
258+
files: ['packages/cli/**/*', 'packages/mcp-server/**/*', 'scripts/**/*', '.github/**/*', 'config/**/*'],
257259
languageOptions: {
258260
globals: {
259261
...globals.node,

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"create-cypress-commands-docs": "documentation build ./packages/cypress-commands/src/commands.ts -f json -o ./packages/cypress-commands/api-commands.json && documentation build ./packages/cypress-commands/src/queries.ts -f json -o ./packages/cypress-commands/api-queries.json",
3737
"sb:prepare-cem": "node packages/cli/dist/bin/index.js resolve-cem --packageName @ui5/webcomponents --out ./.storybook/custom-element-manifests/main.json && node packages/cli/dist/bin/index.js resolve-cem --packageName @ui5/webcomponents-fiori --out ./.storybook/custom-element-manifests/fiori.json && node packages/cli/dist/bin/index.js resolve-cem --packageName @ui5/webcomponents-ai --out ./.storybook/custom-element-manifests/ai.json",
3838
"create-theming-parameters": "node scripts/generate-theming-parameters.js",
39-
"create-exports": "node --experimental-strip-types scripts/create-export-paths.ts"
39+
"create-exports": "node --experimental-strip-types scripts/create-export-paths.ts",
40+
"build:mcp": "yarn workspace @ui5/webcomponents-react-mcp update"
4041
},
4142
"dependencies": {
4243
"@stackblitz/sdk": "1.11.0",

0 commit comments

Comments
 (0)