honeybook-mcp 1.2.6 → 1.2.7

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": "1.2.6"
10
+ "version": "1.2.7"
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.6",
18
+ "version": "1.2.7",
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": "1.2.6",
4
+ "version": "1.2.7",
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/.mcp.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "honeybook": {
4
- "command": "node",
5
- "args": ["${CLAUDE_PLUGIN_ROOT}/dist/bundle.js"]
4
+ "command": "npx",
5
+ "args": ["-y", "honeybook-mcp"]
6
6
  }
7
7
  }
8
8
  }
package/dist/bundle.js CHANGED
@@ -90,6 +90,7 @@ var require_util = __commonJS({
90
90
  exports.explicitlyAborted = explicitlyAborted2;
91
91
  exports.prefixIssues = prefixIssues2;
92
92
  exports.unwrapMessage = unwrapMessage2;
93
+ exports.sizeCaps = sizeCaps2;
93
94
  exports.attachSchema = attachSchema2;
94
95
  exports.finalizeIssue = finalizeIssue2;
95
96
  exports.getSizableOrigin = getSizableOrigin2;
@@ -624,6 +625,18 @@ var require_util = __commonJS({
624
625
  function unwrapMessage2(message) {
625
626
  return typeof message === "string" ? message : message?.message;
626
627
  }
628
+ function sizeCaps2(defChecks) {
629
+ const caps = [];
630
+ for (const ch of defChecks ?? []) {
631
+ const d = ch._zod.def;
632
+ if (!/_(length|size)$|_equals$/.test(d.check))
633
+ break;
634
+ const max = d.maximum ?? d.length ?? d.size;
635
+ if (max >= 0)
636
+ caps.push([max, ch]);
637
+ }
638
+ return caps;
639
+ }
627
640
  function attachSchema2(issues, start, inst) {
628
641
  var _a3;
629
642
  for (let i = start; i < issues.length; i++) {
@@ -2288,7 +2301,7 @@ var require_versions = __commonJS({
2288
2301
  exports.version = {
2289
2302
  major: 4,
2290
2303
  minor: 6,
2291
- patch: 5
2304
+ patch: 7
2292
2305
  };
2293
2306
  (function() {
2294
2307
  var keys = Object.getOwnPropertyNames(exports);
@@ -3122,6 +3135,31 @@ var require_schemas = __commonJS({
3122
3135
  return payload;
3123
3136
  };
3124
3137
  });
3138
+ function capSize2(inst, size) {
3139
+ const caps = util.sizeCaps(inst._zod.def.checks);
3140
+ if (!caps.length)
3141
+ return;
3142
+ const cap = Math.min(...caps.map((c) => c[0]));
3143
+ const parse3 = inst._zod.parse;
3144
+ inst._zod.parse = (payload, ctx) => {
3145
+ const n = size(payload.value);
3146
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
3147
+ for (const [max, ch] of util.sizeCaps(inst._zod.def.checks)) {
3148
+ if (n > max && ch._zod.def.when(payload)) {
3149
+ const start = payload.issues.length;
3150
+ ch._zod.check(payload);
3151
+ payload.issues[start].continue = false;
3152
+ util.attachSchema(payload.issues, start, inst);
3153
+ return payload;
3154
+ }
3155
+ }
3156
+ }
3157
+ return parse3(payload, ctx);
3158
+ };
3159
+ }
3160
+ var arraySize2 = (input2) => Array.isArray(input2) ? input2.length : -1;
3161
+ var mapSize2 = (input2) => input2 instanceof Map ? input2.size : -1;
3162
+ var setSize2 = (input2) => input2 instanceof Set ? input2.size : -1;
3125
3163
  function handleArrayResult2(result, final, index) {
3126
3164
  if (result.issues.length) {
3127
3165
  final.issues.push(...util.prefixIssues(index, result.issues));
@@ -3165,6 +3203,7 @@ var require_schemas = __commonJS({
3165
3203
  }
3166
3204
  return payload;
3167
3205
  };
3206
+ capSize2(inst, arraySize2);
3168
3207
  });
3169
3208
  function handlePropertyResult2(result, final, key, input2, optin, optout) {
3170
3209
  const isPresent = key in input2;
@@ -4121,6 +4160,7 @@ var require_schemas = __commonJS({
4121
4160
  return Promise.all(proms).then(() => payload);
4122
4161
  return payload;
4123
4162
  };
4163
+ capSize2(inst, mapSize2);
4124
4164
  });
4125
4165
  function handleMapResult2(keyResult, valueResult, final, key, input2, inst, ctx) {
4126
4166
  if (keyResult.issues.length) {
@@ -4187,6 +4227,7 @@ var require_schemas = __commonJS({
4187
4227
  return Promise.all(proms).then(() => payload);
4188
4228
  return payload;
4189
4229
  };
4230
+ capSize2(inst, setSize2);
4190
4231
  });
4191
4232
  function handleSetResult2(result, final) {
4192
4233
  if (result.issues.length) {
@@ -16291,9 +16332,15 @@ ${code2}
16291
16332
  doc.write(`}`);
16292
16333
  return outputVar;
16293
16334
  }
16335
+ function generateSizeGate2(doc, schema, size) {
16336
+ for (const [max, check2] of util.sizeCaps(schema._zod.def.checks)) {
16337
+ doc.write(`if (${size} > ${numericOperand2(max, check2._zod.def.check)}) return INVALID;`);
16338
+ }
16339
+ }
16294
16340
  function generateArrayCheck2(doc, ctx, schema, accessor, buildsValue = true) {
16295
16341
  const def = schema._zod.def;
16296
16342
  doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
16343
+ generateSizeGate2(doc, schema, `${accessor}.length`);
16297
16344
  const outputVar = buildsValue ? newVar2(ctx) : null;
16298
16345
  const iVar = newVar2(ctx);
16299
16346
  const elemVar = newVar2(ctx);
@@ -16693,6 +16740,7 @@ ${code2}
16693
16740
  function generateMapCheck2(doc, ctx, schema, accessor) {
16694
16741
  const def = schema._zod.def;
16695
16742
  doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
16743
+ generateSizeGate2(doc, schema, `${accessor}.size`);
16696
16744
  const outputVar = newVar2(ctx);
16697
16745
  const kVar = newVar2(ctx);
16698
16746
  const valVar = newVar2(ctx);
@@ -16709,6 +16757,7 @@ ${code2}
16709
16757
  function generateSetCheck2(doc, ctx, schema, accessor) {
16710
16758
  const def = schema._zod.def;
16711
16759
  doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
16760
+ generateSizeGate2(doc, schema, `${accessor}.size`);
16712
16761
  const outputVar = newVar2(ctx);
16713
16762
  const valVar = newVar2(ctx);
16714
16763
  doc.write(`const ${outputVar} = new Set();`);
@@ -27109,7 +27158,7 @@ function declaredDialect(schema, remedy) {
27109
27158
  throw new Error(`JSON Schema declares an unsupported dialect ("$schema": "${schema.$schema.slice(0, 200)}"). The default validator supports JSON Schema 2020-12, 2019-09, draft-07, and draft-06; ${remedy}`);
27110
27159
  }
27111
27160
 
27112
- // node_modules/@modelcontextprotocol/core/dist/auth-BNDyLTqp.mjs
27161
+ // node_modules/@modelcontextprotocol/server/node_modules/@modelcontextprotocol/core/dist/auth-BNDyLTqp.mjs
27113
27162
  var z = __toESM(require_v4(), 1);
27114
27163
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
27115
27164
  var SUPPORTED_PROTOCOL_VERSIONS = [
@@ -41933,7 +41982,7 @@ var API_KEY_RE = new RegExp([
41933
41982
  // webhook signing secret (Stripe-style)
41934
41983
  ].map((p) => `\\b${p}`).join("|"), "g");
41935
41984
  var GOOGLE_OAUTH_TOKEN_RE = /(?<![A-Za-z0-9+/])(?:ya29\.|1\/\/)[A-Za-z0-9._-]{8,}/g;
41936
- var QUERY_SECRET_RE = new RegExp(`([?&](?:(?:access|refresh|id|auth|session|csrf|xsrf)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|token|key|sig|(?:code[_-]?)?verifier|(?:php|j)?sess(?:ion)?[_-]?id|sid|x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN})=)[^&#\\s"'<>\`]+`, "gi");
41985
+ var QUERY_SECRET_RE = new RegExp(`([?&#;](?:(?:access|refresh|id|auth|session|csrf|xsrf|api)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|secret|token|auth|key|sig|(?:code[_-]?)?verifier|(?:php|j)?sess(?:ion)?[_-]?id|sid|x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN})=)[^&#\\s"'<>\`]+`, "gi");
41937
41986
  var OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
41938
41987
  var FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
41939
41988
  var HEADER_SECRET_RE = new RegExp(`(\\b(?:x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN}|api[-_]?key)\\s*:\\s*)[^\\s,;"'<>\`]+`, "gi");
@@ -41944,6 +41993,8 @@ var JSON_SECRET_KEYS = [
41944
41993
  "api[_-]?secret",
41945
41994
  "(?:x[_-])?api[_-]?key",
41946
41995
  "private[_-]?key",
41996
+ "aws[_-]?secret[_-]?access[_-]?key",
41997
+ // fleet-audit#1297
41947
41998
  "code[_-]?verifier",
41948
41999
  // PKCE; a bare `verifier` key is too generic for JSON
41949
42000
  `x[_-]${HEADER_NAME_RUN}?(?:api[_-]?key|token|secret|auth)${HEADER_NAME_RUN}`,
@@ -42641,6 +42692,7 @@ __export(util_exports, {
42641
42692
  required: () => required,
42642
42693
  safeExtend: () => safeExtend,
42643
42694
  shallowClone: () => shallowClone,
42695
+ sizeCaps: () => sizeCaps,
42644
42696
  slugify: () => slugify,
42645
42697
  stringifyPrimitive: () => stringifyPrimitive,
42646
42698
  toZod: () => toZod,
@@ -43160,6 +43212,18 @@ function prefixIssues(path, issues) {
43160
43212
  function unwrapMessage(message) {
43161
43213
  return typeof message === "string" ? message : message?.message;
43162
43214
  }
43215
+ function sizeCaps(defChecks) {
43216
+ const caps = [];
43217
+ for (const ch of defChecks ?? []) {
43218
+ const d = ch._zod.def;
43219
+ if (!/_(length|size)$|_equals$/.test(d.check))
43220
+ break;
43221
+ const max = d.maximum ?? d.length ?? d.size;
43222
+ if (max >= 0)
43223
+ caps.push([max, ch]);
43224
+ }
43225
+ return caps;
43226
+ }
43163
43227
  function attachSchema(issues, start, inst) {
43164
43228
  var _a3;
43165
43229
  for (let i = start; i < issues.length; i++) {
@@ -44580,7 +44644,7 @@ ${content.join("\n")}
44580
44644
  var version = {
44581
44645
  major: 4,
44582
44646
  minor: 6,
44583
- patch: 5
44647
+ patch: 7
44584
44648
  };
44585
44649
 
44586
44650
  // node_modules/zod/v4/core/schemas.js
@@ -45336,6 +45400,31 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
45336
45400
  return payload;
45337
45401
  };
45338
45402
  });
45403
+ function capSize(inst, size) {
45404
+ const caps = sizeCaps(inst._zod.def.checks);
45405
+ if (!caps.length)
45406
+ return;
45407
+ const cap = Math.min(...caps.map((c) => c[0]));
45408
+ const parse3 = inst._zod.parse;
45409
+ inst._zod.parse = (payload, ctx) => {
45410
+ const n = size(payload.value);
45411
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
45412
+ for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
45413
+ if (n > max && ch._zod.def.when(payload)) {
45414
+ const start = payload.issues.length;
45415
+ ch._zod.check(payload);
45416
+ payload.issues[start].continue = false;
45417
+ attachSchema(payload.issues, start, inst);
45418
+ return payload;
45419
+ }
45420
+ }
45421
+ }
45422
+ return parse3(payload, ctx);
45423
+ };
45424
+ }
45425
+ var arraySize = (input2) => Array.isArray(input2) ? input2.length : -1;
45426
+ var mapSize = (input2) => input2 instanceof Map ? input2.size : -1;
45427
+ var setSize = (input2) => input2 instanceof Set ? input2.size : -1;
45339
45428
  function handleArrayResult(result, final, index) {
45340
45429
  if (result.issues.length) {
45341
45430
  final.issues.push(...prefixIssues(index, result.issues));
@@ -45379,6 +45468,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
45379
45468
  }
45380
45469
  return payload;
45381
45470
  };
45471
+ capSize(inst, arraySize);
45382
45472
  });
45383
45473
  function handlePropertyResult(result, final, key, input2, optin, optout) {
45384
45474
  const isPresent = key in input2;
@@ -46335,6 +46425,7 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
46335
46425
  return Promise.all(proms).then(() => payload);
46336
46426
  return payload;
46337
46427
  };
46428
+ capSize(inst, mapSize);
46338
46429
  });
46339
46430
  function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx) {
46340
46431
  if (keyResult.issues.length) {
@@ -46401,6 +46492,7 @@ var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
46401
46492
  return Promise.all(proms).then(() => payload);
46402
46493
  return payload;
46403
46494
  };
46495
+ capSize(inst, setSize);
46404
46496
  });
46405
46497
  function handleSetResult(result, final) {
46406
46498
  if (result.issues.length) {
@@ -55931,9 +56023,15 @@ function generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {
55931
56023
  doc.write(`}`);
55932
56024
  return outputVar;
55933
56025
  }
56026
+ function generateSizeGate(doc, schema, size) {
56027
+ for (const [max, check2] of sizeCaps(schema._zod.def.checks)) {
56028
+ doc.write(`if (${size} > ${numericOperand(max, check2._zod.def.check)}) return INVALID;`);
56029
+ }
56030
+ }
55934
56031
  function generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {
55935
56032
  const def = schema._zod.def;
55936
56033
  doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
56034
+ generateSizeGate(doc, schema, `${accessor}.length`);
55937
56035
  const outputVar = buildsValue ? newVar(ctx) : null;
55938
56036
  const iVar = newVar(ctx);
55939
56037
  const elemVar = newVar(ctx);
@@ -56333,6 +56431,7 @@ function literalPropertyKey(ctx, key) {
56333
56431
  function generateMapCheck(doc, ctx, schema, accessor) {
56334
56432
  const def = schema._zod.def;
56335
56433
  doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
56434
+ generateSizeGate(doc, schema, `${accessor}.size`);
56336
56435
  const outputVar = newVar(ctx);
56337
56436
  const kVar = newVar(ctx);
56338
56437
  const valVar = newVar(ctx);
@@ -56349,6 +56448,7 @@ function generateMapCheck(doc, ctx, schema, accessor) {
56349
56448
  function generateSetCheck(doc, ctx, schema, accessor) {
56350
56449
  const def = schema._zod.def;
56351
56450
  doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
56451
+ generateSizeGate(doc, schema, `${accessor}.size`);
56352
56452
  const outputVar = newVar(ctx);
56353
56453
  const valVar = newVar(ctx);
56354
56454
  doc.write(`const ${outputVar} = new Set();`);
@@ -62497,10 +62597,34 @@ import { constants as fsConstants2, realpathSync } from "node:fs";
62497
62597
  var O_NOFOLLOW2 = fsConstants2.O_NOFOLLOW ?? 0;
62498
62598
  var O_NONBLOCK = fsConstants2.O_NONBLOCK ?? 0;
62499
62599
 
62600
+ // node_modules/@chrischall/mcp-utils/dist/internal/ascii.js
62601
+ function asciiLower(s) {
62602
+ return s.replace(/[A-Z]+/g, (m) => m.toLowerCase());
62603
+ }
62604
+
62500
62605
  // node_modules/@chrischall/mcp-utils/dist/scrape/index.js
62501
62606
  var NEXT_DATA_MAX_CHARS = 16 * 1024 * 1024;
62502
62607
  function isCloudflareChallenge(html) {
62503
- return /_cf_chl_opt/.test(html) || /<title[^>]*>\s*Just a moment/i.test(html);
62608
+ return html.includes("_cf_chl_opt") || hasJustAMomentTitle(html);
62609
+ }
62610
+ var JUST_A_MOMENT = "just a moment";
62611
+ function hasJustAMomentTitle(html) {
62612
+ const lower = asciiLower(html);
62613
+ let i = 0;
62614
+ for (; ; ) {
62615
+ const open2 = lower.indexOf("<title", i);
62616
+ if (open2 < 0)
62617
+ return false;
62618
+ const gt = lower.indexOf(">", open2 + 6);
62619
+ if (gt < 0)
62620
+ return false;
62621
+ let j = gt + 1;
62622
+ while (j < lower.length && /\s/.test(lower[j]))
62623
+ j++;
62624
+ if (lower.startsWith(JUST_A_MOMENT, j))
62625
+ return true;
62626
+ i = gt + 1;
62627
+ }
62504
62628
  }
62505
62629
 
62506
62630
  // node_modules/@chrischall/mcp-utils/dist/http/index.js
@@ -62607,7 +62731,7 @@ var pageSchema = {
62607
62731
 
62608
62732
  // src/version.ts
62609
62733
  var SERVER_NAME = "honeybook-mcp";
62610
- var VERSION = "1.2.6";
62734
+ var VERSION = "1.2.7";
62611
62735
 
62612
62736
  // src/sessions.ts
62613
62737
  import { homedir } from "node:os";
@@ -62859,25 +62983,9 @@ var SessionStore = class {
62859
62983
  this.mostRecentKey = null;
62860
62984
  }
62861
62985
  }
62862
- /**
62863
- * Move a corrupt store file to `<filePath>.corrupt` (or `.corrupt-<n>` if a
62864
- * previous backup exists) so a subsequent save cannot overwrite the only
62865
- * copy of the prior credentials. Best-effort: returns the backup path, or
62866
- * `null` if the rename failed.
62867
- */
62986
+ /** See {@link preserveCorruptFile}. */
62868
62987
  preserveCorruptFile() {
62869
- try {
62870
- let candidate = `${this.filePath}.corrupt`;
62871
- for (let n = 1; existsSync3(candidate) && n <= 100; n++) {
62872
- candidate = `${this.filePath}.corrupt-${n}`;
62873
- }
62874
- if (existsSync3(candidate))
62875
- return null;
62876
- renameSync2(this.filePath, candidate);
62877
- return candidate;
62878
- } catch {
62879
- return null;
62880
- }
62988
+ return preserveCorruptFile(this.filePath);
62881
62989
  }
62882
62990
  /** Serialize the store to its on-disk JSON form (array, insertion order). */
62883
62991
  serialize() {
@@ -62959,6 +63067,20 @@ var SessionStore = class {
62959
63067
  this.mostRecentKey = null;
62960
63068
  }
62961
63069
  };
63070
+ function preserveCorruptFile(filePath) {
63071
+ try {
63072
+ let candidate = `${filePath}.corrupt`;
63073
+ for (let n = 1; existsSync3(candidate) && n <= 100; n++) {
63074
+ candidate = `${filePath}.corrupt-${n}`;
63075
+ }
63076
+ if (existsSync3(candidate))
63077
+ return null;
63078
+ renameSync2(filePath, candidate);
63079
+ return candidate;
63080
+ } catch {
63081
+ return null;
63082
+ }
63083
+ }
62962
63084
  var TOKEN_REFRESH_SKEW_MS = 5 * 60 * 1e3;
62963
63085
 
62964
63086
  // src/sessions.ts
@@ -63765,6 +63887,17 @@ function isPublicSuffix(host) {
63765
63887
  return false;
63766
63888
  }
63767
63889
 
63890
+ // node_modules/@fetchproxy/protocol/dist/ip-literal.js
63891
+ function isIpLiteralHost(host) {
63892
+ if (host.includes(":") || host.startsWith("["))
63893
+ return true;
63894
+ const labels = host.split(".");
63895
+ if (labels.length > 1 && labels[labels.length - 1] === "")
63896
+ labels.pop();
63897
+ const last = labels[labels.length - 1] ?? "";
63898
+ return /^[0-9]+$/.test(last) || /^0x[0-9a-f]*$/i.test(last);
63899
+ }
63900
+
63768
63901
  // node_modules/@fetchproxy/protocol/dist/validate.js
63769
63902
  var ProtocolError3 = class extends Error {
63770
63903
  constructor(message) {
@@ -64230,6 +64363,9 @@ function validateHello(raw) {
64230
64363
  if (!HOSTNAME_RE.test(d)) {
64231
64364
  throw new ProtocolError3(`hello.domains: invalid hostname ${JSON.stringify(d)}`);
64232
64365
  }
64366
+ if (isIpLiteralHost(d)) {
64367
+ throw new ProtocolError3(`hello.domains: ${JSON.stringify(d)} is an IP address \u2014 declare the site's DNS hostname; IP-literal origins (LAN, loopback, link-local) are not reachable through the bridge`);
64368
+ }
64233
64369
  if (isPublicSuffix(d)) {
64234
64370
  throw new ProtocolError3(`hello.domains: ${JSON.stringify(d)} is a public suffix \u2014 declare a registrable domain (e.g. "example.${d}"), not the suffix every site under it shares`);
64235
64371
  }
@@ -66355,7 +66491,7 @@ async function startHost(opts) {
66355
66491
  if (ownRetryableRefusal)
66356
66492
  resetSessionPromise();
66357
66493
  resolveOwnSession(ownSession);
66358
- } else {
66494
+ } else if (identified === "extension" && extensionWs === ws) {
66359
66495
  const slot = peers.get(frame.mcpId);
66360
66496
  if (slot)
66361
66497
  slot.ws.send(JSON.stringify(frame));
@@ -67381,6 +67517,9 @@ var FetchproxyServer = class {
67381
67517
  throw new Error("FetchproxyServer: opts.domains must be a non-empty array of hostnames");
67382
67518
  }
67383
67519
  for (const d of opts.domains) {
67520
+ if (typeof d === "string" && isIpLiteralHost(d)) {
67521
+ throw new Error(`FetchproxyServer: opts.domains entry ${JSON.stringify(d)} is an IP address \u2014 declare the site's DNS hostname; IP-literal origins (LAN, loopback, link-local) are not reachable through the bridge`);
67522
+ }
67384
67523
  if (typeof d === "string" && isPublicSuffix(d)) {
67385
67524
  throw new Error(`FetchproxyServer: opts.domains entry ${JSON.stringify(d)} is a public suffix \u2014 declare a registrable domain (e.g. "example.${d}"), not the suffix every site under it shares`);
67386
67525
  }
@@ -69315,6 +69454,9 @@ var FetchproxyServer = class {
69315
69454
  }
69316
69455
  };
69317
69456
 
69457
+ // node_modules/@fetchproxy/server/dist/bot-wall.js
69458
+ var CLOUDFLARE_TITLE_SCAN_MAX = 64 * 1024;
69459
+
69318
69460
  // node_modules/@fetchproxy/bootstrap/dist/index.js
69319
69461
  var defaultFactory = (opts) => new FetchproxyServer(opts);
69320
69462
  var CAPTURE_BOOTSTRAP_DEADLINE_MS = 45e3;
@@ -70531,6 +70673,22 @@ function extractPayments(file2) {
70531
70673
  };
70532
70674
  }
70533
70675
  var MAX_WORKSPACE_FILE_PAGES = 20;
70676
+ var WORKSPACE_FILE_LIST_VIEWS = ["summary", "all"];
70677
+ function listRow(file2) {
70678
+ return {
70679
+ _id: file2._id,
70680
+ file_title: file2.file_title,
70681
+ file_type: file2.file_type,
70682
+ status_name: file2.status_name,
70683
+ sent_on: file2.sent_on,
70684
+ created_at: file2.created_at,
70685
+ workspace_id: getStr(getObj(file2, "workspace"), "_id"),
70686
+ workspace_name: getStr(file2, "workspace_name"),
70687
+ has_pending_payment: file2.has_pending_payment,
70688
+ is_file_accepted: file2.is_file_accepted,
70689
+ is_canceled: file2.is_canceled
70690
+ };
70691
+ }
70534
70692
  async function listWorkspaceFiles(args) {
70535
70693
  const client = await getActiveClient(args.origin);
70536
70694
  const base = apiPath`/api/v2/users/${client.scope.userId}/workspace_files`;
@@ -70554,8 +70712,9 @@ async function listWorkspaceFiles(args) {
70554
70712
  if (fresh.length === 0) break;
70555
70713
  }
70556
70714
  const filtered = args.file_type ? files.filter((f) => f.file_type === args.file_type) : files;
70715
+ const project = (args.view ?? "summary") === "all" ? pruneWorkspaceFile : listRow;
70557
70716
  return minifiedResult({
70558
- files: filtered,
70717
+ files: filtered.map(project),
70559
70718
  complete,
70560
70719
  ...complete ? {} : {
70561
70720
  note: "This list is incomplete: HoneyBook reports more files than could be fetched. Files (including ones matching file_type) may be missing."
@@ -70594,12 +70753,15 @@ function registerWorkspaceFileTools(server) {
70594
70753
  server.registerTool(
70595
70754
  "list_workspace_files",
70596
70755
  {
70597
- description: "List all files a vendor has shared with you (contracts, invoices, brochures, proposals). Optionally filter by file_type. Follows every page; returns { files, complete } \u2014 complete:false means some files could not be fetched.",
70756
+ description: 'List all files a vendor has shared with you (contracts, invoices, brochures, proposals). Optionally filter by file_type. Follows every page; returns { files, complete } \u2014 complete:false means some files could not be fetched. Each file is a light summary row by default (id, title, type, status, sent date, workspace, payment/acceptance flags); call get_workspace_file with its _id for pricing, contract or payments, or pass view="all" for every pruned file object (large).',
70598
70757
  inputSchema: external_exports.object({
70599
70758
  origin: schemaOrigin.describe(
70600
70759
  "Portal origin (e.g. https://<vendor>.hbportal.co) to target. Optional \u2014 defaults to the most recently activated session."
70601
70760
  ),
70602
- file_type: external_exports.enum(FILE_TYPES).optional().describe("Filter to one file type. Omit to return all.")
70761
+ file_type: external_exports.enum(FILE_TYPES).optional().describe("Filter to one file type. Omit to return all."),
70762
+ view: external_exports.enum(WORKSPACE_FILE_LIST_VIEWS).optional().describe(
70763
+ 'Default "summary": one light row per file. "all": each file object with the heavy vendor-side company fields pruned (can be hundreds of kB per proposal).'
70764
+ )
70603
70765
  }),
70604
70766
  annotations: { readOnlyHint: true, openWorldHint: true }
70605
70767
  },
@@ -203,6 +203,29 @@ function extractPayments(file) {
203
203
  * file list is a handful of documents per vendor; this only stops a runaway.
204
204
  */
205
205
  export const MAX_WORKSPACE_FILE_PAGES = 20;
206
+ /** The rungs list_workspace_files offers — the names get_workspace_file uses. */
207
+ export const WORKSPACE_FILE_LIST_VIEWS = ['summary', 'all'];
208
+ /**
209
+ * One row of the list: enough to pick a file and call get_workspace_file.
210
+ * The raw object carries `company` (vendor_emails alone measured ~1.3 MB on
211
+ * one proposal) and the whole `vendor_proposal`, so returning it per file let
212
+ * a handful of proposals exceed the host's result-size limit (fleet-audit#1264).
213
+ */
214
+ export function listRow(file) {
215
+ return {
216
+ _id: file._id,
217
+ file_title: file.file_title,
218
+ file_type: file.file_type,
219
+ status_name: file.status_name,
220
+ sent_on: file.sent_on,
221
+ created_at: file.created_at,
222
+ workspace_id: getStr(getObj(file, 'workspace'), '_id'),
223
+ workspace_name: getStr(file, 'workspace_name'),
224
+ has_pending_payment: file.has_pending_payment,
225
+ is_file_accepted: file.is_file_accepted,
226
+ is_canceled: file.is_canceled,
227
+ };
228
+ }
206
229
  /**
207
230
  * Every page of the user's workspace files (fleet-audit#502). Page 1 alone
208
231
  * hid later files entirely — and `file_type` filtering ran on page 1 only, so
@@ -232,8 +255,9 @@ export async function listWorkspaceFiles(args) {
232
255
  break;
233
256
  }
234
257
  const filtered = args.file_type ? files.filter((f) => f.file_type === args.file_type) : files;
258
+ const project = (args.view ?? 'summary') === 'all' ? pruneWorkspaceFile : listRow;
235
259
  return minifiedResult({
236
- files: filtered,
260
+ files: filtered.map(project),
237
261
  complete,
238
262
  ...(complete
239
263
  ? {}
@@ -274,13 +298,19 @@ export async function getWorkspaceFile(args) {
274
298
  export function registerWorkspaceFileTools(server) {
275
299
  server.registerTool('list_workspace_files', {
276
300
  description: 'List all files a vendor has shared with you (contracts, invoices, brochures, proposals). Optionally filter by file_type. ' +
277
- 'Follows every page; returns { files, complete } — complete:false means some files could not be fetched.',
301
+ 'Follows every page; returns { files, complete } — complete:false means some files could not be fetched. ' +
302
+ 'Each file is a light summary row by default (id, title, type, status, sent date, workspace, payment/acceptance flags); ' +
303
+ 'call get_workspace_file with its _id for pricing, contract or payments, or pass view="all" for every pruned file object (large).',
278
304
  inputSchema: z.object({
279
305
  origin: schemaOrigin.describe('Portal origin (e.g. https://<vendor>.hbportal.co) to target. Optional — defaults to the most recently activated session.'),
280
306
  file_type: z
281
307
  .enum(FILE_TYPES)
282
308
  .optional()
283
309
  .describe('Filter to one file type. Omit to return all.'),
310
+ view: z
311
+ .enum(WORKSPACE_FILE_LIST_VIEWS)
312
+ .optional()
313
+ .describe('Default "summary": one light row per file. "all": each file object with the heavy vendor-side company fields pruned (can be hundreds of kB per proposal).'),
284
314
  }),
285
315
  annotations: { readOnlyHint: true, openWorldHint: true },
286
316
  }, listWorkspaceFiles);
package/dist/version.js CHANGED
@@ -4,4 +4,4 @@
4
4
  // package.json drift. Importing these instead of package.json keeps the
5
5
  // whole manifest — npm scripts included — out of dist/bundle.js.
6
6
  export const SERVER_NAME = 'honeybook-mcp';
7
- export const VERSION = '1.2.6'; // x-release-please-version
7
+ export const VERSION = '1.2.7'; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honeybook-mcp",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
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>",
@@ -41,12 +41,12 @@
41
41
  "dev": "node --env-file=.env dist/index.js",
42
42
  "test": "npm run typecheck && vitest run",
43
43
  "test:watch": "vitest",
44
- "typecheck": "tsc -p tsconfig.json --noEmit"
44
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json"
45
45
  },
46
46
  "dependencies": {
47
- "@chrischall/mcp-utils": "^3.0.0",
48
- "@fetchproxy/bootstrap": "^3.6.0",
49
- "@fetchproxy/server": "^3.6.0",
47
+ "@chrischall/mcp-utils": "^3.0.3",
48
+ "@fetchproxy/bootstrap": "^3.6.2",
49
+ "@fetchproxy/server": "^3.6.2",
50
50
  "@modelcontextprotocol/server": "^2.3.0",
51
51
  "dotenv": "^18.0.2",
52
52
  "zod": "^4.6.5"
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": "1.2.6",
9
+ "version": "1.2.7",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "honeybook-mcp",
14
- "version": "1.2.6",
14
+ "version": "1.2.7",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },