@sentientui/mcp 0.12.0 → 0.14.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/dist/{chunk-BMOKDBGH.js → chunk-DZLODBXR.js} +262 -85
- package/dist/index.cjs +262 -85
- package/dist/index.js +1 -1
- package/dist/lib.cjs +260 -85
- package/dist/lib.js +1 -1
- package/package.json +1 -1
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");
|
|
@@ -734,7 +753,7 @@ function registerGoalTools(server, client) {
|
|
|
734
753
|
"get_goal_funnel",
|
|
735
754
|
{
|
|
736
755
|
title: "Goal funnel",
|
|
737
|
-
description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown.",
|
|
756
|
+
description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown. This is a flat per-goal list \u2014 for multi-step funnel drop-off, use get_funnel_report.",
|
|
738
757
|
inputSchema: { projectId: projectIdSchema },
|
|
739
758
|
_meta: uiMeta("goal-funnel"),
|
|
740
759
|
outputSchema: {
|
|
@@ -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
|
|
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: (
|
|
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,14 +896,152 @@ 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
|
})
|
|
869
905
|
);
|
|
870
906
|
}
|
|
871
907
|
|
|
872
|
-
// src/tools/
|
|
908
|
+
// src/tools/funnels.ts
|
|
873
909
|
var import_zod7 = require("zod");
|
|
910
|
+
var funnelIdSchema = import_zod7.z.string().describe('Funnel slug (from list_funnels), e.g. "checkout"');
|
|
911
|
+
function registerFunnelTools(server, client) {
|
|
912
|
+
server.registerTool(
|
|
913
|
+
"list_funnels",
|
|
914
|
+
{
|
|
915
|
+
title: "List funnels",
|
|
916
|
+
description: `List the project's multi-step funnels \u2014 ordered goal steps plus the components serving them. Use get_funnel_report for a funnel's drop-off numbers. Reference a funnelId verbatim from code: <Adaptive funnel="<funnelId>">.`,
|
|
917
|
+
inputSchema: { projectId: projectIdSchema },
|
|
918
|
+
outputSchema: {
|
|
919
|
+
funnels: import_zod7.z.array(
|
|
920
|
+
import_zod7.z.object({
|
|
921
|
+
funnelId: import_zod7.z.string().describe("Stable slug \u2014 use this exact string in code and in get_funnel_report"),
|
|
922
|
+
displayName: import_zod7.z.string(),
|
|
923
|
+
status: import_zod7.z.string().describe("draft | active | archived"),
|
|
924
|
+
windowDays: import_zod7.z.number().describe("Conversion window in days"),
|
|
925
|
+
source: import_zod7.z.string().describe("user | chat | editor | sdk"),
|
|
926
|
+
steps: import_zod7.z.array(
|
|
927
|
+
import_zod7.z.object({
|
|
928
|
+
stepIndex: import_zod7.z.number(),
|
|
929
|
+
goalId: import_zod7.z.string(),
|
|
930
|
+
weight: import_zod7.z.number().nullable().describe("Manual optimizer credit for reaching this step (null = automatic end-weighted)")
|
|
931
|
+
})
|
|
932
|
+
).describe("Ordered steps"),
|
|
933
|
+
components: import_zod7.z.array(import_zod7.z.object({ componentId: import_zod7.z.string(), stepIndex: import_zod7.z.number().nullable() })).describe("Components serving this funnel (stepIndex null = whole funnel)")
|
|
934
|
+
})
|
|
935
|
+
).describe("Defined funnels (empty if none)")
|
|
936
|
+
},
|
|
937
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
938
|
+
},
|
|
939
|
+
withApiErrorGuidance(async ({ projectId }) => {
|
|
940
|
+
var _a2;
|
|
941
|
+
const id = encodeURIComponent(projectId);
|
|
942
|
+
const data = await client.get(`/projects/${id}/funnels`);
|
|
943
|
+
const structuredContent = {
|
|
944
|
+
funnels: ((_a2 = data.funnels) != null ? _a2 : []).map((f) => ({
|
|
945
|
+
funnelId: f.funnel_id,
|
|
946
|
+
displayName: f.display_name,
|
|
947
|
+
status: f.status,
|
|
948
|
+
windowDays: f.window_days,
|
|
949
|
+
source: f.source,
|
|
950
|
+
// NUMERIC arrives serialized as a string; coerce.
|
|
951
|
+
steps: f.steps.map((s) => ({
|
|
952
|
+
stepIndex: s.step_index,
|
|
953
|
+
goalId: s.goal_id,
|
|
954
|
+
weight: s.weight == null ? null : Number(s.weight)
|
|
955
|
+
})),
|
|
956
|
+
components: f.components.map((c) => {
|
|
957
|
+
var _a3;
|
|
958
|
+
return { componentId: c.component_id, stepIndex: (_a3 = c.step_index) != null ? _a3 : null };
|
|
959
|
+
})
|
|
960
|
+
}))
|
|
961
|
+
};
|
|
962
|
+
if (structuredContent.funnels.length === 0) {
|
|
963
|
+
return {
|
|
964
|
+
content: [{
|
|
965
|
+
type: "text",
|
|
966
|
+
text: "No funnels defined yet. Build one in the dashboard (Goals \u2192 Funnels tab) or via the goal chat \u2014 a funnel is 2-12 ordered goal steps, e.g. add_to_cart \u2192 checkout \u2192 purchase."
|
|
967
|
+
}],
|
|
968
|
+
structuredContent
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
const lines = structuredContent.funnels.map(
|
|
972
|
+
(f) => `${f.funnelId} (${f.status}) \u2014 ${f.displayName}: ${f.steps.map((s) => s.goalId).join(" \u2192 ")}`
|
|
973
|
+
);
|
|
974
|
+
lines.push("", 'Reference a funnelId verbatim from code: <Adaptive funnel="<funnelId>">. Use get_funnel_report for drop-off numbers.');
|
|
975
|
+
return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
|
|
976
|
+
})
|
|
977
|
+
);
|
|
978
|
+
server.registerTool(
|
|
979
|
+
"get_funnel_report",
|
|
980
|
+
{
|
|
981
|
+
title: "Funnel drop-off report",
|
|
982
|
+
description: 'Per-step reach and drop-off for one funnel over its conversion window, with per-variant and audience splits per step, final-step revenue, and the holdout ("without optimization") comparison.',
|
|
983
|
+
inputSchema: { projectId: projectIdSchema, funnelId: funnelIdSchema },
|
|
984
|
+
outputSchema: {
|
|
985
|
+
funnelId: import_zod7.z.string(),
|
|
986
|
+
displayName: import_zod7.z.string(),
|
|
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)"),
|
|
989
|
+
currency: import_zod7.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
|
|
990
|
+
steps: import_zod7.z.array(
|
|
991
|
+
import_zod7.z.object({
|
|
992
|
+
stepIndex: import_zod7.z.number(),
|
|
993
|
+
goalId: import_zod7.z.string(),
|
|
994
|
+
displayName: import_zod7.z.string(),
|
|
995
|
+
reached: import_zod7.z.number().describe("Distinct visitors reaching this step in-window"),
|
|
996
|
+
dropOffFromPrevious: import_zod7.z.number().nullable().describe("1 - reached/previousReached (null on the first step)"),
|
|
997
|
+
neverFired: import_zod7.z.boolean().describe("True when the step goal has never been recorded anywhere \u2014 likely a typo"),
|
|
998
|
+
variants: import_zod7.z.array(import_zod7.z.object({
|
|
999
|
+
componentId: import_zod7.z.string(),
|
|
1000
|
+
variantId: import_zod7.z.string(),
|
|
1001
|
+
reached: import_zod7.z.number(),
|
|
1002
|
+
assigned: import_zod7.z.number().describe("Distinct sessions served this variant in-window (the rate denominator)")
|
|
1003
|
+
})),
|
|
1004
|
+
personas: import_zod7.z.array(import_zod7.z.object({ label: import_zod7.z.string(), reached: import_zod7.z.number() }))
|
|
1005
|
+
})
|
|
1006
|
+
),
|
|
1007
|
+
revenue: import_zod7.z.number().nullable().describe("Final-step revenue in the project currency (null when no valued conversions)"),
|
|
1008
|
+
avgOrderValue: import_zod7.z.number().nullable(),
|
|
1009
|
+
revenuePerEnteringVisitor: import_zod7.z.number().nullable(),
|
|
1010
|
+
holdoutCompletion: import_zod7.z.object({ entered: import_zod7.z.number(), reached: import_zod7.z.number() }).nullable().describe('Holdout visitors entering vs finishing \u2014 the "without optimization" line')
|
|
1011
|
+
},
|
|
1012
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1013
|
+
},
|
|
1014
|
+
withApiErrorGuidance(async ({ projectId, funnelId }) => {
|
|
1015
|
+
var _a2;
|
|
1016
|
+
const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
|
|
1017
|
+
const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
|
|
1018
|
+
for (const s of data.steps) {
|
|
1019
|
+
lines.push(
|
|
1020
|
+
`${s.stepIndex + 1}. ${s.displayName}: ${s.reached} reached` + (s.dropOffFromPrevious != null ? ` (${Math.round(s.dropOffFromPrevious * 100)}% drop-off from previous)` : "") + (s.neverFired ? " [never recorded \u2014 check the goal name]" : "")
|
|
1021
|
+
);
|
|
1022
|
+
for (const v of s.variants) {
|
|
1023
|
+
lines.push(` ${v.componentId}/${v.variantId}: ${v.reached}/${v.assigned} assigned sessions reached this step`);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
if (data.revenue != null) {
|
|
1027
|
+
lines.push(
|
|
1028
|
+
`Revenue: ${data.revenue.toFixed(2)} ${data.currency}` + (data.avgOrderValue != null ? ` (${data.avgOrderValue.toFixed(2)} ${data.currency} avg order)` : "") + (data.revenuePerEnteringVisitor != null ? `, ${data.revenuePerEnteringVisitor.toFixed(2)} ${data.currency} per entering visitor` : "")
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
|
|
1032
|
+
lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
|
|
1033
|
+
}
|
|
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 : false })
|
|
1038
|
+
};
|
|
1039
|
+
})
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// src/tools/guardrails.ts
|
|
1044
|
+
var import_zod8 = require("zod");
|
|
874
1045
|
function registerGuardrailTools(server, client) {
|
|
875
1046
|
server.registerTool(
|
|
876
1047
|
"list_guardrail_events",
|
|
@@ -879,11 +1050,12 @@ function registerGuardrailTools(server, client) {
|
|
|
879
1050
|
description: "List variants currently paused by the guardrail in the last 24 hours.",
|
|
880
1051
|
inputSchema: { projectId: projectIdSchema },
|
|
881
1052
|
outputSchema: {
|
|
882
|
-
events:
|
|
883
|
-
|
|
884
|
-
componentId:
|
|
885
|
-
variantIds:
|
|
886
|
-
pausedAt:
|
|
1053
|
+
events: import_zod8.z.array(
|
|
1054
|
+
import_zod8.z.object({
|
|
1055
|
+
componentId: import_zod8.z.string(),
|
|
1056
|
+
variantIds: import_zod8.z.array(import_zod8.z.string()).describe("Variants paused by the guardrail"),
|
|
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")
|
|
887
1059
|
})
|
|
888
1060
|
).describe("Guardrail events in the last 24h (empty if none)")
|
|
889
1061
|
},
|
|
@@ -897,11 +1069,15 @@ function registerGuardrailTools(server, client) {
|
|
|
897
1069
|
const id = encodeURIComponent(projectId);
|
|
898
1070
|
const data = await client.get(`/projects/${id}/guardrail-events`);
|
|
899
1071
|
const structuredContent = {
|
|
900
|
-
events: data.guardrailEvents.map((e) =>
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
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
|
+
})
|
|
905
1081
|
};
|
|
906
1082
|
if (!data.guardrailEvents.length) {
|
|
907
1083
|
return {
|
|
@@ -910,7 +1086,7 @@ function registerGuardrailTools(server, client) {
|
|
|
910
1086
|
};
|
|
911
1087
|
}
|
|
912
1088
|
const lines = data.guardrailEvents.map(
|
|
913
|
-
(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)` : ""}`
|
|
914
1090
|
);
|
|
915
1091
|
return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
|
|
916
1092
|
})
|
|
@@ -918,7 +1094,7 @@ function registerGuardrailTools(server, client) {
|
|
|
918
1094
|
}
|
|
919
1095
|
|
|
920
1096
|
// src/tools/layout.ts
|
|
921
|
-
var
|
|
1097
|
+
var import_zod9 = require("zod");
|
|
922
1098
|
function registerLayoutTools(server, client) {
|
|
923
1099
|
server.registerTool(
|
|
924
1100
|
"get_layout_stats",
|
|
@@ -928,12 +1104,12 @@ function registerLayoutTools(server, client) {
|
|
|
928
1104
|
inputSchema: { projectId: projectIdSchema },
|
|
929
1105
|
_meta: uiMeta("layout-stats"),
|
|
930
1106
|
outputSchema: {
|
|
931
|
-
layouts:
|
|
932
|
-
|
|
933
|
-
persona:
|
|
934
|
-
layoutOrder:
|
|
935
|
-
pulls:
|
|
936
|
-
avgReward:
|
|
1107
|
+
layouts: import_zod9.z.array(
|
|
1108
|
+
import_zod9.z.object({
|
|
1109
|
+
persona: import_zod9.z.string(),
|
|
1110
|
+
layoutOrder: import_zod9.z.array(import_zod9.z.string()).describe("Ranked section order for this persona"),
|
|
1111
|
+
pulls: import_zod9.z.number().describe("Number of times this arm was served"),
|
|
1112
|
+
avgReward: import_zod9.z.number().describe("Average bandit reward weight")
|
|
937
1113
|
})
|
|
938
1114
|
).describe("Per-persona layout rankings (empty until enough sessions)")
|
|
939
1115
|
},
|
|
@@ -970,7 +1146,7 @@ function registerLayoutTools(server, client) {
|
|
|
970
1146
|
}
|
|
971
1147
|
|
|
972
1148
|
// src/tools/variants.ts
|
|
973
|
-
var
|
|
1149
|
+
var import_zod10 = require("zod");
|
|
974
1150
|
function registerVariantWriteTools(server, client) {
|
|
975
1151
|
server.registerTool(
|
|
976
1152
|
"create_variant",
|
|
@@ -979,19 +1155,19 @@ function registerVariantWriteTools(server, client) {
|
|
|
979
1155
|
description: "Create a NO-CODE managed text variant for a component (content stored in SentientUI, rendered by <AdaptiveText>). Use this ONLY for text-only variants the user wants without a code change. For variants that will live in the codebase (full components \u2014 copy, markup, styling), use get_variant_brief and write the variant in code instead; those auto-register on deploy and do not need create_variant. Requires a paid plan (server keys are Starter+; anonymous demo tokens are read-only).",
|
|
980
1156
|
inputSchema: {
|
|
981
1157
|
projectId: projectIdSchema,
|
|
982
|
-
componentId:
|
|
983
|
-
displayName:
|
|
984
|
-
content:
|
|
1158
|
+
componentId: import_zod10.z.string().min(1).max(200).describe("The component ID to add a variant to"),
|
|
1159
|
+
displayName: import_zod10.z.string().min(1).max(200).describe("Human-readable name for the new variant"),
|
|
1160
|
+
content: import_zod10.z.string().max(1e4).optional().describe("The text content for this managed variant (rendered by <AdaptiveText>). Generate it from get_variant_brief context; omit only to create an empty placeholder to fill in from the dashboard.")
|
|
985
1161
|
},
|
|
986
1162
|
outputSchema: {
|
|
987
|
-
variantId:
|
|
1163
|
+
variantId: import_zod10.z.string().describe("The new variant ID"),
|
|
988
1164
|
// API returns `body.displayName ?? null`, so a successful create can
|
|
989
1165
|
// carry a null name — match that contract or outputSchema validation
|
|
990
1166
|
// would reject an otherwise-successful response.
|
|
991
|
-
displayName:
|
|
992
|
-
componentId:
|
|
993
|
-
state:
|
|
994
|
-
hasContent:
|
|
1167
|
+
displayName: import_zod10.z.string().nullable(),
|
|
1168
|
+
componentId: import_zod10.z.string(),
|
|
1169
|
+
state: import_zod10.z.literal("draft").describe("New managed variants start in draft state"),
|
|
1170
|
+
hasContent: import_zod10.z.boolean().describe("Whether text content was provided at creation")
|
|
995
1171
|
},
|
|
996
1172
|
annotations: {
|
|
997
1173
|
readOnlyHint: false,
|
|
@@ -1029,13 +1205,13 @@ function registerVariantWriteTools(server, client) {
|
|
|
1029
1205
|
description: "Pause a variant, stopping traffic from being assigned to it.",
|
|
1030
1206
|
inputSchema: {
|
|
1031
1207
|
projectId: projectIdSchema,
|
|
1032
|
-
componentId:
|
|
1033
|
-
variantId:
|
|
1208
|
+
componentId: import_zod10.z.string().describe("The component ID"),
|
|
1209
|
+
variantId: import_zod10.z.string().describe("The variant ID to pause")
|
|
1034
1210
|
},
|
|
1035
1211
|
outputSchema: {
|
|
1036
|
-
variantId:
|
|
1037
|
-
componentId:
|
|
1038
|
-
paused:
|
|
1212
|
+
variantId: import_zod10.z.string(),
|
|
1213
|
+
componentId: import_zod10.z.string(),
|
|
1214
|
+
paused: import_zod10.z.literal(true).describe("The variant is now paused")
|
|
1039
1215
|
},
|
|
1040
1216
|
annotations: {
|
|
1041
1217
|
readOnlyHint: false,
|
|
@@ -1063,8 +1239,8 @@ function registerVariantWriteTools(server, client) {
|
|
|
1063
1239
|
description: "Trigger fresh AI insight generation for a project. Returns immediately; use get_insights in ~15 seconds to see results.",
|
|
1064
1240
|
inputSchema: { projectId: projectIdSchema },
|
|
1065
1241
|
outputSchema: {
|
|
1066
|
-
projectId:
|
|
1067
|
-
status:
|
|
1242
|
+
projectId: import_zod10.z.string(),
|
|
1243
|
+
status: import_zod10.z.literal("generating").describe("Generation has been triggered")
|
|
1068
1244
|
},
|
|
1069
1245
|
annotations: {
|
|
1070
1246
|
readOnlyHint: false,
|
|
@@ -1088,7 +1264,7 @@ function registerVariantWriteTools(server, client) {
|
|
|
1088
1264
|
}
|
|
1089
1265
|
|
|
1090
1266
|
// src/tools/variant-brief.ts
|
|
1091
|
-
var
|
|
1267
|
+
var import_zod11 = require("zod");
|
|
1092
1268
|
var GOAL_TARGET = 500;
|
|
1093
1269
|
var BEST_PRACTICE_PRIORS = {
|
|
1094
1270
|
ecommerce: [
|
|
@@ -1161,15 +1337,15 @@ function registerVariantBriefTools(server, client) {
|
|
|
1161
1337
|
description: "Get an insight-driven brief for creating a new CODE-NATIVE variant of a component. Returns current variant performance, audience, insights, a data-sufficiency assessment (with a best-practice fallback when there is no data yet), and step-by-step instructions for writing the variant in the customer's code. Use this instead of create_variant when the variant will live in the codebase.",
|
|
1162
1338
|
inputSchema: {
|
|
1163
1339
|
projectId: projectIdSchema,
|
|
1164
|
-
componentId:
|
|
1340
|
+
componentId: import_zod11.z.string().describe('The component ID to write a new variant for (matches <Adaptive id="...">).')
|
|
1165
1341
|
},
|
|
1166
1342
|
outputSchema: {
|
|
1167
|
-
componentId:
|
|
1168
|
-
contextType:
|
|
1169
|
-
dataState:
|
|
1170
|
-
existingVariantIds:
|
|
1171
|
-
priors:
|
|
1172
|
-
markdown:
|
|
1343
|
+
componentId: import_zod11.z.string(),
|
|
1344
|
+
contextType: import_zod11.z.string().describe("The project's context type (or 'unknown')"),
|
|
1345
|
+
dataState: import_zod11.z.enum(["sufficient", "collecting", "empty"]).describe("Data-sufficiency assessment"),
|
|
1346
|
+
existingVariantIds: import_zod11.z.array(import_zod11.z.string()).describe("Variant IDs already in use (do not reuse)"),
|
|
1347
|
+
priors: import_zod11.z.array(import_zod11.z.string()).describe("Best-practice priors applied for this context type"),
|
|
1348
|
+
markdown: import_zod11.z.string().describe("The full variant brief in Markdown")
|
|
1173
1349
|
},
|
|
1174
1350
|
annotations: {
|
|
1175
1351
|
readOnlyHint: true,
|
|
@@ -1286,7 +1462,7 @@ function registerVariantBriefTools(server, client) {
|
|
|
1286
1462
|
}
|
|
1287
1463
|
|
|
1288
1464
|
// src/tools/test-brief.ts
|
|
1289
|
-
var
|
|
1465
|
+
var import_zod12 = require("zod");
|
|
1290
1466
|
async function settled2(p) {
|
|
1291
1467
|
try {
|
|
1292
1468
|
return await p;
|
|
@@ -1302,13 +1478,13 @@ function registerTestBriefTools(server, client) {
|
|
|
1302
1478
|
description: "Get a ready-to-paste test for a SentientUI-wrapped component, populated with the component's real variants and goals. This project uses @sentientui/react/testing. Use this so your tests force a specific variant/layout deterministically and never break when the optimizer serves a different version. Returns a React Testing Library example plus the URL-param recipe for E2E (Playwright/Cypress).",
|
|
1303
1479
|
inputSchema: {
|
|
1304
1480
|
projectId: projectIdSchema,
|
|
1305
|
-
componentId:
|
|
1481
|
+
componentId: import_zod12.z.string().describe('The component ID to write a test for (matches <Adaptive id="...">).')
|
|
1306
1482
|
},
|
|
1307
1483
|
outputSchema: {
|
|
1308
|
-
componentId:
|
|
1309
|
-
forcedVariantId:
|
|
1310
|
-
goalName:
|
|
1311
|
-
markdown:
|
|
1484
|
+
componentId: import_zod12.z.string(),
|
|
1485
|
+
forcedVariantId: import_zod12.z.string().describe("The non-control variant the example forces"),
|
|
1486
|
+
goalName: import_zod12.z.string().describe("The goal the example asserts fires"),
|
|
1487
|
+
markdown: import_zod12.z.string().describe("The full test brief in Markdown")
|
|
1312
1488
|
},
|
|
1313
1489
|
annotations: {
|
|
1314
1490
|
readOnlyHint: true,
|
|
@@ -1391,7 +1567,7 @@ function registerTestBriefTools(server, client) {
|
|
|
1391
1567
|
}
|
|
1392
1568
|
|
|
1393
1569
|
// src/tools/integration-guide.ts
|
|
1394
|
-
var
|
|
1570
|
+
var import_zod13 = require("zod");
|
|
1395
1571
|
var GUIDE = `# SentientUI integration guide \u2014 the adaptive ladder
|
|
1396
1572
|
|
|
1397
1573
|
SentientUI adapts a site per visitor type (personas: buyer, researcher, deal_seeker, browser,
|
|
@@ -1466,7 +1642,7 @@ function registerIntegrationGuideTools(server) {
|
|
|
1466
1642
|
description: "Get the SentientUI adaptive-ladder integration guide: setup (keyless and keyed) plus copy-pasteable examples for every rung (Style, Swap, Reorder). Use this to integrate SentientUI into a codebase.",
|
|
1467
1643
|
inputSchema: {},
|
|
1468
1644
|
outputSchema: {
|
|
1469
|
-
guide:
|
|
1645
|
+
guide: import_zod13.z.string().describe("The full integration guide in Markdown")
|
|
1470
1646
|
},
|
|
1471
1647
|
annotations: {
|
|
1472
1648
|
readOnlyHint: true,
|
|
@@ -1482,7 +1658,7 @@ function registerIntegrationGuideTools(server) {
|
|
|
1482
1658
|
}
|
|
1483
1659
|
|
|
1484
1660
|
// src/tools/agent-traffic.ts
|
|
1485
|
-
var
|
|
1661
|
+
var import_zod14 = require("zod");
|
|
1486
1662
|
var PLAN_GATE_GUIDANCE = {
|
|
1487
1663
|
agent_analytics_requires_paid_plan: "Agent analytics requires a paid SentientUI plan (Starter or above). Upgrade at https://sentient-ui.com, then try again."
|
|
1488
1664
|
};
|
|
@@ -1494,19 +1670,19 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1494
1670
|
description: "Which AI agents and crawlers are reading this site: totals by type (passive crawlers, agentic browsers, agent API calls), engine breakdown, and the paths they fetch most. Agent traffic is tracked separately and never counted in conversion rate.",
|
|
1495
1671
|
inputSchema: { projectId: projectIdSchema },
|
|
1496
1672
|
outputSchema: {
|
|
1497
|
-
totals:
|
|
1498
|
-
engines:
|
|
1499
|
-
|
|
1500
|
-
engine:
|
|
1501
|
-
intent:
|
|
1502
|
-
count:
|
|
1503
|
-
sharePct:
|
|
1504
|
-
lastSeen:
|
|
1505
|
-
firstSeenInRange:
|
|
1673
|
+
totals: import_zod14.z.object({ crawler: import_zod14.z.number(), api: import_zod14.z.number(), browser: import_zod14.z.number() }),
|
|
1674
|
+
engines: import_zod14.z.array(
|
|
1675
|
+
import_zod14.z.object({
|
|
1676
|
+
engine: import_zod14.z.string(),
|
|
1677
|
+
intent: import_zod14.z.string().describe("user | search | training | other"),
|
|
1678
|
+
count: import_zod14.z.number(),
|
|
1679
|
+
sharePct: import_zod14.z.number(),
|
|
1680
|
+
lastSeen: import_zod14.z.string(),
|
|
1681
|
+
firstSeenInRange: import_zod14.z.boolean().describe("First observed within the queried period")
|
|
1506
1682
|
})
|
|
1507
1683
|
),
|
|
1508
|
-
intents:
|
|
1509
|
-
topPaths:
|
|
1684
|
+
intents: import_zod14.z.object({ user: import_zod14.z.number(), search: import_zod14.z.number(), training: import_zod14.z.number(), other: import_zod14.z.number() }).describe("Crawler fetches by purpose: user = an assistant answering a real person live"),
|
|
1685
|
+
topPaths: import_zod14.z.array(import_zod14.z.object({ path: import_zod14.z.string(), count: import_zod14.z.number(), engines: import_zod14.z.number() }))
|
|
1510
1686
|
},
|
|
1511
1687
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1512
1688
|
},
|
|
@@ -1544,26 +1720,26 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1544
1720
|
description: "Whether the pages AI agents actually read are machine-legible: per-path checks for price, product name, positioning, and CTA in the server HTML, plus agent API blocks served without agent data. Each failure comes with a concrete fix.",
|
|
1545
1721
|
inputSchema: { projectId: projectIdSchema },
|
|
1546
1722
|
outputSchema: {
|
|
1547
|
-
paths:
|
|
1548
|
-
|
|
1549
|
-
path:
|
|
1550
|
-
score:
|
|
1551
|
-
checks:
|
|
1552
|
-
price:
|
|
1553
|
-
name:
|
|
1554
|
-
positioning:
|
|
1555
|
-
cta:
|
|
1556
|
-
notes:
|
|
1723
|
+
paths: import_zod14.z.array(
|
|
1724
|
+
import_zod14.z.object({
|
|
1725
|
+
path: import_zod14.z.string(),
|
|
1726
|
+
score: import_zod14.z.number().describe("0\u2013100, 25 per passing check"),
|
|
1727
|
+
checks: import_zod14.z.object({
|
|
1728
|
+
price: import_zod14.z.boolean(),
|
|
1729
|
+
name: import_zod14.z.boolean(),
|
|
1730
|
+
positioning: import_zod14.z.boolean(),
|
|
1731
|
+
cta: import_zod14.z.boolean(),
|
|
1732
|
+
notes: import_zod14.z.array(import_zod14.z.string())
|
|
1557
1733
|
}),
|
|
1558
|
-
fixes:
|
|
1559
|
-
check:
|
|
1560
|
-
advice:
|
|
1561
|
-
snippet:
|
|
1734
|
+
fixes: import_zod14.z.array(import_zod14.z.object({
|
|
1735
|
+
check: import_zod14.z.string(),
|
|
1736
|
+
advice: import_zod14.z.string(),
|
|
1737
|
+
snippet: import_zod14.z.string().optional()
|
|
1562
1738
|
})).optional().describe("Concrete Next.js remediation per failing check"),
|
|
1563
|
-
lastChecked:
|
|
1739
|
+
lastChecked: import_zod14.z.string()
|
|
1564
1740
|
})
|
|
1565
1741
|
),
|
|
1566
|
-
emptyBlocks:
|
|
1742
|
+
emptyBlocks: import_zod14.z.array(import_zod14.z.object({ block: import_zod14.z.string(), variant: import_zod14.z.string(), occurrences: import_zod14.z.number() }))
|
|
1567
1743
|
},
|
|
1568
1744
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1569
1745
|
},
|
|
@@ -1600,7 +1776,7 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1600
1776
|
}
|
|
1601
1777
|
|
|
1602
1778
|
// src/server.ts
|
|
1603
|
-
var PKG_VERSION = true ? "0.
|
|
1779
|
+
var PKG_VERSION = true ? "0.14.0" : "0.0.0-dev";
|
|
1604
1780
|
function createMcpServer(client) {
|
|
1605
1781
|
const server = new import_mcp.McpServer(
|
|
1606
1782
|
{
|
|
@@ -1627,6 +1803,7 @@ function createMcpServer(client) {
|
|
|
1627
1803
|
registerInsightTools(server, client);
|
|
1628
1804
|
registerPersonaTools(server, client);
|
|
1629
1805
|
registerGoalTools(server, client);
|
|
1806
|
+
registerFunnelTools(server, client);
|
|
1630
1807
|
registerGuardrailTools(server, client);
|
|
1631
1808
|
registerLayoutTools(server, client);
|
|
1632
1809
|
registerVariantBriefTools(server, client);
|