umami-compass 0.1.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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +300 -0
  3. package/SECURITY.md +32 -0
  4. package/dist/api/client.d.ts +15 -0
  5. package/dist/api/client.d.ts.map +1 -0
  6. package/dist/api/client.js +313 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/errors.d.ts +18 -0
  9. package/dist/api/errors.d.ts.map +1 -0
  10. package/dist/api/errors.js +28 -0
  11. package/dist/api/errors.js.map +1 -0
  12. package/dist/api/types.d.ts +101 -0
  13. package/dist/api/types.d.ts.map +1 -0
  14. package/dist/api/types.js +2 -0
  15. package/dist/api/types.js.map +1 -0
  16. package/dist/cli.d.ts +3 -0
  17. package/dist/cli.d.ts.map +1 -0
  18. package/dist/cli.js +46 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/config.d.ts +25 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +148 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/index.d.ts +9 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +8 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/mcp/modules/core.d.ts +3 -0
  29. package/dist/mcp/modules/core.d.ts.map +1 -0
  30. package/dist/mcp/modules/core.js +132 -0
  31. package/dist/mcp/modules/core.js.map +1 -0
  32. package/dist/mcp/modules/events.d.ts +3 -0
  33. package/dist/mcp/modules/events.d.ts.map +1 -0
  34. package/dist/mcp/modules/events.js +77 -0
  35. package/dist/mcp/modules/events.js.map +1 -0
  36. package/dist/mcp/modules/heatmaps.d.ts +3 -0
  37. package/dist/mcp/modules/heatmaps.d.ts.map +1 -0
  38. package/dist/mcp/modules/heatmaps.js +90 -0
  39. package/dist/mcp/modules/heatmaps.js.map +1 -0
  40. package/dist/mcp/modules/performance.d.ts +3 -0
  41. package/dist/mcp/modules/performance.d.ts.map +1 -0
  42. package/dist/mcp/modules/performance.js +114 -0
  43. package/dist/mcp/modules/performance.js.map +1 -0
  44. package/dist/mcp/modules/replay.d.ts +3 -0
  45. package/dist/mcp/modules/replay.d.ts.map +1 -0
  46. package/dist/mcp/modules/replay.js +41 -0
  47. package/dist/mcp/modules/replay.js.map +1 -0
  48. package/dist/mcp/modules/reports.d.ts +3 -0
  49. package/dist/mcp/modules/reports.d.ts.map +1 -0
  50. package/dist/mcp/modules/reports.js +301 -0
  51. package/dist/mcp/modules/reports.js.map +1 -0
  52. package/dist/mcp/modules/revenue.d.ts +3 -0
  53. package/dist/mcp/modules/revenue.d.ts.map +1 -0
  54. package/dist/mcp/modules/revenue.js +57 -0
  55. package/dist/mcp/modules/revenue.js.map +1 -0
  56. package/dist/mcp/modules/sessions.d.ts +3 -0
  57. package/dist/mcp/modules/sessions.d.ts.map +1 -0
  58. package/dist/mcp/modules/sessions.js +75 -0
  59. package/dist/mcp/modules/sessions.js.map +1 -0
  60. package/dist/mcp/report-utils.d.ts +15 -0
  61. package/dist/mcp/report-utils.d.ts.map +1 -0
  62. package/dist/mcp/report-utils.js +58 -0
  63. package/dist/mcp/report-utils.js.map +1 -0
  64. package/dist/mcp/result.d.ts +27 -0
  65. package/dist/mcp/result.d.ts.map +1 -0
  66. package/dist/mcp/result.js +42 -0
  67. package/dist/mcp/result.js.map +1 -0
  68. package/dist/mcp/schemas.d.ts +120 -0
  69. package/dist/mcp/schemas.d.ts.map +1 -0
  70. package/dist/mcp/schemas.js +148 -0
  71. package/dist/mcp/schemas.js.map +1 -0
  72. package/dist/mcp/tool-module.d.ts +19 -0
  73. package/dist/mcp/tool-module.d.ts.map +1 -0
  74. package/dist/mcp/tool-module.js +7 -0
  75. package/dist/mcp/tool-module.js.map +1 -0
  76. package/dist/server.d.ts +13 -0
  77. package/dist/server.d.ts.map +1 -0
  78. package/dist/server.js +100 -0
  79. package/dist/server.js.map +1 -0
  80. package/dist/time.d.ts +6 -0
  81. package/dist/time.d.ts.map +1 -0
  82. package/dist/time.js +51 -0
  83. package/dist/time.js.map +1 -0
  84. package/dist/version.d.ts +2 -0
  85. package/dist/version.d.ts.map +1 -0
  86. package/dist/version.js +2 -0
  87. package/dist/version.js.map +1 -0
  88. package/package.json +78 -0
  89. package/server.json +80 -0
@@ -0,0 +1,313 @@
1
+ import { VERSION } from "../version.js";
2
+ import { UmamiError } from "./errors.js";
3
+ function isRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function appendQuery(url, query) {
7
+ if (!query)
8
+ return;
9
+ for (const [key, value] of Object.entries(query)) {
10
+ if (value === undefined)
11
+ continue;
12
+ const values = Array.isArray(value) ? value : [value];
13
+ for (const item of values)
14
+ url.searchParams.append(key, String(item));
15
+ }
16
+ }
17
+ function resolveApiPath(baseUrl, path) {
18
+ if (!path || path.includes("\\") || path.includes("?") || path.includes("#")) {
19
+ throw new UmamiError("CONFIGURATION_ERROR", "The Umami API path is invalid.");
20
+ }
21
+ const url = new URL(path, baseUrl);
22
+ if (url.origin !== baseUrl.origin || !url.pathname.startsWith(baseUrl.pathname)) {
23
+ throw new UmamiError("CONFIGURATION_ERROR", "The Umami API path escaped its fixed origin.");
24
+ }
25
+ return url;
26
+ }
27
+ function requireWebsitePage(value) {
28
+ if (!isRecord(value) ||
29
+ !Array.isArray(value.data) ||
30
+ typeof value.count !== "number" ||
31
+ typeof value.page !== "number" ||
32
+ typeof value.pageSize !== "number") {
33
+ throw new UmamiError("INVALID_RESPONSE", "Umami returned an invalid website list.");
34
+ }
35
+ return value;
36
+ }
37
+ function requireWebsite(value) {
38
+ if (!isRecord(value) || typeof value.id !== "string") {
39
+ throw new UmamiError("INVALID_RESPONSE", "Umami returned invalid website metadata.");
40
+ }
41
+ return value;
42
+ }
43
+ async function readJsonResponse(response, maxBytes, invalidMessage) {
44
+ const declaredLength = Number(response.headers.get("content-length"));
45
+ if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
46
+ await response.body?.cancel().catch(() => undefined);
47
+ throw new UmamiError("INVALID_RESPONSE", `Umami response exceeded the configured ${maxBytes}-byte limit.`);
48
+ }
49
+ if (!response.body) {
50
+ throw new UmamiError("INVALID_RESPONSE", invalidMessage);
51
+ }
52
+ const reader = response.body.getReader();
53
+ const chunks = [];
54
+ let totalBytes = 0;
55
+ while (true) {
56
+ const { done, value } = await reader.read();
57
+ if (done)
58
+ break;
59
+ totalBytes += value.byteLength;
60
+ if (totalBytes > maxBytes) {
61
+ await reader.cancel().catch(() => undefined);
62
+ throw new UmamiError("INVALID_RESPONSE", `Umami response exceeded the configured ${maxBytes}-byte limit.`);
63
+ }
64
+ chunks.push(value);
65
+ }
66
+ const bytes = new Uint8Array(totalBytes);
67
+ let offset = 0;
68
+ for (const chunk of chunks) {
69
+ bytes.set(chunk, offset);
70
+ offset += chunk.byteLength;
71
+ }
72
+ try {
73
+ return JSON.parse(new TextDecoder().decode(bytes));
74
+ }
75
+ catch (error) {
76
+ throw new UmamiError("INVALID_RESPONSE", invalidMessage, { cause: error });
77
+ }
78
+ }
79
+ function waitForSignal(promise, signal) {
80
+ if (!signal)
81
+ return promise;
82
+ if (signal.aborted) {
83
+ return Promise.reject(new UmamiError("ABORTED", "The Umami request was cancelled."));
84
+ }
85
+ return new Promise((resolve, reject) => {
86
+ const onAbort = () => {
87
+ reject(new UmamiError("ABORTED", "The Umami request was cancelled."));
88
+ };
89
+ signal.addEventListener("abort", onAbort, { once: true });
90
+ promise.then((value) => {
91
+ signal.removeEventListener("abort", onAbort);
92
+ resolve(value);
93
+ }, (error) => {
94
+ signal.removeEventListener("abort", onAbort);
95
+ reject(error);
96
+ });
97
+ });
98
+ }
99
+ function statusError(status) {
100
+ if (status === 401) {
101
+ return new UmamiError("AUTHENTICATION_FAILED", "Umami rejected the configured credentials.", {
102
+ status,
103
+ });
104
+ }
105
+ if (status === 403) {
106
+ return new UmamiError("FORBIDDEN", "Umami denied access to this resource.", { status });
107
+ }
108
+ if (status === 404) {
109
+ return new UmamiError("NOT_FOUND", "The requested Umami resource was not found.", { status });
110
+ }
111
+ if (status === 429) {
112
+ return new UmamiError("RATE_LIMITED", "Umami rate-limited the request. Try again later.", {
113
+ retryable: true,
114
+ status,
115
+ });
116
+ }
117
+ return new UmamiError("UPSTREAM_ERROR", status >= 500 ? "Umami is temporarily unavailable." : "Umami rejected the analytics request.", { retryable: status >= 500, status });
118
+ }
119
+ export class UmamiClient {
120
+ #config;
121
+ #fetch;
122
+ #loginGeneration = 0;
123
+ #loginPromise;
124
+ #loginToken;
125
+ constructor(config, fetchImplementation = globalThis.fetch) {
126
+ this.#config = config;
127
+ this.#fetch = fetchImplementation;
128
+ }
129
+ isWebsiteAllowed(websiteId) {
130
+ return !this.#config.websiteIds || this.#config.websiteIds.has(websiteId.toLowerCase());
131
+ }
132
+ assertWebsiteAllowed(websiteId) {
133
+ if (!this.isWebsiteAllowed(websiteId)) {
134
+ throw new UmamiError("FORBIDDEN", "This website is outside the configured UMAMI_WEBSITE_IDS allowlist.");
135
+ }
136
+ }
137
+ async listWebsites(query, signal) {
138
+ if (!this.#config.websiteIds) {
139
+ return requireWebsitePage(await this.get("websites", query, signal));
140
+ }
141
+ const requestedPage = typeof query.page === "number" ? query.page : 1;
142
+ const requestedPageSize = typeof query.pageSize === "number" ? query.pageSize : 20;
143
+ const upstreamQuery = { ...query, page: 1, pageSize: 100 };
144
+ const firstPage = requireWebsitePage(await this.get("websites", upstreamQuery, signal));
145
+ const pageCount = Math.ceil(firstPage.count / 100);
146
+ if (pageCount > 25) {
147
+ throw new UmamiError("VALIDATION_ERROR", "The account has too many websites to apply the local allowlist safely. Use a more limited Umami identity or a search filter.");
148
+ }
149
+ const websites = [...firstPage.data];
150
+ for (let page = 2; page <= pageCount; page += 1) {
151
+ const nextPage = requireWebsitePage(await this.get("websites", { ...upstreamQuery, page }, signal));
152
+ websites.push(...nextPage.data);
153
+ }
154
+ const visible = websites.filter((website) => typeof website.id === "string" && this.#config.websiteIds?.has(website.id.toLowerCase()));
155
+ const start = (requestedPage - 1) * requestedPageSize;
156
+ return {
157
+ data: visible.slice(start, start + requestedPageSize),
158
+ count: visible.length,
159
+ page: requestedPage,
160
+ pageSize: requestedPageSize,
161
+ };
162
+ }
163
+ async getWebsite(websiteId, signal) {
164
+ const normalizedWebsiteId = websiteId.toLowerCase();
165
+ this.assertWebsiteAllowed(normalizedWebsiteId);
166
+ return requireWebsite(await this.get(`websites/${encodeURIComponent(normalizedWebsiteId)}`, undefined, signal));
167
+ }
168
+ async get(path, query, signal) {
169
+ return this.#request(path, { method: "GET", query, signal }, true);
170
+ }
171
+ async getHeatmapReport(request, signal) {
172
+ return this.runReport(request, signal);
173
+ }
174
+ async runReport(request, signal) {
175
+ const allowedTypes = new Set([
176
+ "attribution",
177
+ "breakdown",
178
+ "funnel",
179
+ "goal",
180
+ "heatmap",
181
+ "journey",
182
+ "performance",
183
+ "retention",
184
+ "utm",
185
+ ]);
186
+ if (!allowedTypes.has(request.type)) {
187
+ throw new UmamiError("CONFIGURATION_ERROR", "Unsupported read-only Umami report type.");
188
+ }
189
+ this.assertWebsiteAllowed(request.websiteId);
190
+ return this.#request(`reports/${request.type}`, { body: request, method: "POST", signal }, true);
191
+ }
192
+ async #request(path, options, retryLogin) {
193
+ const url = resolveApiPath(this.#config.apiUrl, path);
194
+ appendQuery(url, options.query);
195
+ const timeoutSignal = AbortSignal.timeout(this.#config.requestTimeoutMs);
196
+ const signal = options.signal
197
+ ? AbortSignal.any([options.signal, timeoutSignal])
198
+ : timeoutSignal;
199
+ let response;
200
+ let loginGeneration;
201
+ try {
202
+ const requestHeaders = await this.#headers(options.signal);
203
+ const { headers } = requestHeaders;
204
+ loginGeneration = requestHeaders.loginGeneration;
205
+ if (options.body !== undefined)
206
+ headers.set("Content-Type", "application/json");
207
+ response = await this.#fetch(url, {
208
+ body: options.body === undefined ? undefined : JSON.stringify(options.body),
209
+ headers,
210
+ method: options.method ?? "GET",
211
+ redirect: "error",
212
+ signal,
213
+ });
214
+ }
215
+ catch (error) {
216
+ if (signal.aborted) {
217
+ throw new UmamiError("ABORTED", "The Umami request was cancelled or timed out.", {
218
+ cause: error,
219
+ retryable: !options.signal?.aborted,
220
+ });
221
+ }
222
+ throw new UmamiError("UPSTREAM_ERROR", "Could not connect to the configured Umami API.", {
223
+ cause: error,
224
+ retryable: true,
225
+ });
226
+ }
227
+ if (response.status === 401 && this.#config.auth.type === "login" && retryLogin) {
228
+ if (this.#loginToken?.generation === loginGeneration)
229
+ this.#loginToken = undefined;
230
+ return this.#request(path, options, false);
231
+ }
232
+ if (!response.ok)
233
+ throw statusError(response.status);
234
+ if (response.status === 204)
235
+ return undefined;
236
+ return (await readJsonResponse(response, this.#config.maxResponseBytes, "Umami returned an invalid JSON response."));
237
+ }
238
+ async #headers(signal) {
239
+ const headers = new Headers({
240
+ Accept: "application/json",
241
+ "User-Agent": `umami-compass/${VERSION}`,
242
+ });
243
+ if (this.#config.auth.type === "apiKey") {
244
+ headers.set("x-umami-api-key", this.#config.auth.apiKey);
245
+ }
246
+ else if (this.#config.auth.type === "accessToken") {
247
+ headers.set("Authorization", `Bearer ${this.#config.auth.accessToken}`);
248
+ }
249
+ else {
250
+ const credential = await this.#login(signal);
251
+ headers.set("Authorization", `Bearer ${credential.token}`);
252
+ return { headers, loginGeneration: credential.generation };
253
+ }
254
+ return { headers };
255
+ }
256
+ async #login(signal) {
257
+ if (this.#loginToken)
258
+ return this.#loginToken;
259
+ if (!this.#loginPromise) {
260
+ this.#loginGeneration += 1;
261
+ const generation = this.#loginGeneration;
262
+ const loginPromise = this.#performLogin().then((token) => ({ generation, token }));
263
+ this.#loginPromise = loginPromise;
264
+ void loginPromise.then((credential) => {
265
+ this.#loginToken = credential;
266
+ if (this.#loginPromise === loginPromise)
267
+ this.#loginPromise = undefined;
268
+ }, () => {
269
+ if (this.#loginPromise === loginPromise)
270
+ this.#loginPromise = undefined;
271
+ });
272
+ }
273
+ return waitForSignal(this.#loginPromise, signal);
274
+ }
275
+ async #performLogin() {
276
+ if (this.#config.auth.type !== "login") {
277
+ throw new UmamiError("CONFIGURATION_ERROR", "Login auth is not configured.");
278
+ }
279
+ const url = resolveApiPath(this.#config.apiUrl, "auth/login");
280
+ const timeoutSignal = AbortSignal.timeout(this.#config.requestTimeoutMs);
281
+ let response;
282
+ try {
283
+ response = await this.#fetch(url, {
284
+ body: JSON.stringify({
285
+ username: this.#config.auth.username,
286
+ password: this.#config.auth.password,
287
+ }),
288
+ headers: {
289
+ Accept: "application/json",
290
+ "Content-Type": "application/json",
291
+ "User-Agent": `umami-compass/${VERSION}`,
292
+ },
293
+ method: "POST",
294
+ redirect: "error",
295
+ signal: timeoutSignal,
296
+ });
297
+ }
298
+ catch (error) {
299
+ throw new UmamiError("AUTHENTICATION_FAILED", "Could not authenticate with Umami.", {
300
+ cause: error,
301
+ retryable: true,
302
+ });
303
+ }
304
+ if (!response.ok)
305
+ throw statusError(response.status);
306
+ const result = await readJsonResponse(response, this.#config.maxResponseBytes, "Umami returned an invalid login response.");
307
+ if (!isRecord(result) || typeof result.token !== "string" || !result.token) {
308
+ throw new UmamiError("INVALID_RESPONSE", "Umami did not return an access token.");
309
+ }
310
+ return result.token;
311
+ }
312
+ }
313
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export type UmamiErrorCode = "ABORTED" | "AUTHENTICATION_FAILED" | "CONFIGURATION_ERROR" | "FORBIDDEN" | "INVALID_RESPONSE" | "NOT_FOUND" | "RATE_LIMITED" | "UPSTREAM_ERROR" | "VALIDATION_ERROR";
2
+ export declare class UmamiError extends Error {
3
+ readonly code: UmamiErrorCode;
4
+ readonly retryable: boolean;
5
+ readonly status?: number;
6
+ constructor(code: UmamiErrorCode, message: string, options?: {
7
+ cause?: unknown;
8
+ retryable?: boolean;
9
+ status?: number;
10
+ });
11
+ }
12
+ export declare function toSafeError(error: unknown): {
13
+ code: UmamiErrorCode;
14
+ message: string;
15
+ retryable: boolean;
16
+ status?: number;
17
+ };
18
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,uBAAuB,GACvB,qBAAqB,GACrB,WAAW,GACX,kBAAkB,GAClB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAGvB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;CAQ1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG;IAC3C,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAeA"}
@@ -0,0 +1,28 @@
1
+ export class UmamiError extends Error {
2
+ code;
3
+ retryable;
4
+ status;
5
+ constructor(code, message, options = {}) {
6
+ super(message, { cause: options.cause });
7
+ this.name = "UmamiError";
8
+ this.code = code;
9
+ this.retryable = options.retryable ?? false;
10
+ this.status = options.status;
11
+ }
12
+ }
13
+ export function toSafeError(error) {
14
+ if (error instanceof UmamiError) {
15
+ return {
16
+ code: error.code,
17
+ message: error.message,
18
+ retryable: error.retryable,
19
+ ...(error.status === undefined ? {} : { status: error.status }),
20
+ };
21
+ }
22
+ return {
23
+ code: "UPSTREAM_ERROR",
24
+ message: "The Umami request failed unexpectedly.",
25
+ retryable: false,
26
+ };
27
+ }
28
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IACrB,SAAS,CAAU;IACnB,MAAM,CAAU;IAEzB,YACE,IAAoB,EACpB,OAAe,EACf,UAAqE,EAAE;QAEvE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IAMxC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;SAChE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,wCAAwC;QACjD,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,101 @@
1
+ export type QueryPrimitive = boolean | number | string;
2
+ export type QueryValue = QueryPrimitive | readonly QueryPrimitive[] | undefined;
3
+ export type Query = Readonly<Record<string, QueryValue>>;
4
+ export interface PagedResponse<T = unknown> {
5
+ count: number;
6
+ data: T[];
7
+ page: number;
8
+ pageSize: number;
9
+ }
10
+ export interface Website {
11
+ createdAt?: string;
12
+ deletedAt?: string | null;
13
+ domain?: string;
14
+ id: string;
15
+ name?: string;
16
+ resetAt?: string | null;
17
+ teamId?: string | null;
18
+ updatedAt?: string;
19
+ userId?: string | null;
20
+ [key: string]: unknown;
21
+ }
22
+ export interface LoginResponse {
23
+ token: string;
24
+ [key: string]: unknown;
25
+ }
26
+ interface ReportRequest<TType extends string, TParameters> {
27
+ filters: Record<string, unknown>;
28
+ parameters: TParameters;
29
+ type: TType;
30
+ websiteId: string;
31
+ }
32
+ export type HeatmapReportRequest = ReportRequest<"heatmap", {
33
+ endDate: string;
34
+ mode: "click" | "scroll";
35
+ startDate: string;
36
+ urlPath?: string;
37
+ }>;
38
+ export type PerformanceMetric = "cls" | "fcp" | "inp" | "lcp" | "ttfb";
39
+ export type PerformanceReportRequest = ReportRequest<"performance", {
40
+ endDate: string;
41
+ metric?: PerformanceMetric;
42
+ startDate: string;
43
+ timezone?: string;
44
+ unit?: "day" | "hour" | "minute" | "month" | "year";
45
+ }>;
46
+ export type GoalReportRequest = ReportRequest<"goal", {
47
+ endDate: string;
48
+ startDate: string;
49
+ type: string;
50
+ value: string;
51
+ }>;
52
+ export interface FunnelStepFilter {
53
+ operator: "c" | "dnc" | "eq" | "neq";
54
+ property: string;
55
+ value: string;
56
+ }
57
+ export interface FunnelStep {
58
+ filters?: FunnelStepFilter[];
59
+ type: "event" | "path";
60
+ value: string;
61
+ }
62
+ export type FunnelReportRequest = ReportRequest<"funnel", {
63
+ endDate: string;
64
+ startDate: string;
65
+ steps: FunnelStep[];
66
+ window: number;
67
+ }>;
68
+ export type JourneyReportRequest = ReportRequest<"journey", {
69
+ endDate: string;
70
+ endStep?: string;
71
+ eventType?: number;
72
+ startDate: string;
73
+ startStep?: string;
74
+ steps: number;
75
+ }>;
76
+ export type RetentionReportRequest = ReportRequest<"retention", {
77
+ endDate: string;
78
+ startDate: string;
79
+ timezone?: string;
80
+ }>;
81
+ export type UtmReportRequest = ReportRequest<"utm", {
82
+ endDate: string;
83
+ startDate: string;
84
+ }>;
85
+ export type AttributionReportRequest = ReportRequest<"attribution", {
86
+ currency?: string;
87
+ endDate: string;
88
+ model: "first-click" | "last-click";
89
+ startDate: string;
90
+ step: string;
91
+ type: "event" | "path";
92
+ }>;
93
+ export type BreakdownField = "browser" | "city" | "country" | "device" | "distinctId" | "event" | "hostname" | "language" | "os" | "path" | "query" | "referrer" | "region" | "tag" | "title" | "utmCampaign" | "utmContent" | "utmMedium" | "utmSource" | "utmTerm";
94
+ export type BreakdownReportRequest = ReportRequest<"breakdown", {
95
+ endDate: string;
96
+ fields: BreakdownField[];
97
+ startDate: string;
98
+ }>;
99
+ export type ReadOnlyReportRequest = AttributionReportRequest | BreakdownReportRequest | FunnelReportRequest | GoalReportRequest | HeatmapReportRequest | JourneyReportRequest | PerformanceReportRequest | RetentionReportRequest | UtmReportRequest;
100
+ export {};
101
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":""}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { toSafeError, UmamiError } from "./api/errors.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { createServer } from "./server.js";
6
+ import { VERSION } from "./version.js";
7
+ const HELP = `Umami Compass ${VERSION}
8
+
9
+ A secure MCP server for Umami Analytics Cloud and self-hosted deployments.
10
+
11
+ Usage:
12
+ umami-compass
13
+ umami-compass --help
14
+ umami-compass --version
15
+
16
+ The server uses stdio. Configure it through environment variables; see .env.example
17
+ and https://github.com/webcredo/umami-compass#configuration.
18
+ `;
19
+ async function main() {
20
+ const argument = process.argv[2];
21
+ if (argument === "--help" || argument === "-h") {
22
+ process.stdout.write(HELP);
23
+ return;
24
+ }
25
+ if (argument === "--version" || argument === "-v") {
26
+ process.stdout.write(`${VERSION}\n`);
27
+ return;
28
+ }
29
+ if (process.argv.length > 2) {
30
+ throw new UmamiError("CONFIGURATION_ERROR", "Umami Compass does not accept positional arguments. Use --help for usage.");
31
+ }
32
+ const server = createServer({ config: loadConfig() });
33
+ const transport = new StdioServerTransport();
34
+ const shutdown = async () => {
35
+ await server.close();
36
+ };
37
+ process.once("SIGINT", shutdown);
38
+ process.once("SIGTERM", shutdown);
39
+ await server.connect(transport);
40
+ }
41
+ main().catch((error) => {
42
+ const safeError = toSafeError(error);
43
+ console.error(`[umami-compass] ${safeError.message}`);
44
+ process.exitCode = 1;
45
+ });
46
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG,iBAAiB,OAAO;;;;;;;;;;;CAWpC,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAClB,qBAAqB,EACrB,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAClC,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,mBAAmB,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ export declare const TOOLSETS: readonly ["core", "events", "sessions", "performance", "reports", "revenue", "replay", "heatmaps"];
2
+ export type Toolset = (typeof TOOLSETS)[number];
3
+ export type UmamiAuth = {
4
+ type: "apiKey";
5
+ apiKey: string;
6
+ } | {
7
+ type: "accessToken";
8
+ accessToken: string;
9
+ } | {
10
+ type: "login";
11
+ username: string;
12
+ password: string;
13
+ };
14
+ export interface UmamiCompassConfig {
15
+ apiUrl: URL;
16
+ auth: UmamiAuth;
17
+ allowInsecureHttp: boolean;
18
+ maxRangeDays: number;
19
+ maxResponseBytes: number;
20
+ requestTimeoutMs: number;
21
+ toolsets: ReadonlySet<Toolset>;
22
+ websiteIds?: ReadonlySet<string>;
23
+ }
24
+ export declare function loadConfig(env?: NodeJS.ProcessEnv): UmamiCompassConfig;
25
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,oGASX,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,GAAG,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAClC;AA8JD,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,kBAAkB,CAgCnF"}