@sentientui/mcp 0.12.0 → 0.13.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/lib.cjs CHANGED
@@ -759,7 +759,7 @@ function registerGoalTools(server, client) {
759
759
  "get_goal_funnel",
760
760
  {
761
761
  title: "Goal funnel",
762
- description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown.",
762
+ 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.",
763
763
  inputSchema: { projectId: projectIdSchema },
764
764
  _meta: uiMeta("goal-funnel"),
765
765
  outputSchema: {
@@ -894,8 +894,137 @@ function registerGoalTools(server, client) {
894
894
  );
895
895
  }
896
896
 
897
- // src/tools/guardrails.ts
897
+ // src/tools/funnels.ts
898
898
  var import_zod7 = require("zod");
899
+ var funnelIdSchema = import_zod7.z.string().describe('Funnel slug (from list_funnels), e.g. "checkout"');
900
+ function registerFunnelTools(server, client) {
901
+ server.registerTool(
902
+ "list_funnels",
903
+ {
904
+ title: "List funnels",
905
+ 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>">.`,
906
+ inputSchema: { projectId: projectIdSchema },
907
+ outputSchema: {
908
+ funnels: import_zod7.z.array(
909
+ import_zod7.z.object({
910
+ funnelId: import_zod7.z.string().describe("Stable slug \u2014 use this exact string in code and in get_funnel_report"),
911
+ displayName: import_zod7.z.string(),
912
+ status: import_zod7.z.string().describe("draft | active | archived"),
913
+ windowDays: import_zod7.z.number().describe("Conversion window in days"),
914
+ source: import_zod7.z.string().describe("user | chat | editor | sdk"),
915
+ steps: import_zod7.z.array(
916
+ import_zod7.z.object({
917
+ stepIndex: import_zod7.z.number(),
918
+ goalId: import_zod7.z.string(),
919
+ weight: import_zod7.z.number().nullable().describe("Manual optimizer credit for reaching this step (null = automatic end-weighted)")
920
+ })
921
+ ).describe("Ordered steps"),
922
+ 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)")
923
+ })
924
+ ).describe("Defined funnels (empty if none)")
925
+ },
926
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
927
+ },
928
+ withApiErrorGuidance(async ({ projectId }) => {
929
+ var _a;
930
+ const id = encodeURIComponent(projectId);
931
+ const data = await client.get(`/projects/${id}/funnels`);
932
+ const structuredContent = {
933
+ funnels: ((_a = data.funnels) != null ? _a : []).map((f) => ({
934
+ funnelId: f.funnel_id,
935
+ displayName: f.display_name,
936
+ status: f.status,
937
+ windowDays: f.window_days,
938
+ source: f.source,
939
+ // NUMERIC arrives serialized as a string; coerce.
940
+ steps: f.steps.map((s) => ({
941
+ stepIndex: s.step_index,
942
+ goalId: s.goal_id,
943
+ weight: s.weight == null ? null : Number(s.weight)
944
+ })),
945
+ components: f.components.map((c) => {
946
+ var _a2;
947
+ return { componentId: c.component_id, stepIndex: (_a2 = c.step_index) != null ? _a2 : null };
948
+ })
949
+ }))
950
+ };
951
+ if (structuredContent.funnels.length === 0) {
952
+ return {
953
+ content: [{
954
+ type: "text",
955
+ 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."
956
+ }],
957
+ structuredContent
958
+ };
959
+ }
960
+ const lines = structuredContent.funnels.map(
961
+ (f) => `${f.funnelId} (${f.status}) \u2014 ${f.displayName}: ${f.steps.map((s) => s.goalId).join(" \u2192 ")}`
962
+ );
963
+ lines.push("", 'Reference a funnelId verbatim from code: <Adaptive funnel="<funnelId>">. Use get_funnel_report for drop-off numbers.');
964
+ return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
965
+ })
966
+ );
967
+ server.registerTool(
968
+ "get_funnel_report",
969
+ {
970
+ title: "Funnel drop-off report",
971
+ 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.',
972
+ inputSchema: { projectId: projectIdSchema, funnelId: funnelIdSchema },
973
+ outputSchema: {
974
+ funnelId: import_zod7.z.string(),
975
+ displayName: import_zod7.z.string(),
976
+ windowDays: import_zod7.z.number(),
977
+ currency: import_zod7.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
978
+ steps: import_zod7.z.array(
979
+ import_zod7.z.object({
980
+ stepIndex: import_zod7.z.number(),
981
+ goalId: import_zod7.z.string(),
982
+ displayName: import_zod7.z.string(),
983
+ reached: import_zod7.z.number().describe("Distinct visitors reaching this step in-window"),
984
+ dropOffFromPrevious: import_zod7.z.number().nullable().describe("1 - reached/previousReached (null on the first step)"),
985
+ neverFired: import_zod7.z.boolean().describe("True when the step goal has never been recorded anywhere \u2014 likely a typo"),
986
+ variants: import_zod7.z.array(import_zod7.z.object({
987
+ componentId: import_zod7.z.string(),
988
+ variantId: import_zod7.z.string(),
989
+ reached: import_zod7.z.number(),
990
+ assigned: import_zod7.z.number().describe("Distinct sessions served this variant in-window (the rate denominator)")
991
+ })),
992
+ personas: import_zod7.z.array(import_zod7.z.object({ label: import_zod7.z.string(), reached: import_zod7.z.number() }))
993
+ })
994
+ ),
995
+ revenue: import_zod7.z.number().nullable().describe("Final-step revenue in the project currency (null when no valued conversions)"),
996
+ avgOrderValue: import_zod7.z.number().nullable(),
997
+ revenuePerEnteringVisitor: import_zod7.z.number().nullable(),
998
+ 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')
999
+ },
1000
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1001
+ },
1002
+ withApiErrorGuidance(async ({ projectId, funnelId }) => {
1003
+ const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
1004
+ const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
1005
+ for (const s of data.steps) {
1006
+ lines.push(
1007
+ `${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]" : "")
1008
+ );
1009
+ for (const v of s.variants) {
1010
+ lines.push(` ${v.componentId}/${v.variantId}: ${v.reached}/${v.assigned} assigned sessions reached this step`);
1011
+ }
1012
+ }
1013
+ if (data.revenue != null) {
1014
+ lines.push(
1015
+ `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` : "")
1016
+ );
1017
+ }
1018
+ if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
1019
+ lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
1020
+ }
1021
+ return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data };
1022
+ })
1023
+ );
1024
+ }
1025
+
1026
+ // src/tools/guardrails.ts
1027
+ var import_zod8 = require("zod");
899
1028
  function registerGuardrailTools(server, client) {
900
1029
  server.registerTool(
901
1030
  "list_guardrail_events",
@@ -904,11 +1033,11 @@ function registerGuardrailTools(server, client) {
904
1033
  description: "List variants currently paused by the guardrail in the last 24 hours.",
905
1034
  inputSchema: { projectId: projectIdSchema },
906
1035
  outputSchema: {
907
- events: import_zod7.z.array(
908
- import_zod7.z.object({
909
- componentId: import_zod7.z.string(),
910
- variantIds: import_zod7.z.array(import_zod7.z.string()).describe("Variants paused by the guardrail"),
911
- pausedAt: import_zod7.z.string().nullable().describe("ISO timestamp the pause fired, or null")
1036
+ events: import_zod8.z.array(
1037
+ import_zod8.z.object({
1038
+ componentId: import_zod8.z.string(),
1039
+ 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")
912
1041
  })
913
1042
  ).describe("Guardrail events in the last 24h (empty if none)")
914
1043
  },
@@ -943,7 +1072,7 @@ function registerGuardrailTools(server, client) {
943
1072
  }
944
1073
 
945
1074
  // src/tools/layout.ts
946
- var import_zod8 = require("zod");
1075
+ var import_zod9 = require("zod");
947
1076
  function registerLayoutTools(server, client) {
948
1077
  server.registerTool(
949
1078
  "get_layout_stats",
@@ -953,12 +1082,12 @@ function registerLayoutTools(server, client) {
953
1082
  inputSchema: { projectId: projectIdSchema },
954
1083
  _meta: uiMeta("layout-stats"),
955
1084
  outputSchema: {
956
- layouts: import_zod8.z.array(
957
- import_zod8.z.object({
958
- persona: import_zod8.z.string(),
959
- layoutOrder: import_zod8.z.array(import_zod8.z.string()).describe("Ranked section order for this persona"),
960
- pulls: import_zod8.z.number().describe("Number of times this arm was served"),
961
- avgReward: import_zod8.z.number().describe("Average bandit reward weight")
1085
+ layouts: import_zod9.z.array(
1086
+ import_zod9.z.object({
1087
+ persona: import_zod9.z.string(),
1088
+ layoutOrder: import_zod9.z.array(import_zod9.z.string()).describe("Ranked section order for this persona"),
1089
+ pulls: import_zod9.z.number().describe("Number of times this arm was served"),
1090
+ avgReward: import_zod9.z.number().describe("Average bandit reward weight")
962
1091
  })
963
1092
  ).describe("Per-persona layout rankings (empty until enough sessions)")
964
1093
  },
@@ -995,7 +1124,7 @@ function registerLayoutTools(server, client) {
995
1124
  }
996
1125
 
997
1126
  // src/tools/variants.ts
998
- var import_zod9 = require("zod");
1127
+ var import_zod10 = require("zod");
999
1128
  function registerVariantWriteTools(server, client) {
1000
1129
  server.registerTool(
1001
1130
  "create_variant",
@@ -1004,19 +1133,19 @@ function registerVariantWriteTools(server, client) {
1004
1133
  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).",
1005
1134
  inputSchema: {
1006
1135
  projectId: projectIdSchema,
1007
- componentId: import_zod9.z.string().min(1).max(200).describe("The component ID to add a variant to"),
1008
- displayName: import_zod9.z.string().min(1).max(200).describe("Human-readable name for the new variant"),
1009
- content: import_zod9.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.")
1136
+ componentId: import_zod10.z.string().min(1).max(200).describe("The component ID to add a variant to"),
1137
+ displayName: import_zod10.z.string().min(1).max(200).describe("Human-readable name for the new variant"),
1138
+ 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.")
1010
1139
  },
1011
1140
  outputSchema: {
1012
- variantId: import_zod9.z.string().describe("The new variant ID"),
1141
+ variantId: import_zod10.z.string().describe("The new variant ID"),
1013
1142
  // API returns `body.displayName ?? null`, so a successful create can
1014
1143
  // carry a null name — match that contract or outputSchema validation
1015
1144
  // would reject an otherwise-successful response.
1016
- displayName: import_zod9.z.string().nullable(),
1017
- componentId: import_zod9.z.string(),
1018
- state: import_zod9.z.literal("draft").describe("New managed variants start in draft state"),
1019
- hasContent: import_zod9.z.boolean().describe("Whether text content was provided at creation")
1145
+ displayName: import_zod10.z.string().nullable(),
1146
+ componentId: import_zod10.z.string(),
1147
+ state: import_zod10.z.literal("draft").describe("New managed variants start in draft state"),
1148
+ hasContent: import_zod10.z.boolean().describe("Whether text content was provided at creation")
1020
1149
  },
1021
1150
  annotations: {
1022
1151
  readOnlyHint: false,
@@ -1054,13 +1183,13 @@ function registerVariantWriteTools(server, client) {
1054
1183
  description: "Pause a variant, stopping traffic from being assigned to it.",
1055
1184
  inputSchema: {
1056
1185
  projectId: projectIdSchema,
1057
- componentId: import_zod9.z.string().describe("The component ID"),
1058
- variantId: import_zod9.z.string().describe("The variant ID to pause")
1186
+ componentId: import_zod10.z.string().describe("The component ID"),
1187
+ variantId: import_zod10.z.string().describe("The variant ID to pause")
1059
1188
  },
1060
1189
  outputSchema: {
1061
- variantId: import_zod9.z.string(),
1062
- componentId: import_zod9.z.string(),
1063
- paused: import_zod9.z.literal(true).describe("The variant is now paused")
1190
+ variantId: import_zod10.z.string(),
1191
+ componentId: import_zod10.z.string(),
1192
+ paused: import_zod10.z.literal(true).describe("The variant is now paused")
1064
1193
  },
1065
1194
  annotations: {
1066
1195
  readOnlyHint: false,
@@ -1088,8 +1217,8 @@ function registerVariantWriteTools(server, client) {
1088
1217
  description: "Trigger fresh AI insight generation for a project. Returns immediately; use get_insights in ~15 seconds to see results.",
1089
1218
  inputSchema: { projectId: projectIdSchema },
1090
1219
  outputSchema: {
1091
- projectId: import_zod9.z.string(),
1092
- status: import_zod9.z.literal("generating").describe("Generation has been triggered")
1220
+ projectId: import_zod10.z.string(),
1221
+ status: import_zod10.z.literal("generating").describe("Generation has been triggered")
1093
1222
  },
1094
1223
  annotations: {
1095
1224
  readOnlyHint: false,
@@ -1113,7 +1242,7 @@ function registerVariantWriteTools(server, client) {
1113
1242
  }
1114
1243
 
1115
1244
  // src/tools/variant-brief.ts
1116
- var import_zod10 = require("zod");
1245
+ var import_zod11 = require("zod");
1117
1246
  var GOAL_TARGET = 500;
1118
1247
  var BEST_PRACTICE_PRIORS = {
1119
1248
  ecommerce: [
@@ -1186,15 +1315,15 @@ function registerVariantBriefTools(server, client) {
1186
1315
  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.",
1187
1316
  inputSchema: {
1188
1317
  projectId: projectIdSchema,
1189
- componentId: import_zod10.z.string().describe('The component ID to write a new variant for (matches <Adaptive id="...">).')
1318
+ componentId: import_zod11.z.string().describe('The component ID to write a new variant for (matches <Adaptive id="...">).')
1190
1319
  },
1191
1320
  outputSchema: {
1192
- componentId: import_zod10.z.string(),
1193
- contextType: import_zod10.z.string().describe("The project's context type (or 'unknown')"),
1194
- dataState: import_zod10.z.enum(["sufficient", "collecting", "empty"]).describe("Data-sufficiency assessment"),
1195
- existingVariantIds: import_zod10.z.array(import_zod10.z.string()).describe("Variant IDs already in use (do not reuse)"),
1196
- priors: import_zod10.z.array(import_zod10.z.string()).describe("Best-practice priors applied for this context type"),
1197
- markdown: import_zod10.z.string().describe("The full variant brief in Markdown")
1321
+ componentId: import_zod11.z.string(),
1322
+ contextType: import_zod11.z.string().describe("The project's context type (or 'unknown')"),
1323
+ dataState: import_zod11.z.enum(["sufficient", "collecting", "empty"]).describe("Data-sufficiency assessment"),
1324
+ existingVariantIds: import_zod11.z.array(import_zod11.z.string()).describe("Variant IDs already in use (do not reuse)"),
1325
+ priors: import_zod11.z.array(import_zod11.z.string()).describe("Best-practice priors applied for this context type"),
1326
+ markdown: import_zod11.z.string().describe("The full variant brief in Markdown")
1198
1327
  },
1199
1328
  annotations: {
1200
1329
  readOnlyHint: true,
@@ -1311,7 +1440,7 @@ function registerVariantBriefTools(server, client) {
1311
1440
  }
1312
1441
 
1313
1442
  // src/tools/test-brief.ts
1314
- var import_zod11 = require("zod");
1443
+ var import_zod12 = require("zod");
1315
1444
  async function settled2(p) {
1316
1445
  try {
1317
1446
  return await p;
@@ -1327,13 +1456,13 @@ function registerTestBriefTools(server, client) {
1327
1456
  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).",
1328
1457
  inputSchema: {
1329
1458
  projectId: projectIdSchema,
1330
- componentId: import_zod11.z.string().describe('The component ID to write a test for (matches <Adaptive id="...">).')
1459
+ componentId: import_zod12.z.string().describe('The component ID to write a test for (matches <Adaptive id="...">).')
1331
1460
  },
1332
1461
  outputSchema: {
1333
- componentId: import_zod11.z.string(),
1334
- forcedVariantId: import_zod11.z.string().describe("The non-control variant the example forces"),
1335
- goalName: import_zod11.z.string().describe("The goal the example asserts fires"),
1336
- markdown: import_zod11.z.string().describe("The full test brief in Markdown")
1462
+ componentId: import_zod12.z.string(),
1463
+ forcedVariantId: import_zod12.z.string().describe("The non-control variant the example forces"),
1464
+ goalName: import_zod12.z.string().describe("The goal the example asserts fires"),
1465
+ markdown: import_zod12.z.string().describe("The full test brief in Markdown")
1337
1466
  },
1338
1467
  annotations: {
1339
1468
  readOnlyHint: true,
@@ -1416,7 +1545,7 @@ function registerTestBriefTools(server, client) {
1416
1545
  }
1417
1546
 
1418
1547
  // src/tools/integration-guide.ts
1419
- var import_zod12 = require("zod");
1548
+ var import_zod13 = require("zod");
1420
1549
  var GUIDE = `# SentientUI integration guide \u2014 the adaptive ladder
1421
1550
 
1422
1551
  SentientUI adapts a site per visitor type (personas: buyer, researcher, deal_seeker, browser,
@@ -1491,7 +1620,7 @@ function registerIntegrationGuideTools(server) {
1491
1620
  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.",
1492
1621
  inputSchema: {},
1493
1622
  outputSchema: {
1494
- guide: import_zod12.z.string().describe("The full integration guide in Markdown")
1623
+ guide: import_zod13.z.string().describe("The full integration guide in Markdown")
1495
1624
  },
1496
1625
  annotations: {
1497
1626
  readOnlyHint: true,
@@ -1507,7 +1636,7 @@ function registerIntegrationGuideTools(server) {
1507
1636
  }
1508
1637
 
1509
1638
  // src/tools/agent-traffic.ts
1510
- var import_zod13 = require("zod");
1639
+ var import_zod14 = require("zod");
1511
1640
  var PLAN_GATE_GUIDANCE = {
1512
1641
  agent_analytics_requires_paid_plan: "Agent analytics requires a paid SentientUI plan (Starter or above). Upgrade at https://sentient-ui.com, then try again."
1513
1642
  };
@@ -1519,19 +1648,19 @@ function registerAgentTrafficTools(server, client) {
1519
1648
  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.",
1520
1649
  inputSchema: { projectId: projectIdSchema },
1521
1650
  outputSchema: {
1522
- totals: import_zod13.z.object({ crawler: import_zod13.z.number(), api: import_zod13.z.number(), browser: import_zod13.z.number() }),
1523
- engines: import_zod13.z.array(
1524
- import_zod13.z.object({
1525
- engine: import_zod13.z.string(),
1526
- intent: import_zod13.z.string().describe("user | search | training | other"),
1527
- count: import_zod13.z.number(),
1528
- sharePct: import_zod13.z.number(),
1529
- lastSeen: import_zod13.z.string(),
1530
- firstSeenInRange: import_zod13.z.boolean().describe("First observed within the queried period")
1651
+ totals: import_zod14.z.object({ crawler: import_zod14.z.number(), api: import_zod14.z.number(), browser: import_zod14.z.number() }),
1652
+ engines: import_zod14.z.array(
1653
+ import_zod14.z.object({
1654
+ engine: import_zod14.z.string(),
1655
+ intent: import_zod14.z.string().describe("user | search | training | other"),
1656
+ count: import_zod14.z.number(),
1657
+ sharePct: import_zod14.z.number(),
1658
+ lastSeen: import_zod14.z.string(),
1659
+ firstSeenInRange: import_zod14.z.boolean().describe("First observed within the queried period")
1531
1660
  })
1532
1661
  ),
1533
- intents: import_zod13.z.object({ user: import_zod13.z.number(), search: import_zod13.z.number(), training: import_zod13.z.number(), other: import_zod13.z.number() }).describe("Crawler fetches by purpose: user = an assistant answering a real person live"),
1534
- topPaths: import_zod13.z.array(import_zod13.z.object({ path: import_zod13.z.string(), count: import_zod13.z.number(), engines: import_zod13.z.number() }))
1662
+ 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"),
1663
+ topPaths: import_zod14.z.array(import_zod14.z.object({ path: import_zod14.z.string(), count: import_zod14.z.number(), engines: import_zod14.z.number() }))
1535
1664
  },
1536
1665
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1537
1666
  },
@@ -1569,26 +1698,26 @@ function registerAgentTrafficTools(server, client) {
1569
1698
  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.",
1570
1699
  inputSchema: { projectId: projectIdSchema },
1571
1700
  outputSchema: {
1572
- paths: import_zod13.z.array(
1573
- import_zod13.z.object({
1574
- path: import_zod13.z.string(),
1575
- score: import_zod13.z.number().describe("0\u2013100, 25 per passing check"),
1576
- checks: import_zod13.z.object({
1577
- price: import_zod13.z.boolean(),
1578
- name: import_zod13.z.boolean(),
1579
- positioning: import_zod13.z.boolean(),
1580
- cta: import_zod13.z.boolean(),
1581
- notes: import_zod13.z.array(import_zod13.z.string())
1701
+ paths: import_zod14.z.array(
1702
+ import_zod14.z.object({
1703
+ path: import_zod14.z.string(),
1704
+ score: import_zod14.z.number().describe("0\u2013100, 25 per passing check"),
1705
+ checks: import_zod14.z.object({
1706
+ price: import_zod14.z.boolean(),
1707
+ name: import_zod14.z.boolean(),
1708
+ positioning: import_zod14.z.boolean(),
1709
+ cta: import_zod14.z.boolean(),
1710
+ notes: import_zod14.z.array(import_zod14.z.string())
1582
1711
  }),
1583
- fixes: import_zod13.z.array(import_zod13.z.object({
1584
- check: import_zod13.z.string(),
1585
- advice: import_zod13.z.string(),
1586
- snippet: import_zod13.z.string().optional()
1712
+ fixes: import_zod14.z.array(import_zod14.z.object({
1713
+ check: import_zod14.z.string(),
1714
+ advice: import_zod14.z.string(),
1715
+ snippet: import_zod14.z.string().optional()
1587
1716
  })).optional().describe("Concrete Next.js remediation per failing check"),
1588
- lastChecked: import_zod13.z.string()
1717
+ lastChecked: import_zod14.z.string()
1589
1718
  })
1590
1719
  ),
1591
- emptyBlocks: import_zod13.z.array(import_zod13.z.object({ block: import_zod13.z.string(), variant: import_zod13.z.string(), occurrences: import_zod13.z.number() }))
1720
+ emptyBlocks: import_zod14.z.array(import_zod14.z.object({ block: import_zod14.z.string(), variant: import_zod14.z.string(), occurrences: import_zod14.z.number() }))
1592
1721
  },
1593
1722
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1594
1723
  },
@@ -1625,7 +1754,7 @@ function registerAgentTrafficTools(server, client) {
1625
1754
  }
1626
1755
 
1627
1756
  // src/server.ts
1628
- var PKG_VERSION = true ? "0.12.0" : "0.0.0-dev";
1757
+ var PKG_VERSION = true ? "0.13.0" : "0.0.0-dev";
1629
1758
  function createMcpServer(client) {
1630
1759
  const server = new import_mcp.McpServer(
1631
1760
  {
@@ -1652,6 +1781,7 @@ function createMcpServer(client) {
1652
1781
  registerInsightTools(server, client);
1653
1782
  registerPersonaTools(server, client);
1654
1783
  registerGoalTools(server, client);
1784
+ registerFunnelTools(server, client);
1655
1785
  registerGuardrailTools(server, client);
1656
1786
  registerLayoutTools(server, client);
1657
1787
  registerVariantBriefTools(server, client);
package/dist/lib.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  ApiClient,
4
4
  ApiError,
5
5
  createMcpServer
6
- } from "./chunk-BMOKDBGH.js";
6
+ } from "./chunk-ZJ2JZ5RR.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.12.0",
3
+ "version": "0.13.0",
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",