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.
- package/LICENSE +21 -0
- package/README.md +300 -0
- package/SECURITY.md +32 -0
- package/dist/api/client.d.ts +15 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +313 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/errors.d.ts +18 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +28 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/types.d.ts +101 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +46 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +148 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/modules/core.d.ts +3 -0
- package/dist/mcp/modules/core.d.ts.map +1 -0
- package/dist/mcp/modules/core.js +132 -0
- package/dist/mcp/modules/core.js.map +1 -0
- package/dist/mcp/modules/events.d.ts +3 -0
- package/dist/mcp/modules/events.d.ts.map +1 -0
- package/dist/mcp/modules/events.js +77 -0
- package/dist/mcp/modules/events.js.map +1 -0
- package/dist/mcp/modules/heatmaps.d.ts +3 -0
- package/dist/mcp/modules/heatmaps.d.ts.map +1 -0
- package/dist/mcp/modules/heatmaps.js +90 -0
- package/dist/mcp/modules/heatmaps.js.map +1 -0
- package/dist/mcp/modules/performance.d.ts +3 -0
- package/dist/mcp/modules/performance.d.ts.map +1 -0
- package/dist/mcp/modules/performance.js +114 -0
- package/dist/mcp/modules/performance.js.map +1 -0
- package/dist/mcp/modules/replay.d.ts +3 -0
- package/dist/mcp/modules/replay.d.ts.map +1 -0
- package/dist/mcp/modules/replay.js +41 -0
- package/dist/mcp/modules/replay.js.map +1 -0
- package/dist/mcp/modules/reports.d.ts +3 -0
- package/dist/mcp/modules/reports.d.ts.map +1 -0
- package/dist/mcp/modules/reports.js +301 -0
- package/dist/mcp/modules/reports.js.map +1 -0
- package/dist/mcp/modules/revenue.d.ts +3 -0
- package/dist/mcp/modules/revenue.d.ts.map +1 -0
- package/dist/mcp/modules/revenue.js +57 -0
- package/dist/mcp/modules/revenue.js.map +1 -0
- package/dist/mcp/modules/sessions.d.ts +3 -0
- package/dist/mcp/modules/sessions.d.ts.map +1 -0
- package/dist/mcp/modules/sessions.js +75 -0
- package/dist/mcp/modules/sessions.js.map +1 -0
- package/dist/mcp/report-utils.d.ts +15 -0
- package/dist/mcp/report-utils.d.ts.map +1 -0
- package/dist/mcp/report-utils.js +58 -0
- package/dist/mcp/report-utils.js.map +1 -0
- package/dist/mcp/result.d.ts +27 -0
- package/dist/mcp/result.d.ts.map +1 -0
- package/dist/mcp/result.js +42 -0
- package/dist/mcp/result.js.map +1 -0
- package/dist/mcp/schemas.d.ts +120 -0
- package/dist/mcp/schemas.d.ts.map +1 -0
- package/dist/mcp/schemas.js +148 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/tool-module.d.ts +19 -0
- package/dist/mcp/tool-module.d.ts.map +1 -0
- package/dist/mcp/tool-module.js +7 -0
- package/dist/mcp/tool-module.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +100 -0
- package/dist/server.js.map +1 -0
- package/dist/time.d.ts +6 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +51 -0
- package/dist/time.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +78 -0
- package/server.json +80 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { UmamiClient } from "./api/client.js";
|
|
4
|
+
import { toSafeError } from "./api/errors.js";
|
|
5
|
+
import { coreModule } from "./mcp/modules/core.js";
|
|
6
|
+
import { eventsModule } from "./mcp/modules/events.js";
|
|
7
|
+
import { heatmapsModule } from "./mcp/modules/heatmaps.js";
|
|
8
|
+
import { performanceModule } from "./mcp/modules/performance.js";
|
|
9
|
+
import { replayModule } from "./mcp/modules/replay.js";
|
|
10
|
+
import { reportsModule } from "./mcp/modules/reports.js";
|
|
11
|
+
import { revenueModule } from "./mcp/modules/revenue.js";
|
|
12
|
+
import { sessionsModule } from "./mcp/modules/sessions.js";
|
|
13
|
+
import { assertModuleAllowed, READ_ONLY_POLICY, } from "./mcp/tool-module.js";
|
|
14
|
+
import { VERSION } from "./version.js";
|
|
15
|
+
export const BUILTIN_MODULES = [
|
|
16
|
+
coreModule,
|
|
17
|
+
eventsModule,
|
|
18
|
+
sessionsModule,
|
|
19
|
+
performanceModule,
|
|
20
|
+
reportsModule,
|
|
21
|
+
revenueModule,
|
|
22
|
+
replayModule,
|
|
23
|
+
heatmapsModule,
|
|
24
|
+
];
|
|
25
|
+
export function createServer(options) {
|
|
26
|
+
const server = new McpServer({
|
|
27
|
+
name: "umami-compass",
|
|
28
|
+
title: "Umami Compass",
|
|
29
|
+
version: VERSION,
|
|
30
|
+
websiteUrl: "https://github.com/webcredo/umami-compass",
|
|
31
|
+
}, {
|
|
32
|
+
instructions: "Secure, read-only Umami Analytics access. Start with list_websites, use bounded time ranges, and request only the dimensions needed for the analysis. Performance, saved reports, session, revenue, heatmap and replay data may require separate Umami permissions. Minimize sensitive data entering model context. No tool in this release changes Umami state.",
|
|
33
|
+
});
|
|
34
|
+
const client = new UmamiClient(options.config, options.fetch);
|
|
35
|
+
const policy = options.accessPolicy ?? READ_ONLY_POLICY;
|
|
36
|
+
const modules = options.modules ?? BUILTIN_MODULES;
|
|
37
|
+
for (const module of modules) {
|
|
38
|
+
if (!options.config.toolsets.has(module.id))
|
|
39
|
+
continue;
|
|
40
|
+
assertModuleAllowed(module, policy);
|
|
41
|
+
module.register(server, { client, config: options.config });
|
|
42
|
+
}
|
|
43
|
+
server.registerResource("websites", "umami://websites", {
|
|
44
|
+
title: "Visible Umami websites",
|
|
45
|
+
description: "Websites visible under the configured identity and optional allowlist.",
|
|
46
|
+
mimeType: "application/json",
|
|
47
|
+
}, async (uri, extra) => {
|
|
48
|
+
try {
|
|
49
|
+
const websites = await client.listWebsites({ page: 1, pageSize: 100 }, extra.signal);
|
|
50
|
+
return {
|
|
51
|
+
contents: [
|
|
52
|
+
{
|
|
53
|
+
uri: uri.href,
|
|
54
|
+
mimeType: "application/json",
|
|
55
|
+
text: JSON.stringify(websites),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(toSafeError(error).message);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
server.registerPrompt("analytics_report", {
|
|
65
|
+
title: "Analyze an Umami website",
|
|
66
|
+
description: "A safe workflow for producing an evidence-based analytics report.",
|
|
67
|
+
argsSchema: {
|
|
68
|
+
websiteId: z
|
|
69
|
+
.string()
|
|
70
|
+
.uuid()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe("Optional Umami website UUID; list websites first if omitted."),
|
|
73
|
+
objective: z
|
|
74
|
+
.string()
|
|
75
|
+
.max(2_000)
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("The decision or question the report should support."),
|
|
78
|
+
},
|
|
79
|
+
}, ({ websiteId, objective }) => ({
|
|
80
|
+
messages: [
|
|
81
|
+
{
|
|
82
|
+
role: "user",
|
|
83
|
+
content: {
|
|
84
|
+
type: "text",
|
|
85
|
+
text: [
|
|
86
|
+
`Analyze ${websiteId ? `website ${websiteId}` : "the relevant Umami website"}.`,
|
|
87
|
+
objective
|
|
88
|
+
? `Objective: ${objective}.`
|
|
89
|
+
: "Clarify the reporting objective before querying.",
|
|
90
|
+
"Confirm an explicit time range and timezone.",
|
|
91
|
+
"Use aggregate stats and pageviews first, then only the smallest necessary metric, event, or session breakdown.",
|
|
92
|
+
"State the queried period, filters, evidence, uncertainty, and recommended next actions.",
|
|
93
|
+
].join(" "),
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
}));
|
|
98
|
+
return server;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/time.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAgDxC,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,SAAS,EACd,YAAY,EAAE,MAAM,GACnB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAapC"}
|
package/dist/time.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { UmamiError } from "./api/errors.js";
|
|
2
|
+
const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
|
|
3
|
+
const HAS_TIMEZONE = /(Z|[+-]\d{2}:?\d{2})$/i;
|
|
4
|
+
function assertCalendarDate(value) {
|
|
5
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})(?:T|$)/.exec(value);
|
|
6
|
+
if (!match)
|
|
7
|
+
return;
|
|
8
|
+
const [, yearText, monthText, dayText] = match;
|
|
9
|
+
const year = Number(yearText);
|
|
10
|
+
const month = Number(monthText);
|
|
11
|
+
const day = Number(dayText);
|
|
12
|
+
const date = new Date(Date.UTC(year, month - 1, day));
|
|
13
|
+
if (date.getUTCFullYear() !== year ||
|
|
14
|
+
date.getUTCMonth() !== month - 1 ||
|
|
15
|
+
date.getUTCDate() !== day) {
|
|
16
|
+
throw new UmamiError("VALIDATION_ERROR", "The supplied date or timestamp is invalid.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function parseTimestamp(value, edge) {
|
|
20
|
+
if (typeof value === "number") {
|
|
21
|
+
if (!Number.isSafeInteger(value) || value < 0 || !Number.isFinite(new Date(value).getTime())) {
|
|
22
|
+
throw new UmamiError("VALIDATION_ERROR", "Timestamps must be positive integer milliseconds.");
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
const trimmed = value.trim();
|
|
27
|
+
assertCalendarDate(trimmed);
|
|
28
|
+
const normalized = DATE_ONLY.test(trimmed)
|
|
29
|
+
? `${trimmed}T${edge === "start" ? "00:00:00.000" : "23:59:59.999"}Z`
|
|
30
|
+
: trimmed;
|
|
31
|
+
if (!DATE_ONLY.test(trimmed) && !HAS_TIMEZONE.test(trimmed)) {
|
|
32
|
+
throw new UmamiError("VALIDATION_ERROR", "Date-times must include Z or an explicit UTC offset; date-only values are interpreted in UTC.");
|
|
33
|
+
}
|
|
34
|
+
const timestamp = Date.parse(normalized);
|
|
35
|
+
if (!Number.isFinite(timestamp)) {
|
|
36
|
+
throw new UmamiError("VALIDATION_ERROR", "The supplied date or timestamp is invalid.");
|
|
37
|
+
}
|
|
38
|
+
return timestamp;
|
|
39
|
+
}
|
|
40
|
+
export function parseTimeRange(start, end, maxRangeDays) {
|
|
41
|
+
const startAt = parseTimestamp(start, "start");
|
|
42
|
+
const endAt = parseTimestamp(end, "end");
|
|
43
|
+
if (startAt > endAt) {
|
|
44
|
+
throw new UmamiError("VALIDATION_ERROR", "start must be earlier than or equal to end.");
|
|
45
|
+
}
|
|
46
|
+
if (endAt - startAt > maxRangeDays * 86_400_000) {
|
|
47
|
+
throw new UmamiError("VALIDATION_ERROR", `The requested range exceeds the configured maximum of ${maxRangeDays} days.`);
|
|
48
|
+
}
|
|
49
|
+
return { startAt, endAt };
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=time.js.map
|
package/dist/time.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "umami-compass",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A secure, read-only MCP server for Umami Analytics 3.2+ — Cloud and self-hosted",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "webcredo",
|
|
7
|
+
"homepage": "https://github.com/webcredo/umami-compass#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/webcredo/umami-compass/issues"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/webcredo/umami-compass.git"
|
|
14
|
+
},
|
|
15
|
+
"mcpName": "io.github.webcredo/umami-compass",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"bin": {
|
|
19
|
+
"umami-compass": "./dist/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md",
|
|
32
|
+
"LICENSE",
|
|
33
|
+
"SECURITY.md",
|
|
34
|
+
"server.json"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.build.json",
|
|
38
|
+
"check": "pnpm lint && pnpm typecheck && pnpm test && pnpm build",
|
|
39
|
+
"dev": "tsx src/cli.ts",
|
|
40
|
+
"lint": "biome check .",
|
|
41
|
+
"lint:fix": "biome check --write .",
|
|
42
|
+
"prepack": "pnpm check",
|
|
43
|
+
"smoke:package": "node scripts/smoke-package.mjs",
|
|
44
|
+
"start": "node dist/cli.js",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"typecheck": "tsc --noEmit"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"analytics",
|
|
54
|
+
"core-web-vitals",
|
|
55
|
+
"heatmaps",
|
|
56
|
+
"mcp",
|
|
57
|
+
"model-context-protocol",
|
|
58
|
+
"privacy",
|
|
59
|
+
"self-hosted",
|
|
60
|
+
"umami"
|
|
61
|
+
],
|
|
62
|
+
"publishConfig": {
|
|
63
|
+
"access": "public",
|
|
64
|
+
"provenance": true
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
68
|
+
"zod": "^4.4.3"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@biomejs/biome": "^2.4.12",
|
|
72
|
+
"@types/node": "^22.5.4",
|
|
73
|
+
"tsx": "^4.21.0",
|
|
74
|
+
"typescript": "^5.9.3",
|
|
75
|
+
"vitest": "^4.1.10"
|
|
76
|
+
},
|
|
77
|
+
"packageManager": "pnpm@11.9.0"
|
|
78
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.webcredo/umami-compass",
|
|
4
|
+
"title": "Umami Compass",
|
|
5
|
+
"description": "Secure Umami Analytics MCP server for Cloud and self-hosted deployments",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"websiteUrl": "https://github.com/webcredo/umami-compass",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "https://github.com/webcredo/umami-compass",
|
|
10
|
+
"source": "github",
|
|
11
|
+
"id": "1298894734"
|
|
12
|
+
},
|
|
13
|
+
"packages": [
|
|
14
|
+
{
|
|
15
|
+
"registryType": "npm",
|
|
16
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
17
|
+
"identifier": "umami-compass",
|
|
18
|
+
"version": "0.1.0",
|
|
19
|
+
"runtimeHint": "npx",
|
|
20
|
+
"transport": {
|
|
21
|
+
"type": "stdio"
|
|
22
|
+
},
|
|
23
|
+
"environmentVariables": [
|
|
24
|
+
{
|
|
25
|
+
"name": "UMAMI_API_KEY",
|
|
26
|
+
"description": "Umami Cloud or client API key",
|
|
27
|
+
"isSecret": true,
|
|
28
|
+
"isRequired": false
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "UMAMI_ACCESS_TOKEN",
|
|
32
|
+
"description": "Existing self-hosted Bearer token",
|
|
33
|
+
"isSecret": true,
|
|
34
|
+
"isRequired": false
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "UMAMI_USERNAME",
|
|
38
|
+
"description": "Self-hosted Umami username",
|
|
39
|
+
"isRequired": false
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "UMAMI_PASSWORD",
|
|
43
|
+
"description": "Self-hosted Umami password",
|
|
44
|
+
"isSecret": true,
|
|
45
|
+
"isRequired": false
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "UMAMI_URL",
|
|
49
|
+
"description": "Self-hosted Umami instance origin",
|
|
50
|
+
"isRequired": false,
|
|
51
|
+
"placeholder": "https://analytics.example.com"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "UMAMI_API_URL",
|
|
55
|
+
"description": "Optional exact Umami API root for a reverse proxy",
|
|
56
|
+
"isRequired": false,
|
|
57
|
+
"placeholder": "https://analytics.example.com/custom/api"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "UMAMI_WEBSITE_IDS",
|
|
61
|
+
"description": "Optional comma-separated website UUID allowlist",
|
|
62
|
+
"isRequired": false
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "UMAMI_TOOLSETS",
|
|
66
|
+
"description": "Comma-separated toolsets or all",
|
|
67
|
+
"isRequired": false,
|
|
68
|
+
"default": "core",
|
|
69
|
+
"placeholder": "core,events,sessions,performance,reports,revenue,replay,heatmaps"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "UMAMI_MAX_RESPONSE_BYTES",
|
|
73
|
+
"description": "Maximum decoded upstream JSON response size in bytes",
|
|
74
|
+
"isRequired": false,
|
|
75
|
+
"default": "10485760"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|