umami-compass 0.1.2 → 0.2.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/README.md +18 -9
- package/SECURITY.md +2 -2
- package/dist/api/client.d.ts +1 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +114 -22
- package/dist/api/client.js.map +1 -1
- package/dist/api/types.d.ts +5 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -6
- package/dist/config.js.map +1 -1
- package/dist/mcp/insights-utils.d.ts +162 -0
- package/dist/mcp/insights-utils.d.ts.map +1 -0
- package/dist/mcp/insights-utils.js +377 -0
- package/dist/mcp/insights-utils.js.map +1 -0
- package/dist/mcp/modules/core.d.ts.map +1 -1
- package/dist/mcp/modules/core.js +7 -7
- package/dist/mcp/modules/core.js.map +1 -1
- package/dist/mcp/modules/events.d.ts.map +1 -1
- package/dist/mcp/modules/events.js +3 -3
- package/dist/mcp/modules/events.js.map +1 -1
- package/dist/mcp/modules/heatmaps.d.ts.map +1 -1
- package/dist/mcp/modules/heatmaps.js +3 -2
- package/dist/mcp/modules/heatmaps.js.map +1 -1
- package/dist/mcp/modules/insights.d.ts +3 -0
- package/dist/mcp/modules/insights.d.ts.map +1 -0
- package/dist/mcp/modules/insights.js +754 -0
- package/dist/mcp/modules/insights.js.map +1 -0
- package/dist/mcp/modules/performance.d.ts.map +1 -1
- package/dist/mcp/modules/performance.js +5 -3
- package/dist/mcp/modules/performance.js.map +1 -1
- package/dist/mcp/modules/replay.d.ts.map +1 -1
- package/dist/mcp/modules/replay.js +3 -2
- package/dist/mcp/modules/replay.js.map +1 -1
- package/dist/mcp/modules/reports.d.ts.map +1 -1
- package/dist/mcp/modules/reports.js +11 -11
- package/dist/mcp/modules/reports.js.map +1 -1
- package/dist/mcp/modules/revenue.d.ts.map +1 -1
- package/dist/mcp/modules/revenue.js +2 -2
- package/dist/mcp/modules/revenue.js.map +1 -1
- package/dist/mcp/modules/sessions.d.ts.map +1 -1
- package/dist/mcp/modules/sessions.js +4 -4
- package/dist/mcp/modules/sessions.js.map +1 -1
- package/dist/mcp/result.d.ts +13 -1
- package/dist/mcp/result.d.ts.map +1 -1
- package/dist/mcp/result.js +88 -2
- package/dist/mcp/result.js.map +1 -1
- package/dist/mcp/schemas.d.ts +122 -0
- package/dist/mcp/schemas.d.ts.map +1 -1
- package/dist/mcp/schemas.js +24 -0
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +165 -31
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/server.json +9 -4
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { UmamiClient } from "../api/client.js";
|
|
3
|
+
import type { Website } from "../api/types.js";
|
|
4
|
+
import type { TimeInput } from "../time.js";
|
|
5
|
+
import { type filtersSchema } from "./schemas.js";
|
|
6
|
+
export declare const TRAFFIC_DIMENSIONS: readonly ["path", "referrer", "country", "device", "channel", "event"];
|
|
7
|
+
export type TrafficDimension = (typeof TRAFFIC_DIMENSIONS)[number];
|
|
8
|
+
export interface TimePeriod {
|
|
9
|
+
endAt: number;
|
|
10
|
+
startAt: number;
|
|
11
|
+
}
|
|
12
|
+
export interface WebsiteTotals {
|
|
13
|
+
bounces: number;
|
|
14
|
+
pageviews: number;
|
|
15
|
+
totaltime: number;
|
|
16
|
+
visitors: number;
|
|
17
|
+
visits: number;
|
|
18
|
+
}
|
|
19
|
+
export interface WebsiteStats extends WebsiteTotals {
|
|
20
|
+
comparison?: WebsiteTotals;
|
|
21
|
+
}
|
|
22
|
+
type Filters = z.infer<typeof filtersSchema> | undefined;
|
|
23
|
+
export declare function finiteNumber(value: unknown): number | undefined;
|
|
24
|
+
export declare function parseWebsiteStats(value: unknown): WebsiteStats;
|
|
25
|
+
export declare function percentChange(current: number, comparison: number): number | null;
|
|
26
|
+
export declare function totalsChanges(current: WebsiteTotals, comparison: WebsiteTotals): {
|
|
27
|
+
[k: string]: {
|
|
28
|
+
absolute: number;
|
|
29
|
+
percent: number | null;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare function isoPeriod(period: TimePeriod): {
|
|
33
|
+
start: string;
|
|
34
|
+
end: string;
|
|
35
|
+
};
|
|
36
|
+
export declare function normalizePeriod(start: TimeInput, end: TimeInput, maxRangeDays: number): TimePeriod;
|
|
37
|
+
export declare function comparisonPeriod(current: TimePeriod, mode: "previous" | "year_over_year"): TimePeriod;
|
|
38
|
+
export declare function mapConcurrent<T, R>(values: readonly T[], concurrency: number, operation: (value: T, index: number) => Promise<R>): Promise<R[]>;
|
|
39
|
+
export declare function fetchWebsiteStats(client: UmamiClient, websiteId: string, period: TimePeriod, maxRangeDays: number, filters: Filters, signal?: AbortSignal): Promise<WebsiteStats>;
|
|
40
|
+
export interface TrafficComparisonInput {
|
|
41
|
+
comparison: TimePeriod;
|
|
42
|
+
current: TimePeriod;
|
|
43
|
+
dimensions: readonly TrafficDimension[];
|
|
44
|
+
filters?: Filters;
|
|
45
|
+
limit: number;
|
|
46
|
+
maxRangeDays: number;
|
|
47
|
+
signal?: AbortSignal;
|
|
48
|
+
website: Pick<Website, "domain" | "id" | "name">;
|
|
49
|
+
}
|
|
50
|
+
export declare function compareTraffic(client: UmamiClient, input: TrafficComparisonInput): Promise<{
|
|
51
|
+
dataStatus: "available" | "empty";
|
|
52
|
+
website: Pick<Website, "domain" | "id" | "name">;
|
|
53
|
+
currentPeriod: {
|
|
54
|
+
start: string;
|
|
55
|
+
end: string;
|
|
56
|
+
};
|
|
57
|
+
comparisonPeriod: {
|
|
58
|
+
start: string;
|
|
59
|
+
end: string;
|
|
60
|
+
};
|
|
61
|
+
current: WebsiteTotals;
|
|
62
|
+
comparison: WebsiteTotals;
|
|
63
|
+
changes: {
|
|
64
|
+
[k: string]: {
|
|
65
|
+
absolute: number;
|
|
66
|
+
percent: number | null;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
direction: string;
|
|
70
|
+
explanation: string;
|
|
71
|
+
breakdownMeasure: string;
|
|
72
|
+
breakdowns: ({
|
|
73
|
+
dimension: "channel" | "country" | "device" | "event" | "path" | "referrer";
|
|
74
|
+
status: "available";
|
|
75
|
+
measure: "visitors";
|
|
76
|
+
rows: {
|
|
77
|
+
name: string;
|
|
78
|
+
current: number;
|
|
79
|
+
comparison: number;
|
|
80
|
+
delta: number;
|
|
81
|
+
percent: number | null;
|
|
82
|
+
direction: string;
|
|
83
|
+
}[];
|
|
84
|
+
dataQuality: {
|
|
85
|
+
currentRowsTruncated: boolean;
|
|
86
|
+
comparisonRowsTruncated: boolean;
|
|
87
|
+
omittedUncertainRows: number;
|
|
88
|
+
};
|
|
89
|
+
error?: undefined;
|
|
90
|
+
} | {
|
|
91
|
+
measure?: undefined;
|
|
92
|
+
rows?: undefined;
|
|
93
|
+
dataQuality?: undefined;
|
|
94
|
+
dimension: "channel" | "country" | "device" | "event" | "path" | "referrer";
|
|
95
|
+
status: "unavailable";
|
|
96
|
+
error: {
|
|
97
|
+
code: import("../api/errors.js").UmamiErrorCode;
|
|
98
|
+
message: string;
|
|
99
|
+
retryable: boolean;
|
|
100
|
+
status?: number;
|
|
101
|
+
};
|
|
102
|
+
})[];
|
|
103
|
+
leadingObservedChanges: {
|
|
104
|
+
name: string;
|
|
105
|
+
current: number;
|
|
106
|
+
comparison: number;
|
|
107
|
+
delta: number;
|
|
108
|
+
percent: number | null;
|
|
109
|
+
direction: string;
|
|
110
|
+
dimension: "channel" | "country" | "device" | "event" | "path" | "referrer";
|
|
111
|
+
}[];
|
|
112
|
+
dataQuality: {
|
|
113
|
+
comparisonBaselineZero: boolean;
|
|
114
|
+
currentPageviews: number;
|
|
115
|
+
comparisonPageviews: number;
|
|
116
|
+
unavailableDimensions: ("channel" | "country" | "device" | "event" | "path" | "referrer")[];
|
|
117
|
+
truncatedDimensions: ("channel" | "country" | "device" | "event" | "path" | "referrer")[];
|
|
118
|
+
omittedUncertainRows: number;
|
|
119
|
+
};
|
|
120
|
+
}>;
|
|
121
|
+
export declare function comparePerformance(client: UmamiClient, input: {
|
|
122
|
+
comparison: TimePeriod;
|
|
123
|
+
current: TimePeriod;
|
|
124
|
+
filters?: Filters;
|
|
125
|
+
signal?: AbortSignal;
|
|
126
|
+
timezone: string;
|
|
127
|
+
websiteId: string;
|
|
128
|
+
}): Promise<{
|
|
129
|
+
error?: undefined;
|
|
130
|
+
status: "available" | "empty";
|
|
131
|
+
currentSampleCount: number;
|
|
132
|
+
comparisonSampleCount: number;
|
|
133
|
+
minimumSampleCount: number;
|
|
134
|
+
sampleSufficient: boolean;
|
|
135
|
+
changes: {
|
|
136
|
+
[k: string]: {
|
|
137
|
+
currentP75: number;
|
|
138
|
+
comparisonP75: number;
|
|
139
|
+
absolute: number;
|
|
140
|
+
percent: number | null;
|
|
141
|
+
impact: string;
|
|
142
|
+
material: boolean;
|
|
143
|
+
currentRating: "good" | "needs_improvement" | "poor";
|
|
144
|
+
comparisonRating: "good" | "needs_improvement" | "poor";
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
} | {
|
|
148
|
+
currentSampleCount?: undefined;
|
|
149
|
+
comparisonSampleCount?: undefined;
|
|
150
|
+
minimumSampleCount?: undefined;
|
|
151
|
+
sampleSufficient?: undefined;
|
|
152
|
+
changes?: undefined;
|
|
153
|
+
status: string;
|
|
154
|
+
error: {
|
|
155
|
+
code: import("../api/errors.js").UmamiErrorCode;
|
|
156
|
+
message: string;
|
|
157
|
+
retryable: boolean;
|
|
158
|
+
status?: number;
|
|
159
|
+
};
|
|
160
|
+
}>;
|
|
161
|
+
export {};
|
|
162
|
+
//# sourceMappingURL=insights-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-utils.d.ts","sourceRoot":"","sources":["../../src/mcp/insights-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { toSafeError, UmamiError } from "../api/errors.js";
|
|
2
|
+
import { parseTimeRange } from "../time.js";
|
|
3
|
+
import { reportFilters } from "./report-utils.js";
|
|
4
|
+
import { rangeQuery } from "./schemas.js";
|
|
5
|
+
export const TRAFFIC_DIMENSIONS = [
|
|
6
|
+
"path",
|
|
7
|
+
"referrer",
|
|
8
|
+
"country",
|
|
9
|
+
"device",
|
|
10
|
+
"channel",
|
|
11
|
+
"event",
|
|
12
|
+
];
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
export function finiteNumber(value) {
|
|
17
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
18
|
+
return value;
|
|
19
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
20
|
+
return undefined;
|
|
21
|
+
const parsed = Number(value);
|
|
22
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
23
|
+
}
|
|
24
|
+
function requireNumber(record, key) {
|
|
25
|
+
const value = finiteNumber(record[key]);
|
|
26
|
+
if (value === undefined) {
|
|
27
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid website statistics.");
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
function parseTotals(value) {
|
|
32
|
+
if (!isRecord(value)) {
|
|
33
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid website statistics.");
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
pageviews: requireNumber(value, "pageviews"),
|
|
37
|
+
visitors: requireNumber(value, "visitors"),
|
|
38
|
+
visits: requireNumber(value, "visits"),
|
|
39
|
+
bounces: requireNumber(value, "bounces"),
|
|
40
|
+
totaltime: requireNumber(value, "totaltime"),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function parseWebsiteStats(value) {
|
|
44
|
+
const totals = parseTotals(value);
|
|
45
|
+
const comparison = isRecord(value) && value.comparison !== undefined ? parseTotals(value.comparison) : undefined;
|
|
46
|
+
return { ...totals, ...(comparison ? { comparison } : {}) };
|
|
47
|
+
}
|
|
48
|
+
export function percentChange(current, comparison) {
|
|
49
|
+
if (comparison === 0)
|
|
50
|
+
return current === 0 ? 0 : null;
|
|
51
|
+
return Math.round(((current - comparison) / Math.abs(comparison)) * 10_000) / 100;
|
|
52
|
+
}
|
|
53
|
+
export function totalsChanges(current, comparison) {
|
|
54
|
+
return Object.fromEntries(Object.keys(current).map((key) => [
|
|
55
|
+
key,
|
|
56
|
+
{
|
|
57
|
+
absolute: current[key] - comparison[key],
|
|
58
|
+
percent: percentChange(current[key], comparison[key]),
|
|
59
|
+
},
|
|
60
|
+
]));
|
|
61
|
+
}
|
|
62
|
+
function websiteTotals(stats) {
|
|
63
|
+
return {
|
|
64
|
+
pageviews: stats.pageviews,
|
|
65
|
+
visitors: stats.visitors,
|
|
66
|
+
visits: stats.visits,
|
|
67
|
+
bounces: stats.bounces,
|
|
68
|
+
totaltime: stats.totaltime,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function isoPeriod(period) {
|
|
72
|
+
return {
|
|
73
|
+
start: new Date(period.startAt).toISOString(),
|
|
74
|
+
end: new Date(period.endAt).toISOString(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function normalizePeriod(start, end, maxRangeDays) {
|
|
78
|
+
return parseTimeRange(start, end, maxRangeDays);
|
|
79
|
+
}
|
|
80
|
+
function shiftUtcYear(timestamp, years) {
|
|
81
|
+
const source = new Date(timestamp);
|
|
82
|
+
const year = source.getUTCFullYear() + years;
|
|
83
|
+
const month = source.getUTCMonth();
|
|
84
|
+
const day = source.getUTCDate();
|
|
85
|
+
const lastDay = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
86
|
+
return Date.UTC(year, month, Math.min(day, lastDay), source.getUTCHours(), source.getUTCMinutes(), source.getUTCSeconds(), source.getUTCMilliseconds());
|
|
87
|
+
}
|
|
88
|
+
export function comparisonPeriod(current, mode) {
|
|
89
|
+
if (mode === "year_over_year") {
|
|
90
|
+
return {
|
|
91
|
+
startAt: shiftUtcYear(current.startAt, -1),
|
|
92
|
+
endAt: shiftUtcYear(current.endAt, -1),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const duration = current.endAt - current.startAt;
|
|
96
|
+
const endAt = current.startAt - 1;
|
|
97
|
+
return { startAt: endAt - duration, endAt };
|
|
98
|
+
}
|
|
99
|
+
export async function mapConcurrent(values, concurrency, operation) {
|
|
100
|
+
const results = new Array(values.length);
|
|
101
|
+
let nextIndex = 0;
|
|
102
|
+
const workers = Array.from({ length: Math.min(concurrency, values.length) }, async () => {
|
|
103
|
+
while (nextIndex < values.length) {
|
|
104
|
+
const index = nextIndex;
|
|
105
|
+
nextIndex += 1;
|
|
106
|
+
results[index] = await operation(values[index], index);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
await Promise.all(workers);
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
export async function fetchWebsiteStats(client, websiteId, period, maxRangeDays, filters, signal) {
|
|
113
|
+
return parseWebsiteStats(await client.get(`websites/${encodeURIComponent(websiteId)}/stats`, rangeQuery(period.startAt, period.endAt, maxRangeDays, {
|
|
114
|
+
filters,
|
|
115
|
+
}), signal));
|
|
116
|
+
}
|
|
117
|
+
const MAX_METRIC_COMPARISON_ROWS = 100;
|
|
118
|
+
function parseMetricRows(value) {
|
|
119
|
+
if (!Array.isArray(value)) {
|
|
120
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid metric breakdown data.");
|
|
121
|
+
}
|
|
122
|
+
const rows = [];
|
|
123
|
+
for (const item of value) {
|
|
124
|
+
if (!isRecord(item))
|
|
125
|
+
continue;
|
|
126
|
+
const number = finiteNumber(item.y);
|
|
127
|
+
if (typeof item.x !== "string" || number === undefined)
|
|
128
|
+
continue;
|
|
129
|
+
rows.push({ name: item.x, value: number });
|
|
130
|
+
}
|
|
131
|
+
return rows;
|
|
132
|
+
}
|
|
133
|
+
async function fetchMetricRows(client, websiteId, period, maxRangeDays, dimension, limit, filters, signal) {
|
|
134
|
+
const rows = parseMetricRows(await client.get(`websites/${encodeURIComponent(websiteId)}/metrics`, {
|
|
135
|
+
...rangeQuery(period.startAt, period.endAt, maxRangeDays, {
|
|
136
|
+
filters,
|
|
137
|
+
}),
|
|
138
|
+
type: dimension,
|
|
139
|
+
limit,
|
|
140
|
+
offset: 0,
|
|
141
|
+
}, signal));
|
|
142
|
+
return { rows, truncated: rows.length >= limit };
|
|
143
|
+
}
|
|
144
|
+
function diffMetricRows(currentResult, comparisonResult, limit) {
|
|
145
|
+
const { rows: current, truncated: currentTruncated } = currentResult;
|
|
146
|
+
const { rows: comparison, truncated: comparisonTruncated } = comparisonResult;
|
|
147
|
+
const names = new Set([
|
|
148
|
+
...current.map(({ name }) => name),
|
|
149
|
+
...comparison.map(({ name }) => name),
|
|
150
|
+
]);
|
|
151
|
+
const currentMap = new Map(current.map(({ name, value }) => [name, value]));
|
|
152
|
+
const comparisonMap = new Map(comparison.map(({ name, value }) => [name, value]));
|
|
153
|
+
let omittedUncertainRows = 0;
|
|
154
|
+
const rows = [...names]
|
|
155
|
+
.flatMap((name) => {
|
|
156
|
+
if ((!currentMap.has(name) && currentTruncated) ||
|
|
157
|
+
(!comparisonMap.has(name) && comparisonTruncated)) {
|
|
158
|
+
omittedUncertainRows += 1;
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
const currentValue = currentMap.get(name) ?? 0;
|
|
162
|
+
const comparisonValue = comparisonMap.get(name) ?? 0;
|
|
163
|
+
const delta = currentValue - comparisonValue;
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
name,
|
|
167
|
+
current: currentValue,
|
|
168
|
+
comparison: comparisonValue,
|
|
169
|
+
delta,
|
|
170
|
+
percent: percentChange(currentValue, comparisonValue),
|
|
171
|
+
direction: delta > 0 ? "up" : delta < 0 ? "down" : "flat",
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
})
|
|
175
|
+
.sort((left, right) => Math.abs(right.delta) - Math.abs(left.delta) || left.name.localeCompare(right.name))
|
|
176
|
+
.slice(0, limit);
|
|
177
|
+
return {
|
|
178
|
+
rows,
|
|
179
|
+
dataQuality: {
|
|
180
|
+
currentRowsTruncated: currentTruncated,
|
|
181
|
+
comparisonRowsTruncated: comparisonTruncated,
|
|
182
|
+
omittedUncertainRows,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export async function compareTraffic(client, input) {
|
|
187
|
+
const { comparison, current, dimensions, filters, limit, maxRangeDays, signal, website } = input;
|
|
188
|
+
const [currentStats, comparisonStats] = await Promise.all([
|
|
189
|
+
fetchWebsiteStats(client, website.id, current, maxRangeDays, filters, signal),
|
|
190
|
+
fetchWebsiteStats(client, website.id, comparison, maxRangeDays, filters, signal),
|
|
191
|
+
]);
|
|
192
|
+
const currentTotals = websiteTotals(currentStats);
|
|
193
|
+
const comparisonTotals = websiteTotals(comparisonStats);
|
|
194
|
+
const metricFetchLimit = Math.min(MAX_METRIC_COMPARISON_ROWS, Math.max(limit * 5, 20));
|
|
195
|
+
const breakdowns = await mapConcurrent(dimensions, 3, async (dimension) => {
|
|
196
|
+
try {
|
|
197
|
+
const [currentRows, comparisonRows] = await Promise.all([
|
|
198
|
+
fetchMetricRows(client, website.id, current, maxRangeDays, dimension, metricFetchLimit, filters, signal),
|
|
199
|
+
fetchMetricRows(client, website.id, comparison, maxRangeDays, dimension, metricFetchLimit, filters, signal),
|
|
200
|
+
]);
|
|
201
|
+
const difference = diffMetricRows(currentRows, comparisonRows, limit);
|
|
202
|
+
return {
|
|
203
|
+
dimension,
|
|
204
|
+
status: "available",
|
|
205
|
+
measure: "visitors",
|
|
206
|
+
rows: difference.rows,
|
|
207
|
+
dataQuality: difference.dataQuality,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
return {
|
|
212
|
+
dimension,
|
|
213
|
+
status: "unavailable",
|
|
214
|
+
error: toSafeError(error),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
const leadingObservedChanges = breakdowns
|
|
219
|
+
.filter((item) => item.status === "available")
|
|
220
|
+
.flatMap((item) => item.rows.slice(0, 1).map((row) => ({
|
|
221
|
+
dimension: item.dimension,
|
|
222
|
+
...row,
|
|
223
|
+
})))
|
|
224
|
+
.sort((left, right) => Math.abs(right.delta) - Math.abs(left.delta))
|
|
225
|
+
.slice(0, 5);
|
|
226
|
+
const pageviewDelta = currentTotals.pageviews - comparisonTotals.pageviews;
|
|
227
|
+
const pageviewPercent = percentChange(currentTotals.pageviews, comparisonTotals.pageviews);
|
|
228
|
+
const direction = pageviewDelta > 0 ? "increase" : pageviewDelta < 0 ? "decrease" : "flat";
|
|
229
|
+
const leading = leadingObservedChanges[0];
|
|
230
|
+
const explanation = leading
|
|
231
|
+
? `Traffic shows a ${direction}${pageviewPercent === null ? "" : ` of ${Math.abs(pageviewPercent)}%`}. The largest observed breakdown change is ${leading.dimension}=${leading.name} (${leading.delta > 0 ? "+" : ""}${leading.delta} visitors); this is evidence of association, not proof of causation.`
|
|
232
|
+
: `Traffic shows a ${direction}${pageviewPercent === null ? "" : ` of ${Math.abs(pageviewPercent)}%`}. No authorized breakdown produced enough evidence to identify a leading observed change.`;
|
|
233
|
+
return {
|
|
234
|
+
dataStatus: currentTotals.pageviews === 0 &&
|
|
235
|
+
currentTotals.visitors === 0 &&
|
|
236
|
+
currentTotals.visits === 0 &&
|
|
237
|
+
comparisonTotals.pageviews === 0 &&
|
|
238
|
+
comparisonTotals.visitors === 0 &&
|
|
239
|
+
comparisonTotals.visits === 0
|
|
240
|
+
? "empty"
|
|
241
|
+
: "available",
|
|
242
|
+
website,
|
|
243
|
+
currentPeriod: isoPeriod(current),
|
|
244
|
+
comparisonPeriod: isoPeriod(comparison),
|
|
245
|
+
current: currentTotals,
|
|
246
|
+
comparison: comparisonTotals,
|
|
247
|
+
changes: totalsChanges(currentTotals, comparisonTotals),
|
|
248
|
+
direction,
|
|
249
|
+
explanation,
|
|
250
|
+
breakdownMeasure: "visitors",
|
|
251
|
+
breakdowns,
|
|
252
|
+
leadingObservedChanges,
|
|
253
|
+
dataQuality: {
|
|
254
|
+
comparisonBaselineZero: comparisonTotals.pageviews === 0,
|
|
255
|
+
currentPageviews: currentTotals.pageviews,
|
|
256
|
+
comparisonPageviews: comparisonTotals.pageviews,
|
|
257
|
+
unavailableDimensions: breakdowns
|
|
258
|
+
.filter((item) => item.status === "unavailable")
|
|
259
|
+
.map(({ dimension }) => dimension),
|
|
260
|
+
truncatedDimensions: breakdowns
|
|
261
|
+
.filter((item) => item.status === "available" &&
|
|
262
|
+
(item.dataQuality.currentRowsTruncated || item.dataQuality.comparisonRowsTruncated))
|
|
263
|
+
.map(({ dimension }) => dimension),
|
|
264
|
+
omittedUncertainRows: breakdowns
|
|
265
|
+
.filter((item) => item.status === "available")
|
|
266
|
+
.reduce((total, item) => total + item.dataQuality.omittedUncertainRows, 0),
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const WEB_VITAL_THRESHOLDS = {
|
|
271
|
+
lcp: [2_500, 4_000],
|
|
272
|
+
inp: [200, 500],
|
|
273
|
+
cls: [0.1, 0.25],
|
|
274
|
+
fcp: [1_800, 3_000],
|
|
275
|
+
ttfb: [800, 1_800],
|
|
276
|
+
};
|
|
277
|
+
const MIN_PERFORMANCE_SAMPLES = 100;
|
|
278
|
+
const MIN_PERFORMANCE_CHANGE_PERCENT = 5;
|
|
279
|
+
const MIN_PERFORMANCE_ABSOLUTE_CHANGE = {
|
|
280
|
+
lcp: 100,
|
|
281
|
+
inp: 20,
|
|
282
|
+
cls: 0.02,
|
|
283
|
+
fcp: 100,
|
|
284
|
+
ttfb: 50,
|
|
285
|
+
};
|
|
286
|
+
function vitalRating(metric, value) {
|
|
287
|
+
const [good, poor] = WEB_VITAL_THRESHOLDS[metric];
|
|
288
|
+
return value <= good ? "good" : value <= poor ? "needs_improvement" : "poor";
|
|
289
|
+
}
|
|
290
|
+
function performanceSummary(value) {
|
|
291
|
+
if (!isRecord(value) || !isRecord(value.summary)) {
|
|
292
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid performance summary data.");
|
|
293
|
+
}
|
|
294
|
+
const summary = value.summary;
|
|
295
|
+
const count = finiteNumber(summary.count);
|
|
296
|
+
if (count === undefined) {
|
|
297
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid performance summary data.");
|
|
298
|
+
}
|
|
299
|
+
const metrics = Object.fromEntries(Object.keys(WEB_VITAL_THRESHOLDS).map((metric) => {
|
|
300
|
+
const row = summary[metric];
|
|
301
|
+
const p75 = isRecord(row) ? finiteNumber(row.p75) : undefined;
|
|
302
|
+
if (p75 === undefined) {
|
|
303
|
+
throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid performance summary data.");
|
|
304
|
+
}
|
|
305
|
+
return [metric, { p75, rating: vitalRating(metric, p75) }];
|
|
306
|
+
}));
|
|
307
|
+
return { count, metrics };
|
|
308
|
+
}
|
|
309
|
+
export async function comparePerformance(client, input) {
|
|
310
|
+
const request = (period) => ({
|
|
311
|
+
websiteId: input.websiteId,
|
|
312
|
+
type: "performance",
|
|
313
|
+
parameters: {
|
|
314
|
+
startDate: new Date(period.startAt).toISOString(),
|
|
315
|
+
endDate: new Date(period.endAt).toISOString(),
|
|
316
|
+
metric: "lcp",
|
|
317
|
+
timezone: input.timezone,
|
|
318
|
+
unit: "day",
|
|
319
|
+
},
|
|
320
|
+
filters: reportFilters(input.filters),
|
|
321
|
+
});
|
|
322
|
+
try {
|
|
323
|
+
const [currentResult, comparisonResult] = await Promise.all([
|
|
324
|
+
client.runReport(request(input.current), input.signal),
|
|
325
|
+
client.runReport(request(input.comparison), input.signal),
|
|
326
|
+
]);
|
|
327
|
+
const current = performanceSummary(currentResult);
|
|
328
|
+
const comparison = performanceSummary(comparisonResult);
|
|
329
|
+
const sampleSufficient = current.count >= MIN_PERFORMANCE_SAMPLES && comparison.count >= MIN_PERFORMANCE_SAMPLES;
|
|
330
|
+
const changes = Object.fromEntries(Object.keys(WEB_VITAL_THRESHOLDS).map((metric) => {
|
|
331
|
+
const currentP75 = current.metrics[metric].p75;
|
|
332
|
+
const comparisonP75 = comparison.metrics[metric].p75;
|
|
333
|
+
const absolute = currentP75 - comparisonP75;
|
|
334
|
+
const percent = percentChange(currentP75, comparisonP75);
|
|
335
|
+
const ratingOrder = { good: 0, needs_improvement: 1, poor: 2 };
|
|
336
|
+
const currentRating = current.metrics[metric].rating;
|
|
337
|
+
const comparisonRating = comparison.metrics[metric].rating;
|
|
338
|
+
const ratingDelta = ratingOrder[currentRating] - ratingOrder[comparisonRating];
|
|
339
|
+
const materiallyChanged = Math.abs(absolute) >= MIN_PERFORMANCE_ABSOLUTE_CHANGE[metric] &&
|
|
340
|
+
percent !== null &&
|
|
341
|
+
Math.abs(percent) >= MIN_PERFORMANCE_CHANGE_PERCENT;
|
|
342
|
+
const impact = !sampleSufficient
|
|
343
|
+
? "inconclusive"
|
|
344
|
+
: ratingDelta > 0 || (absolute > 0 && materiallyChanged)
|
|
345
|
+
? "regressed"
|
|
346
|
+
: ratingDelta < 0 || (absolute < 0 && materiallyChanged)
|
|
347
|
+
? "improved"
|
|
348
|
+
: "unchanged";
|
|
349
|
+
return [
|
|
350
|
+
metric,
|
|
351
|
+
{
|
|
352
|
+
currentP75,
|
|
353
|
+
comparisonP75,
|
|
354
|
+
absolute,
|
|
355
|
+
percent,
|
|
356
|
+
impact,
|
|
357
|
+
material: impact === "regressed" || impact === "improved",
|
|
358
|
+
currentRating,
|
|
359
|
+
comparisonRating,
|
|
360
|
+
},
|
|
361
|
+
];
|
|
362
|
+
}));
|
|
363
|
+
const status = current.count === 0 && comparison.count === 0 ? "empty" : "available";
|
|
364
|
+
return {
|
|
365
|
+
status,
|
|
366
|
+
currentSampleCount: current.count,
|
|
367
|
+
comparisonSampleCount: comparison.count,
|
|
368
|
+
minimumSampleCount: MIN_PERFORMANCE_SAMPLES,
|
|
369
|
+
sampleSufficient,
|
|
370
|
+
changes,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
return { status: "unavailable", error: toSafeError(error) };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=insights-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-utils.js","sourceRoot":"","sources":["../../src/mcp/insights-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/mcp/modules/core.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAyBpD,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/mcp/modules/core.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAyBpD,eAAO,MAAM,UAAU,EAAE,UA6LxB,CAAC"}
|
package/dist/mcp/modules/core.js
CHANGED
|
@@ -29,7 +29,7 @@ export const coreModule = {
|
|
|
29
29
|
register(server, { client, config }) {
|
|
30
30
|
server.registerTool("list_websites", {
|
|
31
31
|
title: "List Umami websites",
|
|
32
|
-
description: "List websites visible
|
|
32
|
+
description: "List websites visible directly or through any team membership of the configured Umami identity. If UMAMI_WEBSITE_IDS is set, returns only that exact allowlist.",
|
|
33
33
|
inputSchema: {
|
|
34
34
|
page: pageSchema,
|
|
35
35
|
pageSize: pageSizeSchema,
|
|
@@ -44,7 +44,7 @@ export const coreModule = {
|
|
|
44
44
|
inputSchema: { websiteId: uuidSchema },
|
|
45
45
|
outputSchema: recordOutputSchema,
|
|
46
46
|
annotations: READ_ONLY_ANNOTATIONS,
|
|
47
|
-
}, ({ websiteId }, extra) => runTool(() => client.getWebsite(websiteId, extra.signal)));
|
|
47
|
+
}, ({ websiteId }, extra) => runTool(() => client.getWebsite(websiteId, extra.signal), { websiteId }));
|
|
48
48
|
server.registerTool("get_website_stats", {
|
|
49
49
|
title: "Get website statistics",
|
|
50
50
|
description: "Get visits, visitors, pageviews, bounces, visit duration and Umami's comparison values for a time range.",
|
|
@@ -59,7 +59,7 @@ export const coreModule = {
|
|
|
59
59
|
}, ({ websiteId, start, end, filters }, extra) => runTool(() => {
|
|
60
60
|
client.assertWebsiteAllowed(websiteId);
|
|
61
61
|
return client.get(`websites/${encodeURIComponent(websiteId)}/stats`, rangeQuery(start, end, config.maxRangeDays, { filters }), extra.signal);
|
|
62
|
-
}));
|
|
62
|
+
}, { websiteId, range: { start, end } }));
|
|
63
63
|
server.registerTool("get_pageviews", {
|
|
64
64
|
title: "Get pageview and session series",
|
|
65
65
|
description: "Get Umami 3.2 pageview and session time series. Both arrays are preserved in the response.",
|
|
@@ -81,7 +81,7 @@ export const coreModule = {
|
|
|
81
81
|
unit,
|
|
82
82
|
seriesCount: 2,
|
|
83
83
|
}), extra.signal), "pageview series");
|
|
84
|
-
}));
|
|
84
|
+
}, { websiteId, range: { start, end }, timezone }));
|
|
85
85
|
server.registerTool("get_metrics", {
|
|
86
86
|
title: "Break down website metrics",
|
|
87
87
|
description: "Get a ranked aggregate Umami metric breakdown such as paths, referrers, countries, devices, events, channels or URLs. Visitor identifiers are excluded from the core toolset.",
|
|
@@ -106,7 +106,7 @@ export const coreModule = {
|
|
|
106
106
|
offset,
|
|
107
107
|
search,
|
|
108
108
|
}, extra.signal);
|
|
109
|
-
}));
|
|
109
|
+
}, { websiteId, range: { start, end } }));
|
|
110
110
|
server.registerTool("get_active_visitors", {
|
|
111
111
|
title: "Get active visitors",
|
|
112
112
|
description: "Get the current number of active visitors for a website.",
|
|
@@ -116,7 +116,7 @@ export const coreModule = {
|
|
|
116
116
|
}, ({ websiteId }, extra) => runTool(() => {
|
|
117
117
|
client.assertWebsiteAllowed(websiteId);
|
|
118
118
|
return client.get(`websites/${encodeURIComponent(websiteId)}/active`, undefined, extra.signal);
|
|
119
|
-
}));
|
|
119
|
+
}, { websiteId }));
|
|
120
120
|
server.registerTool("get_website_date_range", {
|
|
121
121
|
title: "Get website data range",
|
|
122
122
|
description: "Get the earliest and latest analytics timestamps available for a website.",
|
|
@@ -126,7 +126,7 @@ export const coreModule = {
|
|
|
126
126
|
}, ({ websiteId }, extra) => runTool(() => {
|
|
127
127
|
client.assertWebsiteAllowed(websiteId);
|
|
128
128
|
return client.get(`websites/${encodeURIComponent(websiteId)}/daterange`, undefined, extra.signal);
|
|
129
|
-
}));
|
|
129
|
+
}, { websiteId }));
|
|
130
130
|
},
|
|
131
131
|
};
|
|
132
132
|
//# sourceMappingURL=core.js.map
|