honeybook-mcp 0.4.1 → 0.4.3

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.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "HoneyBook client-portal tools for Claude Code",
10
- "version": "0.4.1"
10
+ "version": "0.4.3"
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": "0.4.1",
18
+ "version": "0.4.3",
19
19
  "author": {
20
20
  "name": "Chris Chall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "honeybook",
3
3
  "displayName": "HoneyBook",
4
- "version": "0.4.1",
4
+ "version": "0.4.3",
5
5
  "description": "HoneyBook client-portal MCP for Claude — view wedding-vendor contracts and invoices via MCP",
6
6
  "author": {
7
7
  "name": "Chris Chall",
package/dist/bundle.js CHANGED
@@ -3775,6 +3775,7 @@ var require_fast_uri = __commonJS({
3775
3775
  return uriTokens.join("");
3776
3776
  }
3777
3777
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3778
+ var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
3778
3779
  function getParseError(parsed, matches) {
3779
3780
  if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
3780
3781
  return 'URI path must start with "/" when authority is present.';
@@ -3804,6 +3805,11 @@ var require_fast_uri = __commonJS({
3804
3805
  uri = "//" + uri;
3805
3806
  }
3806
3807
  }
3808
+ const authorityMatch = uri.match(AUTHORITY_PREFIX);
3809
+ if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
3810
+ parsed.error = "URI authority must not contain a literal backslash.";
3811
+ malformedAuthorityOrPort = true;
3812
+ }
3807
3813
  const matches = uri.match(URI_PARSE);
3808
3814
  if (matches) {
3809
3815
  parsed.scheme = matches[1];
@@ -3847,7 +3853,7 @@ var require_fast_uri = __commonJS({
3847
3853
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3848
3854
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3849
3855
  try {
3850
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3856
+ parsed.host = new URL("http://" + parsed.host).hostname;
3851
3857
  } catch (e) {
3852
3858
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3853
3859
  }
@@ -7692,6 +7698,7 @@ var require_receiver = __commonJS({
7692
7698
  this._opcode = 0;
7693
7699
  this._totalPayloadLength = 0;
7694
7700
  this._messageLength = 0;
7701
+ this._numFragments = 0;
7695
7702
  this._fragments = [];
7696
7703
  this._errored = false;
7697
7704
  this._loop = false;
@@ -8042,23 +8049,23 @@ var require_receiver = __commonJS({
8042
8049
  this.controlMessage(data, cb);
8043
8050
  return;
8044
8051
  }
8052
+ if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
8053
+ const error51 = this.createError(
8054
+ RangeError,
8055
+ "Too many message fragments",
8056
+ false,
8057
+ 1008,
8058
+ "WS_ERR_TOO_MANY_BUFFERED_PARTS"
8059
+ );
8060
+ cb(error51);
8061
+ return;
8062
+ }
8045
8063
  if (this._compressed) {
8046
8064
  this._state = INFLATING;
8047
8065
  this.decompress(data, cb);
8048
8066
  return;
8049
8067
  }
8050
8068
  if (data.length) {
8051
- if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
8052
- const error51 = this.createError(
8053
- RangeError,
8054
- "Too many message fragments",
8055
- false,
8056
- 1008,
8057
- "WS_ERR_TOO_MANY_BUFFERED_PARTS"
8058
- );
8059
- cb(error51);
8060
- return;
8061
- }
8062
8069
  this._messageLength = this._totalPayloadLength;
8063
8070
  this._fragments.push(data);
8064
8071
  }
@@ -8088,17 +8095,6 @@ var require_receiver = __commonJS({
8088
8095
  cb(error51);
8089
8096
  return;
8090
8097
  }
8091
- if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
8092
- const error51 = this.createError(
8093
- RangeError,
8094
- "Too many message fragments",
8095
- false,
8096
- 1008,
8097
- "WS_ERR_TOO_MANY_BUFFERED_PARTS"
8098
- );
8099
- cb(error51);
8100
- return;
8101
- }
8102
8098
  this._fragments.push(buf);
8103
8099
  }
8104
8100
  this.dataMessage(cb);
@@ -8121,6 +8117,7 @@ var require_receiver = __commonJS({
8121
8117
  this._totalPayloadLength = 0;
8122
8118
  this._messageLength = 0;
8123
8119
  this._fragmented = 0;
8120
+ this._numFragments = 0;
8124
8121
  this._fragments = [];
8125
8122
  if (this._opcode === 2) {
8126
8123
  let data;
@@ -9621,8 +9618,8 @@ var require_websocket = __commonJS({
9621
9618
  autoPong: true,
9622
9619
  closeTimeout: CLOSE_TIMEOUT,
9623
9620
  protocolVersion: protocolVersions[1],
9624
- maxBufferedChunks: 1024 * 1024,
9625
- maxFragments: 128 * 1024,
9621
+ maxBufferedChunks: 256 * 1024,
9622
+ maxFragments: 16 * 1024,
9626
9623
  maxPayload: 100 * 1024 * 1024,
9627
9624
  skipUTF8Validation: false,
9628
9625
  perMessageDeflate: true,
@@ -10209,9 +10206,9 @@ var require_websocket_server = __commonJS({
10209
10206
  * called
10210
10207
  * @param {Function} [options.handleProtocols] A hook to handle protocols
10211
10208
  * @param {String} [options.host] The hostname where to bind the server
10212
- * @param {Number} [options.maxBufferedChunks=1048576] The maximum number of
10209
+ * @param {Number} [options.maxBufferedChunks=262144] The maximum number of
10213
10210
  * buffered data chunks
10214
- * @param {Number} [options.maxFragments=131072] The maximum number of message
10211
+ * @param {Number} [options.maxFragments=16384] The maximum number of message
10215
10212
  * fragments
10216
10213
  * @param {Number} [options.maxPayload=104857600] The maximum allowed message
10217
10214
  * size
@@ -10234,8 +10231,8 @@ var require_websocket_server = __commonJS({
10234
10231
  options = {
10235
10232
  allowSynchronousEvents: true,
10236
10233
  autoPong: true,
10237
- maxBufferedChunks: 1024 * 1024,
10238
- maxFragments: 128 * 1024,
10234
+ maxBufferedChunks: 256 * 1024,
10235
+ maxFragments: 16 * 1024,
10239
10236
  maxPayload: 100 * 1024 * 1024,
10240
10237
  skipUTF8Validation: false,
10241
10238
  perMessageDeflate: false,
@@ -35072,7 +35069,8 @@ var KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
35072
35069
  "capture_redirect",
35073
35070
  "read_indexed_db",
35074
35071
  "read_dom",
35075
- "download"
35072
+ "download",
35073
+ "graphql"
35076
35074
  ]);
35077
35075
 
35078
35076
  // node_modules/@fetchproxy/protocol/dist/mcp-id.js
@@ -35375,6 +35373,7 @@ function assertIndexedDbScopesArray(value, label) {
35375
35373
  }
35376
35374
  var DOM_SELECTOR_RE = /^[^-]{1,512}$/;
35377
35375
  var DOM_ATTRIBUTE_RE = /^[A-Za-z_:][A-Za-z0-9_:.\-]{0,127}$/;
35376
+ var GRAPHQL_OP_NAME_RE = /^[_A-Za-z][_0-9A-Za-z]{0,127}$/;
35378
35377
  function assertDomSelectorsArray(value, label) {
35379
35378
  if (!Array.isArray(value)) {
35380
35379
  throw new ProtocolError(`${label}: expected array, got ${typeof value}`);
@@ -35411,6 +35410,37 @@ function assertDomSelectorsArray(value, label) {
35411
35410
  }
35412
35411
  }
35413
35412
  }
35413
+ function assertGraphqlOpsArray(value, label) {
35414
+ if (!Array.isArray(value)) {
35415
+ throw new ProtocolError(`${label}: expected array, got ${typeof value}`);
35416
+ }
35417
+ const seen = /* @__PURE__ */ new Set();
35418
+ for (let i = 0; i < value.length; i++) {
35419
+ const entry = value[i];
35420
+ assertObject(entry, `${label}[${i}]`);
35421
+ if (entry.name === void 0) {
35422
+ throw new ProtocolError(`${label}[${i}].name: missing`);
35423
+ }
35424
+ if (entry.operationName === void 0) {
35425
+ throw new ProtocolError(`${label}[${i}].operationName: missing`);
35426
+ }
35427
+ if (typeof entry.name !== "string" || !SCOPE_KEY_RE.test(entry.name)) {
35428
+ throw new ProtocolError(`${label}[${i}].name: invalid ${JSON.stringify(entry.name)}`);
35429
+ }
35430
+ if (typeof entry.operationName !== "string" || !GRAPHQL_OP_NAME_RE.test(entry.operationName)) {
35431
+ throw new ProtocolError(`${label}[${i}].operationName: invalid ${JSON.stringify(entry.operationName)}`);
35432
+ }
35433
+ if (seen.has(entry.name)) {
35434
+ throw new ProtocolError(`${label}: duplicate name ${JSON.stringify(entry.name)}`);
35435
+ }
35436
+ seen.add(entry.name);
35437
+ for (const k of Object.keys(entry)) {
35438
+ if (k !== "name" && k !== "operationName") {
35439
+ throw new ProtocolError(`${label}[${i}]: unexpected field ${JSON.stringify(k)}`);
35440
+ }
35441
+ }
35442
+ }
35443
+ }
35414
35444
  function validateFrame(raw) {
35415
35445
  assertObject(raw, "frame");
35416
35446
  const t = raw.type;
@@ -35489,6 +35519,9 @@ function validateHello(raw) {
35489
35519
  if (raw.domSelectors !== void 0) {
35490
35520
  assertDomSelectorsArray(raw.domSelectors, "hello.domSelectors");
35491
35521
  }
35522
+ if (raw.graphqlOps !== void 0) {
35523
+ assertGraphqlOpsArray(raw.graphqlOps, "hello.graphqlOps");
35524
+ }
35492
35525
  assertBase64(raw.identityX25519Pub, "hello.identityX25519Pub");
35493
35526
  assertBase64(raw.identityEd25519Pub, "hello.identityEd25519Pub");
35494
35527
  assertBase64(raw.sessionNonce, "hello.sessionNonce");
@@ -35738,6 +35771,28 @@ function validateInnerRequest(raw) {
35738
35771
  }
35739
35772
  return raw;
35740
35773
  }
35774
+ if (raw.op === "graphql_query") {
35775
+ assertObject(raw.init, "inner.init");
35776
+ if (raw.init.name === void 0)
35777
+ throw new ProtocolError("inner.init.name: missing");
35778
+ if (raw.init.variables === void 0) {
35779
+ throw new ProtocolError("inner.init.variables: missing");
35780
+ }
35781
+ assertString(raw.init.name, "inner.init.name");
35782
+ if (raw.init.name.length === 0) {
35783
+ throw new ProtocolError("inner.init.name: must be non-empty");
35784
+ }
35785
+ assertObject(raw.init.variables, "inner.init.variables");
35786
+ if (raw.init.tabUrl !== void 0) {
35787
+ assertString(raw.init.tabUrl, "inner.init.tabUrl");
35788
+ }
35789
+ for (const k of Object.keys(raw.init)) {
35790
+ if (k !== "name" && k !== "variables" && k !== "tabUrl") {
35791
+ throw new ProtocolError(`inner.init: unexpected field ${JSON.stringify(k)} on graphql_query`);
35792
+ }
35793
+ }
35794
+ return raw;
35795
+ }
35741
35796
  if (raw.op === "download") {
35742
35797
  assertObject(raw.init, "inner.init");
35743
35798
  if (raw.init.url === void 0) {
@@ -35763,7 +35818,7 @@ function validateInnerRequest(raw) {
35763
35818
  }
35764
35819
  return raw;
35765
35820
  }
35766
- throw new ProtocolError(`inner.op: must be one of "fetch", "read_cookies", "read_local_storage", "read_session_storage", "capture_request_header", "capture_redirect", "read_indexed_db", "read_dom", "download"; got ${JSON.stringify(raw.op)}`);
35821
+ throw new ProtocolError(`inner.op: must be one of "fetch", "read_cookies", "read_local_storage", "read_session_storage", "capture_request_header", "capture_redirect", "read_indexed_db", "read_dom", "download", "graphql_query"; got ${JSON.stringify(raw.op)}`);
35767
35822
  }
35768
35823
  function assertNonEmptyKeyArray(value, label) {
35769
35824
  if (!Array.isArray(value)) {
@@ -35794,6 +35849,10 @@ function assertStringMap(value, label) {
35794
35849
  }
35795
35850
  }
35796
35851
  }
35852
+ var KNOWN_RESPONSE_OPS = /* @__PURE__ */ new Set([
35853
+ ...KNOWN_CAPABILITIES,
35854
+ "graphql_query"
35855
+ ]);
35797
35856
  function validateInnerResponse(raw) {
35798
35857
  assertPositiveInt(raw.id, "inner.id");
35799
35858
  if (raw.ok === true) {
@@ -35855,6 +35914,13 @@ function validateInnerResponse(raw) {
35855
35914
  assertStringMap(raw.values, "inner.values");
35856
35915
  return raw;
35857
35916
  }
35917
+ if (op === "graphql_query") {
35918
+ if (raw.data === void 0) {
35919
+ throw new ProtocolError("inner.data: missing on graphql_query response");
35920
+ }
35921
+ assertObject(raw.data, "inner.data");
35922
+ return raw;
35923
+ }
35858
35924
  if (op === "download") {
35859
35925
  assertObject(raw.value, "inner.value");
35860
35926
  assertString(raw.value.path, "inner.value.path");
@@ -35879,7 +35945,7 @@ function validateInnerResponse(raw) {
35879
35945
  if (raw.ok === false) {
35880
35946
  assertString(raw.error, "inner.error");
35881
35947
  if (raw.op !== void 0) {
35882
- if (typeof raw.op !== "string" || !KNOWN_CAPABILITIES.has(raw.op)) {
35948
+ if (typeof raw.op !== "string" || !KNOWN_RESPONSE_OPS.has(raw.op)) {
35883
35949
  throw new ProtocolError(`inner.op: unknown response op ${JSON.stringify(raw.op)}`);
35884
35950
  }
35885
35951
  }
@@ -36071,11 +36137,33 @@ async function sealInnerFrame(sessionKey, mcpId, seq, inner) {
36071
36137
  };
36072
36138
  }
36073
36139
  async function openEncryptedFrame(sessionKey, frame) {
36074
- const iv = fromB64(frame.iv);
36075
- const ct = fromB64(frame.ciphertext);
36076
- const pt = await aesGcmOpen(sessionKey, iv, ct);
36077
- const parsed = JSON.parse(dec.decode(pt));
36078
- return validateInnerFrame(parsed);
36140
+ const result = await openEncryptedFrameDetailed(sessionKey, frame);
36141
+ if (result.stage === "ok")
36142
+ return result.inner;
36143
+ throw result.error instanceof Error ? result.error : new Error(String(result.error));
36144
+ }
36145
+ async function openEncryptedFrameDetailed(sessionKey, frame) {
36146
+ let pt;
36147
+ try {
36148
+ const iv = fromB64(frame.iv);
36149
+ const ct = fromB64(frame.ciphertext);
36150
+ pt = await aesGcmOpen(sessionKey, iv, ct);
36151
+ } catch (error51) {
36152
+ return { stage: "decrypt-failed", error: error51 };
36153
+ }
36154
+ let parsed;
36155
+ try {
36156
+ parsed = JSON.parse(dec.decode(pt));
36157
+ } catch (error51) {
36158
+ return { stage: "validation-failed", error: error51, recoveredId: void 0 };
36159
+ }
36160
+ try {
36161
+ const inner = validateInnerFrame(parsed);
36162
+ return { stage: "ok", inner };
36163
+ } catch (error51) {
36164
+ const recoveredId = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && typeof parsed.id === "number" && Number.isInteger(parsed.id) && parsed.id > 0 ? parsed.id : void 0;
36165
+ return { stage: "validation-failed", error: error51, recoveredId };
36166
+ }
36079
36167
  }
36080
36168
 
36081
36169
  // node_modules/@fetchproxy/server/dist/election.js
@@ -36201,6 +36289,12 @@ async function buildServerHello(opts) {
36201
36289
  ...d.attribute !== void 0 ? { attribute: d.attribute } : {}
36202
36290
  }));
36203
36291
  }
36292
+ if (opts.graphqlOps && opts.graphqlOps.length > 0) {
36293
+ hello.graphqlOps = opts.graphqlOps.map((d) => ({
36294
+ name: d.name,
36295
+ operationName: d.operationName
36296
+ }));
36297
+ }
36204
36298
  return hello;
36205
36299
  }
36206
36300
 
@@ -36291,7 +36385,8 @@ async function startHost(opts) {
36291
36385
  indexedDbScopes: opts.ownIndexedDbScopes,
36292
36386
  localStoragePointers: opts.ownLocalStoragePointers,
36293
36387
  sessionStoragePointers: opts.ownSessionStoragePointers,
36294
- domSelectors: opts.ownDomSelectors
36388
+ domSelectors: opts.ownDomSelectors,
36389
+ graphqlOps: opts.ownGraphqlOps
36295
36390
  });
36296
36391
  const ownSessionNonce = fromB64(ownHello.sessionNonce);
36297
36392
  let extensionWs = null;
@@ -36528,7 +36623,8 @@ async function startPeer(opts) {
36528
36623
  indexedDbScopes: opts.indexedDbScopes,
36529
36624
  domSelectors: opts.domSelectors,
36530
36625
  localStoragePointers: opts.localStoragePointers,
36531
- sessionStoragePointers: opts.sessionStoragePointers
36626
+ sessionStoragePointers: opts.sessionStoragePointers,
36627
+ graphqlOps: opts.graphqlOps
36532
36628
  });
36533
36629
  const sessionNonce = fromB64(hello.sessionNonce);
36534
36630
  ws.send(JSON.stringify(hello));
@@ -36572,10 +36668,20 @@ async function startPeer(opts) {
36572
36668
  return;
36573
36669
  if (!session.acceptInboundSeq(frame.seq))
36574
36670
  return;
36575
- try {
36576
- const inner = await openEncryptedFrame(session.sessionKey, frame);
36577
- innerListeners.forEach((cb) => cb(inner));
36578
- } catch {
36671
+ const result = await openEncryptedFrameDetailed(session.sessionKey, frame);
36672
+ if (result.stage === "ok") {
36673
+ innerListeners.forEach((cb) => cb(result.inner));
36674
+ } else if (result.stage === "decrypt-failed") {
36675
+ } else {
36676
+ console.error("[fetchproxy] peer: received a frame that decrypted OK but failed validation:", result.error);
36677
+ if (result.recoveredId !== void 0) {
36678
+ innerListeners.forEach((cb) => cb({
36679
+ type: "response",
36680
+ id: result.recoveredId,
36681
+ ok: false,
36682
+ error: `malformed response failed protocol validation: ${String(result.error)}`
36683
+ }));
36684
+ }
36579
36685
  }
36580
36686
  }
36581
36687
  } catch (e) {
@@ -36852,6 +36958,10 @@ var FetchproxyServer = class {
36852
36958
  pendingIdb = /* @__PURE__ */ new Map();
36853
36959
  // download awaiters resolve the saved-file metadata (path + size + mime).
36854
36960
  pendingDownload = /* @__PURE__ */ new Map();
36961
+ // 1.x+: graphql_query awaiters resolve the GraphQL `data` object. Its
36962
+ // shape is operation-specific, so the awaiter resolves `unknown` and the
36963
+ // caller narrows.
36964
+ pendingGraphql = /* @__PURE__ */ new Map();
36855
36965
  mcpId = null;
36856
36966
  identity = null;
36857
36967
  // 0.5.3+: in-flight role-election / handle-start promise. Set the
@@ -36939,6 +37049,10 @@ var FetchproxyServer = class {
36939
37049
  selector: d.selector,
36940
37050
  ...d.attribute !== void 0 ? { attribute: d.attribute } : {}
36941
37051
  })),
37052
+ graphqlOps: (opts.graphqlOps ?? []).map((d) => ({
37053
+ name: d.name,
37054
+ operationName: d.operationName
37055
+ })),
36942
37056
  // 0.8.0+: timer + lazy-revive default to ON. Every realty MCP
36943
37057
  // adapter was about to set these to the same numbers anyway; the
36944
37058
  // back-door is `0` (explicit opt-out) if a caller genuinely wants
@@ -37060,6 +37174,7 @@ var FetchproxyServer = class {
37060
37174
  ownLocalStoragePointers: this.opts.localStoragePointers,
37061
37175
  ownSessionStoragePointers: this.opts.sessionStoragePointers,
37062
37176
  ownDomSelectors: this.opts.domSelectors,
37177
+ ownGraphqlOps: this.opts.graphqlOps,
37063
37178
  onPairCode: this.opts.onPairCode
37064
37179
  });
37065
37180
  this.hostHandle.onOwnInner((inner) => this.onInner(inner));
@@ -37088,7 +37203,8 @@ var FetchproxyServer = class {
37088
37203
  indexedDbScopes: this.opts.indexedDbScopes,
37089
37204
  localStoragePointers: this.opts.localStoragePointers,
37090
37205
  sessionStoragePointers: this.opts.sessionStoragePointers,
37091
- domSelectors: this.opts.domSelectors
37206
+ domSelectors: this.opts.domSelectors,
37207
+ graphqlOps: this.opts.graphqlOps
37092
37208
  });
37093
37209
  this.peerHandle.onInner((inner) => this.onInner(inner));
37094
37210
  this.peerHandle.onRenegotiate(() => {
@@ -37294,6 +37410,7 @@ var FetchproxyServer = class {
37294
37410
  this.pendingRedirect.delete(id);
37295
37411
  this.pendingDownload.delete(id);
37296
37412
  this.pendingIdb.delete(id);
37413
+ this.pendingGraphql.delete(id);
37297
37414
  }
37298
37415
  throw err;
37299
37416
  }
@@ -38103,6 +38220,52 @@ var FetchproxyServer = class {
38103
38220
  await this.sendInnerFrame(inner);
38104
38221
  return this._withVerbTimeout(pending, this.pendingStorage, id, origin);
38105
38222
  }
38223
+ /**
38224
+ * 1.x+: run a declared GraphQL operation through the page's own Apollo
38225
+ * client (`window.__APOLLO_CLIENT__`) in the signed-in tab's MAIN world.
38226
+ * Requires `'graphql'` in capabilities AND `name` to match a declared
38227
+ * `graphqlOps` entry. The extension resolves `name` → `operationName` →
38228
+ * the live DocumentNode the page already observed, then invokes
38229
+ * `client.query({ query, variables })` — the site's own request path, so
38230
+ * per-request bot telemetry (Akamai etc.) runs automatically.
38231
+ *
38232
+ * Returns the GraphQL `data` object on success (shape is
38233
+ * operation-specific; the caller narrows). Throws a plain `Error` on
38234
+ * developer mistakes (undeclared capability, undeclared name) and a
38235
+ * descriptive `Error` on the `ok:false` bridge path — which includes the
38236
+ * typed "operation not yet observed on this tab" case (open the site's
38237
+ * page and retry).
38238
+ */
38239
+ async graphqlQuery(opts) {
38240
+ if (!this.opts.capabilities.includes("graphql")) {
38241
+ throw new Error('FetchproxyServer.graphqlQuery(): MCP did not declare "graphql" in capabilities');
38242
+ }
38243
+ if (typeof opts.name !== "string" || opts.name.length === 0) {
38244
+ throw new Error("FetchproxyServer.graphqlQuery: opts.name must be a non-empty string");
38245
+ }
38246
+ const declaredNames = this.opts.graphqlOps.map((d) => d.name);
38247
+ if (!declaredNames.includes(opts.name)) {
38248
+ throw new Error(`FetchproxyServer.graphqlQuery: operation ${JSON.stringify(opts.name)} not in declared graphqlOps [${declaredNames.map((n) => JSON.stringify(n)).join(", ")}]`);
38249
+ }
38250
+ await this.ensureConnected();
38251
+ this.throwIfPendingPair();
38252
+ const id = this.nextRequestId++;
38253
+ const inner = {
38254
+ type: "request",
38255
+ id,
38256
+ op: "graphql_query",
38257
+ init: {
38258
+ name: opts.name,
38259
+ variables: opts.variables,
38260
+ ...opts.tabUrl !== void 0 ? { tabUrl: opts.tabUrl } : {}
38261
+ }
38262
+ };
38263
+ const pending = new Promise((resolve, reject) => {
38264
+ this.pendingGraphql.set(id, { resolve, reject });
38265
+ });
38266
+ await this.sendInnerFrame(inner);
38267
+ return this._withVerbTimeout(pending, this.pendingGraphql, id, opts.name);
38268
+ }
38106
38269
  assertScopeSubset(requested, declared, label) {
38107
38270
  const undeclared = undeclaredKeys(requested, declared);
38108
38271
  if (undeclared.length > 0) {
@@ -38240,6 +38403,20 @@ var FetchproxyServer = class {
38240
38403
  }
38241
38404
  return;
38242
38405
  }
38406
+ const graphqlCb = this.pendingGraphql.get(inner.id);
38407
+ if (graphqlCb) {
38408
+ this.pendingGraphql.delete(inner.id);
38409
+ if (inner.ok) {
38410
+ if (inner.op === "graphql_query") {
38411
+ graphqlCb.resolve(inner.data);
38412
+ } else {
38413
+ graphqlCb.reject(new FetchproxyProtocolError(`unexpected ${String(inner.op)} response on graphql_query awaiter`));
38414
+ }
38415
+ } else {
38416
+ graphqlCb.reject(new FetchproxyProtocolError(inner.error));
38417
+ }
38418
+ return;
38419
+ }
38243
38420
  const cookiesCb = this.pendingReadCookies.get(inner.id);
38244
38421
  if (cookiesCb) {
38245
38422
  this.pendingReadCookies.delete(inner.id);
@@ -38291,6 +38468,9 @@ var FetchproxyServer = class {
38291
38468
  for (const { reject } of this.pendingDownload.values())
38292
38469
  reject(err);
38293
38470
  this.pendingDownload.clear();
38471
+ for (const { reject } of this.pendingGraphql.values())
38472
+ reject(err);
38473
+ this.pendingGraphql.clear();
38294
38474
  }
38295
38475
  /**
38296
38476
  * 0.5.2+: read the current pair-pending pair code from whichever handle
@@ -38532,7 +38712,7 @@ function bridgeErrorInfo(err) {
38532
38712
  // package.json
38533
38713
  var package_default = {
38534
38714
  name: "honeybook-mcp",
38535
- version: "0.4.1",
38715
+ version: "0.4.3",
38536
38716
  mcpName: "io.github.chrischall/honeybook-mcp",
38537
38717
  description: "HoneyBook client-portal MCP server for Claude",
38538
38718
  author: "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -38572,9 +38752,9 @@ var package_default = {
38572
38752
  "test:watch": "vitest"
38573
38753
  },
38574
38754
  dependencies: {
38575
- "@chrischall/mcp-utils": "^0.13.0",
38576
- "@fetchproxy/bootstrap": "^1.0.0",
38577
- "@fetchproxy/server": "^1.0.0",
38755
+ "@chrischall/mcp-utils": "^0.14.0",
38756
+ "@fetchproxy/bootstrap": "^1.7.0",
38757
+ "@fetchproxy/server": "^1.7.0",
38578
38758
  "@modelcontextprotocol/sdk": "^1.29.0",
38579
38759
  dotenv: "^17.4.2",
38580
38760
  zod: "^4.4.3"
@@ -39169,7 +39349,7 @@ var __dirname = dirname2(fileURLToPath(import.meta.url));
39169
39349
  await loadDotenvSafely({ path: join3(__dirname, "..", ".env"), override: false });
39170
39350
  await runMcp({
39171
39351
  name: "honeybook-mcp",
39172
- version: "0.4.1",
39352
+ version: "0.4.3",
39173
39353
  // x-release-please-version
39174
39354
  tools: [
39175
39355
  registerSessionTools,
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { registerContractTools } from './tools/contracts.js';
11
11
  import { registerInvoiceTools } from './tools/invoices.js';
12
12
  await runMcp({
13
13
  name: 'honeybook-mcp',
14
- version: '0.4.1', // x-release-please-version
14
+ version: '0.4.3', // x-release-please-version
15
15
  tools: [
16
16
  registerSessionTools,
17
17
  registerWorkspaceFileTools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honeybook-mcp",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "mcpName": "io.github.chrischall/honeybook-mcp",
5
5
  "description": "HoneyBook client-portal MCP server for Claude",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -40,9 +40,9 @@
40
40
  "test:watch": "vitest"
41
41
  },
42
42
  "dependencies": {
43
- "@chrischall/mcp-utils": "^0.13.0",
44
- "@fetchproxy/bootstrap": "^1.0.0",
45
- "@fetchproxy/server": "^1.0.0",
43
+ "@chrischall/mcp-utils": "^0.14.0",
44
+ "@fetchproxy/bootstrap": "^1.7.0",
45
+ "@fetchproxy/server": "^1.7.0",
46
46
  "@modelcontextprotocol/sdk": "^1.29.0",
47
47
  "dotenv": "^17.4.2",
48
48
  "zod": "^4.4.3"
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/honeybook-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.4.1",
9
+ "version": "0.4.3",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "honeybook-mcp",
14
- "version": "0.4.1",
14
+ "version": "0.4.3",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },