@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/index.cjs CHANGED
@@ -734,7 +734,7 @@ function registerGoalTools(server, client) {
734
734
  "get_goal_funnel",
735
735
  {
736
736
  title: "Goal funnel",
737
- description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown.",
737
+ 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
738
  inputSchema: { projectId: projectIdSchema },
739
739
  _meta: uiMeta("goal-funnel"),
740
740
  outputSchema: {
@@ -869,8 +869,137 @@ function registerGoalTools(server, client) {
869
869
  );
870
870
  }
871
871
 
872
- // src/tools/guardrails.ts
872
+ // src/tools/funnels.ts
873
873
  var import_zod7 = require("zod");
874
+ var funnelIdSchema = import_zod7.z.string().describe('Funnel slug (from list_funnels), e.g. "checkout"');
875
+ function registerFunnelTools(server, client) {
876
+ server.registerTool(
877
+ "list_funnels",
878
+ {
879
+ title: "List funnels",
880
+ 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>">.`,
881
+ inputSchema: { projectId: projectIdSchema },
882
+ outputSchema: {
883
+ funnels: import_zod7.z.array(
884
+ import_zod7.z.object({
885
+ funnelId: import_zod7.z.string().describe("Stable slug \u2014 use this exact string in code and in get_funnel_report"),
886
+ displayName: import_zod7.z.string(),
887
+ status: import_zod7.z.string().describe("draft | active | archived"),
888
+ windowDays: import_zod7.z.number().describe("Conversion window in days"),
889
+ source: import_zod7.z.string().describe("user | chat | editor | sdk"),
890
+ steps: import_zod7.z.array(
891
+ import_zod7.z.object({
892
+ stepIndex: import_zod7.z.number(),
893
+ goalId: import_zod7.z.string(),
894
+ weight: import_zod7.z.number().nullable().describe("Manual optimizer credit for reaching this step (null = automatic end-weighted)")
895
+ })
896
+ ).describe("Ordered steps"),
897
+ 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)")
898
+ })
899
+ ).describe("Defined funnels (empty if none)")
900
+ },
901
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
902
+ },
903
+ withApiErrorGuidance(async ({ projectId }) => {
904
+ var _a2;
905
+ const id = encodeURIComponent(projectId);
906
+ const data = await client.get(`/projects/${id}/funnels`);
907
+ const structuredContent = {
908
+ funnels: ((_a2 = data.funnels) != null ? _a2 : []).map((f) => ({
909
+ funnelId: f.funnel_id,
910
+ displayName: f.display_name,
911
+ status: f.status,
912
+ windowDays: f.window_days,
913
+ source: f.source,
914
+ // NUMERIC arrives serialized as a string; coerce.
915
+ steps: f.steps.map((s) => ({
916
+ stepIndex: s.step_index,
917
+ goalId: s.goal_id,
918
+ weight: s.weight == null ? null : Number(s.weight)
919
+ })),
920
+ components: f.components.map((c) => {
921
+ var _a3;
922
+ return { componentId: c.component_id, stepIndex: (_a3 = c.step_index) != null ? _a3 : null };
923
+ })
924
+ }))
925
+ };
926
+ if (structuredContent.funnels.length === 0) {
927
+ return {
928
+ content: [{
929
+ type: "text",
930
+ 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."
931
+ }],
932
+ structuredContent
933
+ };
934
+ }
935
+ const lines = structuredContent.funnels.map(
936
+ (f) => `${f.funnelId} (${f.status}) \u2014 ${f.displayName}: ${f.steps.map((s) => s.goalId).join(" \u2192 ")}`
937
+ );
938
+ lines.push("", 'Reference a funnelId verbatim from code: <Adaptive funnel="<funnelId>">. Use get_funnel_report for drop-off numbers.');
939
+ return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
940
+ })
941
+ );
942
+ server.registerTool(
943
+ "get_funnel_report",
944
+ {
945
+ title: "Funnel drop-off report",
946
+ 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.',
947
+ inputSchema: { projectId: projectIdSchema, funnelId: funnelIdSchema },
948
+ outputSchema: {
949
+ funnelId: import_zod7.z.string(),
950
+ displayName: import_zod7.z.string(),
951
+ windowDays: import_zod7.z.number(),
952
+ currency: import_zod7.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
953
+ steps: import_zod7.z.array(
954
+ import_zod7.z.object({
955
+ stepIndex: import_zod7.z.number(),
956
+ goalId: import_zod7.z.string(),
957
+ displayName: import_zod7.z.string(),
958
+ reached: import_zod7.z.number().describe("Distinct visitors reaching this step in-window"),
959
+ dropOffFromPrevious: import_zod7.z.number().nullable().describe("1 - reached/previousReached (null on the first step)"),
960
+ neverFired: import_zod7.z.boolean().describe("True when the step goal has never been recorded anywhere \u2014 likely a typo"),
961
+ variants: import_zod7.z.array(import_zod7.z.object({
962
+ componentId: import_zod7.z.string(),
963
+ variantId: import_zod7.z.string(),
964
+ reached: import_zod7.z.number(),
965
+ assigned: import_zod7.z.number().describe("Distinct sessions served this variant in-window (the rate denominator)")
966
+ })),
967
+ personas: import_zod7.z.array(import_zod7.z.object({ label: import_zod7.z.string(), reached: import_zod7.z.number() }))
968
+ })
969
+ ),
970
+ revenue: import_zod7.z.number().nullable().describe("Final-step revenue in the project currency (null when no valued conversions)"),
971
+ avgOrderValue: import_zod7.z.number().nullable(),
972
+ revenuePerEnteringVisitor: import_zod7.z.number().nullable(),
973
+ 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')
974
+ },
975
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
976
+ },
977
+ withApiErrorGuidance(async ({ projectId, funnelId }) => {
978
+ const data = await client.get(`/projects/${encodeURIComponent(projectId)}/funnels/${encodeURIComponent(funnelId)}/report`);
979
+ const lines = [`${data.displayName} \u2014 last ${data.windowDays} days`];
980
+ for (const s of data.steps) {
981
+ lines.push(
982
+ `${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]" : "")
983
+ );
984
+ for (const v of s.variants) {
985
+ lines.push(` ${v.componentId}/${v.variantId}: ${v.reached}/${v.assigned} assigned sessions reached this step`);
986
+ }
987
+ }
988
+ if (data.revenue != null) {
989
+ lines.push(
990
+ `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` : "")
991
+ );
992
+ }
993
+ if (data.holdoutCompletion && data.holdoutCompletion.entered > 0) {
994
+ lines.push(`Without optimization: ${data.holdoutCompletion.reached} of ${data.holdoutCompletion.entered} holdout visitors finished.`);
995
+ }
996
+ return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data };
997
+ })
998
+ );
999
+ }
1000
+
1001
+ // src/tools/guardrails.ts
1002
+ var import_zod8 = require("zod");
874
1003
  function registerGuardrailTools(server, client) {
875
1004
  server.registerTool(
876
1005
  "list_guardrail_events",
@@ -879,11 +1008,11 @@ function registerGuardrailTools(server, client) {
879
1008
  description: "List variants currently paused by the guardrail in the last 24 hours.",
880
1009
  inputSchema: { projectId: projectIdSchema },
881
1010
  outputSchema: {
882
- events: import_zod7.z.array(
883
- import_zod7.z.object({
884
- componentId: import_zod7.z.string(),
885
- variantIds: import_zod7.z.array(import_zod7.z.string()).describe("Variants paused by the guardrail"),
886
- pausedAt: import_zod7.z.string().nullable().describe("ISO timestamp the pause fired, or null")
1011
+ events: import_zod8.z.array(
1012
+ import_zod8.z.object({
1013
+ componentId: import_zod8.z.string(),
1014
+ 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")
887
1016
  })
888
1017
  ).describe("Guardrail events in the last 24h (empty if none)")
889
1018
  },
@@ -918,7 +1047,7 @@ function registerGuardrailTools(server, client) {
918
1047
  }
919
1048
 
920
1049
  // src/tools/layout.ts
921
- var import_zod8 = require("zod");
1050
+ var import_zod9 = require("zod");
922
1051
  function registerLayoutTools(server, client) {
923
1052
  server.registerTool(
924
1053
  "get_layout_stats",
@@ -928,12 +1057,12 @@ function registerLayoutTools(server, client) {
928
1057
  inputSchema: { projectId: projectIdSchema },
929
1058
  _meta: uiMeta("layout-stats"),
930
1059
  outputSchema: {
931
- layouts: import_zod8.z.array(
932
- import_zod8.z.object({
933
- persona: import_zod8.z.string(),
934
- layoutOrder: import_zod8.z.array(import_zod8.z.string()).describe("Ranked section order for this persona"),
935
- pulls: import_zod8.z.number().describe("Number of times this arm was served"),
936
- avgReward: import_zod8.z.number().describe("Average bandit reward weight")
1060
+ layouts: import_zod9.z.array(
1061
+ import_zod9.z.object({
1062
+ persona: import_zod9.z.string(),
1063
+ layoutOrder: import_zod9.z.array(import_zod9.z.string()).describe("Ranked section order for this persona"),
1064
+ pulls: import_zod9.z.number().describe("Number of times this arm was served"),
1065
+ avgReward: import_zod9.z.number().describe("Average bandit reward weight")
937
1066
  })
938
1067
  ).describe("Per-persona layout rankings (empty until enough sessions)")
939
1068
  },
@@ -970,7 +1099,7 @@ function registerLayoutTools(server, client) {
970
1099
  }
971
1100
 
972
1101
  // src/tools/variants.ts
973
- var import_zod9 = require("zod");
1102
+ var import_zod10 = require("zod");
974
1103
  function registerVariantWriteTools(server, client) {
975
1104
  server.registerTool(
976
1105
  "create_variant",
@@ -979,19 +1108,19 @@ function registerVariantWriteTools(server, client) {
979
1108
  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
1109
  inputSchema: {
981
1110
  projectId: projectIdSchema,
982
- componentId: import_zod9.z.string().min(1).max(200).describe("The component ID to add a variant to"),
983
- displayName: import_zod9.z.string().min(1).max(200).describe("Human-readable name for the new variant"),
984
- 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.")
1111
+ componentId: import_zod10.z.string().min(1).max(200).describe("The component ID to add a variant to"),
1112
+ displayName: import_zod10.z.string().min(1).max(200).describe("Human-readable name for the new variant"),
1113
+ 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
1114
  },
986
1115
  outputSchema: {
987
- variantId: import_zod9.z.string().describe("The new variant ID"),
1116
+ variantId: import_zod10.z.string().describe("The new variant ID"),
988
1117
  // API returns `body.displayName ?? null`, so a successful create can
989
1118
  // carry a null name — match that contract or outputSchema validation
990
1119
  // would reject an otherwise-successful response.
991
- displayName: import_zod9.z.string().nullable(),
992
- componentId: import_zod9.z.string(),
993
- state: import_zod9.z.literal("draft").describe("New managed variants start in draft state"),
994
- hasContent: import_zod9.z.boolean().describe("Whether text content was provided at creation")
1120
+ displayName: import_zod10.z.string().nullable(),
1121
+ componentId: import_zod10.z.string(),
1122
+ state: import_zod10.z.literal("draft").describe("New managed variants start in draft state"),
1123
+ hasContent: import_zod10.z.boolean().describe("Whether text content was provided at creation")
995
1124
  },
996
1125
  annotations: {
997
1126
  readOnlyHint: false,
@@ -1029,13 +1158,13 @@ function registerVariantWriteTools(server, client) {
1029
1158
  description: "Pause a variant, stopping traffic from being assigned to it.",
1030
1159
  inputSchema: {
1031
1160
  projectId: projectIdSchema,
1032
- componentId: import_zod9.z.string().describe("The component ID"),
1033
- variantId: import_zod9.z.string().describe("The variant ID to pause")
1161
+ componentId: import_zod10.z.string().describe("The component ID"),
1162
+ variantId: import_zod10.z.string().describe("The variant ID to pause")
1034
1163
  },
1035
1164
  outputSchema: {
1036
- variantId: import_zod9.z.string(),
1037
- componentId: import_zod9.z.string(),
1038
- paused: import_zod9.z.literal(true).describe("The variant is now paused")
1165
+ variantId: import_zod10.z.string(),
1166
+ componentId: import_zod10.z.string(),
1167
+ paused: import_zod10.z.literal(true).describe("The variant is now paused")
1039
1168
  },
1040
1169
  annotations: {
1041
1170
  readOnlyHint: false,
@@ -1063,8 +1192,8 @@ function registerVariantWriteTools(server, client) {
1063
1192
  description: "Trigger fresh AI insight generation for a project. Returns immediately; use get_insights in ~15 seconds to see results.",
1064
1193
  inputSchema: { projectId: projectIdSchema },
1065
1194
  outputSchema: {
1066
- projectId: import_zod9.z.string(),
1067
- status: import_zod9.z.literal("generating").describe("Generation has been triggered")
1195
+ projectId: import_zod10.z.string(),
1196
+ status: import_zod10.z.literal("generating").describe("Generation has been triggered")
1068
1197
  },
1069
1198
  annotations: {
1070
1199
  readOnlyHint: false,
@@ -1088,7 +1217,7 @@ function registerVariantWriteTools(server, client) {
1088
1217
  }
1089
1218
 
1090
1219
  // src/tools/variant-brief.ts
1091
- var import_zod10 = require("zod");
1220
+ var import_zod11 = require("zod");
1092
1221
  var GOAL_TARGET = 500;
1093
1222
  var BEST_PRACTICE_PRIORS = {
1094
1223
  ecommerce: [
@@ -1161,15 +1290,15 @@ function registerVariantBriefTools(server, client) {
1161
1290
  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
1291
  inputSchema: {
1163
1292
  projectId: projectIdSchema,
1164
- componentId: import_zod10.z.string().describe('The component ID to write a new variant for (matches <Adaptive id="...">).')
1293
+ componentId: import_zod11.z.string().describe('The component ID to write a new variant for (matches <Adaptive id="...">).')
1165
1294
  },
1166
1295
  outputSchema: {
1167
- componentId: import_zod10.z.string(),
1168
- contextType: import_zod10.z.string().describe("The project's context type (or 'unknown')"),
1169
- dataState: import_zod10.z.enum(["sufficient", "collecting", "empty"]).describe("Data-sufficiency assessment"),
1170
- existingVariantIds: import_zod10.z.array(import_zod10.z.string()).describe("Variant IDs already in use (do not reuse)"),
1171
- priors: import_zod10.z.array(import_zod10.z.string()).describe("Best-practice priors applied for this context type"),
1172
- markdown: import_zod10.z.string().describe("The full variant brief in Markdown")
1296
+ componentId: import_zod11.z.string(),
1297
+ contextType: import_zod11.z.string().describe("The project's context type (or 'unknown')"),
1298
+ dataState: import_zod11.z.enum(["sufficient", "collecting", "empty"]).describe("Data-sufficiency assessment"),
1299
+ existingVariantIds: import_zod11.z.array(import_zod11.z.string()).describe("Variant IDs already in use (do not reuse)"),
1300
+ priors: import_zod11.z.array(import_zod11.z.string()).describe("Best-practice priors applied for this context type"),
1301
+ markdown: import_zod11.z.string().describe("The full variant brief in Markdown")
1173
1302
  },
1174
1303
  annotations: {
1175
1304
  readOnlyHint: true,
@@ -1286,7 +1415,7 @@ function registerVariantBriefTools(server, client) {
1286
1415
  }
1287
1416
 
1288
1417
  // src/tools/test-brief.ts
1289
- var import_zod11 = require("zod");
1418
+ var import_zod12 = require("zod");
1290
1419
  async function settled2(p) {
1291
1420
  try {
1292
1421
  return await p;
@@ -1302,13 +1431,13 @@ function registerTestBriefTools(server, client) {
1302
1431
  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
1432
  inputSchema: {
1304
1433
  projectId: projectIdSchema,
1305
- componentId: import_zod11.z.string().describe('The component ID to write a test for (matches <Adaptive id="...">).')
1434
+ componentId: import_zod12.z.string().describe('The component ID to write a test for (matches <Adaptive id="...">).')
1306
1435
  },
1307
1436
  outputSchema: {
1308
- componentId: import_zod11.z.string(),
1309
- forcedVariantId: import_zod11.z.string().describe("The non-control variant the example forces"),
1310
- goalName: import_zod11.z.string().describe("The goal the example asserts fires"),
1311
- markdown: import_zod11.z.string().describe("The full test brief in Markdown")
1437
+ componentId: import_zod12.z.string(),
1438
+ forcedVariantId: import_zod12.z.string().describe("The non-control variant the example forces"),
1439
+ goalName: import_zod12.z.string().describe("The goal the example asserts fires"),
1440
+ markdown: import_zod12.z.string().describe("The full test brief in Markdown")
1312
1441
  },
1313
1442
  annotations: {
1314
1443
  readOnlyHint: true,
@@ -1391,7 +1520,7 @@ function registerTestBriefTools(server, client) {
1391
1520
  }
1392
1521
 
1393
1522
  // src/tools/integration-guide.ts
1394
- var import_zod12 = require("zod");
1523
+ var import_zod13 = require("zod");
1395
1524
  var GUIDE = `# SentientUI integration guide \u2014 the adaptive ladder
1396
1525
 
1397
1526
  SentientUI adapts a site per visitor type (personas: buyer, researcher, deal_seeker, browser,
@@ -1466,7 +1595,7 @@ function registerIntegrationGuideTools(server) {
1466
1595
  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
1596
  inputSchema: {},
1468
1597
  outputSchema: {
1469
- guide: import_zod12.z.string().describe("The full integration guide in Markdown")
1598
+ guide: import_zod13.z.string().describe("The full integration guide in Markdown")
1470
1599
  },
1471
1600
  annotations: {
1472
1601
  readOnlyHint: true,
@@ -1482,7 +1611,7 @@ function registerIntegrationGuideTools(server) {
1482
1611
  }
1483
1612
 
1484
1613
  // src/tools/agent-traffic.ts
1485
- var import_zod13 = require("zod");
1614
+ var import_zod14 = require("zod");
1486
1615
  var PLAN_GATE_GUIDANCE = {
1487
1616
  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
1617
  };
@@ -1494,19 +1623,19 @@ function registerAgentTrafficTools(server, client) {
1494
1623
  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
1624
  inputSchema: { projectId: projectIdSchema },
1496
1625
  outputSchema: {
1497
- totals: import_zod13.z.object({ crawler: import_zod13.z.number(), api: import_zod13.z.number(), browser: import_zod13.z.number() }),
1498
- engines: import_zod13.z.array(
1499
- import_zod13.z.object({
1500
- engine: import_zod13.z.string(),
1501
- intent: import_zod13.z.string().describe("user | search | training | other"),
1502
- count: import_zod13.z.number(),
1503
- sharePct: import_zod13.z.number(),
1504
- lastSeen: import_zod13.z.string(),
1505
- firstSeenInRange: import_zod13.z.boolean().describe("First observed within the queried period")
1626
+ totals: import_zod14.z.object({ crawler: import_zod14.z.number(), api: import_zod14.z.number(), browser: import_zod14.z.number() }),
1627
+ engines: import_zod14.z.array(
1628
+ import_zod14.z.object({
1629
+ engine: import_zod14.z.string(),
1630
+ intent: import_zod14.z.string().describe("user | search | training | other"),
1631
+ count: import_zod14.z.number(),
1632
+ sharePct: import_zod14.z.number(),
1633
+ lastSeen: import_zod14.z.string(),
1634
+ firstSeenInRange: import_zod14.z.boolean().describe("First observed within the queried period")
1506
1635
  })
1507
1636
  ),
1508
- 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"),
1509
- topPaths: import_zod13.z.array(import_zod13.z.object({ path: import_zod13.z.string(), count: import_zod13.z.number(), engines: import_zod13.z.number() }))
1637
+ 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"),
1638
+ 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
1639
  },
1511
1640
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1512
1641
  },
@@ -1544,26 +1673,26 @@ function registerAgentTrafficTools(server, client) {
1544
1673
  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
1674
  inputSchema: { projectId: projectIdSchema },
1546
1675
  outputSchema: {
1547
- paths: import_zod13.z.array(
1548
- import_zod13.z.object({
1549
- path: import_zod13.z.string(),
1550
- score: import_zod13.z.number().describe("0\u2013100, 25 per passing check"),
1551
- checks: import_zod13.z.object({
1552
- price: import_zod13.z.boolean(),
1553
- name: import_zod13.z.boolean(),
1554
- positioning: import_zod13.z.boolean(),
1555
- cta: import_zod13.z.boolean(),
1556
- notes: import_zod13.z.array(import_zod13.z.string())
1676
+ paths: import_zod14.z.array(
1677
+ import_zod14.z.object({
1678
+ path: import_zod14.z.string(),
1679
+ score: import_zod14.z.number().describe("0\u2013100, 25 per passing check"),
1680
+ checks: import_zod14.z.object({
1681
+ price: import_zod14.z.boolean(),
1682
+ name: import_zod14.z.boolean(),
1683
+ positioning: import_zod14.z.boolean(),
1684
+ cta: import_zod14.z.boolean(),
1685
+ notes: import_zod14.z.array(import_zod14.z.string())
1557
1686
  }),
1558
- fixes: import_zod13.z.array(import_zod13.z.object({
1559
- check: import_zod13.z.string(),
1560
- advice: import_zod13.z.string(),
1561
- snippet: import_zod13.z.string().optional()
1687
+ fixes: import_zod14.z.array(import_zod14.z.object({
1688
+ check: import_zod14.z.string(),
1689
+ advice: import_zod14.z.string(),
1690
+ snippet: import_zod14.z.string().optional()
1562
1691
  })).optional().describe("Concrete Next.js remediation per failing check"),
1563
- lastChecked: import_zod13.z.string()
1692
+ lastChecked: import_zod14.z.string()
1564
1693
  })
1565
1694
  ),
1566
- emptyBlocks: import_zod13.z.array(import_zod13.z.object({ block: import_zod13.z.string(), variant: import_zod13.z.string(), occurrences: import_zod13.z.number() }))
1695
+ 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
1696
  },
1568
1697
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
1569
1698
  },
@@ -1600,7 +1729,7 @@ function registerAgentTrafficTools(server, client) {
1600
1729
  }
1601
1730
 
1602
1731
  // src/server.ts
1603
- var PKG_VERSION = true ? "0.12.0" : "0.0.0-dev";
1732
+ var PKG_VERSION = true ? "0.13.0" : "0.0.0-dev";
1604
1733
  function createMcpServer(client) {
1605
1734
  const server = new import_mcp.McpServer(
1606
1735
  {
@@ -1627,6 +1756,7 @@ function createMcpServer(client) {
1627
1756
  registerInsightTools(server, client);
1628
1757
  registerPersonaTools(server, client);
1629
1758
  registerGoalTools(server, client);
1759
+ registerFunnelTools(server, client);
1630
1760
  registerGuardrailTools(server, client);
1631
1761
  registerLayoutTools(server, client);
1632
1762
  registerVariantBriefTools(server, client);
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  ApiClient,
4
4
  createMcpServer
5
- } from "./chunk-BMOKDBGH.js";
5
+ } from "./chunk-ZJ2JZ5RR.js";
6
6
 
7
7
  // src/index.ts
8
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";