zola-mcp 1.3.2 → 1.4.1
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/auth.js +53 -102
- package/dist/bundle.js +650 -108
- package/dist/client.js +5 -2
- package/dist/index.js +3 -1
- package/dist/tools/event-invitations.js +171 -0
- package/dist/tools/guests.js +31 -26
- package/dist/types.js +4 -7
- package/package.json +9 -8
- package/server.json +2 -2
- package/skills/zola/SKILL.md +4 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Zola wedding planning tools for Claude Code",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.4.1"
|
|
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.
|
|
18
|
+
"version": "1.4.1",
|
|
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.
|
|
4
|
+
"version": "1.4.1",
|
|
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/auth.js
CHANGED
|
@@ -1,60 +1,63 @@
|
|
|
1
1
|
// ────────────────────────────────────────────────────────────────────────────
|
|
2
|
-
// Auth resolution —
|
|
2
|
+
// Auth resolution — createAuthResolver (shared skeleton from mcp-utils)
|
|
3
3
|
// ────────────────────────────────────────────────────────────────────────────
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// signupgenius-mcp, …) use the same selector — keep the structure flat,
|
|
8
|
-
// the path-selection explicit, and the error messages actionable.
|
|
5
|
+
// The canonical three-path "browser-bootstrap + Node-direct" resolver, now the
|
|
6
|
+
// shared `createAuthResolver` skeleton from `@chrischall/mcp-utils` (0.7.0+):
|
|
9
7
|
//
|
|
10
|
-
//
|
|
8
|
+
// 1. Env-var credential — ZOLA_REFRESH_TOKEN set → used directly. This is
|
|
9
|
+
// the ~1-year JWT that doubles as the `usr` cookie on zola.com. Reads go
|
|
10
|
+
// through the hardened `readEnvVar` (blank / 'undefined' / 'null' /
|
|
11
|
+
// unexpanded `${VAR}` treated as unset).
|
|
11
12
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
13
|
+
// 2. fetchproxy fallback — unless ZOLA_DISABLE_FETCHPROXY is truthy
|
|
14
|
+
// ('1'/'true'/'yes'/'on' via `parseBoolEnv` inside the resolver), lift
|
|
15
|
+
// the HttpOnly `usr` cookie out of the user's signed-in zola.com tab via
|
|
16
|
+
// `@fetchproxy/bootstrap` (one-shot WebSocket bridge; `chrome.cookies.get`
|
|
17
|
+
// sees HttpOnly cookies). All subsequent Zola API calls go direct to
|
|
18
|
+
// mobile-api.zola.com from Node — fetchproxy is NOT in the hot path.
|
|
19
|
+
// Bridge-down errors surface the FetchproxyBridgeDownError `.hint`
|
|
20
|
+
// verbatim (handled inside createAuthResolver since 0.7.0); a signed-out
|
|
21
|
+
// tab raises SessionNotAuthenticatedError naming Zola + zola.com.
|
|
16
22
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
// The `@fetchproxy/bootstrap` helper spins up a one-shot WebSocket
|
|
21
|
-
// bridge, asks the extension for the HttpOnly `usr` cookie via
|
|
22
|
-
// `chrome.cookies.get`, then closes the bridge. From there, all
|
|
23
|
-
// Zola API calls go out via plain Node `fetch()` to
|
|
24
|
-
// mobile-api.zola.com — fetchproxy is NOT in the hot path.
|
|
23
|
+
// 3. Error — nothing configured: an actionable message naming
|
|
24
|
+
// ZOLA_REFRESH_TOKEN, the browser sign-in fallback, and
|
|
25
|
+
// ZOLA_DISABLE_FETCHPROXY.
|
|
25
26
|
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// Nothing to authenticate with. We throw a message that tells the
|
|
31
|
-
// user exactly what to do: set the env var, OR install the extension
|
|
32
|
-
// and sign in.
|
|
33
|
-
//
|
|
34
|
-
// Why fetchproxy is only a one-shot read:
|
|
35
|
-
// The bootstrap call snapshots the `usr` cookie and returns. The MCP
|
|
36
|
-
// then operates from Node with direct fetch — latency and reliability
|
|
37
|
-
// are not coupled to the browser bridge for normal tool calls. The
|
|
38
|
-
// captured refresh token is fed into the existing
|
|
39
|
-
// `POST /v3/sessions/refresh` flow which mints 30-min session tokens
|
|
40
|
-
// (also in pure Node).
|
|
41
|
-
//
|
|
42
|
-
// Testability:
|
|
43
|
-
// - `@fetchproxy/bootstrap` is mocked at the module boundary in tests.
|
|
44
|
-
// - This module exposes a single async `resolveRefreshToken()` that
|
|
45
|
-
// returns the JWT plus the source — callers (the client) treat the
|
|
46
|
-
// return value as opaque credentials.
|
|
27
|
+
// Testability: `@fetchproxy/bootstrap` is mocked at the module boundary in
|
|
28
|
+
// tests, exactly as before. This module still exposes a single async
|
|
29
|
+
// `resolveRefreshToken()` returning the JWT plus the source — callers (the
|
|
30
|
+
// client) treat the return value as opaque credentials.
|
|
47
31
|
import { bootstrap } from '@fetchproxy/bootstrap';
|
|
48
|
-
import {
|
|
49
|
-
import { readEnvVar } from '@chrischall/mcp-utils';
|
|
32
|
+
import { createAuthResolver } from '@chrischall/mcp-utils';
|
|
50
33
|
import pkg from '../package.json' with { type: 'json' };
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
34
|
+
const resolveAuth = createAuthResolver({
|
|
35
|
+
envVar: 'ZOLA_REFRESH_TOKEN',
|
|
36
|
+
disableEnvVar: 'ZOLA_DISABLE_FETCHPROXY',
|
|
37
|
+
// The real bootstrap has a narrower opts type than the injected boundary;
|
|
38
|
+
// the cast keeps the heavy bridge dep out of the shared module's types.
|
|
39
|
+
bootstrap: bootstrap,
|
|
40
|
+
bootstrapOptions: {
|
|
41
|
+
serverName: pkg.name,
|
|
42
|
+
version: pkg.version,
|
|
43
|
+
// Zola serves www.zola.com (web app) and mobile-api.zola.com (API).
|
|
44
|
+
// The `usr` cookie lives on the web app's apex domain; the extension
|
|
45
|
+
// matches on suffix so listing the apex covers any subdomain.
|
|
46
|
+
domains: ['zola.com'],
|
|
47
|
+
declare: {
|
|
48
|
+
// `usr` is HttpOnly → invisible to page JS, but fetchproxy's
|
|
49
|
+
// read_cookies uses `chrome.cookies.get` which DOES see HttpOnly
|
|
50
|
+
// cookies. The value IS the ~1-year refresh JWT.
|
|
51
|
+
cookies: ['usr'],
|
|
52
|
+
localStorage: [],
|
|
53
|
+
sessionStorage: [],
|
|
54
|
+
captureHeaders: [],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
parseTokens: (session) => session.cookies['usr'],
|
|
58
|
+
serviceName: 'Zola',
|
|
59
|
+
signInHost: 'zola.com',
|
|
60
|
+
});
|
|
58
61
|
/**
|
|
59
62
|
* Resolve the Zola refresh token using the three-path priority described
|
|
60
63
|
* above. Throws with an actionable error message when no path succeeds.
|
|
@@ -64,58 +67,6 @@ function fetchproxyDisabled() {
|
|
|
64
67
|
* logging / future cache-keying only.
|
|
65
68
|
*/
|
|
66
69
|
export async function resolveRefreshToken() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (envToken) {
|
|
70
|
-
return { token: envToken, source: 'env' };
|
|
71
|
-
}
|
|
72
|
-
// ── Path 2: fetchproxy fallback (new).
|
|
73
|
-
if (!fetchproxyDisabled()) {
|
|
74
|
-
try {
|
|
75
|
-
const session = await bootstrap({
|
|
76
|
-
serverName: pkg.name,
|
|
77
|
-
version: pkg.version,
|
|
78
|
-
// Zola serves www.zola.com (web app) and mobile-api.zola.com (API).
|
|
79
|
-
// The `usr` cookie lives on the web app's apex domain; the extension
|
|
80
|
-
// matches on suffix so listing the apex covers any subdomain.
|
|
81
|
-
domains: ['zola.com'],
|
|
82
|
-
declare: {
|
|
83
|
-
// `usr` is HttpOnly → invisible to page JS, but fetchproxy 0.3.0's
|
|
84
|
-
// read_cookies uses `chrome.cookies.get` which DOES see HttpOnly
|
|
85
|
-
// cookies. The value IS the ~1-year refresh JWT.
|
|
86
|
-
cookies: ['usr'],
|
|
87
|
-
localStorage: [],
|
|
88
|
-
sessionStorage: [],
|
|
89
|
-
captureHeaders: [],
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
const token = session.cookies['usr'];
|
|
93
|
-
if (!token) {
|
|
94
|
-
throw new Error('zola: no `usr` cookie found. ' +
|
|
95
|
-
'Sign into zola.com in your browser (with the fetchproxy extension installed) and retry.');
|
|
96
|
-
}
|
|
97
|
-
return { token, source: 'fetchproxy' };
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
// 0.8.0+ typed-error discrimination. The fetchproxy server already
|
|
101
|
-
// retries once on SW eviction (bridgeReviveDelayMs=2000 default), so
|
|
102
|
-
// a thrown FetchproxyBridgeDownError means the retry also failed —
|
|
103
|
-
// the extension's service worker is genuinely down and the user
|
|
104
|
-
// needs to wake it. The `.hint` is the actionable copy
|
|
105
|
-
// ("click the extension toolbar icon...") that we'd otherwise have
|
|
106
|
-
// to hand-write here. Surface it verbatim so users in path 2 get
|
|
107
|
-
// the same self-service guidance as path 3.
|
|
108
|
-
if (classifyBridgeError(e) === 'bridge_down') {
|
|
109
|
-
const downErr = e;
|
|
110
|
-
throw new Error(`Zola auth: fetchproxy bridge is down (extension service worker unreachable after retry). ${downErr.hint}`);
|
|
111
|
-
}
|
|
112
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
113
|
-
throw new Error(`Zola auth: no ZOLA_REFRESH_TOKEN set, and fetchproxy fallback failed: ${msg}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// ── Path 3: nothing configured. Surface both fixes side-by-side so the
|
|
117
|
-
// user can pick whichever fits their setup.
|
|
118
|
-
throw new Error('Zola auth: set ZOLA_REFRESH_TOKEN, ' +
|
|
119
|
-
'or install the fetchproxy extension and sign into zola.com ' +
|
|
120
|
-
'(unset ZOLA_DISABLE_FETCHPROXY if it is set).');
|
|
70
|
+
const { credential, source } = await resolveAuth();
|
|
71
|
+
return { token: credential, source };
|
|
121
72
|
}
|