@shoppexio/mcp-theme-server 0.1.3 → 0.3.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/package.json +2 -2
- package/src/server.mjs +32 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shoppexio/mcp-theme-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shoppex MCP server for theme control plane operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
41
|
-
"@shoppexio/theme-control-client": "^0.
|
|
41
|
+
"@shoppexio/theme-control-client": "^0.2.0"
|
|
42
42
|
}
|
|
43
43
|
}
|
package/src/server.mjs
CHANGED
|
@@ -22,7 +22,13 @@ function jsonContent(value) {
|
|
|
22
22
|
export function createThemeToolCatalog() {
|
|
23
23
|
return [
|
|
24
24
|
{
|
|
25
|
-
name: '
|
|
25
|
+
name: 'theme_list',
|
|
26
|
+
description: 'List all themes belonging to the authenticated shop. Returns id, name, scheme, version, is_active, preview_url for each theme. Use this first when the user asks about a theme by name — find the id, then call theme_inspect.',
|
|
27
|
+
inputSchema: {},
|
|
28
|
+
execute: (_args, client) => client.listThemes(),
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'theme_inspect',
|
|
26
32
|
description: 'Inspect a Shoppex theme and return editable areas, sections, settings, design tokens, and constraints.',
|
|
27
33
|
inputSchema: {
|
|
28
34
|
theme_id: z.string().min(1),
|
|
@@ -30,7 +36,7 @@ export function createThemeToolCatalog() {
|
|
|
30
36
|
execute: ({ theme_id }, client) => client.inspectTheme(theme_id),
|
|
31
37
|
},
|
|
32
38
|
{
|
|
33
|
-
name: '
|
|
39
|
+
name: 'theme_diff',
|
|
34
40
|
description: 'Show changes between the current draft and the latest published theme snapshot.',
|
|
35
41
|
inputSchema: {
|
|
36
42
|
theme_id: z.string().min(1),
|
|
@@ -38,7 +44,7 @@ export function createThemeToolCatalog() {
|
|
|
38
44
|
execute: ({ theme_id }, client) => client.diffTheme(theme_id),
|
|
39
45
|
},
|
|
40
46
|
{
|
|
41
|
-
name: '
|
|
47
|
+
name: 'theme_read_file',
|
|
42
48
|
description: 'Read a single source file from a Shoppex theme.',
|
|
43
49
|
inputSchema: {
|
|
44
50
|
theme_id: z.string().min(1),
|
|
@@ -47,7 +53,7 @@ export function createThemeToolCatalog() {
|
|
|
47
53
|
execute: ({ theme_id, file_path }, client) => client.readThemeFile(theme_id, file_path),
|
|
48
54
|
},
|
|
49
55
|
{
|
|
50
|
-
name: '
|
|
56
|
+
name: 'theme_search_files',
|
|
51
57
|
description: 'Search theme files by path or content.',
|
|
52
58
|
inputSchema: {
|
|
53
59
|
theme_id: z.string().min(1),
|
|
@@ -57,7 +63,7 @@ export function createThemeToolCatalog() {
|
|
|
57
63
|
execute: ({ theme_id, query, limit }, client) => client.searchThemeFiles(theme_id, query, limit),
|
|
58
64
|
},
|
|
59
65
|
{
|
|
60
|
-
name: '
|
|
66
|
+
name: 'theme_apply',
|
|
61
67
|
description: 'Apply one or more text-file changes to a theme draft with server-side verification.',
|
|
62
68
|
inputSchema: {
|
|
63
69
|
theme_id: z.string().min(1),
|
|
@@ -75,7 +81,7 @@ export function createThemeToolCatalog() {
|
|
|
75
81
|
}),
|
|
76
82
|
},
|
|
77
83
|
{
|
|
78
|
-
name: '
|
|
84
|
+
name: 'theme_accept',
|
|
79
85
|
description: 'Accept an already generated draft patch from a dashboard-agent run.',
|
|
80
86
|
inputSchema: {
|
|
81
87
|
theme_id: z.string().min(1),
|
|
@@ -90,7 +96,7 @@ export function createThemeToolCatalog() {
|
|
|
90
96
|
}),
|
|
91
97
|
},
|
|
92
98
|
{
|
|
93
|
-
name: '
|
|
99
|
+
name: 'theme_create',
|
|
94
100
|
description: 'Create a new theme scaffold from a Shoppex base theme.',
|
|
95
101
|
inputSchema: {
|
|
96
102
|
base: z.enum(['default', 'classic', 'nebula', 'pulse', 'phantom', 'starlight']),
|
|
@@ -104,7 +110,7 @@ export function createThemeToolCatalog() {
|
|
|
104
110
|
}),
|
|
105
111
|
},
|
|
106
112
|
{
|
|
107
|
-
name: '
|
|
113
|
+
name: 'theme_create_section',
|
|
108
114
|
description: 'Scaffold a new theme section and wire it into theme.config.ts.',
|
|
109
115
|
inputSchema: {
|
|
110
116
|
theme_id: z.string().min(1),
|
|
@@ -119,7 +125,7 @@ export function createThemeToolCatalog() {
|
|
|
119
125
|
}),
|
|
120
126
|
},
|
|
121
127
|
{
|
|
122
|
-
name: '
|
|
128
|
+
name: 'theme_create_page',
|
|
123
129
|
description: 'Scaffold a new static page and wire its route into src/App.tsx.',
|
|
124
130
|
inputSchema: {
|
|
125
131
|
theme_id: z.string().min(1),
|
|
@@ -134,7 +140,7 @@ export function createThemeToolCatalog() {
|
|
|
134
140
|
}),
|
|
135
141
|
},
|
|
136
142
|
{
|
|
137
|
-
name: '
|
|
143
|
+
name: 'theme_update_config',
|
|
138
144
|
description: 'Extend theme.config.ts with a new settings field.',
|
|
139
145
|
inputSchema: {
|
|
140
146
|
theme_id: z.string().min(1),
|
|
@@ -149,7 +155,7 @@ export function createThemeToolCatalog() {
|
|
|
149
155
|
}),
|
|
150
156
|
},
|
|
151
157
|
{
|
|
152
|
-
name: '
|
|
158
|
+
name: 'theme_preview',
|
|
153
159
|
description: 'Start or reuse a live preview session for the current theme draft.',
|
|
154
160
|
inputSchema: {
|
|
155
161
|
theme_id: z.string().min(1),
|
|
@@ -157,7 +163,7 @@ export function createThemeToolCatalog() {
|
|
|
157
163
|
execute: ({ theme_id }, client) => client.startThemePreview(theme_id),
|
|
158
164
|
},
|
|
159
165
|
{
|
|
160
|
-
name: '
|
|
166
|
+
name: 'theme_stop_preview',
|
|
161
167
|
description: 'Stop a running live preview session.',
|
|
162
168
|
inputSchema: {
|
|
163
169
|
theme_id: z.string().min(1),
|
|
@@ -166,7 +172,7 @@ export function createThemeToolCatalog() {
|
|
|
166
172
|
execute: ({ theme_id, session_id }, client) => client.stopThemePreview(theme_id, session_id),
|
|
167
173
|
},
|
|
168
174
|
{
|
|
169
|
-
name: '
|
|
175
|
+
name: 'theme_publish',
|
|
170
176
|
description: 'Queue a publish/deploy for the current accepted theme draft.',
|
|
171
177
|
inputSchema: {
|
|
172
178
|
theme_id: z.string().min(1),
|
|
@@ -174,7 +180,7 @@ export function createThemeToolCatalog() {
|
|
|
174
180
|
execute: ({ theme_id }, client) => client.publishTheme(theme_id),
|
|
175
181
|
},
|
|
176
182
|
{
|
|
177
|
-
name: '
|
|
183
|
+
name: 'theme_publish_status',
|
|
178
184
|
description: 'Read the current publish job status.',
|
|
179
185
|
inputSchema: {
|
|
180
186
|
theme_id: z.string().min(1),
|
|
@@ -183,7 +189,7 @@ export function createThemeToolCatalog() {
|
|
|
183
189
|
execute: ({ theme_id, job_id }, client) => client.getThemePublishStatus(theme_id, job_id),
|
|
184
190
|
},
|
|
185
191
|
{
|
|
186
|
-
name: '
|
|
192
|
+
name: 'theme_validate',
|
|
187
193
|
description: 'Run a validation-only build and optional typecheck without publishing.',
|
|
188
194
|
inputSchema: {
|
|
189
195
|
theme_id: z.string().min(1),
|
|
@@ -194,7 +200,7 @@ export function createThemeToolCatalog() {
|
|
|
194
200
|
}),
|
|
195
201
|
},
|
|
196
202
|
{
|
|
197
|
-
name: '
|
|
203
|
+
name: 'theme_settings_get',
|
|
198
204
|
description: 'Read the current builder settings values for a theme.',
|
|
199
205
|
inputSchema: {
|
|
200
206
|
theme_id: z.string().min(1),
|
|
@@ -202,7 +208,7 @@ export function createThemeToolCatalog() {
|
|
|
202
208
|
execute: ({ theme_id }, client) => client.getThemeSettings(theme_id),
|
|
203
209
|
},
|
|
204
210
|
{
|
|
205
|
-
name: '
|
|
211
|
+
name: 'theme_settings_update',
|
|
206
212
|
description: 'Update theme builder settings without editing source files directly.',
|
|
207
213
|
inputSchema: {
|
|
208
214
|
theme_id: z.string().min(1),
|
|
@@ -213,7 +219,7 @@ export function createThemeToolCatalog() {
|
|
|
213
219
|
}),
|
|
214
220
|
},
|
|
215
221
|
{
|
|
216
|
-
name: '
|
|
222
|
+
name: 'theme_backups',
|
|
217
223
|
description: 'List available theme backups for rollback.',
|
|
218
224
|
inputSchema: {
|
|
219
225
|
theme_id: z.string().min(1),
|
|
@@ -221,7 +227,7 @@ export function createThemeToolCatalog() {
|
|
|
221
227
|
execute: ({ theme_id }, client) => client.listThemeBackups(theme_id),
|
|
222
228
|
},
|
|
223
229
|
{
|
|
224
|
-
name: '
|
|
230
|
+
name: 'theme_rollback',
|
|
225
231
|
description: 'Rollback a theme to a previous backup snapshot.',
|
|
226
232
|
inputSchema: {
|
|
227
233
|
theme_id: z.string().min(1),
|
|
@@ -230,7 +236,7 @@ export function createThemeToolCatalog() {
|
|
|
230
236
|
execute: ({ theme_id, backup_id }, client) => client.rollbackTheme(theme_id, backup_id),
|
|
231
237
|
},
|
|
232
238
|
{
|
|
233
|
-
name: '
|
|
239
|
+
name: 'theme_latest_run',
|
|
234
240
|
description: 'Read the latest dashboard-agent run metadata for a theme.',
|
|
235
241
|
inputSchema: {
|
|
236
242
|
theme_id: z.string().min(1),
|
|
@@ -240,8 +246,13 @@ export function createThemeToolCatalog() {
|
|
|
240
246
|
];
|
|
241
247
|
}
|
|
242
248
|
|
|
249
|
+
function normalizeToolName(name) {
|
|
250
|
+
return typeof name === 'string' ? name.replace(/\./g, '_') : name;
|
|
251
|
+
}
|
|
252
|
+
|
|
243
253
|
export async function executeThemeTool(toolName, args, client) {
|
|
244
|
-
const
|
|
254
|
+
const normalized = normalizeToolName(toolName);
|
|
255
|
+
const tool = createThemeToolCatalog().find((entry) => entry.name === normalized);
|
|
245
256
|
if (!tool) {
|
|
246
257
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
247
258
|
}
|