@sentientui/mcp 0.16.0 → 0.17.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/AGENTS.md +1 -1
- package/README.md +2 -2
- package/dist/{chunk-SUMKFRQP.js → chunk-2E5M5ESK.js} +95 -28
- package/dist/index.cjs +95 -28
- package/dist/index.js +1 -1
- package/dist/lib.cjs +95 -28
- package/dist/lib.js +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -33,7 +33,7 @@ Server keys start with `sk_` — required for the management API. Public keys (`
|
|
|
33
33
|
| `create_project` | Onboard a new user: creates a project + returns its `pk_` key. Needs an account login (OAuth) — refuses `sk_` project keys and demo tokens. Follow with `get_integration_guide` |
|
|
34
34
|
| `get_project_stats` | Health status + 24h event/session volume |
|
|
35
35
|
| `list_components` | Components + variant counts + impression totals |
|
|
36
|
-
| `get_variant_performance` | CVR
|
|
36
|
+
| `get_variant_performance` | CVR current vs prior window + momentum (range/from/to params; default 7d) |
|
|
37
37
|
| `get_persona_breakdown` | Cluster distribution + avg reliability per cluster |
|
|
38
38
|
| `get_goal_funnel` | Goal hit counts + per-variant completion rates |
|
|
39
39
|
| `list_guardrail_events` | Auto-paused variants (last 24h) |
|
package/README.md
CHANGED
|
@@ -88,11 +88,11 @@ A sandboxed demo token is provisioned automatically — 10 calls/month, read-onl
|
|
|
88
88
|
| `create_project` | Create a new project and return its `pk_` public key (account login required — not usable with an `sk_` project key or demo token) |
|
|
89
89
|
| `get_project_stats` | Events, sessions, agent calls, and health status |
|
|
90
90
|
| `list_components` | All adaptive components with variant counts |
|
|
91
|
-
| `get_variant_performance` | CVR, momentum, and impressions per variant (7d vs prior 7d) |
|
|
91
|
+
| `get_variant_performance` | CVR, momentum, and impressions per variant (windowed: range 7d/30d/90d/all or from/to; default 7d vs prior 7d) |
|
|
92
92
|
| `get_insights` | AI-generated narrator observations and advisor recommendations |
|
|
93
93
|
| `refresh_insights` | Trigger fresh AI insight generation |
|
|
94
94
|
| `get_persona_breakdown` | Visitor cluster distribution with reliability scores |
|
|
95
|
-
| `get_goal_funnel` | Goal hit counts and conversion rates per variant |
|
|
95
|
+
| `get_goal_funnel` | Goal hit counts and conversion rates per variant (windowed; default 30d) |
|
|
96
96
|
| `list_goals` | Defined goals (id, role, event, status) — includes goals with no conversions yet, so agents can wire a dashboard-defined goal into code |
|
|
97
97
|
| `list_guardrail_events` | Variants auto-paused by the guardrail (last 24h) |
|
|
98
98
|
| `get_layout_stats` | Per-persona section layout rankings and reward weights |
|
|
@@ -199,7 +199,11 @@ var RENDER_JS = {
|
|
|
199
199
|
"variant-performance": `
|
|
200
200
|
window.__render = function(data){
|
|
201
201
|
var variants = (data && data.variants) || [];
|
|
202
|
-
|
|
202
|
+
var winText = 'current vs prior period';
|
|
203
|
+
if (data && data.window && data.window.start && data.window.end) {
|
|
204
|
+
winText = String(data.window.start).slice(0, 10) + ' to ' + String(data.window.end).slice(0, 10) + ' vs prior period';
|
|
205
|
+
}
|
|
206
|
+
el('sub').textContent = variants.length + ' variant' + (variants.length === 1 ? '' : 's') + ' \xB7 conversion, ' + winText;
|
|
203
207
|
if (!variants.length) { showEmpty('No variant data available yet.'); return; }
|
|
204
208
|
var max = variants.reduce(function(m,v){ return Math.max(m, v.currentCvr || 0); }, 0) || 1;
|
|
205
209
|
var sorted = variants.slice().sort(function(a,b){ return (b.currentCvr||0) - (a.currentCvr||0); });
|
|
@@ -331,6 +335,44 @@ import { z as z2 } from "zod";
|
|
|
331
335
|
// src/tools/common.ts
|
|
332
336
|
import { z } from "zod";
|
|
333
337
|
var projectIdSchema = z.string().uuid().describe("The project UUID");
|
|
338
|
+
function rangeInputSchema(defaultRange) {
|
|
339
|
+
return {
|
|
340
|
+
range: z.enum(["7d", "30d", "90d", "all"]).optional().describe(
|
|
341
|
+
`Calendar window in the project's reporting timezone (default ${defaultRange}). 'all' means all retained data \u2014 the plan's retention window bounds every lookback.`
|
|
342
|
+
),
|
|
343
|
+
from: z.string().optional().describe(
|
|
344
|
+
"Custom window start (YYYY-MM-DD; overrides range). Must be within the plan retention window."
|
|
345
|
+
),
|
|
346
|
+
to: z.string().optional().describe("Custom window end (YYYY-MM-DD, inclusive; default today).")
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function rangeQuery(args) {
|
|
350
|
+
const p = new URLSearchParams();
|
|
351
|
+
if (args.from) {
|
|
352
|
+
p.set("from", args.from);
|
|
353
|
+
if (args.to) p.set("to", args.to);
|
|
354
|
+
} else if (args.range) {
|
|
355
|
+
p.set("range", args.range);
|
|
356
|
+
}
|
|
357
|
+
const s = p.toString();
|
|
358
|
+
return s ? `?${s}` : "";
|
|
359
|
+
}
|
|
360
|
+
var windowOutputSchema = z.object({
|
|
361
|
+
range: z.string(),
|
|
362
|
+
start: z.string().nullable(),
|
|
363
|
+
end: z.string().nullable(),
|
|
364
|
+
timezone: z.string(),
|
|
365
|
+
bucketUnit: z.string(),
|
|
366
|
+
retentionDays: z.number().describe("The plan's effective data retention in days"),
|
|
367
|
+
earliestAvailable: z.string().describe("First date retention still holds data for (YYYY-MM-DD)")
|
|
368
|
+
}).optional().describe("The window the server actually used for every count in this response");
|
|
369
|
+
function windowLine(window) {
|
|
370
|
+
if (!window) return "";
|
|
371
|
+
if (window.start && window.end) {
|
|
372
|
+
return `Window: ${window.start.slice(0, 10)} to ${window.end.slice(0, 10)} (${window.timezone}, exclusive end)`;
|
|
373
|
+
}
|
|
374
|
+
return `Window: all retained data (${window.retentionDays}-day retention)`;
|
|
375
|
+
}
|
|
334
376
|
function apiErrorGuidance(err, extra) {
|
|
335
377
|
if (extra && Object.prototype.hasOwnProperty.call(extra, err.message)) {
|
|
336
378
|
return extra[err.message];
|
|
@@ -345,6 +387,12 @@ function apiErrorGuidance(err, extra) {
|
|
|
345
387
|
default:
|
|
346
388
|
break;
|
|
347
389
|
}
|
|
390
|
+
if (err.message === "range_out_of_retention") {
|
|
391
|
+
return "The requested window starts before this plan retains data \u2014 older events have been deleted by the retention purge and cannot be recovered. Ask for a more recent window, or upgrade the SentientUI plan for longer history (Growth keeps 180 days, Scale 365).";
|
|
392
|
+
}
|
|
393
|
+
if (err.message === "invalid_range") {
|
|
394
|
+
return "Invalid time window. Use range '7d', '30d', '90d' or 'all', or from/to as YYYY-MM-DD dates.";
|
|
395
|
+
}
|
|
348
396
|
if (err.status === 402) {
|
|
349
397
|
return `This feature requires a higher plan (${err.message}). Upgrade your SentientUI plan, then try again.`;
|
|
350
398
|
}
|
|
@@ -516,8 +564,8 @@ function registerComponentTools(server, client) {
|
|
|
516
564
|
"list_components",
|
|
517
565
|
{
|
|
518
566
|
title: "List components",
|
|
519
|
-
description: "List all adaptive components in a project with variant counts and impression totals.",
|
|
520
|
-
inputSchema: { projectId: projectIdSchema },
|
|
567
|
+
description: "List all adaptive components in a project with variant counts and impression totals. Counts cover all retained data by default; pass range or from/to for a window.",
|
|
568
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("all")),
|
|
521
569
|
outputSchema: {
|
|
522
570
|
components: z3.array(
|
|
523
571
|
z3.object({
|
|
@@ -526,7 +574,8 @@ function registerComponentTools(server, client) {
|
|
|
526
574
|
impressions: z3.number(),
|
|
527
575
|
conversions: z3.number()
|
|
528
576
|
})
|
|
529
|
-
).describe("Adaptive components in the project (empty if none)")
|
|
577
|
+
).describe("Adaptive components in the project (empty if none)"),
|
|
578
|
+
window: windowOutputSchema
|
|
530
579
|
},
|
|
531
580
|
annotations: {
|
|
532
581
|
readOnlyHint: true,
|
|
@@ -534,16 +583,17 @@ function registerComponentTools(server, client) {
|
|
|
534
583
|
openWorldHint: false
|
|
535
584
|
}
|
|
536
585
|
},
|
|
537
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
586
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
538
587
|
const id = encodeURIComponent(projectId);
|
|
539
|
-
const { components } = await client.get(`/projects/${id}/components`);
|
|
588
|
+
const { components, window } = await client.get(`/projects/${id}/components${rangeQuery({ range, from, to })}`);
|
|
540
589
|
const structuredContent = {
|
|
541
590
|
components: components.map((c) => ({
|
|
542
591
|
componentId: c.component_id,
|
|
543
592
|
variantCount: c.variants.length,
|
|
544
593
|
impressions: c.total_impressions,
|
|
545
594
|
conversions: c.total_conversions
|
|
546
|
-
}))
|
|
595
|
+
})),
|
|
596
|
+
window
|
|
547
597
|
};
|
|
548
598
|
if (!components.length) {
|
|
549
599
|
return {
|
|
@@ -561,19 +611,20 @@ function registerComponentTools(server, client) {
|
|
|
561
611
|
"get_variant_performance",
|
|
562
612
|
{
|
|
563
613
|
title: "Variant performance",
|
|
564
|
-
description: "Get CVR and momentum for all variants in a project over the last 7 days vs prior 7
|
|
565
|
-
inputSchema: { projectId: projectIdSchema },
|
|
614
|
+
description: "Get CVR and momentum for all variants in a project over the selected window vs the immediately-preceding window of equal length (default: last 7 calendar days vs prior 7).",
|
|
615
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("7d")),
|
|
566
616
|
_meta: uiMeta("variant-performance"),
|
|
567
617
|
outputSchema: {
|
|
568
618
|
variants: z3.array(
|
|
569
619
|
z3.object({
|
|
570
620
|
variantId: z3.string(),
|
|
571
|
-
currentCvr: z3.number().describe("Conversion rate over the
|
|
572
|
-
priorCvr: z3.number().describe("Conversion rate over the
|
|
621
|
+
currentCvr: z3.number().describe("Conversion rate over the selected window (0-1)"),
|
|
622
|
+
priorCvr: z3.number().describe("Conversion rate over the preceding window (0-1)"),
|
|
573
623
|
deltaPp: z3.number().describe("Change in percentage points"),
|
|
574
624
|
momentum: z3.string().describe("Momentum direction: gaining, losing, or stable")
|
|
575
625
|
})
|
|
576
|
-
).describe("Per-variant performance (empty if no data yet)")
|
|
626
|
+
).describe("Per-variant performance (empty if no data yet)"),
|
|
627
|
+
window: windowOutputSchema
|
|
577
628
|
},
|
|
578
629
|
annotations: {
|
|
579
630
|
readOnlyHint: true,
|
|
@@ -581,10 +632,10 @@ function registerComponentTools(server, client) {
|
|
|
581
632
|
openWorldHint: false
|
|
582
633
|
}
|
|
583
634
|
},
|
|
584
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
635
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
585
636
|
var _a, _b, _c;
|
|
586
637
|
const id = encodeURIComponent(projectId);
|
|
587
|
-
const data = await client.get(`/projects/${id}/trends`);
|
|
638
|
+
const data = await client.get(`/projects/${id}/trends${rangeQuery({ range, from, to })}`);
|
|
588
639
|
const momentumMap = new Map(((_a = data.momentum) != null ? _a : []).map((m) => [m.variantId, m.direction]));
|
|
589
640
|
const structuredContent = {
|
|
590
641
|
variants: ((_b = data.cvr) != null ? _b : []).map((v) => {
|
|
@@ -596,7 +647,8 @@ function registerComponentTools(server, client) {
|
|
|
596
647
|
deltaPp: v.deltaPp,
|
|
597
648
|
momentum: (_a2 = momentumMap.get(v.variantId)) != null ? _a2 : "stable"
|
|
598
649
|
};
|
|
599
|
-
})
|
|
650
|
+
}),
|
|
651
|
+
window: data.window
|
|
600
652
|
};
|
|
601
653
|
if (!((_c = data.cvr) == null ? void 0 : _c.length)) {
|
|
602
654
|
return {
|
|
@@ -605,12 +657,14 @@ function registerComponentTools(server, client) {
|
|
|
605
657
|
_meta: uiMeta("variant-performance")
|
|
606
658
|
};
|
|
607
659
|
}
|
|
608
|
-
const
|
|
660
|
+
const lines = data.cvr.map(
|
|
609
661
|
(v) => {
|
|
610
662
|
var _a2;
|
|
611
663
|
return `- ${v.variantId}: CVR ${(v.currentCvr * 100).toFixed(2)}% (prior ${(v.priorCvr * 100).toFixed(2)}%, ${v.deltaPp > 0 ? "+" : ""}${v.deltaPp.toFixed(1)} pp, ${(_a2 = momentumMap.get(v.variantId)) != null ? _a2 : "stable"})`;
|
|
612
664
|
}
|
|
613
|
-
)
|
|
665
|
+
);
|
|
666
|
+
const win = windowLine(data.window);
|
|
667
|
+
const text = (win ? [win, ...lines] : lines).join("\n");
|
|
614
668
|
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("variant-performance") };
|
|
615
669
|
})
|
|
616
670
|
);
|
|
@@ -796,8 +850,8 @@ function registerGoalTools(server, client) {
|
|
|
796
850
|
"get_goal_funnel",
|
|
797
851
|
{
|
|
798
852
|
title: "Goal funnel",
|
|
799
|
-
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.",
|
|
800
|
-
inputSchema: { projectId: projectIdSchema },
|
|
853
|
+
description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown (default window: last 30 calendar days). This is a flat per-goal list \u2014 for multi-step funnel drop-off, use get_funnel_report.",
|
|
854
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("30d")),
|
|
801
855
|
_meta: uiMeta("goal-funnel"),
|
|
802
856
|
outputSchema: {
|
|
803
857
|
currency: z6.string().describe("Project display currency (ISO-4217) for the revenue fields"),
|
|
@@ -818,7 +872,8 @@ function registerGoalTools(server, client) {
|
|
|
818
872
|
})
|
|
819
873
|
).describe("Per-variant breakdown")
|
|
820
874
|
})
|
|
821
|
-
).describe("Configured goals (empty if none)")
|
|
875
|
+
).describe("Configured goals (empty if none)"),
|
|
876
|
+
window: windowOutputSchema
|
|
822
877
|
},
|
|
823
878
|
annotations: {
|
|
824
879
|
readOnlyHint: true,
|
|
@@ -826,11 +881,12 @@ function registerGoalTools(server, client) {
|
|
|
826
881
|
openWorldHint: false
|
|
827
882
|
}
|
|
828
883
|
},
|
|
829
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
884
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
830
885
|
var _a, _b;
|
|
831
886
|
const id = encodeURIComponent(projectId);
|
|
832
|
-
const data = await client.get(`/projects/${id}/goals`);
|
|
887
|
+
const data = await client.get(`/projects/${id}/goals${rangeQuery({ range, from, to })}`);
|
|
833
888
|
const structuredContent = {
|
|
889
|
+
window: data.window,
|
|
834
890
|
currency: (_a = data.currency) != null ? _a : "USD",
|
|
835
891
|
goals: data.goals.map((g) => {
|
|
836
892
|
var _a2, _b2, _c;
|
|
@@ -858,6 +914,7 @@ function registerGoalTools(server, client) {
|
|
|
858
914
|
};
|
|
859
915
|
}
|
|
860
916
|
const currency = (_b = data.currency) != null ? _b : "USD";
|
|
917
|
+
const win = windowLine(data.window);
|
|
861
918
|
const lines = data.goals.flatMap((g) => {
|
|
862
919
|
var _a2;
|
|
863
920
|
return [
|
|
@@ -866,7 +923,8 @@ function registerGoalTools(server, client) {
|
|
|
866
923
|
""
|
|
867
924
|
];
|
|
868
925
|
});
|
|
869
|
-
|
|
926
|
+
const text = (win ? [win, "", ...lines] : lines).join("\n").trim();
|
|
927
|
+
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("goal-funnel") };
|
|
870
928
|
})
|
|
871
929
|
);
|
|
872
930
|
server.registerTool(
|
|
@@ -1710,8 +1768,12 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1710
1768
|
"get_agent_traffic",
|
|
1711
1769
|
{
|
|
1712
1770
|
title: "Agent traffic",
|
|
1713
|
-
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.",
|
|
1714
|
-
inputSchema: {
|
|
1771
|
+
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. Defaults to the last 30 days; pass from/to for a custom period (agent logs are retained 30 days on Free/Starter, 90 on Growth+). Agent traffic is tracked separately and never counted in conversion rate.",
|
|
1772
|
+
inputSchema: {
|
|
1773
|
+
projectId: projectIdSchema,
|
|
1774
|
+
from: z14.string().optional().describe("Period start (ISO 8601 date or timestamp). Defaults to 30 days ago."),
|
|
1775
|
+
to: z14.string().optional().describe("Period end (ISO 8601 date or timestamp). Defaults to now.")
|
|
1776
|
+
},
|
|
1715
1777
|
outputSchema: {
|
|
1716
1778
|
totals: z14.object({ crawler: z14.number(), api: z14.number(), browser: z14.number() }),
|
|
1717
1779
|
engines: z14.array(
|
|
@@ -1729,9 +1791,14 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1729
1791
|
},
|
|
1730
1792
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1731
1793
|
},
|
|
1732
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
1794
|
+
withApiErrorGuidance(async ({ projectId, from, to }) => {
|
|
1733
1795
|
const id = encodeURIComponent(projectId);
|
|
1734
|
-
const
|
|
1796
|
+
const qs = new URLSearchParams();
|
|
1797
|
+
if (from) qs.set("from", from);
|
|
1798
|
+
if (to) qs.set("to", to);
|
|
1799
|
+
const s = await client.get(
|
|
1800
|
+
`/projects/${id}/agent-activity/summary${qs.size > 0 ? `?${qs.toString()}` : ""}`
|
|
1801
|
+
);
|
|
1735
1802
|
const structuredContent = { totals: s.totals, engines: s.engines, intents: s.intents, topPaths: s.topPaths };
|
|
1736
1803
|
const total = s.totals.crawler + s.totals.api + s.totals.browser;
|
|
1737
1804
|
if (total === 0) {
|
|
@@ -1819,7 +1886,7 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1819
1886
|
}
|
|
1820
1887
|
|
|
1821
1888
|
// src/server.ts
|
|
1822
|
-
var PKG_VERSION = true ? "0.
|
|
1889
|
+
var PKG_VERSION = true ? "0.17.0" : "0.0.0-dev";
|
|
1823
1890
|
function createMcpServer(client) {
|
|
1824
1891
|
const server = new McpServer(
|
|
1825
1892
|
{
|
package/dist/index.cjs
CHANGED
|
@@ -78,6 +78,44 @@ var import_zod2 = require("zod");
|
|
|
78
78
|
// src/tools/common.ts
|
|
79
79
|
var import_zod = require("zod");
|
|
80
80
|
var projectIdSchema = import_zod.z.string().uuid().describe("The project UUID");
|
|
81
|
+
function rangeInputSchema(defaultRange) {
|
|
82
|
+
return {
|
|
83
|
+
range: import_zod.z.enum(["7d", "30d", "90d", "all"]).optional().describe(
|
|
84
|
+
`Calendar window in the project's reporting timezone (default ${defaultRange}). 'all' means all retained data \u2014 the plan's retention window bounds every lookback.`
|
|
85
|
+
),
|
|
86
|
+
from: import_zod.z.string().optional().describe(
|
|
87
|
+
"Custom window start (YYYY-MM-DD; overrides range). Must be within the plan retention window."
|
|
88
|
+
),
|
|
89
|
+
to: import_zod.z.string().optional().describe("Custom window end (YYYY-MM-DD, inclusive; default today).")
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function rangeQuery(args) {
|
|
93
|
+
const p = new URLSearchParams();
|
|
94
|
+
if (args.from) {
|
|
95
|
+
p.set("from", args.from);
|
|
96
|
+
if (args.to) p.set("to", args.to);
|
|
97
|
+
} else if (args.range) {
|
|
98
|
+
p.set("range", args.range);
|
|
99
|
+
}
|
|
100
|
+
const s = p.toString();
|
|
101
|
+
return s ? `?${s}` : "";
|
|
102
|
+
}
|
|
103
|
+
var windowOutputSchema = import_zod.z.object({
|
|
104
|
+
range: import_zod.z.string(),
|
|
105
|
+
start: import_zod.z.string().nullable(),
|
|
106
|
+
end: import_zod.z.string().nullable(),
|
|
107
|
+
timezone: import_zod.z.string(),
|
|
108
|
+
bucketUnit: import_zod.z.string(),
|
|
109
|
+
retentionDays: import_zod.z.number().describe("The plan's effective data retention in days"),
|
|
110
|
+
earliestAvailable: import_zod.z.string().describe("First date retention still holds data for (YYYY-MM-DD)")
|
|
111
|
+
}).optional().describe("The window the server actually used for every count in this response");
|
|
112
|
+
function windowLine(window) {
|
|
113
|
+
if (!window) return "";
|
|
114
|
+
if (window.start && window.end) {
|
|
115
|
+
return `Window: ${window.start.slice(0, 10)} to ${window.end.slice(0, 10)} (${window.timezone}, exclusive end)`;
|
|
116
|
+
}
|
|
117
|
+
return `Window: all retained data (${window.retentionDays}-day retention)`;
|
|
118
|
+
}
|
|
81
119
|
function apiErrorGuidance(err, extra) {
|
|
82
120
|
if (extra && Object.prototype.hasOwnProperty.call(extra, err.message)) {
|
|
83
121
|
return extra[err.message];
|
|
@@ -92,6 +130,12 @@ function apiErrorGuidance(err, extra) {
|
|
|
92
130
|
default:
|
|
93
131
|
break;
|
|
94
132
|
}
|
|
133
|
+
if (err.message === "range_out_of_retention") {
|
|
134
|
+
return "The requested window starts before this plan retains data \u2014 older events have been deleted by the retention purge and cannot be recovered. Ask for a more recent window, or upgrade the SentientUI plan for longer history (Growth keeps 180 days, Scale 365).";
|
|
135
|
+
}
|
|
136
|
+
if (err.message === "invalid_range") {
|
|
137
|
+
return "Invalid time window. Use range '7d', '30d', '90d' or 'all', or from/to as YYYY-MM-DD dates.";
|
|
138
|
+
}
|
|
95
139
|
if (err.status === 402) {
|
|
96
140
|
return `This feature requires a higher plan (${err.message}). Upgrade your SentientUI plan, then try again.`;
|
|
97
141
|
}
|
|
@@ -393,7 +437,11 @@ var RENDER_JS = {
|
|
|
393
437
|
"variant-performance": `
|
|
394
438
|
window.__render = function(data){
|
|
395
439
|
var variants = (data && data.variants) || [];
|
|
396
|
-
|
|
440
|
+
var winText = 'current vs prior period';
|
|
441
|
+
if (data && data.window && data.window.start && data.window.end) {
|
|
442
|
+
winText = String(data.window.start).slice(0, 10) + ' to ' + String(data.window.end).slice(0, 10) + ' vs prior period';
|
|
443
|
+
}
|
|
444
|
+
el('sub').textContent = variants.length + ' variant' + (variants.length === 1 ? '' : 's') + ' \xB7 conversion, ' + winText;
|
|
397
445
|
if (!variants.length) { showEmpty('No variant data available yet.'); return; }
|
|
398
446
|
var max = variants.reduce(function(m,v){ return Math.max(m, v.currentCvr || 0); }, 0) || 1;
|
|
399
447
|
var sorted = variants.slice().sort(function(a,b){ return (b.currentCvr||0) - (a.currentCvr||0); });
|
|
@@ -522,8 +570,8 @@ function registerComponentTools(server, client) {
|
|
|
522
570
|
"list_components",
|
|
523
571
|
{
|
|
524
572
|
title: "List components",
|
|
525
|
-
description: "List all adaptive components in a project with variant counts and impression totals.",
|
|
526
|
-
inputSchema: { projectId: projectIdSchema },
|
|
573
|
+
description: "List all adaptive components in a project with variant counts and impression totals. Counts cover all retained data by default; pass range or from/to for a window.",
|
|
574
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("all")),
|
|
527
575
|
outputSchema: {
|
|
528
576
|
components: import_zod3.z.array(
|
|
529
577
|
import_zod3.z.object({
|
|
@@ -532,7 +580,8 @@ function registerComponentTools(server, client) {
|
|
|
532
580
|
impressions: import_zod3.z.number(),
|
|
533
581
|
conversions: import_zod3.z.number()
|
|
534
582
|
})
|
|
535
|
-
).describe("Adaptive components in the project (empty if none)")
|
|
583
|
+
).describe("Adaptive components in the project (empty if none)"),
|
|
584
|
+
window: windowOutputSchema
|
|
536
585
|
},
|
|
537
586
|
annotations: {
|
|
538
587
|
readOnlyHint: true,
|
|
@@ -540,16 +589,17 @@ function registerComponentTools(server, client) {
|
|
|
540
589
|
openWorldHint: false
|
|
541
590
|
}
|
|
542
591
|
},
|
|
543
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
592
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
544
593
|
const id = encodeURIComponent(projectId);
|
|
545
|
-
const { components } = await client.get(`/projects/${id}/components`);
|
|
594
|
+
const { components, window } = await client.get(`/projects/${id}/components${rangeQuery({ range, from, to })}`);
|
|
546
595
|
const structuredContent = {
|
|
547
596
|
components: components.map((c) => ({
|
|
548
597
|
componentId: c.component_id,
|
|
549
598
|
variantCount: c.variants.length,
|
|
550
599
|
impressions: c.total_impressions,
|
|
551
600
|
conversions: c.total_conversions
|
|
552
|
-
}))
|
|
601
|
+
})),
|
|
602
|
+
window
|
|
553
603
|
};
|
|
554
604
|
if (!components.length) {
|
|
555
605
|
return {
|
|
@@ -567,19 +617,20 @@ function registerComponentTools(server, client) {
|
|
|
567
617
|
"get_variant_performance",
|
|
568
618
|
{
|
|
569
619
|
title: "Variant performance",
|
|
570
|
-
description: "Get CVR and momentum for all variants in a project over the last 7 days vs prior 7
|
|
571
|
-
inputSchema: { projectId: projectIdSchema },
|
|
620
|
+
description: "Get CVR and momentum for all variants in a project over the selected window vs the immediately-preceding window of equal length (default: last 7 calendar days vs prior 7).",
|
|
621
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("7d")),
|
|
572
622
|
_meta: uiMeta("variant-performance"),
|
|
573
623
|
outputSchema: {
|
|
574
624
|
variants: import_zod3.z.array(
|
|
575
625
|
import_zod3.z.object({
|
|
576
626
|
variantId: import_zod3.z.string(),
|
|
577
|
-
currentCvr: import_zod3.z.number().describe("Conversion rate over the
|
|
578
|
-
priorCvr: import_zod3.z.number().describe("Conversion rate over the
|
|
627
|
+
currentCvr: import_zod3.z.number().describe("Conversion rate over the selected window (0-1)"),
|
|
628
|
+
priorCvr: import_zod3.z.number().describe("Conversion rate over the preceding window (0-1)"),
|
|
579
629
|
deltaPp: import_zod3.z.number().describe("Change in percentage points"),
|
|
580
630
|
momentum: import_zod3.z.string().describe("Momentum direction: gaining, losing, or stable")
|
|
581
631
|
})
|
|
582
|
-
).describe("Per-variant performance (empty if no data yet)")
|
|
632
|
+
).describe("Per-variant performance (empty if no data yet)"),
|
|
633
|
+
window: windowOutputSchema
|
|
583
634
|
},
|
|
584
635
|
annotations: {
|
|
585
636
|
readOnlyHint: true,
|
|
@@ -587,10 +638,10 @@ function registerComponentTools(server, client) {
|
|
|
587
638
|
openWorldHint: false
|
|
588
639
|
}
|
|
589
640
|
},
|
|
590
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
641
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
591
642
|
var _a2, _b, _c;
|
|
592
643
|
const id = encodeURIComponent(projectId);
|
|
593
|
-
const data = await client.get(`/projects/${id}/trends`);
|
|
644
|
+
const data = await client.get(`/projects/${id}/trends${rangeQuery({ range, from, to })}`);
|
|
594
645
|
const momentumMap = new Map(((_a2 = data.momentum) != null ? _a2 : []).map((m) => [m.variantId, m.direction]));
|
|
595
646
|
const structuredContent = {
|
|
596
647
|
variants: ((_b = data.cvr) != null ? _b : []).map((v) => {
|
|
@@ -602,7 +653,8 @@ function registerComponentTools(server, client) {
|
|
|
602
653
|
deltaPp: v.deltaPp,
|
|
603
654
|
momentum: (_a3 = momentumMap.get(v.variantId)) != null ? _a3 : "stable"
|
|
604
655
|
};
|
|
605
|
-
})
|
|
656
|
+
}),
|
|
657
|
+
window: data.window
|
|
606
658
|
};
|
|
607
659
|
if (!((_c = data.cvr) == null ? void 0 : _c.length)) {
|
|
608
660
|
return {
|
|
@@ -611,12 +663,14 @@ function registerComponentTools(server, client) {
|
|
|
611
663
|
_meta: uiMeta("variant-performance")
|
|
612
664
|
};
|
|
613
665
|
}
|
|
614
|
-
const
|
|
666
|
+
const lines = data.cvr.map(
|
|
615
667
|
(v) => {
|
|
616
668
|
var _a3;
|
|
617
669
|
return `- ${v.variantId}: CVR ${(v.currentCvr * 100).toFixed(2)}% (prior ${(v.priorCvr * 100).toFixed(2)}%, ${v.deltaPp > 0 ? "+" : ""}${v.deltaPp.toFixed(1)} pp, ${(_a3 = momentumMap.get(v.variantId)) != null ? _a3 : "stable"})`;
|
|
618
670
|
}
|
|
619
|
-
)
|
|
671
|
+
);
|
|
672
|
+
const win = windowLine(data.window);
|
|
673
|
+
const text = (win ? [win, ...lines] : lines).join("\n");
|
|
620
674
|
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("variant-performance") };
|
|
621
675
|
})
|
|
622
676
|
);
|
|
@@ -802,8 +856,8 @@ function registerGoalTools(server, client) {
|
|
|
802
856
|
"get_goal_funnel",
|
|
803
857
|
{
|
|
804
858
|
title: "Goal funnel",
|
|
805
|
-
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.",
|
|
806
|
-
inputSchema: { projectId: projectIdSchema },
|
|
859
|
+
description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown (default window: last 30 calendar days). This is a flat per-goal list \u2014 for multi-step funnel drop-off, use get_funnel_report.",
|
|
860
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("30d")),
|
|
807
861
|
_meta: uiMeta("goal-funnel"),
|
|
808
862
|
outputSchema: {
|
|
809
863
|
currency: import_zod6.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
|
|
@@ -824,7 +878,8 @@ function registerGoalTools(server, client) {
|
|
|
824
878
|
})
|
|
825
879
|
).describe("Per-variant breakdown")
|
|
826
880
|
})
|
|
827
|
-
).describe("Configured goals (empty if none)")
|
|
881
|
+
).describe("Configured goals (empty if none)"),
|
|
882
|
+
window: windowOutputSchema
|
|
828
883
|
},
|
|
829
884
|
annotations: {
|
|
830
885
|
readOnlyHint: true,
|
|
@@ -832,11 +887,12 @@ function registerGoalTools(server, client) {
|
|
|
832
887
|
openWorldHint: false
|
|
833
888
|
}
|
|
834
889
|
},
|
|
835
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
890
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
836
891
|
var _a2, _b;
|
|
837
892
|
const id = encodeURIComponent(projectId);
|
|
838
|
-
const data = await client.get(`/projects/${id}/goals`);
|
|
893
|
+
const data = await client.get(`/projects/${id}/goals${rangeQuery({ range, from, to })}`);
|
|
839
894
|
const structuredContent = {
|
|
895
|
+
window: data.window,
|
|
840
896
|
currency: (_a2 = data.currency) != null ? _a2 : "USD",
|
|
841
897
|
goals: data.goals.map((g) => {
|
|
842
898
|
var _a3, _b2, _c;
|
|
@@ -864,6 +920,7 @@ function registerGoalTools(server, client) {
|
|
|
864
920
|
};
|
|
865
921
|
}
|
|
866
922
|
const currency = (_b = data.currency) != null ? _b : "USD";
|
|
923
|
+
const win = windowLine(data.window);
|
|
867
924
|
const lines = data.goals.flatMap((g) => {
|
|
868
925
|
var _a3;
|
|
869
926
|
return [
|
|
@@ -872,7 +929,8 @@ function registerGoalTools(server, client) {
|
|
|
872
929
|
""
|
|
873
930
|
];
|
|
874
931
|
});
|
|
875
|
-
|
|
932
|
+
const text = (win ? [win, "", ...lines] : lines).join("\n").trim();
|
|
933
|
+
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("goal-funnel") };
|
|
876
934
|
})
|
|
877
935
|
);
|
|
878
936
|
server.registerTool(
|
|
@@ -1716,8 +1774,12 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1716
1774
|
"get_agent_traffic",
|
|
1717
1775
|
{
|
|
1718
1776
|
title: "Agent traffic",
|
|
1719
|
-
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.",
|
|
1720
|
-
inputSchema: {
|
|
1777
|
+
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. Defaults to the last 30 days; pass from/to for a custom period (agent logs are retained 30 days on Free/Starter, 90 on Growth+). Agent traffic is tracked separately and never counted in conversion rate.",
|
|
1778
|
+
inputSchema: {
|
|
1779
|
+
projectId: projectIdSchema,
|
|
1780
|
+
from: import_zod14.z.string().optional().describe("Period start (ISO 8601 date or timestamp). Defaults to 30 days ago."),
|
|
1781
|
+
to: import_zod14.z.string().optional().describe("Period end (ISO 8601 date or timestamp). Defaults to now.")
|
|
1782
|
+
},
|
|
1721
1783
|
outputSchema: {
|
|
1722
1784
|
totals: import_zod14.z.object({ crawler: import_zod14.z.number(), api: import_zod14.z.number(), browser: import_zod14.z.number() }),
|
|
1723
1785
|
engines: import_zod14.z.array(
|
|
@@ -1735,9 +1797,14 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1735
1797
|
},
|
|
1736
1798
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1737
1799
|
},
|
|
1738
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
1800
|
+
withApiErrorGuidance(async ({ projectId, from, to }) => {
|
|
1739
1801
|
const id = encodeURIComponent(projectId);
|
|
1740
|
-
const
|
|
1802
|
+
const qs = new URLSearchParams();
|
|
1803
|
+
if (from) qs.set("from", from);
|
|
1804
|
+
if (to) qs.set("to", to);
|
|
1805
|
+
const s = await client.get(
|
|
1806
|
+
`/projects/${id}/agent-activity/summary${qs.size > 0 ? `?${qs.toString()}` : ""}`
|
|
1807
|
+
);
|
|
1741
1808
|
const structuredContent = { totals: s.totals, engines: s.engines, intents: s.intents, topPaths: s.topPaths };
|
|
1742
1809
|
const total = s.totals.crawler + s.totals.api + s.totals.browser;
|
|
1743
1810
|
if (total === 0) {
|
|
@@ -1825,7 +1892,7 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1825
1892
|
}
|
|
1826
1893
|
|
|
1827
1894
|
// src/server.ts
|
|
1828
|
-
var PKG_VERSION = true ? "0.
|
|
1895
|
+
var PKG_VERSION = true ? "0.17.0" : "0.0.0-dev";
|
|
1829
1896
|
function createMcpServer(client) {
|
|
1830
1897
|
const server = new import_mcp.McpServer(
|
|
1831
1898
|
{
|
package/dist/index.js
CHANGED
package/dist/lib.cjs
CHANGED
|
@@ -102,6 +102,44 @@ var ApiClient = class {
|
|
|
102
102
|
|
|
103
103
|
// src/tools/common.ts
|
|
104
104
|
var projectIdSchema = import_zod.z.string().uuid().describe("The project UUID");
|
|
105
|
+
function rangeInputSchema(defaultRange) {
|
|
106
|
+
return {
|
|
107
|
+
range: import_zod.z.enum(["7d", "30d", "90d", "all"]).optional().describe(
|
|
108
|
+
`Calendar window in the project's reporting timezone (default ${defaultRange}). 'all' means all retained data \u2014 the plan's retention window bounds every lookback.`
|
|
109
|
+
),
|
|
110
|
+
from: import_zod.z.string().optional().describe(
|
|
111
|
+
"Custom window start (YYYY-MM-DD; overrides range). Must be within the plan retention window."
|
|
112
|
+
),
|
|
113
|
+
to: import_zod.z.string().optional().describe("Custom window end (YYYY-MM-DD, inclusive; default today).")
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function rangeQuery(args) {
|
|
117
|
+
const p = new URLSearchParams();
|
|
118
|
+
if (args.from) {
|
|
119
|
+
p.set("from", args.from);
|
|
120
|
+
if (args.to) p.set("to", args.to);
|
|
121
|
+
} else if (args.range) {
|
|
122
|
+
p.set("range", args.range);
|
|
123
|
+
}
|
|
124
|
+
const s = p.toString();
|
|
125
|
+
return s ? `?${s}` : "";
|
|
126
|
+
}
|
|
127
|
+
var windowOutputSchema = import_zod.z.object({
|
|
128
|
+
range: import_zod.z.string(),
|
|
129
|
+
start: import_zod.z.string().nullable(),
|
|
130
|
+
end: import_zod.z.string().nullable(),
|
|
131
|
+
timezone: import_zod.z.string(),
|
|
132
|
+
bucketUnit: import_zod.z.string(),
|
|
133
|
+
retentionDays: import_zod.z.number().describe("The plan's effective data retention in days"),
|
|
134
|
+
earliestAvailable: import_zod.z.string().describe("First date retention still holds data for (YYYY-MM-DD)")
|
|
135
|
+
}).optional().describe("The window the server actually used for every count in this response");
|
|
136
|
+
function windowLine(window) {
|
|
137
|
+
if (!window) return "";
|
|
138
|
+
if (window.start && window.end) {
|
|
139
|
+
return `Window: ${window.start.slice(0, 10)} to ${window.end.slice(0, 10)} (${window.timezone}, exclusive end)`;
|
|
140
|
+
}
|
|
141
|
+
return `Window: all retained data (${window.retentionDays}-day retention)`;
|
|
142
|
+
}
|
|
105
143
|
function apiErrorGuidance(err, extra) {
|
|
106
144
|
if (extra && Object.prototype.hasOwnProperty.call(extra, err.message)) {
|
|
107
145
|
return extra[err.message];
|
|
@@ -116,6 +154,12 @@ function apiErrorGuidance(err, extra) {
|
|
|
116
154
|
default:
|
|
117
155
|
break;
|
|
118
156
|
}
|
|
157
|
+
if (err.message === "range_out_of_retention") {
|
|
158
|
+
return "The requested window starts before this plan retains data \u2014 older events have been deleted by the retention purge and cannot be recovered. Ask for a more recent window, or upgrade the SentientUI plan for longer history (Growth keeps 180 days, Scale 365).";
|
|
159
|
+
}
|
|
160
|
+
if (err.message === "invalid_range") {
|
|
161
|
+
return "Invalid time window. Use range '7d', '30d', '90d' or 'all', or from/to as YYYY-MM-DD dates.";
|
|
162
|
+
}
|
|
119
163
|
if (err.status === 402) {
|
|
120
164
|
return `This feature requires a higher plan (${err.message}). Upgrade your SentientUI plan, then try again.`;
|
|
121
165
|
}
|
|
@@ -417,7 +461,11 @@ var RENDER_JS = {
|
|
|
417
461
|
"variant-performance": `
|
|
418
462
|
window.__render = function(data){
|
|
419
463
|
var variants = (data && data.variants) || [];
|
|
420
|
-
|
|
464
|
+
var winText = 'current vs prior period';
|
|
465
|
+
if (data && data.window && data.window.start && data.window.end) {
|
|
466
|
+
winText = String(data.window.start).slice(0, 10) + ' to ' + String(data.window.end).slice(0, 10) + ' vs prior period';
|
|
467
|
+
}
|
|
468
|
+
el('sub').textContent = variants.length + ' variant' + (variants.length === 1 ? '' : 's') + ' \xB7 conversion, ' + winText;
|
|
421
469
|
if (!variants.length) { showEmpty('No variant data available yet.'); return; }
|
|
422
470
|
var max = variants.reduce(function(m,v){ return Math.max(m, v.currentCvr || 0); }, 0) || 1;
|
|
423
471
|
var sorted = variants.slice().sort(function(a,b){ return (b.currentCvr||0) - (a.currentCvr||0); });
|
|
@@ -546,8 +594,8 @@ function registerComponentTools(server, client) {
|
|
|
546
594
|
"list_components",
|
|
547
595
|
{
|
|
548
596
|
title: "List components",
|
|
549
|
-
description: "List all adaptive components in a project with variant counts and impression totals.",
|
|
550
|
-
inputSchema: { projectId: projectIdSchema },
|
|
597
|
+
description: "List all adaptive components in a project with variant counts and impression totals. Counts cover all retained data by default; pass range or from/to for a window.",
|
|
598
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("all")),
|
|
551
599
|
outputSchema: {
|
|
552
600
|
components: import_zod3.z.array(
|
|
553
601
|
import_zod3.z.object({
|
|
@@ -556,7 +604,8 @@ function registerComponentTools(server, client) {
|
|
|
556
604
|
impressions: import_zod3.z.number(),
|
|
557
605
|
conversions: import_zod3.z.number()
|
|
558
606
|
})
|
|
559
|
-
).describe("Adaptive components in the project (empty if none)")
|
|
607
|
+
).describe("Adaptive components in the project (empty if none)"),
|
|
608
|
+
window: windowOutputSchema
|
|
560
609
|
},
|
|
561
610
|
annotations: {
|
|
562
611
|
readOnlyHint: true,
|
|
@@ -564,16 +613,17 @@ function registerComponentTools(server, client) {
|
|
|
564
613
|
openWorldHint: false
|
|
565
614
|
}
|
|
566
615
|
},
|
|
567
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
616
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
568
617
|
const id = encodeURIComponent(projectId);
|
|
569
|
-
const { components } = await client.get(`/projects/${id}/components`);
|
|
618
|
+
const { components, window } = await client.get(`/projects/${id}/components${rangeQuery({ range, from, to })}`);
|
|
570
619
|
const structuredContent = {
|
|
571
620
|
components: components.map((c) => ({
|
|
572
621
|
componentId: c.component_id,
|
|
573
622
|
variantCount: c.variants.length,
|
|
574
623
|
impressions: c.total_impressions,
|
|
575
624
|
conversions: c.total_conversions
|
|
576
|
-
}))
|
|
625
|
+
})),
|
|
626
|
+
window
|
|
577
627
|
};
|
|
578
628
|
if (!components.length) {
|
|
579
629
|
return {
|
|
@@ -591,19 +641,20 @@ function registerComponentTools(server, client) {
|
|
|
591
641
|
"get_variant_performance",
|
|
592
642
|
{
|
|
593
643
|
title: "Variant performance",
|
|
594
|
-
description: "Get CVR and momentum for all variants in a project over the last 7 days vs prior 7
|
|
595
|
-
inputSchema: { projectId: projectIdSchema },
|
|
644
|
+
description: "Get CVR and momentum for all variants in a project over the selected window vs the immediately-preceding window of equal length (default: last 7 calendar days vs prior 7).",
|
|
645
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("7d")),
|
|
596
646
|
_meta: uiMeta("variant-performance"),
|
|
597
647
|
outputSchema: {
|
|
598
648
|
variants: import_zod3.z.array(
|
|
599
649
|
import_zod3.z.object({
|
|
600
650
|
variantId: import_zod3.z.string(),
|
|
601
|
-
currentCvr: import_zod3.z.number().describe("Conversion rate over the
|
|
602
|
-
priorCvr: import_zod3.z.number().describe("Conversion rate over the
|
|
651
|
+
currentCvr: import_zod3.z.number().describe("Conversion rate over the selected window (0-1)"),
|
|
652
|
+
priorCvr: import_zod3.z.number().describe("Conversion rate over the preceding window (0-1)"),
|
|
603
653
|
deltaPp: import_zod3.z.number().describe("Change in percentage points"),
|
|
604
654
|
momentum: import_zod3.z.string().describe("Momentum direction: gaining, losing, or stable")
|
|
605
655
|
})
|
|
606
|
-
).describe("Per-variant performance (empty if no data yet)")
|
|
656
|
+
).describe("Per-variant performance (empty if no data yet)"),
|
|
657
|
+
window: windowOutputSchema
|
|
607
658
|
},
|
|
608
659
|
annotations: {
|
|
609
660
|
readOnlyHint: true,
|
|
@@ -611,10 +662,10 @@ function registerComponentTools(server, client) {
|
|
|
611
662
|
openWorldHint: false
|
|
612
663
|
}
|
|
613
664
|
},
|
|
614
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
665
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
615
666
|
var _a, _b, _c;
|
|
616
667
|
const id = encodeURIComponent(projectId);
|
|
617
|
-
const data = await client.get(`/projects/${id}/trends`);
|
|
668
|
+
const data = await client.get(`/projects/${id}/trends${rangeQuery({ range, from, to })}`);
|
|
618
669
|
const momentumMap = new Map(((_a = data.momentum) != null ? _a : []).map((m) => [m.variantId, m.direction]));
|
|
619
670
|
const structuredContent = {
|
|
620
671
|
variants: ((_b = data.cvr) != null ? _b : []).map((v) => {
|
|
@@ -626,7 +677,8 @@ function registerComponentTools(server, client) {
|
|
|
626
677
|
deltaPp: v.deltaPp,
|
|
627
678
|
momentum: (_a2 = momentumMap.get(v.variantId)) != null ? _a2 : "stable"
|
|
628
679
|
};
|
|
629
|
-
})
|
|
680
|
+
}),
|
|
681
|
+
window: data.window
|
|
630
682
|
};
|
|
631
683
|
if (!((_c = data.cvr) == null ? void 0 : _c.length)) {
|
|
632
684
|
return {
|
|
@@ -635,12 +687,14 @@ function registerComponentTools(server, client) {
|
|
|
635
687
|
_meta: uiMeta("variant-performance")
|
|
636
688
|
};
|
|
637
689
|
}
|
|
638
|
-
const
|
|
690
|
+
const lines = data.cvr.map(
|
|
639
691
|
(v) => {
|
|
640
692
|
var _a2;
|
|
641
693
|
return `- ${v.variantId}: CVR ${(v.currentCvr * 100).toFixed(2)}% (prior ${(v.priorCvr * 100).toFixed(2)}%, ${v.deltaPp > 0 ? "+" : ""}${v.deltaPp.toFixed(1)} pp, ${(_a2 = momentumMap.get(v.variantId)) != null ? _a2 : "stable"})`;
|
|
642
694
|
}
|
|
643
|
-
)
|
|
695
|
+
);
|
|
696
|
+
const win = windowLine(data.window);
|
|
697
|
+
const text = (win ? [win, ...lines] : lines).join("\n");
|
|
644
698
|
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("variant-performance") };
|
|
645
699
|
})
|
|
646
700
|
);
|
|
@@ -826,8 +880,8 @@ function registerGoalTools(server, client) {
|
|
|
826
880
|
"get_goal_funnel",
|
|
827
881
|
{
|
|
828
882
|
title: "Goal funnel",
|
|
829
|
-
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.",
|
|
830
|
-
inputSchema: { projectId: projectIdSchema },
|
|
883
|
+
description: "Get goal hit counts, unique-session conversion rates, and per-variant breakdown (default window: last 30 calendar days). This is a flat per-goal list \u2014 for multi-step funnel drop-off, use get_funnel_report.",
|
|
884
|
+
inputSchema: __spreadValues({ projectId: projectIdSchema }, rangeInputSchema("30d")),
|
|
831
885
|
_meta: uiMeta("goal-funnel"),
|
|
832
886
|
outputSchema: {
|
|
833
887
|
currency: import_zod6.z.string().describe("Project display currency (ISO-4217) for the revenue fields"),
|
|
@@ -848,7 +902,8 @@ function registerGoalTools(server, client) {
|
|
|
848
902
|
})
|
|
849
903
|
).describe("Per-variant breakdown")
|
|
850
904
|
})
|
|
851
|
-
).describe("Configured goals (empty if none)")
|
|
905
|
+
).describe("Configured goals (empty if none)"),
|
|
906
|
+
window: windowOutputSchema
|
|
852
907
|
},
|
|
853
908
|
annotations: {
|
|
854
909
|
readOnlyHint: true,
|
|
@@ -856,11 +911,12 @@ function registerGoalTools(server, client) {
|
|
|
856
911
|
openWorldHint: false
|
|
857
912
|
}
|
|
858
913
|
},
|
|
859
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
914
|
+
withApiErrorGuidance(async ({ projectId, range, from, to }) => {
|
|
860
915
|
var _a, _b;
|
|
861
916
|
const id = encodeURIComponent(projectId);
|
|
862
|
-
const data = await client.get(`/projects/${id}/goals`);
|
|
917
|
+
const data = await client.get(`/projects/${id}/goals${rangeQuery({ range, from, to })}`);
|
|
863
918
|
const structuredContent = {
|
|
919
|
+
window: data.window,
|
|
864
920
|
currency: (_a = data.currency) != null ? _a : "USD",
|
|
865
921
|
goals: data.goals.map((g) => {
|
|
866
922
|
var _a2, _b2, _c;
|
|
@@ -888,6 +944,7 @@ function registerGoalTools(server, client) {
|
|
|
888
944
|
};
|
|
889
945
|
}
|
|
890
946
|
const currency = (_b = data.currency) != null ? _b : "USD";
|
|
947
|
+
const win = windowLine(data.window);
|
|
891
948
|
const lines = data.goals.flatMap((g) => {
|
|
892
949
|
var _a2;
|
|
893
950
|
return [
|
|
@@ -896,7 +953,8 @@ function registerGoalTools(server, client) {
|
|
|
896
953
|
""
|
|
897
954
|
];
|
|
898
955
|
});
|
|
899
|
-
|
|
956
|
+
const text = (win ? [win, "", ...lines] : lines).join("\n").trim();
|
|
957
|
+
return { content: [{ type: "text", text }], structuredContent, _meta: uiMeta("goal-funnel") };
|
|
900
958
|
})
|
|
901
959
|
);
|
|
902
960
|
server.registerTool(
|
|
@@ -1740,8 +1798,12 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1740
1798
|
"get_agent_traffic",
|
|
1741
1799
|
{
|
|
1742
1800
|
title: "Agent traffic",
|
|
1743
|
-
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.",
|
|
1744
|
-
inputSchema: {
|
|
1801
|
+
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. Defaults to the last 30 days; pass from/to for a custom period (agent logs are retained 30 days on Free/Starter, 90 on Growth+). Agent traffic is tracked separately and never counted in conversion rate.",
|
|
1802
|
+
inputSchema: {
|
|
1803
|
+
projectId: projectIdSchema,
|
|
1804
|
+
from: import_zod14.z.string().optional().describe("Period start (ISO 8601 date or timestamp). Defaults to 30 days ago."),
|
|
1805
|
+
to: import_zod14.z.string().optional().describe("Period end (ISO 8601 date or timestamp). Defaults to now.")
|
|
1806
|
+
},
|
|
1745
1807
|
outputSchema: {
|
|
1746
1808
|
totals: import_zod14.z.object({ crawler: import_zod14.z.number(), api: import_zod14.z.number(), browser: import_zod14.z.number() }),
|
|
1747
1809
|
engines: import_zod14.z.array(
|
|
@@ -1759,9 +1821,14 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1759
1821
|
},
|
|
1760
1822
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
1761
1823
|
},
|
|
1762
|
-
withApiErrorGuidance(async ({ projectId }) => {
|
|
1824
|
+
withApiErrorGuidance(async ({ projectId, from, to }) => {
|
|
1763
1825
|
const id = encodeURIComponent(projectId);
|
|
1764
|
-
const
|
|
1826
|
+
const qs = new URLSearchParams();
|
|
1827
|
+
if (from) qs.set("from", from);
|
|
1828
|
+
if (to) qs.set("to", to);
|
|
1829
|
+
const s = await client.get(
|
|
1830
|
+
`/projects/${id}/agent-activity/summary${qs.size > 0 ? `?${qs.toString()}` : ""}`
|
|
1831
|
+
);
|
|
1765
1832
|
const structuredContent = { totals: s.totals, engines: s.engines, intents: s.intents, topPaths: s.topPaths };
|
|
1766
1833
|
const total = s.totals.crawler + s.totals.api + s.totals.browser;
|
|
1767
1834
|
if (total === 0) {
|
|
@@ -1849,7 +1916,7 @@ function registerAgentTrafficTools(server, client) {
|
|
|
1849
1916
|
}
|
|
1850
1917
|
|
|
1851
1918
|
// src/server.ts
|
|
1852
|
-
var PKG_VERSION = true ? "0.
|
|
1919
|
+
var PKG_VERSION = true ? "0.17.0" : "0.0.0-dev";
|
|
1853
1920
|
function createMcpServer(client) {
|
|
1854
1921
|
const server = new import_mcp.McpServer(
|
|
1855
1922
|
{
|
package/dist/lib.js
CHANGED