@webiny/mcp 0.0.0-unstable.f6dc066313

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.
Files changed (47) hide show
  1. package/Extension.d.ts +2 -0
  2. package/Extension.js +11 -0
  3. package/Extension.js.map +1 -0
  4. package/LICENSE +21 -0
  5. package/README.md +11 -0
  6. package/agents/claude.d.ts +15 -0
  7. package/agents/claude.js +33 -0
  8. package/agents/claude.js.map +1 -0
  9. package/agents/cline.d.ts +17 -0
  10. package/agents/cline.js +29 -0
  11. package/agents/cline.js.map +1 -0
  12. package/agents/copilot.d.ts +17 -0
  13. package/agents/copilot.js +64 -0
  14. package/agents/copilot.js.map +1 -0
  15. package/agents/cursor.d.ts +15 -0
  16. package/agents/cursor.js +33 -0
  17. package/agents/cursor.js.map +1 -0
  18. package/agents/instructions.d.ts +7 -0
  19. package/agents/instructions.js +13 -0
  20. package/agents/instructions.js.map +1 -0
  21. package/agents/shared.d.ts +41 -0
  22. package/agents/shared.js +124 -0
  23. package/agents/shared.js.map +1 -0
  24. package/agents/windsurf.d.ts +15 -0
  25. package/agents/windsurf.js +33 -0
  26. package/agents/windsurf.js.map +1 -0
  27. package/cli/ConfigureMcp.d.ts +15 -0
  28. package/cli/ConfigureMcp.js +57 -0
  29. package/cli/ConfigureMcp.js.map +1 -0
  30. package/cli/McpServer.d.ts +12 -0
  31. package/cli/McpServer.js +239 -0
  32. package/cli/McpServer.js.map +1 -0
  33. package/index.d.ts +1 -0
  34. package/index.js +3 -0
  35. package/index.js.map +1 -0
  36. package/package.json +49 -0
  37. package/skills/admin-ui-extensions/SKILL.md +267 -0
  38. package/skills/cli-extensions/SKILL.md +133 -0
  39. package/skills/content-models/SKILL.md +306 -0
  40. package/skills/custom-graphql-api/SKILL.md +199 -0
  41. package/skills/dependency-injection/SKILL.md +252 -0
  42. package/skills/infrastructure-extensions/SKILL.md +192 -0
  43. package/skills/lifecycle-events/SKILL.md +203 -0
  44. package/skills/local-development/SKILL.md +245 -0
  45. package/skills/project-structure/SKILL.md +156 -0
  46. package/skills/webiny-sdk/SKILL.md +271 -0
  47. package/skills/website-builder/SKILL.md +384 -0
@@ -0,0 +1,267 @@
1
+ ---
2
+ name: webiny-admin-ui-extensions
3
+ context: webiny-extensions
4
+ description: >
5
+ Customizing the Webiny Admin UI -- white-labeling, custom data list columns, page-type forms,
6
+ and Lexical editor plugins. Use this skill when the developer wants to change branding (logo,
7
+ title, theme colors), add custom columns to content entry list views, create custom forms
8
+ for Website Builder page types, or extend the Lexical rich text editor. Covers AdminConfig,
9
+ ContentEntryListConfig, Browser.Table.Column, Bind, useForm, and form validation.
10
+ ---
11
+
12
+ # Admin UI Extensions
13
+
14
+ ## TL;DR
15
+
16
+ Admin extensions customize the Webiny Admin application. There are three main categories: **white-labeling** (logos, titles, theme colors), **custom data list columns** (adding columns to content entry tables), and **custom page-type forms** (custom form fields for Website Builder page types). All are React components registered via `<Admin.Extension>` in `webiny.config.tsx`.
17
+
18
+ ## White-Labeling
19
+
20
+ ### Theme Colors
21
+
22
+ ```tsx
23
+ // extensions/AdminBranding/AdminTheme.tsx
24
+ import React from "react";
25
+ import { AdminConfig } from "webiny/admin/configs";
26
+
27
+ const { Theme } = AdminConfig;
28
+
29
+ const AdminTheme = () => {
30
+ return (
31
+ <AdminConfig.Public>
32
+ <Theme.Color palette={"primary"} color={"purple"} />
33
+ <Theme.Color palette={"secondary"} color={"green"} />
34
+ </AdminConfig.Public>
35
+ );
36
+ };
37
+
38
+ export default AdminTheme;
39
+ ```
40
+
41
+ - `palette` -- `"primary"`, `"secondary"`, `"neutral"`, etc.
42
+ - `color` -- any CSS color value: named colors, hex (`"#6B46C1"`), or RGB.
43
+
44
+ ### Logo and Title
45
+
46
+ ```tsx
47
+ // extensions/AdminBranding/AdminTitleLogo.tsx
48
+ import React from "react";
49
+ import { AdminConfig } from "webiny/admin/configs";
50
+ import squareLogo from "./logo.png";
51
+ import horizontalLogo from "./logo.png";
52
+
53
+ const { Title, Logo } = AdminConfig;
54
+
55
+ const AdminTitleLogo = () => {
56
+ return (
57
+ <AdminConfig.Public>
58
+ <Title value={"ACME Corp"} />
59
+ <Logo
60
+ squareLogo={<img src={squareLogo} alt={"ACME Corp"} />}
61
+ horizontalLogo={<img src={horizontalLogo} alt={"ACME Corp"} />}
62
+ />
63
+ </AdminConfig.Public>
64
+ );
65
+ };
66
+
67
+ export default AdminTitleLogo;
68
+ ```
69
+
70
+ Register both:
71
+
72
+ ```tsx
73
+ <Admin.Extension src={"/extensions/AdminBranding/AdminTheme.tsx"} />
74
+ <Admin.Extension src={"/extensions/AdminBranding/AdminTitleLogo.tsx"} />
75
+ ```
76
+
77
+ ### Available AdminConfig Components
78
+
79
+ | Component | Purpose |
80
+ |---|---|
81
+ | `<Theme.Color palette="..." color="..." />` | Set theme color palette |
82
+ | `<Title value="..." />` | Set the Admin app title |
83
+ | `<Logo squareLogo={...} horizontalLogo={...} />` | Set square and horizontal logos |
84
+
85
+ All must be wrapped in `<AdminConfig.Public>`.
86
+
87
+ ## Custom Data List Columns
88
+
89
+ Add custom columns to the content entry list view in the Admin UI. Columns can be restricted to specific content models.
90
+
91
+ ### Full Example: Email Columns for Contact Submissions
92
+
93
+ ```tsx
94
+ // extensions/contactSubmission/EmailEntryListColumn.tsx
95
+ import React from "react";
96
+ import { ContentEntryListConfig } from "webiny/admin/cms/entry/list";
97
+
98
+ const { Browser } = ContentEntryListConfig;
99
+
100
+ // Custom cell component for the Email Type column
101
+ interface ContactSubmissionTableRow {
102
+ values: {
103
+ emailType: "work" | "personal";
104
+ };
105
+ }
106
+
107
+ export const EmailTypeCell = () => {
108
+ const { useTableRow, isFolderRow } = ContentEntryListConfig.Browser.Table.Column;
109
+ const { row } = useTableRow<ContactSubmissionTableRow>();
110
+
111
+ if (isFolderRow(row)) {
112
+ return <>{"-"}</>;
113
+ }
114
+
115
+ const emailType = row.data.values.emailType;
116
+ return emailType === "work" ? <>{"Business"}</> : <>{"Personal"}</>;
117
+ };
118
+
119
+ // Main extension component
120
+ const EmailEntryListColumn = () => {
121
+ return (
122
+ <ContentEntryListConfig>
123
+ {/* Simple column using path (no custom cell needed) */}
124
+ <Browser.Table.Column
125
+ name={"email"}
126
+ after={"name"}
127
+ path={"values.email"}
128
+ header={"Email"}
129
+ modelIds={["contactSubmission"]}
130
+ />
131
+ {/* Custom cell column */}
132
+ <Browser.Table.Column
133
+ name={"emailType"}
134
+ after={"email"}
135
+ header={"Email Type"}
136
+ modelIds={["contactSubmission"]}
137
+ cell={<EmailTypeCell />}
138
+ />
139
+ </ContentEntryListConfig>
140
+ );
141
+ };
142
+
143
+ export default EmailEntryListColumn;
144
+ ```
145
+
146
+ Register:
147
+
148
+ ```tsx
149
+ <Admin.Extension src={"/extensions/contactSubmission/EmailEntryListColumn.tsx"} />
150
+ ```
151
+
152
+ ### Column Props Reference
153
+
154
+ | Prop | Type | Description |
155
+ |---|---|---|
156
+ | `name` | `string` | Unique column identifier |
157
+ | `header` | `string` | Column header text |
158
+ | `path` | `string` | Dot-path to the data field (e.g., `"values.email"`) -- for simple columns |
159
+ | `cell` | `ReactElement` | Custom React component for complex rendering |
160
+ | `modelIds` | `string[]` | Restrict column to specific content models |
161
+ | `after` | `string` | Position this column after another column by name |
162
+
163
+ ### Custom Cell Hooks
164
+
165
+ Inside a custom `cell` component:
166
+
167
+ - `useTableRow<T>()` -- access the full row data, typed with your interface
168
+ - `isFolderRow(row)` -- check if the current row is a folder (return placeholder content)
169
+
170
+ ## Custom Page-Type Forms
171
+
172
+ Create custom forms for Website Builder page types using Webiny's form components:
173
+
174
+ ```tsx
175
+ // extensions/customPageTypes/RetailPageForm.tsx
176
+ import React from "react";
177
+ import { Grid, Input, Select } from "webiny/admin/ui";
178
+ import { pagePathFromTitle } from "webiny/admin/website-builder";
179
+ import type { FormApi } from "webiny/admin/form";
180
+ import { Bind, UnsetOnUnmount, useForm, validation } from "webiny/admin/form";
181
+
182
+ const generatePath = (form: FormApi) => () => {
183
+ const title = form.getValue("properties.title");
184
+ const language = form.getValue("extensions.language");
185
+
186
+ const titlePath = pagePathFromTitle(title ?? "");
187
+ const parts = [language, titlePath].filter(Boolean);
188
+
189
+ form.setValue("properties.path", `/${parts.join("/")}`);
190
+ };
191
+
192
+ export const RetailPageForm = () => {
193
+ const form = useForm();
194
+
195
+ return (
196
+ <>
197
+ <Grid.Column span={12}>
198
+ <UnsetOnUnmount name={"properties.title"}>
199
+ <Bind name={"properties.title"} validators={[validation.create("required")]}>
200
+ <Input label={"Title"} onBlur={generatePath(form)} />
201
+ </Bind>
202
+ </UnsetOnUnmount>
203
+ </Grid.Column>
204
+ <Grid.Column span={12}>
205
+ <UnsetOnUnmount name={"extensions.language"}>
206
+ <Bind
207
+ name={"extensions.language"}
208
+ validators={[validation.create("required")]}
209
+ afterChange={generatePath(form)}
210
+ >
211
+ <Select
212
+ placeholder={"Select a language"}
213
+ label={"Language"}
214
+ options={[
215
+ { label: "English", value: "en" },
216
+ { label: "German", value: "de" },
217
+ { label: "French", value: "fr" }
218
+ ]}
219
+ />
220
+ </Bind>
221
+ </UnsetOnUnmount>
222
+ </Grid.Column>
223
+ <Grid.Column span={12}>
224
+ <UnsetOnUnmount name={"properties.path"}>
225
+ <Bind name={"properties.path"} validators={[validation.create("required")]}>
226
+ <Input label={"Path"} />
227
+ </Bind>
228
+ </UnsetOnUnmount>
229
+ </Grid.Column>
230
+ </>
231
+ );
232
+ };
233
+ ```
234
+
235
+ ### Form Components Reference
236
+
237
+ | Component / Hook | Import | Purpose |
238
+ |---|---|---|
239
+ | `Bind` | `"webiny/admin/form"` | Bind a form field to a name path |
240
+ | `useForm()` | `"webiny/admin/form"` | Access the form API (`getValue`, `setValue`) |
241
+ | `validation` | `"webiny/admin/form"` | Create validators (`validation.create("required")`) |
242
+ | `UnsetOnUnmount` | `"webiny/admin/form"` | Clear the field value when the component unmounts |
243
+ | `Grid.Column` | `"webiny/admin/ui"` | Layout grid column (`span={12}` for full width) |
244
+ | `Input` | `"webiny/admin/ui"` | Text input field |
245
+ | `Select` | `"webiny/admin/ui"` | Dropdown select with options |
246
+ | `FormApi` | `"webiny/admin/form"` | Type for the form API object |
247
+
248
+ ## Lexical Editor Plugins
249
+
250
+ Admin extensions can also add custom plugins to the Lexical rich text editor used in both the Headless CMS and the Website Builder. These are registered as `<Admin.Extension>` and use imports from `"webiny/admin/lexical"`, `"webiny/admin/cms/lexical"`, and `"webiny/admin/website-builder/lexical"`.
251
+
252
+ ## Quick Reference
253
+
254
+ ```
255
+ White-label import: import { AdminConfig } from "webiny/admin/configs";
256
+ Data list import: import { ContentEntryListConfig } from "webiny/admin/cms/entry/list";
257
+ Form imports: import { Bind, useForm, validation } from "webiny/admin/form";
258
+ UI imports: import { Grid, Input, Select } from "webiny/admin/ui";
259
+ Register: <Admin.Extension src={"/extensions/MyAdminExtension.tsx"} />
260
+ Develop: yarn webiny watch admin
261
+ Deploy: yarn webiny deploy admin
262
+ ```
263
+
264
+ ## Related Skills
265
+
266
+ - `project-structure` -- How to register Admin extensions
267
+ - `content-models` -- Define models that your list columns target
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: webiny-cli-extensions
3
+ context: webiny-extensions
4
+ description: >
5
+ Adding custom commands to the Webiny CLI using CliCommandFactory.
6
+ Use this skill when the developer wants to create a custom CLI command, add a data migration
7
+ script, build a code generator, create deployment scripts, export CMS content, or add
8
+ health check commands. Covers CliCommandFactory.Interface, command definition, typed
9
+ parameters, the Ui service for terminal output, and registration via <Cli.Command>.
10
+ ---
11
+
12
+ # CLI Extensions
13
+
14
+ ## TL;DR
15
+
16
+ Add custom commands to the Webiny CLI using the `CliCommandFactory` pattern. Define a class implementing `CliCommandFactory.Interface<TParams>`, specify command name, description, params, and handler, then export with `CliCommandFactory.createImplementation()`. Register in `webiny.config.tsx` via `<Cli.Command>`.
17
+
18
+ ## The CliCommandFactory Pattern
19
+
20
+ ```typescript
21
+ // extensions/MyCustomCommand.ts
22
+ import { Ui } from "webiny/cli";
23
+ import { CliCommandFactory } from "webiny/cli/command";
24
+
25
+ export interface IMyCustomCommandParams {
26
+ name: string;
27
+ }
28
+
29
+ class MyCustomCommandImpl implements CliCommandFactory.Interface<IMyCustomCommandParams> {
30
+ constructor(private ui: Ui.Interface) {}
31
+
32
+ execute(): CliCommandFactory.CommandDefinition<IMyCustomCommandParams> {
33
+ return {
34
+ name: "my-custom-command",
35
+ description: "This is my custom command",
36
+ examples: [
37
+ "$0 my-custom-command test1",
38
+ "$0 my-custom-command test2"
39
+ ],
40
+ params: [
41
+ {
42
+ name: "name",
43
+ description: "Your name",
44
+ type: "string"
45
+ }
46
+ ],
47
+ handler: async params => {
48
+ this.ui.info("Starting my custom command...");
49
+ this.ui.emptyLine();
50
+ this.ui.success(`Hello, ${params.name}! This is my custom command.`);
51
+ }
52
+ };
53
+ }
54
+ }
55
+
56
+ export default CliCommandFactory.createImplementation({
57
+ implementation: MyCustomCommandImpl,
58
+ dependencies: [Ui]
59
+ });
60
+ ```
61
+
62
+ Register in `webiny.config.tsx`:
63
+
64
+ ```tsx
65
+ <Cli.Command src={"/extensions/MyCustomCommand.ts"} />
66
+ ```
67
+
68
+ Run it:
69
+
70
+ ```bash
71
+ yarn webiny my-custom-command "World"
72
+ ```
73
+
74
+ ## Command Definition Properties
75
+
76
+ | Property | Type | Description |
77
+ |---|---|---|
78
+ | `name` | `string` | The command name used on the CLI (e.g., `"my-custom-command"`) |
79
+ | `description` | `string` | Help text shown when listing commands |
80
+ | `examples` | `string[]` | Usage examples (`$0` is replaced with the CLI binary name) |
81
+ | `params` | `ParamDefinition[]` | Positional parameters and options |
82
+ | `handler` | `(params: TParams) => Promise<void>` | The function that executes the command |
83
+
84
+ ## Parameter Definition
85
+
86
+ Each param in the `params` array:
87
+
88
+ | Property | Type | Description |
89
+ |---|---|---|
90
+ | `name` | `string` | Parameter name (matches the key in your `TParams` interface) |
91
+ | `description` | `string` | Help text for this parameter |
92
+ | `type` | `"string" \| "number" \| "boolean"` | Parameter value type |
93
+
94
+ ## The `Ui` Service
95
+
96
+ Inject `Ui` for formatted terminal output:
97
+
98
+ ```typescript
99
+ import { Ui } from "webiny/cli";
100
+ ```
101
+
102
+ | Method | Description |
103
+ |---|---|
104
+ | `this.ui.info("message")` | Print an info message (blue) |
105
+ | `this.ui.success("message")` | Print a success message (green) |
106
+ | `this.ui.warning("message")` | Print a warning message (yellow) |
107
+ | `this.ui.error("message")` | Print an error message (red) |
108
+ | `this.ui.emptyLine()` | Print a blank line for spacing |
109
+
110
+ ## Use Cases
111
+
112
+ - **Data migrations** -- Scripts to migrate or seed CMS data
113
+ - **Code generators** -- Generate boilerplate extension files
114
+ - **Deployment scripts** -- Custom deployment workflows
115
+ - **Data exports** -- Export CMS content to files
116
+ - **Health checks** -- Verify infrastructure or API status
117
+
118
+ ## Quick Reference
119
+
120
+ ```
121
+ Import: import { CliCommandFactory } from "webiny/cli/command";
122
+ Ui import: import { Ui } from "webiny/cli";
123
+ Interface: CliCommandFactory.Interface<TParams>
124
+ Definition: CliCommandFactory.CommandDefinition<TParams>
125
+ Export: CliCommandFactory.createImplementation({ implementation, dependencies })
126
+ Register: <Cli.Command src={"/extensions/MyCommand.ts"} />
127
+ Run: yarn webiny <command-name> [args]
128
+ ```
129
+
130
+ ## Related Skills
131
+
132
+ - `dependency-injection` -- The `createImplementation` pattern and available injectable services
133
+ - `project-structure` -- How to register CLI commands in `webiny.config.tsx`