@togglhq/mcp 1.6.16 → 1.7.0

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/build/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as runMcpCli } from "./src-DO6utvuq.js";
2
+ import { n as runMcpCli } from "./src-BlWD3FwF.js";
3
3
  //#region src/cli.ts
4
4
  runMcpCli();
5
5
  //#endregion
package/build/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { n as runMcpCli, t as bootstrapServer } from "./src-DO6utvuq.js";
2
+ import { n as runMcpCli, t as bootstrapServer } from "./src-BlWD3FwF.js";
3
3
  export { bootstrapServer, runMcpCli };
@@ -11521,7 +11521,7 @@ const _safeParse = (_Err) => (schema, value, _ctx) => {
11521
11521
  data: result.value
11522
11522
  };
11523
11523
  };
11524
- const safeParse$2 = /* @__PURE__ */ _safeParse($ZodRealError);
11524
+ const safeParse$3 = /* @__PURE__ */ _safeParse($ZodRealError);
11525
11525
  const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
11526
11526
  const ctx = _ctx ? Object.assign(_ctx, { async: true }) : { async: true };
11527
11527
  let result = schema._zod.run({
@@ -12101,7 +12101,7 @@ const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
12101
12101
  defineLazy(inst, "~standard", () => ({
12102
12102
  validate: (value) => {
12103
12103
  try {
12104
- const r = safeParse$2(inst, value);
12104
+ const r = safeParse$3(inst, value);
12105
12105
  return r.success ? { value: r.data } : { issues: r.error?.issues };
12106
12106
  } catch (_) {
12107
12107
  return safeParseAsync$1(inst, value).then((r) => r.success ? { value: r.data } : { issues: r.error?.issues });
@@ -14440,9 +14440,9 @@ $constructor("ZodError", initializer);
14440
14440
  const ZodRealError = $constructor("ZodError", initializer, { Parent: Error });
14441
14441
  //#endregion
14442
14442
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/parse.js
14443
- const parse$1 = /* @__PURE__ */ _parse(ZodRealError);
14443
+ const parse = /* @__PURE__ */ _parse(ZodRealError);
14444
14444
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
14445
- const safeParse$1 = /* @__PURE__ */ _safeParse(ZodRealError);
14445
+ const safeParse$2 = /* @__PURE__ */ _safeParse(ZodRealError);
14446
14446
  const safeParseAsync = /* @__PURE__ */ _safeParseAsync(ZodRealError);
14447
14447
  const encode = /* @__PURE__ */ _encode(ZodRealError);
14448
14448
  const decode = /* @__PURE__ */ _decode(ZodRealError);
@@ -14478,8 +14478,8 @@ const ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
14478
14478
  reg.add(inst, meta);
14479
14479
  return inst;
14480
14480
  });
14481
- inst.parse = (data, params) => parse$1(inst, data, params, { callee: inst.parse });
14482
- inst.safeParse = (data, params) => safeParse$1(inst, data, params);
14481
+ inst.parse = (data, params) => parse(inst, data, params, { callee: inst.parse });
14482
+ inst.safeParse = (data, params) => safeParse$2(inst, data, params);
14483
14483
  inst.parseAsync = async (data, params) => parseAsync(inst, data, params, { callee: inst.parseAsync });
14484
14484
  inst.safeParseAsync = async (data, params) => safeParseAsync(inst, data, params);
14485
14485
  inst.spa = inst.safeParseAsync;
@@ -16640,7 +16640,7 @@ function assertCompleteRequestResourceTemplate(request) {
16640
16640
  * Returns a discriminated union with success/error.
16641
16641
  */
16642
16642
  function parseSchema(schema, data) {
16643
- return safeParse$1(schema, data);
16643
+ return safeParse$2(schema, data);
16644
16644
  }
16645
16645
  /**
16646
16646
  * Checks if a task status represents a terminal state.
@@ -25636,6 +25636,46 @@ function minValue$1(requirement, message$1) {
25636
25636
  }
25637
25637
  };
25638
25638
  }
25639
+ /**
25640
+ * Checks if a dataset is partially typed.
25641
+ *
25642
+ * @param dataset The dataset to check.
25643
+ * @param paths The paths to check.
25644
+ *
25645
+ * @returns Whether it is partially typed.
25646
+ *
25647
+ * @internal
25648
+ */
25649
+ /* @__NO_SIDE_EFFECTS__ */
25650
+ function _isPartiallyTyped(dataset, paths) {
25651
+ if (dataset.issues) for (const path of paths) for (const issue of dataset.issues) {
25652
+ let typed = false;
25653
+ const bound = Math.min(path.length, issue.path?.length ?? 0);
25654
+ for (let index = 0; index < bound; index++) if (path[index] !== issue.path[index].key && (path[index] !== "$" || issue.path[index].type !== "array")) {
25655
+ typed = true;
25656
+ break;
25657
+ }
25658
+ if (!typed) return false;
25659
+ }
25660
+ return true;
25661
+ }
25662
+ /* @__NO_SIDE_EFFECTS__ */
25663
+ function partialCheck(paths, requirement, message$1) {
25664
+ return {
25665
+ kind: "validation",
25666
+ type: "partial_check",
25667
+ reference: partialCheck,
25668
+ async: false,
25669
+ expects: null,
25670
+ paths,
25671
+ requirement,
25672
+ message: message$1,
25673
+ "~run"(dataset, config$1) {
25674
+ if ((dataset.typed || /* @__PURE__ */ _isPartiallyTyped(dataset, paths)) && !this.requirement(dataset.value)) _addIssue$1(this, "input", dataset, config$1);
25675
+ return dataset;
25676
+ }
25677
+ };
25678
+ }
25639
25679
  /* @__NO_SIDE_EFFECTS__ */
25640
25680
  function regex(requirement, message$1) {
25641
25681
  return {
@@ -25653,6 +25693,24 @@ function regex(requirement, message$1) {
25653
25693
  };
25654
25694
  }
25655
25695
  /**
25696
+ * Creates a to upper case transformation action.
25697
+ *
25698
+ * @returns A to upper case action.
25699
+ */
25700
+ /* @__NO_SIDE_EFFECTS__ */
25701
+ function toUpperCase() {
25702
+ return {
25703
+ kind: "transformation",
25704
+ type: "to_upper_case",
25705
+ reference: toUpperCase,
25706
+ async: false,
25707
+ "~run"(dataset) {
25708
+ dataset.value = dataset.value.toUpperCase();
25709
+ return dataset;
25710
+ }
25711
+ };
25712
+ }
25713
+ /**
25656
25714
  * Creates a custom transformation action.
25657
25715
  *
25658
25716
  * @param operation The transformation operation.
@@ -25674,6 +25732,24 @@ function transform$1(operation) {
25674
25732
  };
25675
25733
  }
25676
25734
  /**
25735
+ * Creates a trim transformation action.
25736
+ *
25737
+ * @returns A trim action.
25738
+ */
25739
+ /* @__NO_SIDE_EFFECTS__ */
25740
+ function trim() {
25741
+ return {
25742
+ kind: "transformation",
25743
+ type: "trim",
25744
+ reference: trim,
25745
+ async: false,
25746
+ "~run"(dataset) {
25747
+ dataset.value = dataset.value.trim();
25748
+ return dataset;
25749
+ }
25750
+ };
25751
+ }
25752
+ /**
25677
25753
  * Returns the fallback value of the schema.
25678
25754
  *
25679
25755
  * @param schema The schema to get it from.
@@ -25687,6 +25763,44 @@ function getFallback$1(schema, dataset, config$1) {
25687
25763
  return typeof schema.fallback === "function" ? schema.fallback(dataset, config$1) : schema.fallback;
25688
25764
  }
25689
25765
  /**
25766
+ * Forwards the issues of the passed validation action.
25767
+ *
25768
+ * @param action The validation action.
25769
+ * @param path The path to forward the issues to.
25770
+ *
25771
+ * @returns The modified action.
25772
+ */
25773
+ /* @__NO_SIDE_EFFECTS__ */
25774
+ function forward(action, path) {
25775
+ return {
25776
+ ...action,
25777
+ "~run"(dataset, config$1) {
25778
+ const prevIssues = dataset.issues && [...dataset.issues];
25779
+ dataset = action["~run"](dataset, config$1);
25780
+ if (dataset.issues) {
25781
+ for (const issue of dataset.issues) if (!prevIssues?.includes(issue)) {
25782
+ let pathInput = dataset.value;
25783
+ for (const key of path) {
25784
+ const pathValue = pathInput[key];
25785
+ const pathItem = {
25786
+ type: "unknown",
25787
+ origin: "value",
25788
+ input: pathInput,
25789
+ key,
25790
+ value: pathValue
25791
+ };
25792
+ if (issue.path) issue.path.push(pathItem);
25793
+ else issue.path = [pathItem];
25794
+ if (!pathValue) break;
25795
+ pathInput = pathValue;
25796
+ }
25797
+ }
25798
+ }
25799
+ return dataset;
25800
+ }
25801
+ };
25802
+ }
25803
+ /**
25690
25804
  * Returns the default value of the schema.
25691
25805
  *
25692
25806
  * @param schema The schema to get it from.
@@ -26140,6 +26254,87 @@ function record$1(key, value$1, message$1) {
26140
26254
  };
26141
26255
  }
26142
26256
  /* @__NO_SIDE_EFFECTS__ */
26257
+ function strictObject(entries$1, message$1) {
26258
+ return {
26259
+ kind: "schema",
26260
+ type: "strict_object",
26261
+ reference: strictObject,
26262
+ expects: "Object",
26263
+ async: false,
26264
+ entries: entries$1,
26265
+ message: message$1,
26266
+ get "~standard"() {
26267
+ return /* @__PURE__ */ _getStandardProps$1(this);
26268
+ },
26269
+ "~run"(dataset, config$1) {
26270
+ const input = dataset.value;
26271
+ if (input && typeof input === "object") {
26272
+ dataset.typed = true;
26273
+ dataset.value = {};
26274
+ for (const key in this.entries) {
26275
+ const valueSchema = this.entries[key];
26276
+ if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) {
26277
+ const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault$1(valueSchema);
26278
+ const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1);
26279
+ if (valueDataset.issues) {
26280
+ const pathItem = {
26281
+ type: "object",
26282
+ origin: "value",
26283
+ input,
26284
+ key,
26285
+ value: value$1
26286
+ };
26287
+ for (const issue of valueDataset.issues) {
26288
+ if (issue.path) issue.path.unshift(pathItem);
26289
+ else issue.path = [pathItem];
26290
+ dataset.issues?.push(issue);
26291
+ }
26292
+ if (!dataset.issues) dataset.issues = valueDataset.issues;
26293
+ if (config$1.abortEarly) {
26294
+ dataset.typed = false;
26295
+ break;
26296
+ }
26297
+ }
26298
+ if (!valueDataset.typed) dataset.typed = false;
26299
+ dataset.value[key] = valueDataset.value;
26300
+ } else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback$1(valueSchema);
26301
+ else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
26302
+ _addIssue$1(this, "key", dataset, config$1, {
26303
+ input: void 0,
26304
+ expected: `"${key}"`,
26305
+ path: [{
26306
+ type: "object",
26307
+ origin: "key",
26308
+ input,
26309
+ key,
26310
+ value: input[key]
26311
+ }]
26312
+ });
26313
+ if (config$1.abortEarly) break;
26314
+ }
26315
+ }
26316
+ if (!dataset.issues || !config$1.abortEarly) {
26317
+ for (const key in input) if (!(key in this.entries)) {
26318
+ _addIssue$1(this, "key", dataset, config$1, {
26319
+ input: key,
26320
+ expected: "never",
26321
+ path: [{
26322
+ type: "object",
26323
+ origin: "key",
26324
+ input,
26325
+ key,
26326
+ value: input[key]
26327
+ }]
26328
+ });
26329
+ break;
26330
+ }
26331
+ }
26332
+ } else _addIssue$1(this, "type", dataset, config$1);
26333
+ return dataset;
26334
+ }
26335
+ };
26336
+ }
26337
+ /* @__NO_SIDE_EFFECTS__ */
26143
26338
  function string$1(message$1) {
26144
26339
  return {
26145
26340
  kind: "schema",
@@ -26277,7 +26472,7 @@ function pipe$2(...pipe$1) {
26277
26472
  * @returns The parse result.
26278
26473
  */
26279
26474
  /* @__NO_SIDE_EFFECTS__ */
26280
- function safeParse(schema, input, config$1) {
26475
+ function safeParse$1(schema, input, config$1) {
26281
26476
  const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig$1(config$1));
26282
26477
  return {
26283
26478
  typed: dataset.typed,
@@ -28227,21 +28422,6 @@ function _joinExpects(values$1, separator) {
28227
28422
  return list[0] ?? "never";
28228
28423
  }
28229
28424
  /**
28230
- * A Valibot error with useful information.
28231
- */
28232
- var ValiError = class extends Error {
28233
- /**
28234
- * Creates a Valibot error with useful information.
28235
- *
28236
- * @param issues The error issues.
28237
- */
28238
- constructor(issues) {
28239
- super(issues[0].message);
28240
- this.name = "ValiError";
28241
- this.issues = issues;
28242
- }
28243
- };
28244
- /**
28245
28425
  * [Email address](https://en.wikipedia.org/wiki/Email_address) regex.
28246
28426
  */
28247
28427
  const EMAIL_REGEX = /^[\w+-]+(?:\.[\w+-]+)*@[\da-z]+(?:[.-][\da-z]+)*\.[a-z]{2,}$/iu;
@@ -28893,20 +29073,6 @@ function unknown() {
28893
29073
  }
28894
29074
  };
28895
29075
  }
28896
- /**
28897
- * Parses an unknown input based on a schema.
28898
- *
28899
- * @param schema The schema to be used.
28900
- * @param input The input to be parsed.
28901
- * @param config The parse configuration.
28902
- *
28903
- * @returns The parsed input.
28904
- */
28905
- function parse(schema, input, config$1) {
28906
- const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
28907
- if (dataset.issues) throw new ValiError(dataset.issues);
28908
- return dataset.value;
28909
- }
28910
29076
  /* @__NO_SIDE_EFFECTS__ */
28911
29077
  function pipe(...pipe$1) {
28912
29078
  return {
@@ -28927,6 +29093,25 @@ function pipe(...pipe$1) {
28927
29093
  }
28928
29094
  };
28929
29095
  }
29096
+ /**
29097
+ * Parses an unknown input based on a schema.
29098
+ *
29099
+ * @param schema The schema to be used.
29100
+ * @param input The input to be parsed.
29101
+ * @param config The parse configuration.
29102
+ *
29103
+ * @returns The parse result.
29104
+ */
29105
+ /* @__NO_SIDE_EFFECTS__ */
29106
+ function safeParse(schema, input, config$1) {
29107
+ const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
29108
+ return {
29109
+ typed: dataset.typed,
29110
+ success: !dataset.issues,
29111
+ output: dataset.value,
29112
+ issues: dataset.issues
29113
+ };
29114
+ }
28930
29115
  //#endregion
28931
29116
  //#region ../focus-queries/dist/schemas/index.ts
28932
29117
  const ClientLiteSchema = /* @__PURE__ */ object({
@@ -31063,7 +31248,7 @@ function validationErrorMessage(issues) {
31063
31248
  return issues.map((issue) => issue.message ?? "invalid").join("; ");
31064
31249
  }
31065
31250
  function validateOutput(schema, data, label) {
31066
- const result = /* @__PURE__ */ safeParse(schema, data);
31251
+ const result = /* @__PURE__ */ safeParse$1(schema, data);
31067
31252
  if (!result.success) return {
31068
31253
  ok: false,
31069
31254
  status: 422,
@@ -32668,7 +32853,7 @@ function createAuthenticatedClientProxy() {
32668
32853
  } });
32669
32854
  }
32670
32855
  //#endregion
32671
- //#region ../operations/build/safety-DUCLJgdI.js
32856
+ //#region ../operations/build/validation-v3-RQf0k.js
32672
32857
  const optionalNumber = /* @__PURE__ */ optional$1(/* @__PURE__ */ number$2());
32673
32858
  const perPageField = (max) => /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ integer(), /* @__PURE__ */ minValue$1(1), /* @__PURE__ */ maxValue$1(max), /* @__PURE__ */ description$1(`Results per page (1-${max})`)));
32674
32859
  const perPageSchema = perPageField(100);
@@ -32676,6 +32861,13 @@ const orgUserPerPageSchema = perPageField(200);
32676
32861
  const DATE_FIELD_RE = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2}))?$/;
32677
32862
  const dateField = (description) => /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ regex(DATE_FIELD_RE, "must be YYYY-MM-DD or RFC3339 datetime (e.g. '2025-01-01' or '2025-01-01T00:00:00Z')"), /* @__PURE__ */ description$1(description));
32678
32863
  const apiDateTimeString = /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoTimestamp());
32864
+ const rateDateSchema = /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1());
32865
+ const rateSchedulePayloadSchema = /* @__PURE__ */ pipe$2(/* @__PURE__ */ strictObject({
32866
+ currency: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ trim(), /* @__PURE__ */ toUpperCase(), /* @__PURE__ */ regex(/^[A-Z]{3}$/, "must be exactly three A-Z letters")),
32867
+ hourly_rate: /* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ minValue$1(0)),
32868
+ start_date: rateDateSchema,
32869
+ end_date: /* @__PURE__ */ optional$1(rateDateSchema)
32870
+ }), /* @__PURE__ */ forward(/* @__PURE__ */ partialCheck([["start_date"], ["end_date"]], ({ start_date, end_date }) => end_date === void 0 || end_date >= start_date, "must be on or after start_date"), ["end_date"]));
32679
32871
  const tagIdFilterSchema = /* @__PURE__ */ union$1([/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ transform$1((tagId) => [tagId])), /* @__PURE__ */ pipe$2(/* @__PURE__ */ array$1(/* @__PURE__ */ number$2()), /* @__PURE__ */ minLength$1(1))]);
32680
32872
  const timeBlockListSchema = /* @__PURE__ */ object$2({
32681
32873
  date_from: dateField("Range start — date-only (e.g. '2025-01-01') or RFC3339 datetime. Date-only is expanded to T00:00:00Z."),
@@ -32912,10 +33104,58 @@ const clientOverrides = { "focus.clients.list": {
32912
33104
  }],
32913
33105
  aliases: ["ls"]
32914
33106
  } };
33107
+ const RATE_CONFLICT_CHECK = {
33108
+ safety: "read",
33109
+ destructive: false
33110
+ };
33111
+ const RATE_SCHEDULE_GUIDANCE = "hourly_rate is in the currency's smallest unit, so it depends on the currency: two-decimal currencies like USD/EUR use cents (5000 = 50.00), zero-decimal ones like JPY/KRW use whole units (5000 = 5000), three-decimal ones like KWD/BHD use thousandths. Reads return the same unit. Omit end_date for an open-ended schedule; when set it must be on or after start_date.";
33112
+ const rateOverrides = {
33113
+ "focus.rates.create-project": { mcp: { entityTool: void 0 } },
33114
+ "focus.rates.billable-check-project-billable-rate-conflicts": {
33115
+ ...RATE_CONFLICT_CHECK,
33116
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33117
+ },
33118
+ "focus.rates.billable-check-project-user-billable-rate-conflicts": {
33119
+ ...RATE_CONFLICT_CHECK,
33120
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33121
+ },
33122
+ "focus.rates.billable-check-workspace-billable-rate-conflicts": {
33123
+ ...RATE_CONFLICT_CHECK,
33124
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33125
+ },
33126
+ "focus.rates.billable-check-workspace-user-billable-rate-conflicts": {
33127
+ ...RATE_CONFLICT_CHECK,
33128
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33129
+ },
33130
+ "focus.rates.billable-upsert-project": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33131
+ "focus.rates.billable-upsert-project-user": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33132
+ "focus.rates.billable-upsert-workspace": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33133
+ "focus.rates.billable-upsert-workspace-user": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33134
+ "focus.rates.labor-check-project-labor-cost-conflicts": {
33135
+ ...RATE_CONFLICT_CHECK,
33136
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33137
+ },
33138
+ "focus.rates.labor-check-project-user-labor-cost-conflicts": {
33139
+ ...RATE_CONFLICT_CHECK,
33140
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33141
+ },
33142
+ "focus.rates.labor-check-workspace-labor-cost-conflicts": {
33143
+ ...RATE_CONFLICT_CHECK,
33144
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33145
+ },
33146
+ "focus.rates.labor-check-workspace-user-labor-cost-conflicts": {
33147
+ ...RATE_CONFLICT_CHECK,
33148
+ agentGuidance: RATE_SCHEDULE_GUIDANCE
33149
+ },
33150
+ "focus.rates.labor-upsert-project-labor-cost-rate": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33151
+ "focus.rates.labor-upsert-project-user-labor-cost-rate": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33152
+ "focus.rates.labor-upsert-workspace-labor-cost-rate": { agentGuidance: RATE_SCHEDULE_GUIDANCE },
33153
+ "focus.rates.labor-upsert-workspace-user-labor-cost-rate": { agentGuidance: RATE_SCHEDULE_GUIDANCE }
33154
+ };
32915
33155
  const compositeOverrides = {
32916
33156
  "focus.composite.create-project": {
32917
33157
  description: "Create a project with related data such as members, milestones, rates, and billable rates.",
32918
- agentGuidance: "Follow the create action's privacy and billable guidance. Project fields go under payload.project.",
33158
+ agentGuidance: `Follow the create action's privacy and billable guidance. Project fields go under payload.project. Set rates through payload.billable_rates, not the legacy payload.rates (start_at/end_at). For payload.billable_rates: ${RATE_SCHEDULE_GUIDANCE}`,
32919
33159
  cli: {
32920
33160
  group: ["projects"],
32921
33161
  command: "create-advanced",
@@ -33282,6 +33522,18 @@ const projectOverrides = {
33282
33522
  }
33283
33523
  };
33284
33524
  const publicHolidayOverrides = { "focus.public-holidays.get-by-user-ids": { cli: { interactive: "hidden" } } };
33525
+ const readOnlyPostOverrides = Object.fromEntries([
33526
+ "focus.reports.get-flexq-data",
33527
+ "focus.reports.get-flexq-dictionary",
33528
+ "focus.reports.get-workload",
33529
+ "focus.tasks.suggestions-get-project-suggestion-for-atask",
33530
+ "focus.tasks.suggestions-get-project-suggestions-for-multiple-tasks",
33531
+ "focus.time-log-suggestions.get-for-acalendar-event-title",
33532
+ "focus.time-log-suggestions.get-for-multiple-calendar-event-titles"
33533
+ ].map((id) => [id, {
33534
+ safety: "read",
33535
+ destructive: false
33536
+ }]));
33285
33537
  const savedViewOverrides = {
33286
33538
  "focus.saved-views.list": {
33287
33539
  agentGuidance: "Saved views are per-user, so results belong to the authenticated user. Filter by type (inbox, archive, board, timeline, project, project.tasks, project.board, project.timeline, projects) or by partial name match. pinned=true entries are the user's starred views.",
@@ -34055,6 +34307,41 @@ const orgSharedOperations = [
34055
34307
  function operationRequiresConfirmation(operation) {
34056
34308
  return operation.destructive || operation.safety !== "read";
34057
34309
  }
34310
+ const MAX_ERROR_LENGTH = 200;
34311
+ const MAX_RECEIVED_LENGTH = 40;
34312
+ function formatIssueMessage(issue) {
34313
+ if (issue.message.includes("but received undefined")) return "required";
34314
+ if (issue.received.length <= MAX_RECEIVED_LENGTH) return issue.message;
34315
+ const index = issue.message.lastIndexOf(issue.received);
34316
+ if (index === -1) return issue.message;
34317
+ const closer = issue.received.startsWith("\"") && issue.received.endsWith("\"") ? "\"" : "";
34318
+ const received = `${issue.received.slice(0, MAX_RECEIVED_LENGTH - 3 - closer.length)}...${closer}`;
34319
+ return issue.message.slice(0, index) + received + issue.message.slice(index + issue.received.length);
34320
+ }
34321
+ function formatValibotError(issues, maxLength = MAX_ERROR_LENGTH) {
34322
+ const messages = issues.map((issue) => {
34323
+ const path = issue.path?.map((segment) => String(segment.key)).join(".") ?? "";
34324
+ const message = formatIssueMessage(issue);
34325
+ return path ? `${path}: ${message}` : message;
34326
+ });
34327
+ if (messages.length === 0) return "";
34328
+ const separators = (messages.length - 1) * 2;
34329
+ if (messages.reduce((sum, message) => sum + message.length, separators) <= maxLength) return messages.join("; ");
34330
+ let included = 0;
34331
+ let length = 0;
34332
+ for (const message of messages) {
34333
+ const next = length + (included === 0 ? 0 : 2) + message.length;
34334
+ if (next + `; (+${messages.length - included - 1} more)`.length > maxLength) break;
34335
+ length = next;
34336
+ included += 1;
34337
+ }
34338
+ if (included === 0) {
34339
+ const suffix = messages.length > 1 ? `; (+${messages.length - 1} more)` : "";
34340
+ if (suffix.length >= maxLength) return messages[0].slice(0, Math.max(maxLength, 1));
34341
+ return messages[0].slice(0, maxLength - suffix.length) + suffix;
34342
+ }
34343
+ return [...messages.slice(0, included), `(+${messages.length - included} more)`].join("; ");
34344
+ }
34058
34345
  //#endregion
34059
34346
  //#region ../focus-queries/dist/audit-log/requests.ts
34060
34347
  async function getAuditLog(httpClient, organization_id, workspace_id, from, to, { entity_type, entity_id, action, user_id, page_size, page_number, export: export_ } = {}, signal) {
@@ -35231,7 +35518,7 @@ const generatedFocusOperations = [
35231
35518
  action: "get-computations",
35232
35519
  title: "Get Computations Capacities",
35233
35520
  description: "Get Computations Capacities.",
35234
- safety: "update",
35521
+ safety: "read",
35235
35522
  destructive: false,
35236
35523
  cli: {
35237
35524
  group: ["capacities"],
@@ -35437,12 +35724,7 @@ const generatedFocusOperations = [
35437
35724
  rrule: /* @__PURE__ */ optional$1(/* @__PURE__ */ string$1()),
35438
35725
  start_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
35439
35726
  }),
35440
- billable_rates: /* @__PURE__ */ optional$1(/* @__PURE__ */ array$1(/* @__PURE__ */ looseObject({
35441
- currency: /* @__PURE__ */ string$1(),
35442
- hourly_rate: /* @__PURE__ */ number$2(),
35443
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
35444
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
35445
- }))),
35727
+ billable_rates: /* @__PURE__ */ optional$1(/* @__PURE__ */ array$1(rateSchedulePayloadSchema)),
35446
35728
  members: /* @__PURE__ */ optional$1(/* @__PURE__ */ looseObject({
35447
35729
  role_id: /* @__PURE__ */ number$2(),
35448
35730
  group_ids: /* @__PURE__ */ optional$1(/* @__PURE__ */ array$1(/* @__PURE__ */ number$2())),
@@ -36865,12 +37147,12 @@ const generatedFocusOperations = [
36865
37147
  action: "complete",
36866
37148
  title: "Complete Projects",
36867
37149
  description: "Complete Projects.",
36868
- safety: "read",
37150
+ safety: "update",
36869
37151
  destructive: false,
36870
37152
  cli: {
36871
37153
  group: ["projects"],
36872
37154
  command: "complete",
36873
- interactive: "available"
37155
+ interactive: "default"
36874
37156
  },
36875
37157
  mcp: { entityTool: "projects" },
36876
37158
  inputSchema: /* @__PURE__ */ looseObject({ project_id: /* @__PURE__ */ number$2() }),
@@ -37529,12 +37811,12 @@ const generatedFocusOperations = [
37529
37811
  action: "pin",
37530
37812
  title: "Pin Projects",
37531
37813
  description: "Pin Projects.",
37532
- safety: "read",
37814
+ safety: "update",
37533
37815
  destructive: false,
37534
37816
  cli: {
37535
37817
  group: ["projects"],
37536
37818
  command: "pin",
37537
- interactive: "available"
37819
+ interactive: "default"
37538
37820
  },
37539
37821
  mcp: { entityTool: "projects" },
37540
37822
  inputSchema: /* @__PURE__ */ looseObject({ project_id: /* @__PURE__ */ number$2() }),
@@ -37556,12 +37838,12 @@ const generatedFocusOperations = [
37556
37838
  action: "remove-project-member",
37557
37839
  title: "Remove Project Member Projects",
37558
37840
  description: "Remove Project Member Projects.",
37559
- safety: "read",
37560
- destructive: false,
37841
+ safety: "delete",
37842
+ destructive: true,
37561
37843
  cli: {
37562
37844
  group: ["projects"],
37563
37845
  command: "remove-project-member",
37564
- interactive: "available"
37846
+ interactive: "default"
37565
37847
  },
37566
37848
  mcp: { entityTool: "projects" },
37567
37849
  inputSchema: /* @__PURE__ */ looseObject({
@@ -37644,12 +37926,12 @@ const generatedFocusOperations = [
37644
37926
  action: "uncomplete",
37645
37927
  title: "Uncomplete Projects",
37646
37928
  description: "Uncomplete Projects.",
37647
- safety: "read",
37929
+ safety: "update",
37648
37930
  destructive: false,
37649
37931
  cli: {
37650
37932
  group: ["projects"],
37651
37933
  command: "uncomplete",
37652
- interactive: "available"
37934
+ interactive: "default"
37653
37935
  },
37654
37936
  mcp: { entityTool: "projects" },
37655
37937
  inputSchema: /* @__PURE__ */ looseObject({ project_id: /* @__PURE__ */ number$2() }),
@@ -37671,12 +37953,12 @@ const generatedFocusOperations = [
37671
37953
  action: "unpin",
37672
37954
  title: "Unpin Projects",
37673
37955
  description: "Unpin Projects.",
37674
- safety: "read",
37675
- destructive: false,
37956
+ safety: "delete",
37957
+ destructive: true,
37676
37958
  cli: {
37677
37959
  group: ["projects"],
37678
37960
  command: "unpin",
37679
- interactive: "available"
37961
+ interactive: "default"
37680
37962
  },
37681
37963
  mcp: { entityTool: "projects" },
37682
37964
  inputSchema: /* @__PURE__ */ looseObject({ project_id: /* @__PURE__ */ number$2() }),
@@ -37842,21 +38124,16 @@ const generatedFocusOperations = [
37842
38124
  action: "billable-check-project-billable-rate-conflicts",
37843
38125
  title: "Billable Check Project Billable Rate Conflicts Rates",
37844
38126
  description: "Billable Check Project Billable Rate Conflicts Rates.",
37845
- safety: "read",
38127
+ safety: "update",
37846
38128
  destructive: false,
37847
38129
  cli: {
37848
38130
  group: ["rates", "billable"],
37849
38131
  command: "check-project-billable-rate-conflicts",
37850
- interactive: "available"
38132
+ interactive: "default"
37851
38133
  },
37852
38134
  mcp: { entityTool: "rates" },
37853
38135
  inputSchema: /* @__PURE__ */ looseObject({
37854
- payload: /* @__PURE__ */ looseObject({
37855
- currency: /* @__PURE__ */ string$1(),
37856
- hourly_rate: /* @__PURE__ */ number$2(),
37857
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
37858
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
37859
- }),
38136
+ payload: rateSchedulePayloadSchema,
37860
38137
  project_id: /* @__PURE__ */ number$2()
37861
38138
  }),
37862
38139
  execute: (input, { client }) => {
@@ -37878,21 +38155,16 @@ const generatedFocusOperations = [
37878
38155
  action: "billable-check-project-user-billable-rate-conflicts",
37879
38156
  title: "Billable Check Project User Billable Rate Conflicts Rates",
37880
38157
  description: "Billable Check Project User Billable Rate Conflicts Rates.",
37881
- safety: "read",
38158
+ safety: "update",
37882
38159
  destructive: false,
37883
38160
  cli: {
37884
38161
  group: ["rates", "billable"],
37885
38162
  command: "check-project-user-billable-rate-conflicts",
37886
- interactive: "available"
38163
+ interactive: "default"
37887
38164
  },
37888
38165
  mcp: { entityTool: "rates" },
37889
38166
  inputSchema: /* @__PURE__ */ looseObject({
37890
- payload: /* @__PURE__ */ looseObject({
37891
- currency: /* @__PURE__ */ string$1(),
37892
- hourly_rate: /* @__PURE__ */ number$2(),
37893
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
37894
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
37895
- }),
38167
+ payload: rateSchedulePayloadSchema,
37896
38168
  project_id: /* @__PURE__ */ number$2(),
37897
38169
  user_id: /* @__PURE__ */ number$2()
37898
38170
  }),
@@ -37916,20 +38188,15 @@ const generatedFocusOperations = [
37916
38188
  action: "billable-check-workspace-billable-rate-conflicts",
37917
38189
  title: "Billable Check Workspace Billable Rate Conflicts Rates",
37918
38190
  description: "Billable Check Workspace Billable Rate Conflicts Rates.",
37919
- safety: "read",
38191
+ safety: "update",
37920
38192
  destructive: false,
37921
38193
  cli: {
37922
38194
  group: ["rates", "billable"],
37923
38195
  command: "check-workspace-billable-rate-conflicts",
37924
- interactive: "available"
38196
+ interactive: "default"
37925
38197
  },
37926
38198
  mcp: { entityTool: "rates" },
37927
- inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
37928
- currency: /* @__PURE__ */ string$1(),
37929
- hourly_rate: /* @__PURE__ */ number$2(),
37930
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
37931
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
37932
- }) }),
38199
+ inputSchema: /* @__PURE__ */ looseObject({ payload: rateSchedulePayloadSchema }),
37933
38200
  execute: (input, { client }) => {
37934
38201
  const data = input;
37935
38202
  return client.runGeneratedRequest("checkWorkspaceBillableRateConflicts", () => callGeneratedRequest(checkWorkspaceBillableRateConflicts, [
@@ -37948,21 +38215,16 @@ const generatedFocusOperations = [
37948
38215
  action: "billable-check-workspace-user-billable-rate-conflicts",
37949
38216
  title: "Billable Check Workspace User Billable Rate Conflicts Rates",
37950
38217
  description: "Billable Check Workspace User Billable Rate Conflicts Rates.",
37951
- safety: "read",
38218
+ safety: "update",
37952
38219
  destructive: false,
37953
38220
  cli: {
37954
38221
  group: ["rates", "billable"],
37955
38222
  command: "check-workspace-user-billable-rate-conflicts",
37956
- interactive: "available"
38223
+ interactive: "default"
37957
38224
  },
37958
38225
  mcp: { entityTool: "rates" },
37959
38226
  inputSchema: /* @__PURE__ */ looseObject({
37960
- payload: /* @__PURE__ */ looseObject({
37961
- currency: /* @__PURE__ */ string$1(),
37962
- hourly_rate: /* @__PURE__ */ number$2(),
37963
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
37964
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
37965
- }),
38227
+ payload: rateSchedulePayloadSchema,
37966
38228
  user_id: /* @__PURE__ */ number$2()
37967
38229
  }),
37968
38230
  execute: (input, { client }) => {
@@ -38366,12 +38628,7 @@ const generatedFocusOperations = [
38366
38628
  },
38367
38629
  mcp: { entityTool: "rates" },
38368
38630
  inputSchema: /* @__PURE__ */ looseObject({
38369
- payload: /* @__PURE__ */ looseObject({
38370
- currency: /* @__PURE__ */ string$1(),
38371
- hourly_rate: /* @__PURE__ */ number$2(),
38372
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38373
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38374
- }),
38631
+ payload: rateSchedulePayloadSchema,
38375
38632
  project_id: /* @__PURE__ */ number$2()
38376
38633
  }),
38377
38634
  execute: (input, { client }) => {
@@ -38402,12 +38659,7 @@ const generatedFocusOperations = [
38402
38659
  },
38403
38660
  mcp: { entityTool: "rates" },
38404
38661
  inputSchema: /* @__PURE__ */ looseObject({
38405
- payload: /* @__PURE__ */ looseObject({
38406
- currency: /* @__PURE__ */ string$1(),
38407
- hourly_rate: /* @__PURE__ */ number$2(),
38408
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38409
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38410
- }),
38662
+ payload: rateSchedulePayloadSchema,
38411
38663
  project_id: /* @__PURE__ */ number$2(),
38412
38664
  user_id: /* @__PURE__ */ number$2()
38413
38665
  }),
@@ -38439,12 +38691,7 @@ const generatedFocusOperations = [
38439
38691
  interactive: "default"
38440
38692
  },
38441
38693
  mcp: { entityTool: "rates" },
38442
- inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
38443
- currency: /* @__PURE__ */ string$1(),
38444
- hourly_rate: /* @__PURE__ */ number$2(),
38445
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38446
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38447
- }) }),
38694
+ inputSchema: /* @__PURE__ */ looseObject({ payload: rateSchedulePayloadSchema }),
38448
38695
  execute: (input, { client }) => {
38449
38696
  const data = input;
38450
38697
  return client.runGeneratedRequest("upsertWorkspaceBillableRate", () => callGeneratedRequest(upsertWorkspaceBillableRate, [
@@ -38472,12 +38719,7 @@ const generatedFocusOperations = [
38472
38719
  },
38473
38720
  mcp: { entityTool: "rates" },
38474
38721
  inputSchema: /* @__PURE__ */ looseObject({
38475
- payload: /* @__PURE__ */ looseObject({
38476
- currency: /* @__PURE__ */ string$1(),
38477
- hourly_rate: /* @__PURE__ */ number$2(),
38478
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38479
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38480
- }),
38722
+ payload: rateSchedulePayloadSchema,
38481
38723
  user_id: /* @__PURE__ */ number$2()
38482
38724
  }),
38483
38725
  execute: (input, { client }) => {
@@ -38689,21 +38931,16 @@ const generatedFocusOperations = [
38689
38931
  action: "labor-check-project-labor-cost-conflicts",
38690
38932
  title: "Labor Check Project Labor Cost Conflicts Rates",
38691
38933
  description: "Labor Check Project Labor Cost Conflicts Rates.",
38692
- safety: "read",
38934
+ safety: "update",
38693
38935
  destructive: false,
38694
38936
  cli: {
38695
38937
  group: ["rates", "labor"],
38696
38938
  command: "check-project-labor-cost-conflicts",
38697
- interactive: "available"
38939
+ interactive: "default"
38698
38940
  },
38699
38941
  mcp: { entityTool: "rates" },
38700
38942
  inputSchema: /* @__PURE__ */ looseObject({
38701
- payload: /* @__PURE__ */ looseObject({
38702
- currency: /* @__PURE__ */ string$1(),
38703
- hourly_rate: /* @__PURE__ */ number$2(),
38704
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38705
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38706
- }),
38943
+ payload: rateSchedulePayloadSchema,
38707
38944
  project_id: /* @__PURE__ */ number$2()
38708
38945
  }),
38709
38946
  execute: (input, { client }) => {
@@ -38725,21 +38962,16 @@ const generatedFocusOperations = [
38725
38962
  action: "labor-check-project-user-labor-cost-conflicts",
38726
38963
  title: "Labor Check Project User Labor Cost Conflicts Rates",
38727
38964
  description: "Labor Check Project User Labor Cost Conflicts Rates.",
38728
- safety: "read",
38965
+ safety: "update",
38729
38966
  destructive: false,
38730
38967
  cli: {
38731
38968
  group: ["rates", "labor"],
38732
38969
  command: "check-project-user-labor-cost-conflicts",
38733
- interactive: "available"
38970
+ interactive: "default"
38734
38971
  },
38735
38972
  mcp: { entityTool: "rates" },
38736
38973
  inputSchema: /* @__PURE__ */ looseObject({
38737
- payload: /* @__PURE__ */ looseObject({
38738
- currency: /* @__PURE__ */ string$1(),
38739
- hourly_rate: /* @__PURE__ */ number$2(),
38740
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38741
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38742
- }),
38974
+ payload: rateSchedulePayloadSchema,
38743
38975
  project_id: /* @__PURE__ */ number$2(),
38744
38976
  user_id: /* @__PURE__ */ number$2()
38745
38977
  }),
@@ -38763,20 +38995,15 @@ const generatedFocusOperations = [
38763
38995
  action: "labor-check-workspace-labor-cost-conflicts",
38764
38996
  title: "Labor Check Workspace Labor Cost Conflicts Rates",
38765
38997
  description: "Labor Check Workspace Labor Cost Conflicts Rates.",
38766
- safety: "read",
38998
+ safety: "update",
38767
38999
  destructive: false,
38768
39000
  cli: {
38769
39001
  group: ["rates", "labor"],
38770
39002
  command: "check-workspace-labor-cost-conflicts",
38771
- interactive: "available"
39003
+ interactive: "default"
38772
39004
  },
38773
39005
  mcp: { entityTool: "rates" },
38774
- inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
38775
- currency: /* @__PURE__ */ string$1(),
38776
- hourly_rate: /* @__PURE__ */ number$2(),
38777
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38778
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38779
- }) }),
39006
+ inputSchema: /* @__PURE__ */ looseObject({ payload: rateSchedulePayloadSchema }),
38780
39007
  execute: (input, { client }) => {
38781
39008
  const data = input;
38782
39009
  return client.runGeneratedRequest("checkWorkspaceLaborCostConflicts", () => callGeneratedRequest(checkWorkspaceLaborCostConflicts, [
@@ -38795,21 +39022,16 @@ const generatedFocusOperations = [
38795
39022
  action: "labor-check-workspace-user-labor-cost-conflicts",
38796
39023
  title: "Labor Check Workspace User Labor Cost Conflicts Rates",
38797
39024
  description: "Labor Check Workspace User Labor Cost Conflicts Rates.",
38798
- safety: "read",
39025
+ safety: "update",
38799
39026
  destructive: false,
38800
39027
  cli: {
38801
39028
  group: ["rates", "labor"],
38802
39029
  command: "check-workspace-user-labor-cost-conflicts",
38803
- interactive: "available"
39030
+ interactive: "default"
38804
39031
  },
38805
39032
  mcp: { entityTool: "rates" },
38806
39033
  inputSchema: /* @__PURE__ */ looseObject({
38807
- payload: /* @__PURE__ */ looseObject({
38808
- currency: /* @__PURE__ */ string$1(),
38809
- hourly_rate: /* @__PURE__ */ number$2(),
38810
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
38811
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
38812
- }),
39034
+ payload: rateSchedulePayloadSchema,
38813
39035
  user_id: /* @__PURE__ */ number$2()
38814
39036
  }),
38815
39037
  execute: (input, { client }) => {
@@ -39183,12 +39405,7 @@ const generatedFocusOperations = [
39183
39405
  },
39184
39406
  mcp: { entityTool: "rates" },
39185
39407
  inputSchema: /* @__PURE__ */ looseObject({
39186
- payload: /* @__PURE__ */ looseObject({
39187
- currency: /* @__PURE__ */ string$1(),
39188
- hourly_rate: /* @__PURE__ */ number$2(),
39189
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
39190
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
39191
- }),
39408
+ payload: rateSchedulePayloadSchema,
39192
39409
  project_id: /* @__PURE__ */ number$2()
39193
39410
  }),
39194
39411
  execute: (input, { client }) => {
@@ -39219,12 +39436,7 @@ const generatedFocusOperations = [
39219
39436
  },
39220
39437
  mcp: { entityTool: "rates" },
39221
39438
  inputSchema: /* @__PURE__ */ looseObject({
39222
- payload: /* @__PURE__ */ looseObject({
39223
- currency: /* @__PURE__ */ string$1(),
39224
- hourly_rate: /* @__PURE__ */ number$2(),
39225
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
39226
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
39227
- }),
39439
+ payload: rateSchedulePayloadSchema,
39228
39440
  project_id: /* @__PURE__ */ number$2(),
39229
39441
  user_id: /* @__PURE__ */ number$2()
39230
39442
  }),
@@ -39256,12 +39468,7 @@ const generatedFocusOperations = [
39256
39468
  interactive: "default"
39257
39469
  },
39258
39470
  mcp: { entityTool: "rates" },
39259
- inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
39260
- currency: /* @__PURE__ */ string$1(),
39261
- hourly_rate: /* @__PURE__ */ number$2(),
39262
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
39263
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
39264
- }) }),
39471
+ inputSchema: /* @__PURE__ */ looseObject({ payload: rateSchedulePayloadSchema }),
39265
39472
  execute: (input, { client }) => {
39266
39473
  const data = input;
39267
39474
  return client.runGeneratedRequest("upsertWorkspaceLaborCostRate", () => callGeneratedRequest(upsertWorkspaceLaborCostRate, [
@@ -39289,12 +39496,7 @@ const generatedFocusOperations = [
39289
39496
  },
39290
39497
  mcp: { entityTool: "rates" },
39291
39498
  inputSchema: /* @__PURE__ */ looseObject({
39292
- payload: /* @__PURE__ */ looseObject({
39293
- currency: /* @__PURE__ */ string$1(),
39294
- hourly_rate: /* @__PURE__ */ number$2(),
39295
- start_date: /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()),
39296
- end_date: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1()))
39297
- }),
39499
+ payload: rateSchedulePayloadSchema,
39298
39500
  user_id: /* @__PURE__ */ number$2()
39299
39501
  }),
39300
39502
  execute: (input, { client }) => {
@@ -39316,7 +39518,7 @@ const generatedFocusOperations = [
39316
39518
  action: "get-flexq-data",
39317
39519
  title: "Get Flexq Data Reports",
39318
39520
  description: "Get Flexq Data Reports.",
39319
- safety: "read",
39521
+ safety: "update",
39320
39522
  destructive: false,
39321
39523
  cli: {
39322
39524
  group: ["reports"],
@@ -39385,7 +39587,7 @@ const generatedFocusOperations = [
39385
39587
  action: "get-flexq-dictionary",
39386
39588
  title: "Get Flexq Dictionary Reports",
39387
39589
  description: "Get Flexq Dictionary Reports.",
39388
- safety: "read",
39590
+ safety: "update",
39389
39591
  destructive: false,
39390
39592
  cli: {
39391
39593
  group: ["reports"],
@@ -39411,7 +39613,7 @@ const generatedFocusOperations = [
39411
39613
  action: "get-workload",
39412
39614
  title: "Get Workload Reports",
39413
39615
  description: "Get Workload Reports.",
39414
- safety: "read",
39616
+ safety: "update",
39415
39617
  destructive: false,
39416
39618
  cli: {
39417
39619
  group: ["reports"],
@@ -40893,12 +41095,12 @@ const generatedFocusOperations = [
40893
41095
  action: "suggestions-get-project-suggestion-for-atask",
40894
41096
  title: "Suggestions Get Project Suggestion For Atask Tasks",
40895
41097
  description: "Suggestions Get Project Suggestion For Atask Tasks.",
40896
- safety: "read",
41098
+ safety: "update",
40897
41099
  destructive: false,
40898
41100
  cli: {
40899
41101
  group: ["tasks", "suggestions"],
40900
41102
  command: "get-project-suggestion-for-atask",
40901
- interactive: "available"
41103
+ interactive: "default"
40902
41104
  },
40903
41105
  mcp: { entityTool: "tasks" },
40904
41106
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({ task_id: /* @__PURE__ */ number$2() }) }),
@@ -40920,12 +41122,12 @@ const generatedFocusOperations = [
40920
41122
  action: "suggestions-get-project-suggestions-for-multiple-tasks",
40921
41123
  title: "Suggestions Get Project Suggestions For Multiple Tasks Tasks",
40922
41124
  description: "Suggestions Get Project Suggestions For Multiple Tasks Tasks.",
40923
- safety: "read",
41125
+ safety: "update",
40924
41126
  destructive: false,
40925
41127
  cli: {
40926
41128
  group: ["tasks", "suggestions"],
40927
41129
  command: "get-project-suggestions-for-multiple-tasks",
40928
- interactive: "available"
41130
+ interactive: "default"
40929
41131
  },
40930
41132
  mcp: { entityTool: "tasks" },
40931
41133
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({ task_ids: /* @__PURE__ */ array$1(/* @__PURE__ */ number$2()) }) }),
@@ -41561,7 +41763,7 @@ const generatedFocusOperations = [
41561
41763
  action: "bulk-set-day-duration",
41562
41764
  title: "Bulk Set Day Duration Time Entries",
41563
41765
  description: "Bulk Set Day Duration Time Entries.",
41564
- safety: "read",
41766
+ safety: "update",
41565
41767
  destructive: false,
41566
41768
  cli: {
41567
41769
  group: ["time-entries", "bulk"],
@@ -42057,12 +42259,12 @@ const generatedFocusOperations = [
42057
42259
  action: "tracking-start-tracking-from-description",
42058
42260
  title: "Tracking Start Tracking From Description Time Entries",
42059
42261
  description: "Tracking Start Tracking From Description Time Entries.",
42060
- safety: "read",
42262
+ safety: "update",
42061
42263
  destructive: false,
42062
42264
  cli: {
42063
42265
  group: ["time-entries", "tracking"],
42064
42266
  command: "start-tracking-from-description",
42065
- interactive: "available"
42267
+ interactive: "default"
42066
42268
  },
42067
42269
  mcp: { entityTool: "time-entries" },
42068
42270
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
@@ -42163,12 +42365,12 @@ const generatedFocusOperations = [
42163
42365
  action: "get-for-acalendar-event-title",
42164
42366
  title: "Get For Acalendar Event Title Time Log Suggestions",
42165
42367
  description: "Get For Acalendar Event Title Time Log Suggestions.",
42166
- safety: "read",
42368
+ safety: "update",
42167
42369
  destructive: false,
42168
42370
  cli: {
42169
42371
  group: ["time-log-suggestions"],
42170
42372
  command: "get-for-acalendar-event-title",
42171
- interactive: "available"
42373
+ interactive: "default"
42172
42374
  },
42173
42375
  mcp: { entityTool: "time-log-suggestions" },
42174
42376
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({ title: /* @__PURE__ */ string$1() }) }),
@@ -42190,12 +42392,12 @@ const generatedFocusOperations = [
42190
42392
  action: "get-for-multiple-calendar-event-titles",
42191
42393
  title: "Get For Multiple Calendar Event Titles Time Log Suggestions",
42192
42394
  description: "Get For Multiple Calendar Event Titles Time Log Suggestions.",
42193
- safety: "read",
42395
+ safety: "update",
42194
42396
  destructive: false,
42195
42397
  cli: {
42196
42398
  group: ["time-log-suggestions"],
42197
42399
  command: "get-for-multiple-calendar-event-titles",
42198
- interactive: "available"
42400
+ interactive: "default"
42199
42401
  },
42200
42402
  mcp: { entityTool: "time-log-suggestions" },
42201
42403
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({ items: /* @__PURE__ */ array$1(/* @__PURE__ */ looseObject({
@@ -42565,12 +42767,12 @@ const generatedFocusOperations = [
42565
42767
  action: "approve",
42566
42768
  title: "Approve Timesheets",
42567
42769
  description: "Approve Timesheets.",
42568
- safety: "read",
42770
+ safety: "update",
42569
42771
  destructive: false,
42570
42772
  cli: {
42571
42773
  group: ["timesheets"],
42572
42774
  command: "approve",
42573
- interactive: "available"
42775
+ interactive: "default"
42574
42776
  },
42575
42777
  mcp: { entityTool: "timesheets" },
42576
42778
  inputSchema: /* @__PURE__ */ looseObject({
@@ -42598,12 +42800,12 @@ const generatedFocusOperations = [
42598
42800
  action: "bulk-approve",
42599
42801
  title: "Bulk Approve Timesheets",
42600
42802
  description: "Bulk Approve Timesheets.",
42601
- safety: "read",
42803
+ safety: "update",
42602
42804
  destructive: false,
42603
42805
  cli: {
42604
42806
  group: ["timesheets", "bulk"],
42605
42807
  command: "approve",
42606
- interactive: "available"
42808
+ interactive: "default"
42607
42809
  },
42608
42810
  mcp: { entityTool: "timesheets" },
42609
42811
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({ keys: /* @__PURE__ */ array$1(/* @__PURE__ */ looseObject({
@@ -42629,12 +42831,12 @@ const generatedFocusOperations = [
42629
42831
  action: "bulk-request-changes",
42630
42832
  title: "Bulk Request Changes Timesheets",
42631
42833
  description: "Bulk Request Changes Timesheets.",
42632
- safety: "read",
42834
+ safety: "update",
42633
42835
  destructive: false,
42634
42836
  cli: {
42635
42837
  group: ["timesheets", "bulk"],
42636
42838
  command: "request-changes",
42637
- interactive: "available"
42839
+ interactive: "default"
42638
42840
  },
42639
42841
  mcp: { entityTool: "timesheets" },
42640
42842
  inputSchema: /* @__PURE__ */ looseObject({ payload: /* @__PURE__ */ looseObject({
@@ -42855,12 +43057,12 @@ const generatedFocusOperations = [
42855
43057
  action: "remove-timesheet-flag",
42856
43058
  title: "Remove Timesheet Flag Timesheets",
42857
43059
  description: "Remove Timesheet Flag Timesheets.",
42858
- safety: "read",
42859
- destructive: false,
43060
+ safety: "delete",
43061
+ destructive: true,
42860
43062
  cli: {
42861
43063
  group: ["timesheets"],
42862
43064
  command: "remove-timesheet-flag",
42863
- interactive: "available"
43065
+ interactive: "default"
42864
43066
  },
42865
43067
  mcp: { entityTool: "timesheets" },
42866
43068
  inputSchema: /* @__PURE__ */ looseObject({ flag_id: /* @__PURE__ */ number$2() }),
@@ -42882,12 +43084,12 @@ const generatedFocusOperations = [
42882
43084
  action: "request-changes",
42883
43085
  title: "Request Changes Timesheets",
42884
43086
  description: "Request Changes Timesheets.",
42885
- safety: "read",
43087
+ safety: "update",
42886
43088
  destructive: false,
42887
43089
  cli: {
42888
43090
  group: ["timesheets"],
42889
43091
  command: "request-changes",
42890
- interactive: "available"
43092
+ interactive: "default"
42891
43093
  },
42892
43094
  mcp: { entityTool: "timesheets" },
42893
43095
  inputSchema: /* @__PURE__ */ looseObject({
@@ -42917,12 +43119,12 @@ const generatedFocusOperations = [
42917
43119
  action: "resubmit",
42918
43120
  title: "Resubmit Timesheets",
42919
43121
  description: "Resubmit Timesheets.",
42920
- safety: "read",
43122
+ safety: "update",
42921
43123
  destructive: false,
42922
43124
  cli: {
42923
43125
  group: ["timesheets"],
42924
43126
  command: "resubmit",
42925
- interactive: "available"
43127
+ interactive: "default"
42926
43128
  },
42927
43129
  mcp: { entityTool: "timesheets" },
42928
43130
  inputSchema: /* @__PURE__ */ looseObject({
@@ -43017,12 +43219,12 @@ const generatedFocusOperations = [
43017
43219
  action: "setups-discontinue",
43018
43220
  title: "Setups Discontinue Timesheets",
43019
43221
  description: "Setups Discontinue Timesheets.",
43020
- safety: "read",
43222
+ safety: "update",
43021
43223
  destructive: false,
43022
43224
  cli: {
43023
43225
  group: ["timesheets", "setups"],
43024
43226
  command: "discontinue",
43025
- interactive: "available"
43227
+ interactive: "default"
43026
43228
  },
43027
43229
  mcp: { entityTool: "timesheets" },
43028
43230
  inputSchema: /* @__PURE__ */ looseObject({
@@ -43203,12 +43405,12 @@ const generatedFocusOperations = [
43203
43405
  action: "submit",
43204
43406
  title: "Submit Timesheets",
43205
43407
  description: "Submit Timesheets.",
43206
- safety: "read",
43408
+ safety: "update",
43207
43409
  destructive: false,
43208
43410
  cli: {
43209
43411
  group: ["timesheets"],
43210
43412
  command: "submit",
43211
- interactive: "available"
43413
+ interactive: "default"
43212
43414
  },
43213
43415
  mcp: { entityTool: "timesheets" },
43214
43416
  inputSchema: /* @__PURE__ */ looseObject({
@@ -43236,12 +43438,12 @@ const generatedFocusOperations = [
43236
43438
  action: "withdraw",
43237
43439
  title: "Withdraw Timesheets",
43238
43440
  description: "Withdraw Timesheets.",
43239
- safety: "read",
43441
+ safety: "update",
43240
43442
  destructive: false,
43241
43443
  cli: {
43242
43444
  group: ["timesheets"],
43243
43445
  command: "withdraw",
43244
- interactive: "available"
43446
+ interactive: "default"
43245
43447
  },
43246
43448
  mcp: { entityTool: "timesheets" },
43247
43449
  inputSchema: /* @__PURE__ */ looseObject({
@@ -43769,6 +43971,8 @@ const focusOperationOverrides = {
43769
43971
  ...taskAttachmentOverrides,
43770
43972
  ...projectOverrides,
43771
43973
  ...projectAttachmentOverrides,
43974
+ ...rateOverrides,
43975
+ ...readOnlyPostOverrides,
43772
43976
  ...timeBlockOverrides,
43773
43977
  ...timeEntryOverrides,
43774
43978
  ...statusOverrides,
@@ -44461,6 +44665,15 @@ function mcpText(text) {
44461
44665
  text
44462
44666
  }] };
44463
44667
  }
44668
+ function mcpFailure(text) {
44669
+ return {
44670
+ content: [{
44671
+ type: "text",
44672
+ text
44673
+ }],
44674
+ isError: true
44675
+ };
44676
+ }
44464
44677
  //#endregion
44465
44678
  //#region src/runtime/safety/mutation-gate.ts
44466
44679
  var MutationConfirmationRequired = class extends Error {
@@ -44883,29 +45096,44 @@ function inputFor(operations) {
44883
45096
  if (!first) throw new Error("Entity tool has no operations");
44884
45097
  return rest.length === 0 ? buildSingleActionInput(first) : buildMultiActionInput(operations);
44885
45098
  }
44886
- /**
44887
- * Render an operation's parameters as a compact, human-readable summary for the
44888
- * tool description. Required fields are suffixed with `*`. Falls back gracefully
44889
- * for array payloads or schemas that cannot be converted to JSON Schema.
44890
- */
45099
+ const MAX_INLINE_OBJECT_KEYS = 12;
44891
45100
  function summarizeParams(operation) {
44892
45101
  try {
44893
45102
  const schema = toJsonSchema(operation.inputSchema, { errorMode: "ignore" });
44894
45103
  if (schema.type === "array") return "array payload";
44895
- const keys = Object.keys(schema.properties ?? {});
45104
+ const properties = schema.properties ?? {};
45105
+ const keys = Object.keys(properties);
44896
45106
  if (keys.length === 0) return "none";
44897
45107
  const required = new Set(schema.required ?? []);
44898
- return keys.map((key) => required.has(key) ? `${key}*` : key).join(", ");
45108
+ return keys.map((key) => {
45109
+ const label = required.has(key) ? `${key}*` : key;
45110
+ const property = properties[key];
45111
+ if (property?.type !== "object") return label;
45112
+ const nestedKeys = Object.keys(property.properties ?? {});
45113
+ if (nestedKeys.length === 0) return label;
45114
+ if (nestedKeys.length > MAX_INLINE_OBJECT_KEYS) return `${label}{...}`;
45115
+ const nestedRequired = new Set(property.required ?? []);
45116
+ return `${label}{${nestedKeys.map((nestedKey) => nestedRequired.has(nestedKey) ? `${nestedKey}*` : nestedKey).join(", ")}}`;
45117
+ }).join(", ");
44899
45118
  } catch {
44900
45119
  return "see API docs";
44901
45120
  }
44902
45121
  }
44903
45122
  function buildToolDescription(entityTool, operations) {
45123
+ const byGuidance = /* @__PURE__ */ new Map();
45124
+ for (const op of operations) {
45125
+ if (!op.agentGuidance) continue;
45126
+ const actions = byGuidance.get(op.agentGuidance);
45127
+ if (actions) actions.push(op.action);
45128
+ else byGuidance.set(op.agentGuidance, [op.action]);
45129
+ }
45130
+ const shared = new Map([...byGuidance].filter(([, actions]) => actions.length > 1));
44904
45131
  const lines = [`Manage Focus ${entityTool} with the following actions:`, ""];
44905
45132
  for (const op of operations) {
44906
- const guidance = op.agentGuidance ? ` ${op.agentGuidance}` : "";
44907
- lines.push(`- **${op.action}**: ${op.description}${guidance} (data: ${summarizeParams(op)})`);
45133
+ const inline = op.agentGuidance && !shared.has(op.agentGuidance) ? ` ${op.agentGuidance}` : "";
45134
+ lines.push(`- **${op.action}**: ${op.description}${inline} (data: ${summarizeParams(op)})`);
44908
45135
  }
45136
+ for (const [guidance, actions] of shared) lines.push("", `Applies to ${actions.join(", ")}: ${guidance}`);
44909
45137
  lines.push("", "Pass the action-specific fields under `data` (required fields are marked with *).", "Mutations require a confirm_token handshake: call without confirm_token first to receive a token, then call again with the token to confirm.", "Optional dry_run: true validates input and returns { dry_run, operation, input } without calling the API.");
44910
45138
  return lines.join("\n");
44911
45139
  }
@@ -44933,7 +45161,9 @@ async function runOperation(operation, data, client, confirmToken, dryRun) {
44933
45161
  status: 403,
44934
45162
  message: `Operation '${operation.id}' is not available in this build.`
44935
45163
  });
44936
- const input = parse(operation.inputSchema, coercePayload(data) ?? {});
45164
+ const parseResult = /* @__PURE__ */ safeParse(operation.inputSchema, coercePayload(data) ?? {});
45165
+ if (!parseResult.success) return mcpFailure(`Invalid input: ${formatValibotError(parseResult.issues)}`);
45166
+ const input = parseResult.output;
44937
45167
  if (dryRun) return mcpText(JSON.stringify({
44938
45168
  dry_run: true,
44939
45169
  operation: operation.id,
@@ -44983,7 +45213,7 @@ import_main.default.config({
44983
45213
  quiet: true,
44984
45214
  ignore: ["MISSING_ENV_FILE"]
44985
45215
  });
44986
- const packageVersion = "1.6.16";
45216
+ const packageVersion = "1.7.0";
44987
45217
  function resolvePublicUrls() {
44988
45218
  return {
44989
45219
  focusApiUrl: process.env.TOGGL_FOCUS_API_URL ?? "https://focus.toggl.com",
@@ -45047,4 +45277,4 @@ function bootstrapServer(options = {}) {
45047
45277
  //#endregion
45048
45278
  export { runMcpCli as n, bootstrapServer as t };
45049
45279
 
45050
- //# sourceMappingURL=src-DO6utvuq.js.map
45280
+ //# sourceMappingURL=src-BlWD3FwF.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@togglhq/mcp",
3
- "version": "1.6.16",
3
+ "version": "1.7.0",
4
4
  "description": "Toggl 2.0 MCP server for Claude Code, Claude Desktop, and other MCP clients.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",