honeybook-mcp 1.2.1 → 1.2.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/README.md +10 -8
- package/dist/auth.js +15 -5
- package/dist/bridge-errors.js +16 -0
- package/dist/bundle.js +790 -132
- package/dist/flow-auth.js +17 -7
- package/dist/index.js +1 -1
- package/dist/tools/flows.js +2 -2
- package/dist/tools/sessions.js +3 -3
- package/package.json +4 -4
- package/server.json +2 -2
- package/skills/honeybook/SKILL.md +1 -1
- package/skills/honeybook-fpx/SKILL.md +11 -6
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "HoneyBook client-portal tools for Claude Code",
|
|
10
|
-
"version": "1.2.
|
|
10
|
+
"version": "1.2.2"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "HoneyBook",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "HoneyBook client-portal MCP for Claude — view wedding-vendor contracts and invoices via MCP",
|
|
18
|
-
"version": "1.2.
|
|
18
|
+
"version": "1.2.2",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Chall"
|
|
21
21
|
},
|
package/README.md
CHANGED
|
@@ -28,13 +28,13 @@ Ask Claude things like:
|
|
|
28
28
|
- [Claude Desktop](https://claude.ai/download) or [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
29
29
|
- [Node.js](https://nodejs.org) 22 or later
|
|
30
30
|
- Magic-link emails from the wedding vendors that use HoneyBook
|
|
31
|
-
- [
|
|
31
|
+
- [ContextMint Bridge](https://github.com/nullnet-app/contextmint-bridge/releases) browser extension — in Chrome, download the chrome zip from the releases page and load it unpacked (`chrome://extensions` → Developer mode → Load unpacked). Safari isn't available yet (it will ship inside the ContextMint app, which has no public download), so use Chrome for now. Used by `use_magic_link` to snapshot the session out of your signed-in vendor portal tab.
|
|
32
32
|
|
|
33
33
|
## Acknowledgement of Terms
|
|
34
34
|
|
|
35
35
|
By using this MCP server, you acknowledge and agree to the following:
|
|
36
36
|
|
|
37
|
-
**1. This server accesses your own HoneyBook workspace.** Every request is dispatched through your own signed-in browser session via the
|
|
37
|
+
**1. This server accesses your own HoneyBook workspace.** Every request is dispatched through your own signed-in browser session via the ContextMint Bridge extension. It does not — and cannot — access anyone else's workspace.
|
|
38
38
|
|
|
39
39
|
**2. [HoneyBook's Terms of Service](https://www.honeybook.com/legal/terms-of-service) govern your use of this server**, just as they govern your direct use of honeybook.com. The clauses most relevant here:
|
|
40
40
|
|
|
@@ -80,17 +80,18 @@ No environment variables are required. The optional ones below tune how writes a
|
|
|
80
80
|
|
|
81
81
|
## Sessions
|
|
82
82
|
|
|
83
|
-
HoneyBook has no public client-portal API. This MCP reuses the same auth state your browser has after clicking a vendor's magic link, via the [
|
|
83
|
+
HoneyBook has no public client-portal API. This MCP reuses the same auth state your browser has after clicking a vendor's magic link, via the [ContextMint Bridge](https://github.com/nullnet-app/contextmint-bridge/releases) browser extension.
|
|
84
84
|
|
|
85
85
|
**One-time setup:**
|
|
86
86
|
|
|
87
|
-
1. Install
|
|
87
|
+
1. Install ContextMint Bridge from its [releases page](https://github.com/nullnet-app/contextmint-bridge/releases): in Chrome, load the chrome zip unpacked. Safari isn't available yet (it will ship inside the ContextMint app, which has no public download) — use Chrome for now.
|
|
88
|
+
ContextMint Bridge is the fetchproxy browser extension under its new name, from the same maintainer — fetchproxy's own README ([fetchproxy#extension](https://github.com/chrischall/fetchproxy#extension)) points to it. Its source is public at [nullnet-app/contextmint-bridge](https://github.com/nullnet-app/contextmint-bridge): build it yourself, or check a release zip against the `.sha256` file published beside it (`shasum -a 256 -c contextmint-bridge-chrome-<version>.zip.sha256`).
|
|
88
89
|
2. Click each vendor's magic link in your normal browser. That signs you into their `*.hbportal.co` portal.
|
|
89
90
|
|
|
90
91
|
**Per-vendor activation:**
|
|
91
92
|
|
|
92
93
|
1. Make sure the vendor's portal tab is open (the magic link from their email).
|
|
93
|
-
2. In Claude, call `use_magic_link` with the magic-link URL — the tool asks the
|
|
94
|
+
2. In Claude, call `use_magic_link` with the magic-link URL — the tool asks the ContextMint Bridge extension to snapshot the auth fields out of the page's `localStorage["HONEYBOOK_REACT_CURR_USER"]`, then closes the bridge. The tab only has to be open and signed in; nothing is read off a live request. No headless browser is spawned.
|
|
94
95
|
3. All other tools use the most-recently-activated session by default. Pass `origin` explicitly when multiple vendors are active.
|
|
95
96
|
|
|
96
97
|
Sessions are stored in memory and persisted to `~/.honeybook-mcp/sessions.json` (mode 0600) so they survive MCP restarts. Re-run `use_magic_link` when a session expires.
|
|
@@ -172,9 +173,10 @@ Until you confirm it only previews the recipients, subject and body — see [Con
|
|
|
172
173
|
- **"no auth hash for flow …"** — the link you passed had lost its `?hash=` parameter (the page rewrites the URL after it loads). Re-copy the original link out of the vendor email.
|
|
173
174
|
- **"HoneyBook error 400 … NOT an auth failure"** on `get_flow` — a required input was missing, not your credential. Usually a pinned `HONEYBOOK_API_VERSION` that has gone stale: unset it so the live value is read from `/api/gon`. Re-running `use_flow_link` will not help.
|
|
174
175
|
- **"no context id for flow …"** — HoneyBook's public `/minimal` route did not return the vendor company id the questionnaire read needs. Also not a credential problem.
|
|
175
|
-
- **"fetchproxy capture failed"** — install
|
|
176
|
+
- **"fetchproxy capture failed"** — install [ContextMint Bridge](https://github.com/nullnet-app/contextmint-bridge/releases), then open the vendor's magic link in that browser.
|
|
176
177
|
- **"fetchproxy capture timed out"** — the extension found no signed-in portal tab to read. Open the vendor's magic link, confirm the portal page has loaded, then retry.
|
|
177
|
-
- **"no confirmed browser session"** — the extension is connected but has not approved this MCP. Open the
|
|
178
|
+
- **"no confirmed browser session"** — the extension is connected but has not approved this MCP. Open the ContextMint Bridge popup and approve the pair code it shows, then retry.
|
|
179
|
+
- **"this browser … cannot serve the … capability"** — the browser you paired lacks an API the capture needs. Nothing is wrong with the MCP or your pairing, and retrying or re-approving will not help: run it from a browser that provides the API (for example Chrome).
|
|
178
180
|
- **"localStorage keys not in declared set"** — the MCP now reads a storage key your existing pairing doesn't cover. See [Upgrading from 0.4.4 or earlier](#upgrading-from-044-or-earlier). Retrying will not help, and this is not a version problem.
|
|
179
181
|
|
|
180
182
|
## Upgrading from 0.4.4 or earlier
|
|
@@ -187,7 +189,7 @@ localStorage keys not in declared set: HONEYBOOK_REACT_CURR_USER
|
|
|
187
189
|
|
|
188
190
|
To fix it, once:
|
|
189
191
|
|
|
190
|
-
1. Open the **
|
|
192
|
+
1. Open the **ContextMint Bridge** extension popup.
|
|
191
193
|
2. **Revoke** `honeybook-mcp`.
|
|
192
194
|
3. Re-run `use_magic_link` — a fresh pair code appears.
|
|
193
195
|
4. Approve it in the popup. You are approving the new scope.
|
package/dist/auth.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
//
|
|
20
20
|
// 2. fetchproxy bootstrap (this module).
|
|
21
21
|
// The user has signed into their vendor portal via a magic link in
|
|
22
|
-
// their real Chrome (the
|
|
22
|
+
// their real Chrome (the ContextMint Bridge extension is installed).
|
|
23
23
|
// We call `@fetchproxy/bootstrap` once to read the auth fields out
|
|
24
24
|
// of localStorage["HONEYBOOK_REACT_CURR_USER"], then close the
|
|
25
25
|
// bridge and operate from Node thereafter.
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
import { bootstrap } from '@fetchproxy/bootstrap';
|
|
67
67
|
import { bridgeErrorInfo } from '@chrischall/mcp-utils/fetchproxy';
|
|
68
68
|
import { parseBoolEnv } from '@chrischall/mcp-utils';
|
|
69
|
+
import { isBrowserCapabilityGap } from './bridge-errors.js';
|
|
69
70
|
import pkg from '../package.json' with { type: 'json' };
|
|
70
71
|
import { sessionStore, normalizeOrigin, vendorPortalSubdomain } from './sessions.js';
|
|
71
72
|
/** True if the user has explicitly disabled the fetchproxy capture path. */
|
|
@@ -77,7 +78,7 @@ function fetchproxyDisabled() {
|
|
|
77
78
|
* browser tab via `@fetchproxy/bootstrap`. Persists the result through
|
|
78
79
|
* `sessionStore` and returns it.
|
|
79
80
|
*
|
|
80
|
-
* Preconditions: the user has the
|
|
81
|
+
* Preconditions: the user has the ContextMint Bridge Chrome
|
|
81
82
|
* extension installed and is signed into the vendor's HoneyBook portal
|
|
82
83
|
* (typically by clicking the magic link in their vendor email). If
|
|
83
84
|
* either is missing, this throws with an actionable error message.
|
|
@@ -174,9 +175,18 @@ export async function captureSessionViaFetchproxy(opts) {
|
|
|
174
175
|
// SW eviction retry exhausted — surface library's typed `.hint` instead of the generic "open magic link" message.
|
|
175
176
|
const bridgeError = bridgeErrorInfo(e);
|
|
176
177
|
if (bridgeError.type === 'bridge_down') {
|
|
177
|
-
throw new Error(`HoneyBook auth:
|
|
178
|
+
throw new Error(`HoneyBook auth: ContextMint Bridge is down (its service worker was unreachable after retry). ${bridgeError.hint ?? ''}`.trimEnd());
|
|
178
179
|
}
|
|
179
180
|
const msg = e instanceof Error ? e.message : String(e);
|
|
181
|
+
// The paired browser lacks a capability we declared; the message carries the remedy.
|
|
182
|
+
if (bridgeError.type === 'capability_unavailable' || isBrowserCapabilityGap(e)) {
|
|
183
|
+
throw new Error(`HoneyBook auth: ${msg}`);
|
|
184
|
+
}
|
|
185
|
+
// We asked for a capability we never declared — our bug, not the user's
|
|
186
|
+
// browser or pairing, so retrying the link would not help.
|
|
187
|
+
if (bridgeError.type === 'capability_denied') {
|
|
188
|
+
throw new Error(`HoneyBook auth: ${bridgeError.hint} (${bridgeError.message})`);
|
|
189
|
+
}
|
|
180
190
|
// The extension gates on the scope approved at pair time, so widening the
|
|
181
191
|
// declaration — as the HONEYBOOK_REACT_CURR_USER migration did — is refused
|
|
182
192
|
// until the user re-approves. Every user paired before that upgrade hits
|
|
@@ -198,11 +208,11 @@ export async function captureSessionViaFetchproxy(opts) {
|
|
|
198
208
|
if (bridgeError.type === 'timeout' || /timeout/i.test(msg)) {
|
|
199
209
|
throw new Error('HoneyBook auth: fetchproxy capture timed out. The extension never returned the vendor ' +
|
|
200
210
|
"portal's stored session, which usually means no tab is open and signed in on that portal. " +
|
|
201
|
-
'Open the vendor magic-link URL in Chrome (with the
|
|
211
|
+
'Open the vendor magic-link URL in Chrome (with the ContextMint Bridge extension installed), confirm ' +
|
|
202
212
|
'the portal page has loaded, then re-run use_magic_link.');
|
|
203
213
|
}
|
|
204
214
|
throw new Error(`HoneyBook auth: fetchproxy capture failed: ${msg} — ` +
|
|
205
|
-
'open the vendor magic-link URL in Chrome (with the
|
|
215
|
+
'open the vendor magic-link URL in Chrome (with the ContextMint Bridge extension installed), ' +
|
|
206
216
|
'then retry.');
|
|
207
217
|
}
|
|
208
218
|
// 0.4.0: pointer extractions land in `session.localStorage` keyed by
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// fetchproxy 3.3+ distinguishes "this browser cannot serve a capability"
|
|
2
|
+
// (e.g. Safari lacking a WebExtension API) from a scope/pairing problem. That
|
|
3
|
+
// is the browser's limitation — not the MCP's fault, and not fixed by
|
|
4
|
+
// re-approving or retrying — so callers surface the library's own message
|
|
5
|
+
// verbatim instead of appending their generic "open the link, then retry".
|
|
6
|
+
//
|
|
7
|
+
// Matched on the class NAME rather than `instanceof` so a duplicated
|
|
8
|
+
// @fetchproxy/server copy in the dependency tree cannot defeat the check.
|
|
9
|
+
export function isBrowserCapabilityGap(e) {
|
|
10
|
+
const err = e;
|
|
11
|
+
if (err?.name === 'FetchproxyCapabilityUnavailableError')
|
|
12
|
+
return true;
|
|
13
|
+
return (err?.name === 'FetchproxyHelloRejectedError' &&
|
|
14
|
+
Array.isArray(err.unavailableCapabilities) &&
|
|
15
|
+
err.unavailableCapabilities.length > 0);
|
|
16
|
+
}
|