@sentientui/mcp 0.13.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,23 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2
21
 
3
22
  // src/api-client.ts
4
23
  var ApiError = class extends Error {
@@ -820,7 +839,11 @@ function registerGoalTools(server, client) {
820
839
  status: z6.string().describe("active | archived"),
821
840
  defaultValue: z6.number().nullable().describe("Fixed worth applied when a conversion carries no explicit value (project currency); null when unset")
822
841
  })
823
- ).describe("Defined goals (empty if none)")
842
+ ).describe("Defined goals (empty if none)"),
843
+ warnings: z6.array(z6.object({
844
+ goalName: z6.string().describe("The suspicious (probably typo) goal name"),
845
+ suggestion: z6.string().describe("The existing goal it likely meant")
846
+ })).describe("Recent goal names that look like typos of existing goals \u2014 verify before firing a new name")
824
847
  },
825
848
  annotations: {
826
849
  readOnlyHint: true,
@@ -829,23 +852,33 @@ function registerGoalTools(server, client) {
829
852
  }
830
853
  },
831
854
  withApiErrorGuidance(async ({ projectId }) => {
855
+ var _a;
832
856
  const id = encodeURIComponent(projectId);
833
857
  const data = await client.get(`/projects/${id}/goal-definitions`);
858
+ let warnings = [];
859
+ try {
860
+ const w = await client.get(
861
+ `/projects/${id}/goal-warnings`
862
+ );
863
+ warnings = ((_a = w.warnings) != null ? _a : []).map((x) => ({ goalName: x.goalName, suggestion: x.suggestion }));
864
+ } catch (e) {
865
+ }
834
866
  const structuredContent = {
835
867
  goals: data.goals.map((g) => {
836
- var _a;
868
+ var _a2;
837
869
  return {
838
870
  goalId: g.goal_id,
839
871
  displayName: g.display_name,
840
872
  role: g.role,
841
873
  event: g.event,
842
- urlPattern: (_a = g.url_pattern) != null ? _a : null,
874
+ urlPattern: (_a2 = g.url_pattern) != null ? _a2 : null,
843
875
  status: g.status,
844
876
  // NUMERIC arrives serialized as a string; coerce and tolerate its
845
877
  // absence from an older API deploy.
846
878
  defaultValue: g.default_value != null ? Number(g.default_value) : null
847
879
  };
848
- })
880
+ }),
881
+ warnings
849
882
  };
850
883
  if (!structuredContent.goals.length) {
851
884
  return {
@@ -859,6 +892,9 @@ function registerGoalTools(server, client) {
859
892
  const lines = structuredContent.goals.map(
860
893
  (g) => `${g.goalId} (${g.role}, ${g.event}${g.status === "archived" ? ", archived" : ""}) \u2014 ${g.displayName}`
861
894
  );
895
+ for (const w of warnings) {
896
+ lines.push(`\u26A0 "${w.goalName}" looks like a typo of "${w.suggestion}" \u2014 check before using it.`);
897
+ }
862
898
  lines.push("", `Reference a goalId verbatim from code: client.goal('<goalId>') or <Adaptive goal="<goalId>">.`);
863
899
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
864
900
  })
@@ -945,6 +981,7 @@ function registerFunnelTools(server, client) {
945
981
  funnelId: z7.string(),
946
982
  displayName: z7.string(),
947
983
  windowDays: z7.number(),
984
+ strictOrder: z7.boolean().describe("True when the chart counts a step only if the previous step happened first (reporting only \u2014 the optimizer always credits max progress)"),
948
985
  currency: z7.string().describe("Project display currency (ISO-4217) for the revenue fields"),
949
986
  steps: z7.array(
950
987
  z7.object({
@@ -971,6 +1008,7 @@ function registerFunnelTools(server, client) {
971
1008
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
972
1009
  },
973
1010
  withApiErrorGuidance(async ({ projectId, funnelId }) => {
1011
+ var _a;
974
1012
  const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
975
1013
  const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
976
1014
  for (const s of data.steps) {
@@ -989,7 +1027,11 @@ function registerFunnelTools(server, client) {
989
1027
  if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
990
1028
  lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
991
1029
  }
992
- return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data };
1030
+ return {
1031
+ content: [{ type: "text", text: lines.join("\n") }],
1032
+ // Tolerate an API deployed before strict funnels existed.
1033
+ structuredContent: __spreadProps(__spreadValues({}, data), { strictOrder: (_a = data.strictOrder) != null ? _a : true })
1034
+ };
993
1035
  })
994
1036
  );
995
1037
  }
@@ -1008,7 +1050,8 @@ function registerGuardrailTools(server, client) {
1008
1050
  z8.object({
1009
1051
  componentId: z8.string(),
1010
1052
  variantIds: z8.array(z8.string()).describe("Variants paused by the guardrail"),
1011
- pausedAt: z8.string().nullable().describe("ISO timestamp the pause fired, or null")
1053
+ pausedAt: z8.string().nullable().describe("ISO timestamp the pause fired, or null"),
1054
+ funnelId: z8.string().nullable().describe("Set when the pause came from a funnel guardrail")
1012
1055
  })
1013
1056
  ).describe("Guardrail events in the last 24h (empty if none)")
1014
1057
  },
@@ -1022,11 +1065,15 @@ function registerGuardrailTools(server, client) {
1022
1065
  const id = encodeURIComponent(projectId);
1023
1066
  const data = await client.get(`/projects/${id}/guardrail-events`);
1024
1067
  const structuredContent = {
1025
- events: data.guardrailEvents.map((e) => ({
1026
- componentId: e.componentId,
1027
- variantIds: e.variantIds,
1028
- pausedAt: e.pausedAt
1029
- }))
1068
+ events: data.guardrailEvents.map((e) => {
1069
+ var _a;
1070
+ return {
1071
+ componentId: e.componentId,
1072
+ variantIds: e.variantIds,
1073
+ pausedAt: e.pausedAt,
1074
+ funnelId: (_a = e.funnelId) != null ? _a : null
1075
+ };
1076
+ })
1030
1077
  };
1031
1078
  if (!data.guardrailEvents.length) {
1032
1079
  return {
@@ -1035,7 +1082,7 @@ function registerGuardrailTools(server, client) {
1035
1082
  };
1036
1083
  }
1037
1084
  const lines = data.guardrailEvents.map(
1038
- (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}`
1085
+ (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}${e.funnelId ? ` (protecting the "${e.funnelId}" funnel)` : ""}`
1039
1086
  );
1040
1087
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
1041
1088
  })
@@ -1725,7 +1772,7 @@ function registerAgentTrafficTools(server, client) {
1725
1772
  }
1726
1773
 
1727
1774
  // src/server.ts
1728
- var PKG_VERSION = true ? "0.13.0" : "0.0.0-dev";
1775
+ var PKG_VERSION = true ? "0.14.1" : "0.0.0-dev";
1729
1776
  function createMcpServer(client) {
1730
1777
  const server = new McpServer(
1731
1778
  {
package/dist/index.cjs CHANGED
@@ -1,5 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __spreadValues = (a, b) => {
11
+ for (var prop in b || (b = {}))
12
+ if (__hasOwnProp.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ if (__getOwnPropSymbols)
15
+ for (var prop of __getOwnPropSymbols(b)) {
16
+ if (__propIsEnum.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ }
19
+ return a;
20
+ };
21
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3
22
 
4
23
  // src/index.ts
5
24
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
@@ -824,7 +843,11 @@ function registerGoalTools(server, client) {
824
843
  status: import_zod6.z.string().describe("active | archived"),
825
844
  defaultValue: import_zod6.z.number().nullable().describe("Fixed worth applied when a conversion carries no explicit value (project currency); null when unset")
826
845
  })
827
- ).describe("Defined goals (empty if none)")
846
+ ).describe("Defined goals (empty if none)"),
847
+ warnings: import_zod6.z.array(import_zod6.z.object({
848
+ goalName: import_zod6.z.string().describe("The suspicious (probably typo) goal name"),
849
+ suggestion: import_zod6.z.string().describe("The existing goal it likely meant")
850
+ })).describe("Recent goal names that look like typos of existing goals \u2014 verify before firing a new name")
828
851
  },
829
852
  annotations: {
830
853
  readOnlyHint: true,
@@ -833,23 +856,33 @@ function registerGoalTools(server, client) {
833
856
  }
834
857
  },
835
858
  withApiErrorGuidance(async ({ projectId }) => {
859
+ var _a2;
836
860
  const id = encodeURIComponent(projectId);
837
861
  const data = await client.get(`/projects/${id}/goal-definitions`);
862
+ let warnings = [];
863
+ try {
864
+ const w = await client.get(
865
+ `/projects/${id}/goal-warnings`
866
+ );
867
+ warnings = ((_a2 = w.warnings) != null ? _a2 : []).map((x) => ({ goalName: x.goalName, suggestion: x.suggestion }));
868
+ } catch (e) {
869
+ }
838
870
  const structuredContent = {
839
871
  goals: data.goals.map((g) => {
840
- var _a2;
872
+ var _a3;
841
873
  return {
842
874
  goalId: g.goal_id,
843
875
  displayName: g.display_name,
844
876
  role: g.role,
845
877
  event: g.event,
846
- urlPattern: (_a2 = g.url_pattern) != null ? _a2 : null,
878
+ urlPattern: (_a3 = g.url_pattern) != null ? _a3 : null,
847
879
  status: g.status,
848
880
  // NUMERIC arrives serialized as a string; coerce and tolerate its
849
881
  // absence from an older API deploy.
850
882
  defaultValue: g.default_value != null ? Number(g.default_value) : null
851
883
  };
852
- })
884
+ }),
885
+ warnings
853
886
  };
854
887
  if (!structuredContent.goals.length) {
855
888
  return {
@@ -863,6 +896,9 @@ function registerGoalTools(server, client) {
863
896
  const lines = structuredContent.goals.map(
864
897
  (g) => `${g.goalId} (${g.role}, ${g.event}${g.status === "archived" ? ", archived" : ""}) \u2014 ${g.displayName}`
865
898
  );
899
+ for (const w of warnings) {
900
+ lines.push(`\u26A0 "${w.goalName}" looks like a typo of "${w.suggestion}" \u2014 check before using it.`);
901
+ }
866
902
  lines.push("", `Reference a goalId verbatim from code: client.goal('<goalId>') or <Adaptive goal="<goalId>">.`);
867
903
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
868
904
  })
@@ -949,6 +985,7 @@ function registerFunnelTools(server, client) {
949
985
  funnelId: import_zod7.z.string(),
950
986
  displayName: import_zod7.z.string(),
951
987
  windowDays: import_zod7.z.number(),
988
+ strictOrder: import_zod7.z.boolean().describe("True when the chart counts a step only if the previous step happened first (reporting only \u2014 the optimizer always credits max progress)"),
952
989
  currency: import_zod7.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
953
990
  steps: import_zod7.z.array(
954
991
  import_zod7.z.object({
@@ -975,6 +1012,7 @@ function registerFunnelTools(server, client) {
975
1012
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
976
1013
  },
977
1014
  withApiErrorGuidance(async ({ projectId, funnelId }) => {
1015
+ var _a2;
978
1016
  const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
979
1017
  const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
980
1018
  for (const s of data.steps) {
@@ -993,7 +1031,11 @@ function registerFunnelTools(server, client) {
993
1031
  if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
994
1032
  lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
995
1033
  }
996
- return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data };
1034
+ return {
1035
+ content: [{ type: "text", text: lines.join("\n") }],
1036
+ // Tolerate an API deployed before strict funnels existed.
1037
+ structuredContent: __spreadProps(__spreadValues({}, data), { strictOrder: (_a2 = data.strictOrder) != null ? _a2 : true })
1038
+ };
997
1039
  })
998
1040
  );
999
1041
  }
@@ -1012,7 +1054,8 @@ function registerGuardrailTools(server, client) {
1012
1054
  import_zod8.z.object({
1013
1055
  componentId: import_zod8.z.string(),
1014
1056
  variantIds: import_zod8.z.array(import_zod8.z.string()).describe("Variants paused by the guardrail"),
1015
- pausedAt: import_zod8.z.string().nullable().describe("ISO timestamp the pause fired, or null")
1057
+ pausedAt: import_zod8.z.string().nullable().describe("ISO timestamp the pause fired, or null"),
1058
+ funnelId: import_zod8.z.string().nullable().describe("Set when the pause came from a funnel guardrail")
1016
1059
  })
1017
1060
  ).describe("Guardrail events in the last 24h (empty if none)")
1018
1061
  },
@@ -1026,11 +1069,15 @@ function registerGuardrailTools(server, client) {
1026
1069
  const id = encodeURIComponent(projectId);
1027
1070
  const data = await client.get(`/projects/${id}/guardrail-events`);
1028
1071
  const structuredContent = {
1029
- events: data.guardrailEvents.map((e) => ({
1030
- componentId: e.componentId,
1031
- variantIds: e.variantIds,
1032
- pausedAt: e.pausedAt
1033
- }))
1072
+ events: data.guardrailEvents.map((e) => {
1073
+ var _a2;
1074
+ return {
1075
+ componentId: e.componentId,
1076
+ variantIds: e.variantIds,
1077
+ pausedAt: e.pausedAt,
1078
+ funnelId: (_a2 = e.funnelId) != null ? _a2 : null
1079
+ };
1080
+ })
1034
1081
  };
1035
1082
  if (!data.guardrailEvents.length) {
1036
1083
  return {
@@ -1039,7 +1086,7 @@ function registerGuardrailTools(server, client) {
1039
1086
  };
1040
1087
  }
1041
1088
  const lines = data.guardrailEvents.map(
1042
- (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}`
1089
+ (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}${e.funnelId ? ` (protecting the "${e.funnelId}" funnel)` : ""}`
1043
1090
  );
1044
1091
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
1045
1092
  })
@@ -1729,7 +1776,7 @@ function registerAgentTrafficTools(server, client) {
1729
1776
  }
1730
1777
 
1731
1778
  // src/server.ts
1732
- var PKG_VERSION = true ? "0.13.0" : "0.0.0-dev";
1779
+ var PKG_VERSION = true ? "0.14.1" : "0.0.0-dev";
1733
1780
  function createMcpServer(client) {
1734
1781
  const server = new import_mcp.McpServer(
1735
1782
  {
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  ApiClient,
4
4
  createMcpServer
5
- } from "./chunk-ZJ2JZ5RR.js";
5
+ } from "./chunk-O335LMWF.js";
6
6
 
7
7
  // src/index.ts
8
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/dist/lib.cjs CHANGED
@@ -1,9 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
9
  var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
7
24
  var __export = (target, all) => {
8
25
  for (var name in all)
9
26
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -849,7 +866,11 @@ function registerGoalTools(server, client) {
849
866
  status: import_zod6.z.string().describe("active | archived"),
850
867
  defaultValue: import_zod6.z.number().nullable().describe("Fixed worth applied when a conversion carries no explicit value (project currency); null when unset")
851
868
  })
852
- ).describe("Defined goals (empty if none)")
869
+ ).describe("Defined goals (empty if none)"),
870
+ warnings: import_zod6.z.array(import_zod6.z.object({
871
+ goalName: import_zod6.z.string().describe("The suspicious (probably typo) goal name"),
872
+ suggestion: import_zod6.z.string().describe("The existing goal it likely meant")
873
+ })).describe("Recent goal names that look like typos of existing goals \u2014 verify before firing a new name")
853
874
  },
854
875
  annotations: {
855
876
  readOnlyHint: true,
@@ -858,23 +879,33 @@ function registerGoalTools(server, client) {
858
879
  }
859
880
  },
860
881
  withApiErrorGuidance(async ({ projectId }) => {
882
+ var _a;
861
883
  const id = encodeURIComponent(projectId);
862
884
  const data = await client.get(`/projects/${id}/goal-definitions`);
885
+ let warnings = [];
886
+ try {
887
+ const w = await client.get(
888
+ `/projects/${id}/goal-warnings`
889
+ );
890
+ warnings = ((_a = w.warnings) != null ? _a : []).map((x) => ({ goalName: x.goalName, suggestion: x.suggestion }));
891
+ } catch (e) {
892
+ }
863
893
  const structuredContent = {
864
894
  goals: data.goals.map((g) => {
865
- var _a;
895
+ var _a2;
866
896
  return {
867
897
  goalId: g.goal_id,
868
898
  displayName: g.display_name,
869
899
  role: g.role,
870
900
  event: g.event,
871
- urlPattern: (_a = g.url_pattern) != null ? _a : null,
901
+ urlPattern: (_a2 = g.url_pattern) != null ? _a2 : null,
872
902
  status: g.status,
873
903
  // NUMERIC arrives serialized as a string; coerce and tolerate its
874
904
  // absence from an older API deploy.
875
905
  defaultValue: g.default_value != null ? Number(g.default_value) : null
876
906
  };
877
- })
907
+ }),
908
+ warnings
878
909
  };
879
910
  if (!structuredContent.goals.length) {
880
911
  return {
@@ -888,6 +919,9 @@ function registerGoalTools(server, client) {
888
919
  const lines = structuredContent.goals.map(
889
920
  (g) => `${g.goalId} (${g.role}, ${g.event}${g.status === "archived" ? ", archived" : ""}) \u2014 ${g.displayName}`
890
921
  );
922
+ for (const w of warnings) {
923
+ lines.push(`\u26A0 "${w.goalName}" looks like a typo of "${w.suggestion}" \u2014 check before using it.`);
924
+ }
891
925
  lines.push("", `Reference a goalId verbatim from code: client.goal('<goalId>') or <Adaptive goal="<goalId>">.`);
892
926
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
893
927
  })
@@ -974,6 +1008,7 @@ function registerFunnelTools(server, client) {
974
1008
  funnelId: import_zod7.z.string(),
975
1009
  displayName: import_zod7.z.string(),
976
1010
  windowDays: import_zod7.z.number(),
1011
+ strictOrder: import_zod7.z.boolean().describe("True when the chart counts a step only if the previous step happened first (reporting only \u2014 the optimizer always credits max progress)"),
977
1012
  currency: import_zod7.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
978
1013
  steps: import_zod7.z.array(
979
1014
  import_zod7.z.object({
@@ -1000,6 +1035,7 @@ function registerFunnelTools(server, client) {
1000
1035
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1001
1036
  },
1002
1037
  withApiErrorGuidance(async ({ projectId, funnelId }) => {
1038
+ var _a;
1003
1039
  const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
1004
1040
  const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
1005
1041
  for (const s of data.steps) {
@@ -1018,7 +1054,11 @@ function registerFunnelTools(server, client) {
1018
1054
  if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
1019
1055
  lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
1020
1056
  }
1021
- return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data };
1057
+ return {
1058
+ content: [{ type: "text", text: lines.join("\n") }],
1059
+ // Tolerate an API deployed before strict funnels existed.
1060
+ structuredContent: __spreadProps(__spreadValues({}, data), { strictOrder: (_a = data.strictOrder) != null ? _a : true })
1061
+ };
1022
1062
  })
1023
1063
  );
1024
1064
  }
@@ -1037,7 +1077,8 @@ function registerGuardrailTools(server, client) {
1037
1077
  import_zod8.z.object({
1038
1078
  componentId: import_zod8.z.string(),
1039
1079
  variantIds: import_zod8.z.array(import_zod8.z.string()).describe("Variants paused by the guardrail"),
1040
- pausedAt: import_zod8.z.string().nullable().describe("ISO timestamp the pause fired, or null")
1080
+ pausedAt: import_zod8.z.string().nullable().describe("ISO timestamp the pause fired, or null"),
1081
+ funnelId: import_zod8.z.string().nullable().describe("Set when the pause came from a funnel guardrail")
1041
1082
  })
1042
1083
  ).describe("Guardrail events in the last 24h (empty if none)")
1043
1084
  },
@@ -1051,11 +1092,15 @@ function registerGuardrailTools(server, client) {
1051
1092
  const id = encodeURIComponent(projectId);
1052
1093
  const data = await client.get(`/projects/${id}/guardrail-events`);
1053
1094
  const structuredContent = {
1054
- events: data.guardrailEvents.map((e) => ({
1055
- componentId: e.componentId,
1056
- variantIds: e.variantIds,
1057
- pausedAt: e.pausedAt
1058
- }))
1095
+ events: data.guardrailEvents.map((e) => {
1096
+ var _a;
1097
+ return {
1098
+ componentId: e.componentId,
1099
+ variantIds: e.variantIds,
1100
+ pausedAt: e.pausedAt,
1101
+ funnelId: (_a = e.funnelId) != null ? _a : null
1102
+ };
1103
+ })
1059
1104
  };
1060
1105
  if (!data.guardrailEvents.length) {
1061
1106
  return {
@@ -1064,7 +1109,7 @@ function registerGuardrailTools(server, client) {
1064
1109
  };
1065
1110
  }
1066
1111
  const lines = data.guardrailEvents.map(
1067
- (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}`
1112
+ (e) => `- ${e.componentId}: variants [${e.variantIds.join(", ")}] paused${e.pausedAt ? ` at ${e.pausedAt}` : ""}${e.funnelId ? ` (protecting the "${e.funnelId}" funnel)` : ""}`
1068
1113
  );
1069
1114
  return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
1070
1115
  })
@@ -1754,7 +1799,7 @@ function registerAgentTrafficTools(server, client) {
1754
1799
  }
1755
1800
 
1756
1801
  // src/server.ts
1757
- var PKG_VERSION = true ? "0.13.0" : "0.0.0-dev";
1802
+ var PKG_VERSION = true ? "0.14.1" : "0.0.0-dev";
1758
1803
  function createMcpServer(client) {
1759
1804
  const server = new import_mcp.McpServer(
1760
1805
  {
package/dist/lib.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  ApiClient,
4
4
  ApiError,
5
5
  createMcpServer
6
- } from "./chunk-ZJ2JZ5RR.js";
6
+ } from "./chunk-O335LMWF.js";
7
7
  export {
8
8
  ApiClient,
9
9
  ApiError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentientui/mcp",
3
- "version": "0.13.0",
3
+ "version": "0.14.1",
4
4
  "description": "MCP server for SentientUI — exposes project data and actions to AI agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sentient-ui.com",