@asif2bd/umami-mcp 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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +400 -0
  3. package/dist/client.d.ts +43 -0
  4. package/dist/client.js +163 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/config.d.ts +37 -0
  7. package/dist/config.js +121 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/envfile.d.ts +21 -0
  10. package/dist/envfile.js +72 -0
  11. package/dist/envfile.js.map +1 -0
  12. package/dist/http.d.ts +7 -0
  13. package/dist/http.js +133 -0
  14. package/dist/http.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +72 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/oauth/consent.d.ts +13 -0
  19. package/dist/oauth/consent.js +99 -0
  20. package/dist/oauth/consent.js.map +1 -0
  21. package/dist/oauth/router.d.ts +27 -0
  22. package/dist/oauth/router.js +329 -0
  23. package/dist/oauth/router.js.map +1 -0
  24. package/dist/oauth/seal.d.ts +22 -0
  25. package/dist/oauth/seal.js +82 -0
  26. package/dist/oauth/seal.js.map +1 -0
  27. package/dist/oauth/store.d.ts +40 -0
  28. package/dist/oauth/store.js +48 -0
  29. package/dist/oauth/store.js.map +1 -0
  30. package/dist/redact.d.ts +14 -0
  31. package/dist/redact.js +54 -0
  32. package/dist/redact.js.map +1 -0
  33. package/dist/server.d.ts +12 -0
  34. package/dist/server.js +47 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/tools/admin.d.ts +1 -0
  37. package/dist/tools/admin.js +99 -0
  38. package/dist/tools/admin.js.map +1 -0
  39. package/dist/tools/analytics.d.ts +1 -0
  40. package/dist/tools/analytics.js +141 -0
  41. package/dist/tools/analytics.js.map +1 -0
  42. package/dist/tools/common.d.ts +46 -0
  43. package/dist/tools/common.js +86 -0
  44. package/dist/tools/common.js.map +1 -0
  45. package/dist/tools/index.d.ts +3 -0
  46. package/dist/tools/index.js +7 -0
  47. package/dist/tools/index.js.map +1 -0
  48. package/dist/tools/reports.d.ts +1 -0
  49. package/dist/tools/reports.js +122 -0
  50. package/dist/tools/reports.js.map +1 -0
  51. package/dist/tools/websites.d.ts +1 -0
  52. package/dist/tools/websites.js +194 -0
  53. package/dist/tools/websites.js.map +1 -0
  54. package/package.json +54 -0
@@ -0,0 +1,194 @@
1
+ import { z } from 'zod';
2
+ import { defineTool, websiteIdSchema } from './common.js';
3
+ const emptyPage = () => ({ data: [], count: 0 });
4
+ export const websiteTools = [
5
+ defineTool({
6
+ name: 'umami_list_websites',
7
+ title: 'List websites',
8
+ description: 'List every website this account can reach, with their UUIDs. ' +
9
+ 'Covers both personally-owned websites and those owned by teams the account belongs to. ' +
10
+ 'Every analytics tool needs a websiteId, so this is usually the first call.',
11
+ tier: 'read',
12
+ schema: {
13
+ query: z.string().optional().describe('Filter by name or domain (substring match).'),
14
+ teamId: z.string().optional().describe('Restrict to a single team\'s websites.'),
15
+ page: z.number().int().min(1).optional().describe('Page number, default 1.'),
16
+ pageSize: z.number().int().min(1).max(200).optional().describe('Results per page, default 20.'),
17
+ },
18
+ handler: async ({ client, config }, args) => {
19
+ const q = { query: args.query, page: args.page, pageSize: args.pageSize };
20
+ const scopedTeam = args.teamId ?? config.teamId;
21
+ if (scopedTeam) {
22
+ const r = await client.get(`/api/teams/${encodeURIComponent(scopedTeam)}/websites`, q);
23
+ return { ...r, scope: `team:${scopedTeam}` };
24
+ }
25
+ // Umami scopes /api/websites to websites the account owns personally.
26
+ // Websites owned by a team are only reachable through the team endpoint,
27
+ // so an account that works purely through team membership -- which is the
28
+ // recommended setup for a service account -- would otherwise see nothing.
29
+ const own = await client.get('/api/websites', q).catch(() => emptyPage());
30
+ let teams = emptyPage();
31
+ try {
32
+ teams = await client.get('/api/me/teams');
33
+ }
34
+ catch {
35
+ /* no team access; personal websites are the whole picture */
36
+ }
37
+ const seen = new Set((own.data ?? []).map((w) => w.id));
38
+ const merged = [...(own.data ?? [])];
39
+ // `count` must stay the number of websites that EXIST, not the number
40
+ // returned by this page. Conflating them makes a model report
41
+ // "you have 4 websites" when it has merely fetched four of twenty-one.
42
+ let total = own.count ?? own.data?.length ?? 0;
43
+ for (const team of teams.data ?? []) {
44
+ const teamId = team.id ?? team.teamId;
45
+ if (!teamId)
46
+ continue;
47
+ try {
48
+ const tw = await client.get(`/api/teams/${encodeURIComponent(teamId)}/websites`, q);
49
+ total += tw.count ?? tw.data?.length ?? 0;
50
+ for (const w of tw.data ?? []) {
51
+ if (seen.has(w.id))
52
+ continue;
53
+ seen.add(w.id);
54
+ merged.push({ ...w, teamName: team.name ?? undefined });
55
+ }
56
+ }
57
+ catch {
58
+ /* a team we cannot read is simply skipped */
59
+ }
60
+ }
61
+ return {
62
+ data: merged,
63
+ count: total,
64
+ returned: merged.length,
65
+ scope: 'personal+teams',
66
+ ...(merged.length < total
67
+ ? { note: 'More websites exist than were returned. Paging applies per scope; raise pageSize or pass teamId to narrow.' }
68
+ : {}),
69
+ };
70
+ },
71
+ }),
72
+ defineTool({
73
+ name: 'umami_get_website',
74
+ title: 'Get website',
75
+ description: 'Fetch a single website by UUID, including its domain, owner and creation date.',
76
+ tier: 'read',
77
+ schema: { ...websiteIdSchema },
78
+ handler: async ({ client }, args) => client.get(`/api/websites/${encodeURIComponent(args.websiteId)}`),
79
+ }),
80
+ defineTool({
81
+ name: 'umami_create_website',
82
+ title: 'Create website',
83
+ description: 'Register a new website for tracking and return its UUID, which is the value to put in the ' +
84
+ 'data-website-id attribute of the Umami tracking script.',
85
+ tier: 'write',
86
+ schema: {
87
+ name: z.string().min(1).describe('Display name shown in the Umami dashboard.'),
88
+ domain: z
89
+ .string()
90
+ .min(1)
91
+ .describe('Hostname to track, without scheme or trailing slash, e.g. "example.com".'),
92
+ shareId: z.string().optional().describe('Optional slug to enable a public share URL.'),
93
+ teamId: z.string().optional().describe('Optional team UUID to own this website.'),
94
+ },
95
+ handler: async ({ client, config }, args) => client.post('/api/websites', {
96
+ name: args.name,
97
+ domain: args.domain,
98
+ shareId: args.shareId,
99
+ teamId: args.teamId ?? config.teamId,
100
+ }),
101
+ }),
102
+ defineTool({
103
+ name: 'umami_update_website',
104
+ title: 'Update website',
105
+ description: 'Change a website\'s name, domain or share slug. Only the fields you pass are modified.',
106
+ tier: 'write',
107
+ schema: {
108
+ ...websiteIdSchema,
109
+ name: z.string().min(1).optional(),
110
+ domain: z.string().min(1).optional(),
111
+ shareId: z.string().nullable().optional().describe('Set to null to disable public sharing.'),
112
+ },
113
+ handler: async ({ client }, args) => {
114
+ const body = {};
115
+ for (const k of ['name', 'domain', 'shareId']) {
116
+ if (args[k] !== undefined)
117
+ body[k] = args[k];
118
+ }
119
+ if (Object.keys(body).length === 0) {
120
+ throw new Error('Nothing to update: pass at least one of name, domain or shareId.');
121
+ }
122
+ return client.post(`/api/websites/${encodeURIComponent(args.websiteId)}`, body);
123
+ },
124
+ }),
125
+ defineTool({
126
+ name: 'umami_reset_website',
127
+ title: 'Reset website data',
128
+ description: 'PERMANENTLY DELETE all collected analytics data for a website, keeping the website itself. ' +
129
+ 'This cannot be undone and there is no backup. Requires admin mode with destructive operations enabled.',
130
+ tier: 'admin',
131
+ destructive: true,
132
+ schema: {
133
+ ...websiteIdSchema,
134
+ confirmDomain: z
135
+ .string()
136
+ .min(1)
137
+ .describe('Type the website\'s exact domain to confirm. The call fails if it does not match.'),
138
+ },
139
+ handler: async ({ client }, args) => {
140
+ const site = await client.get(`/api/websites/${encodeURIComponent(args.websiteId)}`);
141
+ if (!site?.domain)
142
+ throw new Error(`Website ${args.websiteId} not found.`);
143
+ if (site.domain !== args.confirmDomain) {
144
+ throw new Error(`Refusing to reset: confirmDomain ${JSON.stringify(args.confirmDomain)} does not match ` +
145
+ `the website's actual domain ${JSON.stringify(site.domain)}.`);
146
+ }
147
+ await client.post(`/api/websites/${encodeURIComponent(args.websiteId)}/reset`);
148
+ return { reset: true, websiteId: args.websiteId, domain: site.domain };
149
+ },
150
+ }),
151
+ defineTool({
152
+ name: 'umami_delete_website',
153
+ title: 'Delete website',
154
+ description: 'PERMANENTLY DELETE a website and every event ever recorded for it. This cannot be undone. ' +
155
+ 'Requires admin mode with destructive operations enabled.',
156
+ tier: 'admin',
157
+ destructive: true,
158
+ schema: {
159
+ ...websiteIdSchema,
160
+ confirmDomain: z
161
+ .string()
162
+ .min(1)
163
+ .describe('Type the website\'s exact domain to confirm. The call fails if it does not match.'),
164
+ },
165
+ handler: async ({ client }, args) => {
166
+ const site = await client.get(`/api/websites/${encodeURIComponent(args.websiteId)}`);
167
+ if (!site?.domain)
168
+ throw new Error(`Website ${args.websiteId} not found.`);
169
+ if (site.domain !== args.confirmDomain) {
170
+ throw new Error(`Refusing to delete: confirmDomain ${JSON.stringify(args.confirmDomain)} does not match ` +
171
+ `the website's actual domain ${JSON.stringify(site.domain)}.`);
172
+ }
173
+ await client.del(`/api/websites/${encodeURIComponent(args.websiteId)}`);
174
+ return { deleted: true, websiteId: args.websiteId, domain: site.domain };
175
+ },
176
+ }),
177
+ defineTool({
178
+ name: 'umami_get_tracking_snippet',
179
+ title: 'Get tracking snippet',
180
+ description: 'Return the ready-to-paste HTML script tag that sends data to this Umami instance for a given website.',
181
+ tier: 'read',
182
+ schema: { ...websiteIdSchema },
183
+ handler: async ({ client, config }, args) => {
184
+ const site = await client.get(`/api/websites/${encodeURIComponent(args.websiteId)}`);
185
+ return {
186
+ websiteId: site.id,
187
+ domain: site.domain,
188
+ snippet: `<script defer src="${config.url}/script.js" data-website-id="${site.id}"></script>`,
189
+ instructions: 'Paste this immediately before the closing </head> tag of every page you want tracked.',
190
+ };
191
+ },
192
+ }),
193
+ ];
194
+ //# sourceMappingURL=websites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websites.js","sourceRoot":"","sources":["../../src/tools/websites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAe1D,MAAM,SAAS,GAAG,GAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAExD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,UAAU,CAAC;QACT,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,+DAA+D;YAC/D,yFAAyF;YACzF,4EAA4E;QAC9E,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE;YACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACpF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;YAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAC5E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;SAChG;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YAC1C,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YAE1E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;YAChD,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,CAAQ,cAAc,kBAAkB,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;gBAC9F,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,EAAE,CAAC;YAC/C,CAAC;YAED,sEAAsE;YACtE,yEAAyE;YACzE,0EAA0E;YAC1E,0EAA0E;YAC1E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAQ,eAAe,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;YAEjF,IAAI,KAAK,GAAU,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAQ,eAAe,CAAC,CAAC;YACnD,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACxD,MAAM,MAAM,GAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAChD,sEAAsE;YACtE,8DAA8D;YAC9D,uEAAuE;YACvE,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC;YAE/C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;gBACpC,MAAM,MAAM,GAAI,IAAY,CAAC,EAAE,IAAK,IAAY,CAAC,MAAM,CAAC;gBACxD,IAAI,CAAC,MAAM;oBAAE,SAAS;gBACtB,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAQ,cAAc,kBAAkB,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;oBAC3F,KAAK,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC;oBAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;wBAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;4BAAE,SAAS;wBAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAG,IAAY,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;oBACnE,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;YACH,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,MAAM,CAAC,MAAM;gBACvB,KAAK,EAAE,gBAAgB;gBACvB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK;oBACvB,CAAC,CAAC,EAAE,IAAI,EAAE,4GAA4G,EAAE;oBACxH,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,gFAAgF;QAC7F,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,EAAE,GAAG,eAAe,EAAE;QAC9B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;KACvG,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,4FAA4F;YAC5F,yDAAyD;QAC3D,IAAI,EAAE,OAAO;QACb,MAAM,EAAE;YACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;YAC9E,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,0EAA0E,CAAC;YACvF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACtF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SAClF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAC1C,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;SACrC,CAAC;KACL,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,wFAAwF;QACrG,IAAI,EAAE,OAAO;QACb,MAAM,EAAE;YACN,GAAG,eAAe;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;SAC7F;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,IAAI,GAA4B,EAAE,CAAC;YACzC,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAU,EAAE,CAAC;gBACvD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;oBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;YACtF,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAClF,CAAC;KACF,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,6FAA6F;YAC7F,wGAAwG;QAC1G,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE;YACN,GAAG,eAAe;YAClB,aAAa,EAAE,CAAC;iBACb,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,mFAAmF,CAAC;SACjG;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAC3B,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CACtD,CAAC;YACF,IAAI,CAAC,IAAI,EAAE,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,aAAa,CAAC,CAAC;YAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB;oBACtF,+BAA+B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAChE,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC/E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QACzE,CAAC;KACF,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,4FAA4F;YAC5F,0DAA0D;QAC5D,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE;YACN,GAAG,eAAe;YAClB,aAAa,EAAE,CAAC;iBACb,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,mFAAmF,CAAC;SACjG;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAsB,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAC1G,IAAI,CAAC,IAAI,EAAE,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,aAAa,CAAC,CAAC;YAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CACb,qCAAqC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB;oBACvF,+BAA+B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAChE,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3E,CAAC;KACF,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,uGAAuG;QACzG,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,EAAE,GAAG,eAAe,EAAE;QAC9B,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YAC1C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAC3B,iBAAiB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CACtD,CAAC;YACF,OAAO;gBACL,SAAS,EAAE,IAAI,CAAC,EAAE;gBAClB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,sBAAsB,MAAM,CAAC,GAAG,gCAAgC,IAAI,CAAC,EAAE,aAAa;gBAC7F,YAAY,EAAE,uFAAuF;aACtG,CAAC;QACJ,CAAC;KACF,CAAC;CACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@asif2bd/umami-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Model Context Protocol server for Umami Analytics. Self-hosted, credentials never leave your environment.",
5
+ "type": "module",
6
+ "bin": {
7
+ "umami-mcp": "dist/index.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "start": "node dist/index.js",
21
+ "dev": "tsc --watch",
22
+ "test": "node --test test/*.test.js",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "keywords": [
26
+ "mcp",
27
+ "model-context-protocol",
28
+ "umami",
29
+ "analytics",
30
+ "claude",
31
+ "ai"
32
+ ],
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.22.0",
36
+ "zod": "^3.25.76"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.10.0",
40
+ "typescript": "^5.7.0"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/Asif2BD/umami-mcp.git"
48
+ },
49
+ "homepage": "https://github.com/Asif2BD/umami-mcp#readme",
50
+ "bugs": {
51
+ "url": "https://github.com/Asif2BD/umami-mcp/issues"
52
+ },
53
+ "author": "M Asif Rahman"
54
+ }