datafast-mcp-server 1.0.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 (3) hide show
  1. package/README.md +88 -0
  2. package/build/index.js +457 -0
  3. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Datafast MCP Server
2
+
3
+ An MCP (Model Context Protocol) server for the [Datafast](https://datafa.st) analytics API. This server allows AI assistants like Claude to query your website analytics data.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install
9
+ npm run build
10
+ ```
11
+
12
+ ## Configuration
13
+
14
+ Add the server to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
15
+
16
+ ```json
17
+ {
18
+ "mcpServers": {
19
+ "datafast": {
20
+ "command": "node",
21
+ "args": ["/path/to/datafast-mcp-server/build/index.js"]
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Available Tools
28
+
29
+ ### Analytics Tools
30
+
31
+ | Tool | Description |
32
+ |------|-------------|
33
+ | `get_overview` | Get aggregate analytics metrics (visitors, sessions, bounce rate, revenue, conversion rate) |
34
+ | `get_realtime` | Get real-time visitor count (last 5 minutes) |
35
+ | `get_pages` | Get analytics broken down by page path |
36
+ | `get_referrers` | Get analytics by referrer source |
37
+ | `get_countries` | Get analytics by country |
38
+ | `get_regions` | Get analytics by region/state |
39
+ | `get_cities` | Get analytics by city |
40
+ | `get_devices` | Get analytics by device type (desktop, mobile, tablet) |
41
+ | `get_browsers` | Get analytics by browser |
42
+ | `get_operating_systems` | Get analytics by operating system |
43
+ | `get_goals` | Get analytics by custom goals |
44
+ | `get_campaigns` | Get analytics by UTM campaigns |
45
+
46
+ ### Common Parameters
47
+
48
+ All tools require an `apiKey` parameter. Get your API key from **Website Settings > API** in your Datafast dashboard.
49
+
50
+ #### Date Range Parameters
51
+ - `startAt`: Start date in ISO 8601 format (e.g., `2024-01-01`)
52
+ - `endAt`: End date in ISO 8601 format (e.g., `2024-01-31`)
53
+ - `timezone`: Timezone for aggregation (e.g., `America/New_York`)
54
+
55
+ #### Pagination Parameters
56
+ - `limit`: Maximum results (1-1000, default: 100)
57
+ - `offset`: Number of results to skip
58
+
59
+ #### Filter Parameters
60
+ - `country`: Filter by country name(s)
61
+ - `region`: Filter by region(s)
62
+ - `city`: Filter by city/cities
63
+ - `device`: Filter by device type
64
+ - `browser`: Filter by browser name
65
+ - `os`: Filter by operating system
66
+ - `referrer`: Filter by referrer URL
67
+ - `utm_source`, `utm_medium`, `utm_campaign`: Filter by UTM parameters
68
+ - `page`: Filter by page path
69
+ - `hostname`: Filter by hostname
70
+
71
+ ## Example Usage
72
+
73
+ Once configured, you can ask Claude:
74
+
75
+ - "Show me my website's overview analytics for last month"
76
+ - "How many visitors do I have right now?"
77
+ - "What are my top pages by visitors?"
78
+ - "Which countries are my visitors from?"
79
+ - "Show me traffic by device type"
80
+ - "What referrers are driving the most revenue?"
81
+
82
+ ## API Documentation
83
+
84
+ For more details, see the [Datafast API Documentation](https://datafa.st/docs/api-introduction).
85
+
86
+ ## License
87
+
88
+ MIT
package/build/index.js ADDED
@@ -0,0 +1,457 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ const DATAFAST_API_BASE = "https://datafa.st/api/v1";
6
+ // Create server instance
7
+ const server = new McpServer({
8
+ name: "datafast",
9
+ version: "1.0.0",
10
+ });
11
+ // Helper function for making Datafast API requests
12
+ async function makeDatafastRequest(endpoint, apiKey, params) {
13
+ const url = new URL(`${DATAFAST_API_BASE}${endpoint}`);
14
+ if (params) {
15
+ Object.entries(params).forEach(([key, value]) => {
16
+ if (value !== undefined) {
17
+ url.searchParams.append(key, String(value));
18
+ }
19
+ });
20
+ }
21
+ const response = await fetch(url.toString(), {
22
+ method: "GET",
23
+ headers: {
24
+ Authorization: `Bearer ${apiKey}`,
25
+ Accept: "application/json",
26
+ },
27
+ });
28
+ if (!response.ok) {
29
+ const error = await response.json().catch(() => ({}));
30
+ throw new Error(`Datafast API error: ${response.status} - ${error.error?.message || response.statusText}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ // Common filter parameters schema
35
+ const filterParams = {
36
+ country: z
37
+ .string()
38
+ .optional()
39
+ .describe("Filter by country name(s), comma-separated"),
40
+ region: z.string().optional().describe("Filter by region(s), comma-separated"),
41
+ city: z.string().optional().describe("Filter by city/cities, comma-separated"),
42
+ device: z
43
+ .string()
44
+ .optional()
45
+ .describe("Filter by device type (desktop, mobile, tablet)"),
46
+ browser: z.string().optional().describe("Filter by browser name"),
47
+ os: z.string().optional().describe("Filter by operating system"),
48
+ referrer: z.string().optional().describe("Filter by referrer URL"),
49
+ utm_source: z.string().optional().describe("Filter by UTM source"),
50
+ utm_medium: z.string().optional().describe("Filter by UTM medium"),
51
+ utm_campaign: z.string().optional().describe("Filter by UTM campaign"),
52
+ page: z.string().optional().describe("Filter by page path"),
53
+ hostname: z.string().optional().describe("Filter by hostname"),
54
+ };
55
+ // Common date/pagination parameters
56
+ const dateParams = {
57
+ startAt: z
58
+ .string()
59
+ .optional()
60
+ .describe("Start date in ISO 8601 format (e.g., 2024-01-01)"),
61
+ endAt: z
62
+ .string()
63
+ .optional()
64
+ .describe("End date in ISO 8601 format (e.g., 2024-01-31)"),
65
+ timezone: z
66
+ .string()
67
+ .optional()
68
+ .describe("Timezone for aggregation (e.g., America/New_York)"),
69
+ };
70
+ const paginationParams = {
71
+ limit: z
72
+ .number()
73
+ .min(1)
74
+ .max(1000)
75
+ .optional()
76
+ .describe("Maximum results to return (1-1000, default: 100)"),
77
+ offset: z
78
+ .number()
79
+ .min(0)
80
+ .optional()
81
+ .describe("Number of results to skip for pagination"),
82
+ };
83
+ // Register tools
84
+ // Get Overview
85
+ server.registerTool("get_overview", {
86
+ description: "Get aggregate analytics metrics for your website including visitors, sessions, bounce rate, revenue, and conversion rate",
87
+ inputSchema: {
88
+ apiKey: z.string().describe("Your Datafast API key"),
89
+ fields: z
90
+ .string()
91
+ .optional()
92
+ .describe("Comma-separated fields to return: visitors, sessions, bounce_rate, avg_session_duration, currency, revenue, revenue_per_visitor, conversion_rate"),
93
+ ...dateParams,
94
+ },
95
+ }, async ({ apiKey, fields, startAt, endAt, timezone }) => {
96
+ const data = await makeDatafastRequest("/analytics/overview", apiKey, {
97
+ fields,
98
+ startAt,
99
+ endAt,
100
+ timezone,
101
+ });
102
+ return {
103
+ content: [
104
+ {
105
+ type: "text",
106
+ text: JSON.stringify(data, null, 2),
107
+ },
108
+ ],
109
+ };
110
+ });
111
+ // Get Realtime
112
+ server.registerTool("get_realtime", {
113
+ description: "Get the count of active visitors on your website in real-time (visitors with activity in the last 5 minutes)",
114
+ inputSchema: {
115
+ apiKey: z.string().describe("Your Datafast API key"),
116
+ },
117
+ }, async ({ apiKey }) => {
118
+ const data = await makeDatafastRequest("/analytics/realtime", apiKey);
119
+ return {
120
+ content: [
121
+ {
122
+ type: "text",
123
+ text: JSON.stringify(data, null, 2),
124
+ },
125
+ ],
126
+ };
127
+ });
128
+ // Get Pages
129
+ server.registerTool("get_pages", {
130
+ description: "Get analytics data broken down by page with hostname and path information",
131
+ inputSchema: {
132
+ apiKey: z.string().describe("Your Datafast API key"),
133
+ fields: z
134
+ .string()
135
+ .optional()
136
+ .describe("Comma-separated fields to return: hostname, path, visitors, revenue"),
137
+ ...dateParams,
138
+ ...paginationParams,
139
+ ...filterParams,
140
+ },
141
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
142
+ const data = await makeDatafastRequest("/analytics/pages", apiKey, {
143
+ fields,
144
+ startAt,
145
+ endAt,
146
+ timezone,
147
+ limit,
148
+ offset,
149
+ ...filters,
150
+ });
151
+ return {
152
+ content: [
153
+ {
154
+ type: "text",
155
+ text: JSON.stringify(data, null, 2),
156
+ },
157
+ ],
158
+ };
159
+ });
160
+ // Get Referrers
161
+ server.registerTool("get_referrers", {
162
+ description: "Get analytics data segmented by referrer source",
163
+ inputSchema: {
164
+ apiKey: z.string().describe("Your Datafast API key"),
165
+ fields: z
166
+ .string()
167
+ .optional()
168
+ .describe("Comma-separated fields to return: referrer, visitors, revenue"),
169
+ ...dateParams,
170
+ ...paginationParams,
171
+ ...filterParams,
172
+ },
173
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
174
+ const data = await makeDatafastRequest("/analytics/referrers", apiKey, {
175
+ fields,
176
+ startAt,
177
+ endAt,
178
+ timezone,
179
+ limit,
180
+ offset,
181
+ ...filters,
182
+ });
183
+ return {
184
+ content: [
185
+ {
186
+ type: "text",
187
+ text: JSON.stringify(data, null, 2),
188
+ },
189
+ ],
190
+ };
191
+ });
192
+ // Get Countries
193
+ server.registerTool("get_countries", {
194
+ description: "Get analytics data broken down by country",
195
+ inputSchema: {
196
+ apiKey: z.string().describe("Your Datafast API key"),
197
+ fields: z
198
+ .string()
199
+ .optional()
200
+ .describe("Comma-separated fields to return: country, image, visitors, revenue"),
201
+ ...dateParams,
202
+ ...paginationParams,
203
+ ...filterParams,
204
+ },
205
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
206
+ const data = await makeDatafastRequest("/analytics/countries", apiKey, {
207
+ fields,
208
+ startAt,
209
+ endAt,
210
+ timezone,
211
+ limit,
212
+ offset,
213
+ ...filters,
214
+ });
215
+ return {
216
+ content: [
217
+ {
218
+ type: "text",
219
+ text: JSON.stringify(data, null, 2),
220
+ },
221
+ ],
222
+ };
223
+ });
224
+ // Get Devices
225
+ server.registerTool("get_devices", {
226
+ description: "Get analytics data segmented by device type (desktop, mobile, tablet)",
227
+ inputSchema: {
228
+ apiKey: z.string().describe("Your Datafast API key"),
229
+ fields: z
230
+ .string()
231
+ .optional()
232
+ .describe("Comma-separated fields to return: device, visitors, revenue"),
233
+ ...dateParams,
234
+ ...paginationParams,
235
+ ...filterParams,
236
+ },
237
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
238
+ const data = await makeDatafastRequest("/analytics/devices", apiKey, {
239
+ fields,
240
+ startAt,
241
+ endAt,
242
+ timezone,
243
+ limit,
244
+ offset,
245
+ ...filters,
246
+ });
247
+ return {
248
+ content: [
249
+ {
250
+ type: "text",
251
+ text: JSON.stringify(data, null, 2),
252
+ },
253
+ ],
254
+ };
255
+ });
256
+ // Get Browsers
257
+ server.registerTool("get_browsers", {
258
+ description: "Get analytics data broken down by browser",
259
+ inputSchema: {
260
+ apiKey: z.string().describe("Your Datafast API key"),
261
+ fields: z
262
+ .string()
263
+ .optional()
264
+ .describe("Comma-separated fields to return: browser, visitors, revenue"),
265
+ ...dateParams,
266
+ ...paginationParams,
267
+ ...filterParams,
268
+ },
269
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
270
+ const data = await makeDatafastRequest("/analytics/browsers", apiKey, {
271
+ fields,
272
+ startAt,
273
+ endAt,
274
+ timezone,
275
+ limit,
276
+ offset,
277
+ ...filters,
278
+ });
279
+ return {
280
+ content: [
281
+ {
282
+ type: "text",
283
+ text: JSON.stringify(data, null, 2),
284
+ },
285
+ ],
286
+ };
287
+ });
288
+ // Get Operating Systems
289
+ server.registerTool("get_operating_systems", {
290
+ description: "Get analytics data broken down by operating system",
291
+ inputSchema: {
292
+ apiKey: z.string().describe("Your Datafast API key"),
293
+ fields: z
294
+ .string()
295
+ .optional()
296
+ .describe("Comma-separated fields to return: os, visitors, revenue"),
297
+ ...dateParams,
298
+ ...paginationParams,
299
+ ...filterParams,
300
+ },
301
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
302
+ const data = await makeDatafastRequest("/analytics/os", apiKey, {
303
+ fields,
304
+ startAt,
305
+ endAt,
306
+ timezone,
307
+ limit,
308
+ offset,
309
+ ...filters,
310
+ });
311
+ return {
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify(data, null, 2),
316
+ },
317
+ ],
318
+ };
319
+ });
320
+ // Get Goals
321
+ server.registerTool("get_goals", {
322
+ description: "Get analytics data broken down by custom goals",
323
+ inputSchema: {
324
+ apiKey: z.string().describe("Your Datafast API key"),
325
+ fields: z
326
+ .string()
327
+ .optional()
328
+ .describe("Comma-separated fields to return: name, completions, visitors"),
329
+ ...dateParams,
330
+ ...paginationParams,
331
+ ...filterParams,
332
+ },
333
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
334
+ const data = await makeDatafastRequest("/analytics/goals", apiKey, {
335
+ fields,
336
+ startAt,
337
+ endAt,
338
+ timezone,
339
+ limit,
340
+ offset,
341
+ ...filters,
342
+ });
343
+ return {
344
+ content: [
345
+ {
346
+ type: "text",
347
+ text: JSON.stringify(data, null, 2),
348
+ },
349
+ ],
350
+ };
351
+ });
352
+ // Get Regions
353
+ server.registerTool("get_regions", {
354
+ description: "Get analytics data broken down by region/state",
355
+ inputSchema: {
356
+ apiKey: z.string().describe("Your Datafast API key"),
357
+ fields: z
358
+ .string()
359
+ .optional()
360
+ .describe("Comma-separated fields to return: region, visitors, revenue"),
361
+ ...dateParams,
362
+ ...paginationParams,
363
+ ...filterParams,
364
+ },
365
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
366
+ const data = await makeDatafastRequest("/analytics/regions", apiKey, {
367
+ fields,
368
+ startAt,
369
+ endAt,
370
+ timezone,
371
+ limit,
372
+ offset,
373
+ ...filters,
374
+ });
375
+ return {
376
+ content: [
377
+ {
378
+ type: "text",
379
+ text: JSON.stringify(data, null, 2),
380
+ },
381
+ ],
382
+ };
383
+ });
384
+ // Get Cities
385
+ server.registerTool("get_cities", {
386
+ description: "Get analytics data broken down by city",
387
+ inputSchema: {
388
+ apiKey: z.string().describe("Your Datafast API key"),
389
+ fields: z
390
+ .string()
391
+ .optional()
392
+ .describe("Comma-separated fields to return: city, visitors, revenue"),
393
+ ...dateParams,
394
+ ...paginationParams,
395
+ ...filterParams,
396
+ },
397
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
398
+ const data = await makeDatafastRequest("/analytics/cities", apiKey, {
399
+ fields,
400
+ startAt,
401
+ endAt,
402
+ timezone,
403
+ limit,
404
+ offset,
405
+ ...filters,
406
+ });
407
+ return {
408
+ content: [
409
+ {
410
+ type: "text",
411
+ text: JSON.stringify(data, null, 2),
412
+ },
413
+ ],
414
+ };
415
+ });
416
+ // Get Campaigns (UTM)
417
+ server.registerTool("get_campaigns", {
418
+ description: "Get analytics data broken down by UTM campaigns",
419
+ inputSchema: {
420
+ apiKey: z.string().describe("Your Datafast API key"),
421
+ fields: z
422
+ .string()
423
+ .optional()
424
+ .describe("Comma-separated fields to return: campaign, source, medium, visitors, revenue"),
425
+ ...dateParams,
426
+ ...paginationParams,
427
+ ...filterParams,
428
+ },
429
+ }, async ({ apiKey, fields, startAt, endAt, timezone, limit, offset, ...filters }) => {
430
+ const data = await makeDatafastRequest("/analytics/campaigns", apiKey, {
431
+ fields,
432
+ startAt,
433
+ endAt,
434
+ timezone,
435
+ limit,
436
+ offset,
437
+ ...filters,
438
+ });
439
+ return {
440
+ content: [
441
+ {
442
+ type: "text",
443
+ text: JSON.stringify(data, null, 2),
444
+ },
445
+ ],
446
+ };
447
+ });
448
+ // Run the server
449
+ async function main() {
450
+ const transport = new StdioServerTransport();
451
+ await server.connect(transport);
452
+ console.error("Datafast MCP Server running on stdio");
453
+ }
454
+ main().catch((error) => {
455
+ console.error("Fatal error in main():", error);
456
+ process.exit(1);
457
+ });
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "datafast-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Datafast analytics API",
5
+ "type": "module",
6
+ "bin": {
7
+ "datafast-mcp-server": "./build/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && chmod 755 build/index.js",
11
+ "dev": "tsc --watch",
12
+ "start": "node build/index.js",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "files": [
16
+ "build"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/FujiwaraChoki/datafast-mcp-server.git"
21
+ },
22
+ "homepage": "https://github.com/FujiwaraChoki/datafast-mcp-server#readme",
23
+ "bugs": {
24
+ "url": "https://github.com/FujiwaraChoki/datafast-mcp-server/issues"
25
+ },
26
+ "author": "FujiwaraChoki",
27
+ "dependencies": {
28
+ "@modelcontextprotocol/sdk": "^1.0.0",
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "typescript": "^5.7.0"
34
+ },
35
+ "keywords": [
36
+ "mcp",
37
+ "model-context-protocol",
38
+ "datafast",
39
+ "analytics",
40
+ "claude",
41
+ "ai"
42
+ ],
43
+ "license": "MIT"
44
+ }