zola-mcp 1.1.0 → 1.1.2
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +43 -4
- package/dist/index.js +1 -1
- package/dist/tools/website-theme.js +53 -4
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Zola wedding planning tools for Claude Code",
|
|
10
|
-
"version": "1.1.
|
|
10
|
+
"version": "1.1.2"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "Zola",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Zola wedding planning tools for Claude — vendors, budget, guests, seating, events, registry, inquiries, and more via MCP",
|
|
18
|
-
"version": "1.1.
|
|
18
|
+
"version": "1.1.2",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Chall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zola",
|
|
3
3
|
"displayName": "Zola",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"description": "Zola wedding planning tools for Claude — vendors, budget, guests, seating, events, registry, inquiries, and more via MCP",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Chall",
|
package/dist/bundle.js
CHANGED
|
@@ -31562,11 +31562,48 @@ async function updateCurrentTheme(args) {
|
|
|
31562
31562
|
);
|
|
31563
31563
|
return jsonResult(response.data);
|
|
31564
31564
|
}
|
|
31565
|
+
var ALLOWED_BODY_FONT_FAMILY_IDS = [68, 198];
|
|
31566
|
+
var WEB_API_ONLY_FIELDS = ["header_color", "nav_font_color"];
|
|
31565
31567
|
async function updateWebsiteCustomization(args) {
|
|
31568
|
+
for (const field of WEB_API_ONLY_FIELDS) {
|
|
31569
|
+
if (args[field] !== void 0) {
|
|
31570
|
+
throw new Error(
|
|
31571
|
+
`${field} is not writable via the mobile-api endpoint this MCP uses. The Zola web UI sets it via POST www.zola.com/web-api/v1/websiteCustomization/update (cookie + CSRF auth), which this MCP does not yet support. For now, change it in the Zola web UI under Website > Design.`
|
|
31572
|
+
);
|
|
31573
|
+
}
|
|
31574
|
+
}
|
|
31575
|
+
if (args.body_font_family_id !== void 0 && !ALLOWED_BODY_FONT_FAMILY_IDS.includes(args.body_font_family_id)) {
|
|
31576
|
+
throw new Error(
|
|
31577
|
+
`body_font_family_id must be one of [${ALLOWED_BODY_FONT_FAMILY_IDS.join(
|
|
31578
|
+
", "
|
|
31579
|
+
)}] (68=Libre Baskerville, 198=Circular). The header font catalog does not apply to the body font.`
|
|
31580
|
+
);
|
|
31581
|
+
}
|
|
31582
|
+
let preserved;
|
|
31583
|
+
if (args.header_font_family_id !== void 0) {
|
|
31584
|
+
const current = await client.requestMobile(
|
|
31585
|
+
"GET",
|
|
31586
|
+
"/v3/websites/website-customizations/context"
|
|
31587
|
+
);
|
|
31588
|
+
preserved = current.data.current_style_customizations;
|
|
31589
|
+
}
|
|
31566
31590
|
const body = {};
|
|
31591
|
+
if (preserved) {
|
|
31592
|
+
if (preserved.accent_color != null) body.accent_color = preserved.accent_color;
|
|
31593
|
+
if (preserved.background_color != null) body.background_color = preserved.background_color;
|
|
31594
|
+
if (preserved.body?.color != null) body.body_font = { color: preserved.body.color };
|
|
31595
|
+
if (preserved.navigation_customization?.background_color != null) {
|
|
31596
|
+
body.navigation_customization = {
|
|
31597
|
+
background_color: preserved.navigation_customization.background_color
|
|
31598
|
+
};
|
|
31599
|
+
}
|
|
31600
|
+
}
|
|
31567
31601
|
if (args.accent_color !== void 0) body.accent_color = args.accent_color;
|
|
31568
31602
|
if (args.background_color !== void 0) body.background_color = args.background_color;
|
|
31569
|
-
if (args.body_font_color !== void 0)
|
|
31603
|
+
if (args.body_font_color !== void 0) {
|
|
31604
|
+
const existing = body.body_font ?? {};
|
|
31605
|
+
body.body_font = { ...existing, color: args.body_font_color };
|
|
31606
|
+
}
|
|
31570
31607
|
if (args.navigation_background_color !== void 0) {
|
|
31571
31608
|
body.navigation_customization = { background_color: args.navigation_background_color };
|
|
31572
31609
|
}
|
|
@@ -31611,14 +31648,16 @@ function registerWebsiteThemeTools(server2) {
|
|
|
31611
31648
|
annotations: { destructiveHint: false }
|
|
31612
31649
|
}, updateCurrentTheme);
|
|
31613
31650
|
server2.registerTool("update_website_customization", {
|
|
31614
|
-
description: "Update website colors and fonts. Provide only what changes
|
|
31651
|
+
description: "Update website colors and fonts. Provide only what changes. Colors are 6-char hex without #. Note: when header_font_family_id changes, the wrapper auto-fetches current state and re-sends all active colors to defend against a Zola partial-update wipe bug. body_font_family_id is restricted to [68, 198]. header_color and nav_font_color exist on Zola's web-api endpoint but are NOT writable via the mobile-api this MCP uses \u2014 change them in the Zola web UI for now.",
|
|
31615
31652
|
inputSchema: {
|
|
31616
31653
|
accent_color: external_exports3.string().optional().describe("6-char hex (no #)"),
|
|
31617
31654
|
background_color: external_exports3.string().optional(),
|
|
31618
31655
|
body_font_color: external_exports3.string().optional(),
|
|
31619
31656
|
navigation_background_color: external_exports3.string().optional(),
|
|
31620
31657
|
header_font_family_id: external_exports3.number().optional().describe("Font family ID \u2014 call get_website_customizations to see available font_family_ids"),
|
|
31621
|
-
body_font_family_id: external_exports3.number().optional()
|
|
31658
|
+
body_font_family_id: external_exports3.number().optional().describe("Restricted to 68 (Libre Baskerville) or 198 (Circular). Other IDs return a generic API error."),
|
|
31659
|
+
header_color: external_exports3.string().optional().describe("Writable only via Zola's web-api (cookie+CSRF), not the mobile-api this MCP uses. Passing this throws."),
|
|
31660
|
+
nav_font_color: external_exports3.string().optional().describe("Writable only via Zola's web-api (cookie+CSRF), not the mobile-api this MCP uses. Passing this throws.")
|
|
31622
31661
|
},
|
|
31623
31662
|
annotations: { destructiveHint: false }
|
|
31624
31663
|
}, updateWebsiteCustomization);
|
|
@@ -31752,7 +31791,7 @@ function registerRegistryItemTools(server2) {
|
|
|
31752
31791
|
// src/index.ts
|
|
31753
31792
|
var server = new McpServer({
|
|
31754
31793
|
name: "zola-mcp",
|
|
31755
|
-
version: "1.1.
|
|
31794
|
+
version: "1.1.2"
|
|
31756
31795
|
});
|
|
31757
31796
|
registerVendorTools(server);
|
|
31758
31797
|
registerBudgetTools(server);
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { registerWebsiteThemeTools } from './tools/website-theme.js';
|
|
|
13
13
|
import { registerRegistryItemTools } from './tools/registry-items.js';
|
|
14
14
|
const server = new McpServer({
|
|
15
15
|
name: 'zola-mcp',
|
|
16
|
-
version: '1.1.
|
|
16
|
+
version: '1.1.2',
|
|
17
17
|
});
|
|
18
18
|
registerVendorTools(server);
|
|
19
19
|
registerBudgetTools(server);
|
|
@@ -26,14 +26,57 @@ export async function updateCurrentTheme(args) {
|
|
|
26
26
|
const response = await client.requestMobile('PUT', '/v3/themes/current', body);
|
|
27
27
|
return jsonResult(response.data);
|
|
28
28
|
}
|
|
29
|
+
// Only these two font_family_id values work for the body font; sending any other
|
|
30
|
+
// (even ones valid for the header) yields a generic "tool execution failed" error.
|
|
31
|
+
// See docs/zola-api-quirks.md for the empirical evidence.
|
|
32
|
+
const ALLOWED_BODY_FONT_FAMILY_IDS = [68, 198];
|
|
33
|
+
// These fields exist on the web-api endpoint (POST www.zola.com/web-api/v1/
|
|
34
|
+
// websiteCustomization/update) but NOT on the mobile-api endpoint this MCP
|
|
35
|
+
// currently uses. Until web-api support is added, callers passing these get a
|
|
36
|
+
// clear pointer at the only paths that work today.
|
|
37
|
+
const WEB_API_ONLY_FIELDS = ['header_color', 'nav_font_color'];
|
|
29
38
|
export async function updateWebsiteCustomization(args) {
|
|
39
|
+
for (const field of WEB_API_ONLY_FIELDS) {
|
|
40
|
+
if (args[field] !== undefined) {
|
|
41
|
+
throw new Error(`${field} is not writable via the mobile-api endpoint this MCP uses. ` +
|
|
42
|
+
`The Zola web UI sets it via POST www.zola.com/web-api/v1/websiteCustomization/update ` +
|
|
43
|
+
`(cookie + CSRF auth), which this MCP does not yet support. ` +
|
|
44
|
+
`For now, change it in the Zola web UI under Website > Design.`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (args.body_font_family_id !== undefined &&
|
|
48
|
+
!ALLOWED_BODY_FONT_FAMILY_IDS.includes(args.body_font_family_id)) {
|
|
49
|
+
throw new Error(`body_font_family_id must be one of [${ALLOWED_BODY_FONT_FAMILY_IDS.join(', ')}] (68=Libre Baskerville, 198=Circular). The header font catalog does not apply to the body font.`);
|
|
50
|
+
}
|
|
51
|
+
// Partial-update wipe defence: when header_font_family_id changes the server
|
|
52
|
+
// resets every other active customization to null unless we resend them.
|
|
53
|
+
let preserved;
|
|
54
|
+
if (args.header_font_family_id !== undefined) {
|
|
55
|
+
const current = await client.requestMobile('GET', '/v3/websites/website-customizations/context');
|
|
56
|
+
preserved = current.data.current_style_customizations;
|
|
57
|
+
}
|
|
30
58
|
const body = {};
|
|
59
|
+
if (preserved) {
|
|
60
|
+
if (preserved.accent_color != null)
|
|
61
|
+
body.accent_color = preserved.accent_color;
|
|
62
|
+
if (preserved.background_color != null)
|
|
63
|
+
body.background_color = preserved.background_color;
|
|
64
|
+
if (preserved.body?.color != null)
|
|
65
|
+
body.body_font = { color: preserved.body.color };
|
|
66
|
+
if (preserved.navigation_customization?.background_color != null) {
|
|
67
|
+
body.navigation_customization = {
|
|
68
|
+
background_color: preserved.navigation_customization.background_color,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
31
72
|
if (args.accent_color !== undefined)
|
|
32
73
|
body.accent_color = args.accent_color;
|
|
33
74
|
if (args.background_color !== undefined)
|
|
34
75
|
body.background_color = args.background_color;
|
|
35
|
-
if (args.body_font_color !== undefined)
|
|
36
|
-
body.body_font
|
|
76
|
+
if (args.body_font_color !== undefined) {
|
|
77
|
+
const existing = body.body_font ?? {};
|
|
78
|
+
body.body_font = { ...existing, color: args.body_font_color };
|
|
79
|
+
}
|
|
37
80
|
if (args.navigation_background_color !== undefined) {
|
|
38
81
|
body.navigation_customization = { background_color: args.navigation_background_color };
|
|
39
82
|
}
|
|
@@ -74,14 +117,20 @@ export function registerWebsiteThemeTools(server) {
|
|
|
74
117
|
annotations: { destructiveHint: false },
|
|
75
118
|
}, updateCurrentTheme);
|
|
76
119
|
server.registerTool('update_website_customization', {
|
|
77
|
-
description: 'Update website colors and fonts. Provide only what changes
|
|
120
|
+
description: 'Update website colors and fonts. Provide only what changes. Colors are 6-char hex without #. ' +
|
|
121
|
+
'Note: when header_font_family_id changes, the wrapper auto-fetches current state and re-sends all active colors ' +
|
|
122
|
+
'to defend against a Zola partial-update wipe bug. body_font_family_id is restricted to [68, 198]. ' +
|
|
123
|
+
'header_color and nav_font_color exist on Zola\'s web-api endpoint but are NOT writable via the mobile-api ' +
|
|
124
|
+
'this MCP uses — change them in the Zola web UI for now.',
|
|
78
125
|
inputSchema: {
|
|
79
126
|
accent_color: z.string().optional().describe('6-char hex (no #)'),
|
|
80
127
|
background_color: z.string().optional(),
|
|
81
128
|
body_font_color: z.string().optional(),
|
|
82
129
|
navigation_background_color: z.string().optional(),
|
|
83
130
|
header_font_family_id: z.number().optional().describe('Font family ID — call get_website_customizations to see available font_family_ids'),
|
|
84
|
-
body_font_family_id: z.number().optional(),
|
|
131
|
+
body_font_family_id: z.number().optional().describe('Restricted to 68 (Libre Baskerville) or 198 (Circular). Other IDs return a generic API error.'),
|
|
132
|
+
header_color: z.string().optional().describe('Writable only via Zola\'s web-api (cookie+CSRF), not the mobile-api this MCP uses. Passing this throws.'),
|
|
133
|
+
nav_font_color: z.string().optional().describe('Writable only via Zola\'s web-api (cookie+CSRF), not the mobile-api this MCP uses. Passing this throws.'),
|
|
85
134
|
},
|
|
86
135
|
annotations: { destructiveHint: false },
|
|
87
136
|
}, updateWebsiteCustomization);
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/zola-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "zola-mcp",
|
|
14
|
-
"version": "1.1.
|
|
14
|
+
"version": "1.1.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|