@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.
Files changed (2) hide show
  1. package/package.json +2 -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.1.3",
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.1.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: 'theme.inspect',
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: 'theme.diff',
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: 'theme.read_file',
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: 'theme.search_files',
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: 'theme.apply',
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: 'theme.accept',
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: 'theme.create',
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: 'theme.create_section',
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: 'theme.create_page',
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: 'theme.update_config',
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: 'theme.preview',
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: 'theme.stop_preview',
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: 'theme.publish',
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: 'theme.publish_status',
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: 'theme.validate',
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: 'theme.settings_get',
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: 'theme.settings_update',
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: 'theme.backups',
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: 'theme.rollback',
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: 'theme.latest_run',
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 tool = createThemeToolCatalog().find((entry) => entry.name === toolName);
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
  }