detrics 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/dist/api/client.d.ts +13 -0
- package/dist/api/client.js +66 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/types.d.ts +57 -0
- package/dist/api/types.js +3 -0
- package/dist/api/types.js.map +1 -0
- package/dist/constants/platforms.d.ts +2 -0
- package/dist/constants/platforms.js +40 -0
- package/dist/constants/platforms.js.map +1 -0
- package/dist/constants/query-guide.d.ts +1 -0
- package/dist/constants/query-guide.js +69 -0
- package/dist/constants/query-guide.js.map +1 -0
- package/dist/formatters/markdown-table.d.ts +6 -0
- package/dist/formatters/markdown-table.js +76 -0
- package/dist/formatters/markdown-table.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.js +74 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +358 -0
- package/dist/server.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface ApiResponse {
|
|
2
|
+
status: number;
|
|
3
|
+
data: unknown;
|
|
4
|
+
}
|
|
5
|
+
export declare class DetricApiClient {
|
|
6
|
+
private apiKey;
|
|
7
|
+
private baseUrl;
|
|
8
|
+
constructor(apiKey: string);
|
|
9
|
+
get(path: string): Promise<ApiResponse>;
|
|
10
|
+
post(path: string, body?: unknown): Promise<ApiResponse>;
|
|
11
|
+
private request;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DetricApiClient = void 0;
|
|
7
|
+
const https_1 = __importDefault(require("https"));
|
|
8
|
+
const http_1 = __importDefault(require("http"));
|
|
9
|
+
const API_BASE_URL = process.env.DETRICS_API_URL || "https://api.detrics.io";
|
|
10
|
+
class DetricApiClient {
|
|
11
|
+
apiKey;
|
|
12
|
+
baseUrl;
|
|
13
|
+
constructor(apiKey) {
|
|
14
|
+
this.apiKey = apiKey;
|
|
15
|
+
this.baseUrl = API_BASE_URL;
|
|
16
|
+
}
|
|
17
|
+
async get(path) {
|
|
18
|
+
return this.request("GET", path);
|
|
19
|
+
}
|
|
20
|
+
async post(path, body) {
|
|
21
|
+
return this.request("POST", path, body);
|
|
22
|
+
}
|
|
23
|
+
request(method, path, body) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const url = new URL(path, this.baseUrl);
|
|
26
|
+
const isHttps = url.protocol === "https:";
|
|
27
|
+
const lib = isHttps ? https_1.default : http_1.default;
|
|
28
|
+
const postData = body ? JSON.stringify(body) : undefined;
|
|
29
|
+
const options = {
|
|
30
|
+
hostname: url.hostname,
|
|
31
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
32
|
+
path: url.pathname + url.search,
|
|
33
|
+
method,
|
|
34
|
+
headers: {
|
|
35
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
"Accept": "application/json",
|
|
38
|
+
...(postData ? { "Content-Length": Buffer.byteLength(postData) } : {}),
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const req = lib.request(options, (res) => {
|
|
42
|
+
let data = "";
|
|
43
|
+
res.on("data", (chunk) => { data += chunk; });
|
|
44
|
+
res.on("end", () => {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = data ? JSON.parse(data) : null;
|
|
47
|
+
resolve({ status: res.statusCode || 500, data: parsed });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
resolve({ status: res.statusCode || 500, data: { raw: data } });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
req.on("error", reject);
|
|
55
|
+
req.setTimeout(60000, () => {
|
|
56
|
+
req.destroy(new Error("Request timeout"));
|
|
57
|
+
});
|
|
58
|
+
if (postData) {
|
|
59
|
+
req.write(postData);
|
|
60
|
+
}
|
|
61
|
+
req.end();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.DetricApiClient = DetricApiClient;
|
|
66
|
+
//# 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,57 @@
|
|
|
1
|
+
export interface McpQueryRequest {
|
|
2
|
+
platform_api: string;
|
|
3
|
+
metrics: string[];
|
|
4
|
+
dimensions?: string[];
|
|
5
|
+
start_date: string;
|
|
6
|
+
end_date?: string;
|
|
7
|
+
time_aggregation?: string;
|
|
8
|
+
account_ids?: string[];
|
|
9
|
+
filters?: unknown[];
|
|
10
|
+
connection_id?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface McpQueryResponse {
|
|
13
|
+
data: {
|
|
14
|
+
rows?: Record<string, unknown>[];
|
|
15
|
+
columns?: string[];
|
|
16
|
+
};
|
|
17
|
+
cached: boolean;
|
|
18
|
+
rowCount: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ConnectionInfo {
|
|
21
|
+
token: {
|
|
22
|
+
api_name: string;
|
|
23
|
+
token_owner_email: string;
|
|
24
|
+
token_owner_display_name: string;
|
|
25
|
+
};
|
|
26
|
+
connection: {
|
|
27
|
+
workspace_connection_id: string;
|
|
28
|
+
platform_api: string;
|
|
29
|
+
created_at: string;
|
|
30
|
+
is_active: boolean;
|
|
31
|
+
};
|
|
32
|
+
accounts: Array<{
|
|
33
|
+
platform_api_account_id: string;
|
|
34
|
+
account_display_name: string;
|
|
35
|
+
account_external_id: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export interface ConnectInitiateResponse {
|
|
39
|
+
oauthUrl: string;
|
|
40
|
+
pollingJobId: string;
|
|
41
|
+
platformApi: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ConnectStatusResponse {
|
|
44
|
+
connectionStatus: "WAITING" | "SUCCESS" | "FAILED" | "LOADING_ACCOUNTS" | "FAILED_LOADING_ACCOUNTS" | "NO_ACCOUNTS_FOUND" | "TIMEOUT";
|
|
45
|
+
errorMessage?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface FieldInfo {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
type: string;
|
|
52
|
+
group?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface FieldsResponse {
|
|
55
|
+
metrics: FieldInfo[];
|
|
56
|
+
dimensions: FieldInfo[];
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AD_PLATFORMS = exports.PLATFORM_DISPLAY_NAMES = void 0;
|
|
4
|
+
exports.PLATFORM_DISPLAY_NAMES = {
|
|
5
|
+
"facebook-ads": "Meta Ads (Facebook & Instagram)",
|
|
6
|
+
"facebook-insights": "Facebook Page Insights",
|
|
7
|
+
"instagram-insights": "Instagram Insights",
|
|
8
|
+
"google-ads": "Google Ads",
|
|
9
|
+
"google-analytics-4": "Google Analytics 4",
|
|
10
|
+
"google-search-console": "Google Search Console",
|
|
11
|
+
"google-dv-360": "Google Display & Video 360",
|
|
12
|
+
"google-campaign-manager-360": "Google Campaign Manager 360",
|
|
13
|
+
"tiktok-ads": "TikTok Ads",
|
|
14
|
+
"tiktok-organic": "TikTok Organic",
|
|
15
|
+
"linkedin-ads": "LinkedIn Ads",
|
|
16
|
+
"linkedin-pages": "LinkedIn Pages",
|
|
17
|
+
"pinterest-ads": "Pinterest Ads",
|
|
18
|
+
"bing-ads": "Microsoft (Bing) Ads",
|
|
19
|
+
"x-ads": "X (Twitter) Ads",
|
|
20
|
+
"mercado-ads": "MercadoLibre Ads",
|
|
21
|
+
"amazon-ads": "Amazon Ads",
|
|
22
|
+
"shopify-store": "Shopify",
|
|
23
|
+
"tiendanube-store": "TiendaNube",
|
|
24
|
+
"woocommerce": "WooCommerce",
|
|
25
|
+
"stripe": "Stripe",
|
|
26
|
+
"klaviyo": "Klaviyo",
|
|
27
|
+
"hubspot": "HubSpot",
|
|
28
|
+
};
|
|
29
|
+
exports.AD_PLATFORMS = [
|
|
30
|
+
"facebook-ads",
|
|
31
|
+
"google-ads",
|
|
32
|
+
"tiktok-ads",
|
|
33
|
+
"linkedin-ads",
|
|
34
|
+
"pinterest-ads",
|
|
35
|
+
"bing-ads",
|
|
36
|
+
"x-ads",
|
|
37
|
+
"mercado-ads",
|
|
38
|
+
"amazon-ads",
|
|
39
|
+
];
|
|
40
|
+
//# sourceMappingURL=platforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../../src/constants/platforms.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAA2B;IAC7D,cAAc,EAAE,iCAAiC;IACjD,mBAAmB,EAAE,wBAAwB;IAC7C,oBAAoB,EAAE,oBAAoB;IAC1C,YAAY,EAAE,YAAY;IAC1B,oBAAoB,EAAE,oBAAoB;IAC1C,uBAAuB,EAAE,uBAAuB;IAChD,eAAe,EAAE,4BAA4B;IAC7C,6BAA6B,EAAE,6BAA6B;IAC5D,YAAY,EAAE,YAAY;IAC1B,gBAAgB,EAAE,gBAAgB;IAClC,cAAc,EAAE,cAAc;IAC9B,gBAAgB,EAAE,gBAAgB;IAClC,eAAe,EAAE,eAAe;IAChC,UAAU,EAAE,sBAAsB;IAClC,OAAO,EAAE,iBAAiB;IAC1B,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,YAAY;IAC1B,eAAe,EAAE,SAAS;IAC1B,kBAAkB,EAAE,YAAY;IAChC,aAAa,EAAE,aAAa;IAC5B,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;CACpB,CAAC;AAEW,QAAA,YAAY,GAAG;IAC3B,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,eAAe;IACf,UAAU;IACV,OAAO;IACP,aAAa;IACb,YAAY;CACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const QUERY_GUIDE = "# Detrics Query Guide\n\n## Querying Marketing Data\n\nUse the `query_marketing_data` tool to fetch data from connected platforms.\n\n### Required Parameters\n- **platform_api**: The platform identifier (e.g., \"facebook-ads\", \"google-ads\")\n- **metrics**: Array of metric IDs to fetch (e.g., [\"spend\", \"impressions\", \"clicks\"])\n- **start_date**: Start date in YYYY-MM-DD format\n\n### Optional Parameters\n- **end_date**: End date (defaults to today)\n- **dimensions**: Array of dimension IDs for grouping (e.g., [\"campaign_name\", \"date\"])\n- **time_aggregation**: \"day\", \"week\", \"month\", or \"total\" (default: \"day\")\n- **account_ids**: Specific account IDs to query (defaults to all)\n- **filters**: Array of filter objects for narrowing results\n- **connection_id**: Specific connection ID to use\n\n### Common Metrics by Platform\n\n#### Meta/Facebook Ads\n- spend, impressions, clicks, cpc, cpm, ctr\n- reach, frequency, conversions, cost_per_conversion\n- link_clicks, video_views\n\n#### Google Ads\n- cost, impressions, clicks, cpc, cpm, ctr\n- conversions, cost_per_conversion, conversion_rate\n- search_impression_share\n\n#### TikTok Ads\n- spend, impressions, clicks, cpc, cpm, ctr\n- conversions, cost_per_conversion, video_views\n\n#### Shopify\n- total_sales, orders_count, average_order_value\n- gross_sales, discounts, returns, net_sales\n\n### Example Queries\n\n1. **Last 30 days Meta Ads spend by campaign**:\n ```\n platform_api: \"facebook-ads\"\n metrics: [\"spend\", \"impressions\", \"clicks\", \"ctr\"]\n dimensions: [\"campaign_name\"]\n start_date: \"2024-01-01\"\n end_date: \"2024-01-31\"\n time_aggregation: \"total\"\n ```\n\n2. **Daily Google Ads performance**:\n ```\n platform_api: \"google-ads\"\n metrics: [\"cost\", \"conversions\", \"cost_per_conversion\"]\n dimensions: [\"date\"]\n start_date: \"2024-01-01\"\n ```\n\n### Tips\n- Use `list_fields` to see all available metrics and dimensions for a platform\n- Use `list_connections` to see which platforms are connected\n- Use `list_accounts` to see available ad accounts\n- Use `get_spend_summary` for a quick overview across all ad platforms\n";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QUERY_GUIDE = void 0;
|
|
4
|
+
exports.QUERY_GUIDE = `# Detrics Query Guide
|
|
5
|
+
|
|
6
|
+
## Querying Marketing Data
|
|
7
|
+
|
|
8
|
+
Use the \`query_marketing_data\` tool to fetch data from connected platforms.
|
|
9
|
+
|
|
10
|
+
### Required Parameters
|
|
11
|
+
- **platform_api**: The platform identifier (e.g., "facebook-ads", "google-ads")
|
|
12
|
+
- **metrics**: Array of metric IDs to fetch (e.g., ["spend", "impressions", "clicks"])
|
|
13
|
+
- **start_date**: Start date in YYYY-MM-DD format
|
|
14
|
+
|
|
15
|
+
### Optional Parameters
|
|
16
|
+
- **end_date**: End date (defaults to today)
|
|
17
|
+
- **dimensions**: Array of dimension IDs for grouping (e.g., ["campaign_name", "date"])
|
|
18
|
+
- **time_aggregation**: "day", "week", "month", or "total" (default: "day")
|
|
19
|
+
- **account_ids**: Specific account IDs to query (defaults to all)
|
|
20
|
+
- **filters**: Array of filter objects for narrowing results
|
|
21
|
+
- **connection_id**: Specific connection ID to use
|
|
22
|
+
|
|
23
|
+
### Common Metrics by Platform
|
|
24
|
+
|
|
25
|
+
#### Meta/Facebook Ads
|
|
26
|
+
- spend, impressions, clicks, cpc, cpm, ctr
|
|
27
|
+
- reach, frequency, conversions, cost_per_conversion
|
|
28
|
+
- link_clicks, video_views
|
|
29
|
+
|
|
30
|
+
#### Google Ads
|
|
31
|
+
- cost, impressions, clicks, cpc, cpm, ctr
|
|
32
|
+
- conversions, cost_per_conversion, conversion_rate
|
|
33
|
+
- search_impression_share
|
|
34
|
+
|
|
35
|
+
#### TikTok Ads
|
|
36
|
+
- spend, impressions, clicks, cpc, cpm, ctr
|
|
37
|
+
- conversions, cost_per_conversion, video_views
|
|
38
|
+
|
|
39
|
+
#### Shopify
|
|
40
|
+
- total_sales, orders_count, average_order_value
|
|
41
|
+
- gross_sales, discounts, returns, net_sales
|
|
42
|
+
|
|
43
|
+
### Example Queries
|
|
44
|
+
|
|
45
|
+
1. **Last 30 days Meta Ads spend by campaign**:
|
|
46
|
+
\`\`\`
|
|
47
|
+
platform_api: "facebook-ads"
|
|
48
|
+
metrics: ["spend", "impressions", "clicks", "ctr"]
|
|
49
|
+
dimensions: ["campaign_name"]
|
|
50
|
+
start_date: "2024-01-01"
|
|
51
|
+
end_date: "2024-01-31"
|
|
52
|
+
time_aggregation: "total"
|
|
53
|
+
\`\`\`
|
|
54
|
+
|
|
55
|
+
2. **Daily Google Ads performance**:
|
|
56
|
+
\`\`\`
|
|
57
|
+
platform_api: "google-ads"
|
|
58
|
+
metrics: ["cost", "conversions", "cost_per_conversion"]
|
|
59
|
+
dimensions: ["date"]
|
|
60
|
+
start_date: "2024-01-01"
|
|
61
|
+
\`\`\`
|
|
62
|
+
|
|
63
|
+
### Tips
|
|
64
|
+
- Use \`list_fields\` to see all available metrics and dimensions for a platform
|
|
65
|
+
- Use \`list_connections\` to see which platforms are connected
|
|
66
|
+
- Use \`list_accounts\` to see available ad accounts
|
|
67
|
+
- Use \`get_spend_summary\` for a quick overview across all ad platforms
|
|
68
|
+
`;
|
|
69
|
+
//# sourceMappingURL=query-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-guide.js","sourceRoot":"","sources":["../../src/constants/query-guide.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgE1B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function formatAsMarkdownTable(data: Record<string, unknown>[]): string;
|
|
2
|
+
export declare function formatConnectionsList(connections: unknown[]): string;
|
|
3
|
+
export declare function formatFieldsList(fields: {
|
|
4
|
+
metrics?: unknown[];
|
|
5
|
+
dimensions?: unknown[];
|
|
6
|
+
}): string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatAsMarkdownTable = formatAsMarkdownTable;
|
|
4
|
+
exports.formatConnectionsList = formatConnectionsList;
|
|
5
|
+
exports.formatFieldsList = formatFieldsList;
|
|
6
|
+
function formatAsMarkdownTable(data) {
|
|
7
|
+
if (!data || data.length === 0) {
|
|
8
|
+
return "_No data returned_";
|
|
9
|
+
}
|
|
10
|
+
const columns = Object.keys(data[0]);
|
|
11
|
+
// Header
|
|
12
|
+
const header = "| " + columns.join(" | ") + " |";
|
|
13
|
+
const separator = "| " + columns.map(() => "---").join(" | ") + " |";
|
|
14
|
+
// Rows
|
|
15
|
+
const rows = data.map((row) => {
|
|
16
|
+
const cells = columns.map((col) => {
|
|
17
|
+
const val = row[col];
|
|
18
|
+
if (val === null || val === undefined)
|
|
19
|
+
return "";
|
|
20
|
+
if (typeof val === "number") {
|
|
21
|
+
// Format numbers with commas for readability
|
|
22
|
+
return val.toLocaleString("en-US", { maximumFractionDigits: 2 });
|
|
23
|
+
}
|
|
24
|
+
return String(val);
|
|
25
|
+
});
|
|
26
|
+
return "| " + cells.join(" | ") + " |";
|
|
27
|
+
});
|
|
28
|
+
return [header, separator, ...rows].join("\n");
|
|
29
|
+
}
|
|
30
|
+
function formatConnectionsList(connections) {
|
|
31
|
+
if (!connections || connections.length === 0) {
|
|
32
|
+
return "No platforms connected. Use `connect_platform` to connect one.";
|
|
33
|
+
}
|
|
34
|
+
const items = connections;
|
|
35
|
+
const lines = ["## Connected Platforms\n"];
|
|
36
|
+
for (const conn of items) {
|
|
37
|
+
const platformApi = conn.connection?.platform_api || "unknown";
|
|
38
|
+
const ownerName = conn.token?.token_owner_display_name || conn.token?.token_owner_email || "Unknown";
|
|
39
|
+
const createdAt = conn.connection?.created_at ? new Date(conn.connection.created_at).toLocaleDateString() : "Unknown";
|
|
40
|
+
const accountCount = conn.accounts?.length || 0;
|
|
41
|
+
lines.push(`### ${platformApi}`);
|
|
42
|
+
lines.push(`- **Connected by**: ${ownerName}`);
|
|
43
|
+
lines.push(`- **Connected on**: ${createdAt}`);
|
|
44
|
+
lines.push(`- **Accounts**: ${accountCount}`);
|
|
45
|
+
if (conn.accounts && conn.accounts.length > 0) {
|
|
46
|
+
for (const account of conn.accounts) {
|
|
47
|
+
lines.push(` - ${account.account_display_name || account.account_external_id || "Unnamed"}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
lines.push("");
|
|
51
|
+
}
|
|
52
|
+
return lines.join("\n");
|
|
53
|
+
}
|
|
54
|
+
function formatFieldsList(fields) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
if (fields.metrics && fields.metrics.length > 0) {
|
|
57
|
+
lines.push("## Metrics\n");
|
|
58
|
+
lines.push("| ID | Name | Description |");
|
|
59
|
+
lines.push("| --- | --- | --- |");
|
|
60
|
+
for (const m of fields.metrics) {
|
|
61
|
+
lines.push(`| ${m.id || ""} | ${m.name || ""} | ${m.description || ""} |`);
|
|
62
|
+
}
|
|
63
|
+
lines.push("");
|
|
64
|
+
}
|
|
65
|
+
if (fields.dimensions && fields.dimensions.length > 0) {
|
|
66
|
+
lines.push("## Dimensions\n");
|
|
67
|
+
lines.push("| ID | Name | Description |");
|
|
68
|
+
lines.push("| --- | --- | --- |");
|
|
69
|
+
for (const d of fields.dimensions) {
|
|
70
|
+
lines.push(`| ${d.id || ""} | ${d.name || ""} | ${d.description || ""} |`);
|
|
71
|
+
}
|
|
72
|
+
lines.push("");
|
|
73
|
+
}
|
|
74
|
+
return lines.join("\n") || "_No fields available_";
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=markdown-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-table.js","sourceRoot":"","sources":["../../src/formatters/markdown-table.ts"],"names":[],"mappings":";;AAAA,sDA0BC;AAED,sDAkCC;AAED,4CA+BC;AA/FD,SAAgB,qBAAqB,CAAC,IAA+B;IACpE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,oBAAoB,CAAC;IAC7B,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAErC,SAAS;IACT,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAErE,OAAO;IACP,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;YACjD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC7B,6CAA6C;gBAC7C,OAAO,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,qBAAqB,CAAC,WAAsB;IAC3D,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,gEAAgE,CAAC;IACzE,CAAC;IAQD,MAAM,KAAK,GAAG,WAA+B,CAAC;IAC9C,MAAM,KAAK,GAAa,CAAC,0BAA0B,CAAC,CAAC;IAErD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,IAAI,SAAS,CAAC;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,wBAAwB,IAAI,IAAI,CAAC,KAAK,EAAE,iBAAiB,IAAI,SAAS,CAAC;QACrG,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACtH,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAEhD,KAAK,CAAC,IAAI,CAAC,OAAO,WAAW,EAAE,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,oBAAoB,IAAI,OAAO,CAAC,mBAAmB,IAAI,SAAS,EAAE,CAAC,CAAC;YAC/F,CAAC;QACF,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAAuD;IACvF,MAAM,KAAK,GAAa,EAAE,CAAC;IAS3B,IAAI,MAAM,CAAC,OAAO,IAAK,MAAM,CAAC,OAAuB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAsB,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,IAAK,MAAM,CAAC,UAA0B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAyB,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC,WAAW,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,uBAAuB,CAAC;AACpD,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const server_js_1 = require("./server.js");
|
|
7
|
+
const index_js_2 = require("./resources/index.js");
|
|
8
|
+
const API_KEY = process.env.DETRICS_API_KEY;
|
|
9
|
+
if (!API_KEY) {
|
|
10
|
+
console.error("Error: DETRICS_API_KEY environment variable is required.\n" +
|
|
11
|
+
"Generate one at https://app.detrics.io/settings/api-keys");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const server = new index_js_1.Server({
|
|
15
|
+
name: "detrics",
|
|
16
|
+
version: "0.1.0",
|
|
17
|
+
}, {
|
|
18
|
+
capabilities: {
|
|
19
|
+
tools: {},
|
|
20
|
+
resources: {},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
(0, server_js_1.setupTools)(server, API_KEY);
|
|
24
|
+
(0, index_js_2.setupResources)(server, API_KEY);
|
|
25
|
+
async function main() {
|
|
26
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
27
|
+
await server.connect(transport);
|
|
28
|
+
console.error("Detrics MCP server running on stdio");
|
|
29
|
+
}
|
|
30
|
+
main().catch((error) => {
|
|
31
|
+
console.error("Fatal error:", error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,wEAAmE;AACnE,wEAAiF;AACjF,2CAAyC;AACzC,mDAAsD;AAEtD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAE5C,IAAI,CAAC,OAAO,EAAE,CAAC;IACd,OAAO,CAAC,KAAK,CACZ,4DAA4D;QAC5D,0DAA0D,CAC1D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,iBAAM,CACxB;IACC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,OAAO;CAChB,EACD;IACC,YAAY,EAAE;QACb,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;KACb;CACD,CACD,CAAC;AAEF,IAAA,sBAAU,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5B,IAAA,yBAAc,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IAClB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;AACtD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupResources = setupResources;
|
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
5
|
+
const client_js_1 = require("../api/client.js");
|
|
6
|
+
const query_guide_js_1 = require("../constants/query-guide.js");
|
|
7
|
+
const markdown_table_js_1 = require("../formatters/markdown-table.js");
|
|
8
|
+
const platforms_js_1 = require("../constants/platforms.js");
|
|
9
|
+
function setupResources(server, apiKey) {
|
|
10
|
+
const client = new client_js_1.DetricApiClient(apiKey);
|
|
11
|
+
server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async () => ({
|
|
12
|
+
resources: [
|
|
13
|
+
{
|
|
14
|
+
uri: "detrics://platforms",
|
|
15
|
+
name: "Connected Platforms",
|
|
16
|
+
description: "List of all connected marketing platforms in this workspace",
|
|
17
|
+
mimeType: "text/markdown",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
uri: "detrics://docs/query-guide",
|
|
21
|
+
name: "Query Guide",
|
|
22
|
+
description: "How to query marketing data: available metrics, filter syntax, and examples",
|
|
23
|
+
mimeType: "text/markdown",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
}));
|
|
27
|
+
server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
|
|
28
|
+
const uri = request.params.uri;
|
|
29
|
+
if (uri === "detrics://platforms") {
|
|
30
|
+
const response = await client.get("/api/v1/mcp/connections");
|
|
31
|
+
const result = response.data;
|
|
32
|
+
const content = (0, markdown_table_js_1.formatConnectionsList)(result?.connections || []);
|
|
33
|
+
return {
|
|
34
|
+
contents: [
|
|
35
|
+
{
|
|
36
|
+
uri,
|
|
37
|
+
mimeType: "text/markdown",
|
|
38
|
+
text: content,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (uri === "detrics://docs/query-guide") {
|
|
44
|
+
return {
|
|
45
|
+
contents: [
|
|
46
|
+
{
|
|
47
|
+
uri,
|
|
48
|
+
mimeType: "text/markdown",
|
|
49
|
+
text: query_guide_js_1.QUERY_GUIDE,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Dynamic platform fields resource: detrics://platforms/{api}/fields
|
|
55
|
+
const fieldsMatch = uri.match(/^detrics:\/\/platforms\/([^/]+)\/fields$/);
|
|
56
|
+
if (fieldsMatch) {
|
|
57
|
+
const platformApi = fieldsMatch[1];
|
|
58
|
+
const response = await client.post("/api/v1/mcp/fields", { platform_api: platformApi });
|
|
59
|
+
const platformName = platforms_js_1.PLATFORM_DISPLAY_NAMES[platformApi] || platformApi;
|
|
60
|
+
const content = `# ${platformName} Fields\n\n${(0, markdown_table_js_1.formatFieldsList)(response.data)}`;
|
|
61
|
+
return {
|
|
62
|
+
contents: [
|
|
63
|
+
{
|
|
64
|
+
uri,
|
|
65
|
+
mimeType: "text/markdown",
|
|
66
|
+
text: content,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":";;AAUA,wCAsEC;AA/ED,iEAG4C;AAC5C,gDAAmD;AACnD,gEAA0D;AAC1D,uEAA0F;AAC1F,4DAAmE;AAEnE,SAAgB,cAAc,CAAC,MAAc,EAAE,MAAc;IAC5D,MAAM,MAAM,GAAG,IAAI,2BAAe,CAAC,MAAM,CAAC,CAAC;IAE3C,MAAM,CAAC,iBAAiB,CAAC,qCAA0B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACjE,SAAS,EAAE;YACV;gBACC,GAAG,EAAE,qBAAqB;gBAC1B,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EAAE,6DAA6D;gBAC1E,QAAQ,EAAE,eAAe;aACzB;YACD;gBACC,GAAG,EAAE,4BAA4B;gBACjC,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,6EAA6E;gBAC1F,QAAQ,EAAE,eAAe;aACzB;SACD;KACD,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,oCAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACrE,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;QAE/B,IAAI,GAAG,KAAK,qBAAqB,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAmC,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAA,yCAAqB,EAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;YACjE,OAAO;gBACN,QAAQ,EAAE;oBACT;wBACC,GAAG;wBACH,QAAQ,EAAE,eAAe;wBACzB,IAAI,EAAE,OAAO;qBACb;iBACD;aACD,CAAC;QACH,CAAC;QAED,IAAI,GAAG,KAAK,4BAA4B,EAAE,CAAC;YAC1C,OAAO;gBACN,QAAQ,EAAE;oBACT;wBACC,GAAG;wBACH,QAAQ,EAAE,eAAe;wBACzB,IAAI,EAAE,4BAAW;qBACjB;iBACD;aACD,CAAC;QACH,CAAC;QAED,qEAAqE;QACrE,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1E,IAAI,WAAW,EAAE,CAAC;YACjB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YACxF,MAAM,YAAY,GAAG,qCAAsB,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC;YACxE,MAAM,OAAO,GAAG,KAAK,YAAY,cAAc,IAAA,oCAAgB,EAAC,QAAQ,CAAC,IAAuD,CAAC,EAAE,CAAC;YACpI,OAAO;gBACN,QAAQ,EAAE;oBACT;wBACC,GAAG;wBACH,QAAQ,EAAE,eAAe;wBACzB,IAAI,EAAE,OAAO;qBACb;iBACD;aACD,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/server.d.ts
ADDED
package/dist/server.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupTools = setupTools;
|
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
5
|
+
const client_js_1 = require("./api/client.js");
|
|
6
|
+
const markdown_table_js_1 = require("./formatters/markdown-table.js");
|
|
7
|
+
const platforms_js_1 = require("./constants/platforms.js");
|
|
8
|
+
function setupTools(server, apiKey) {
|
|
9
|
+
const client = new client_js_1.DetricApiClient(apiKey);
|
|
10
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
11
|
+
tools: [
|
|
12
|
+
{
|
|
13
|
+
name: "query_marketing_data",
|
|
14
|
+
description: "Query marketing data from a connected platform (Meta Ads, Google Ads, TikTok, Shopify, etc.). Returns metrics like spend, impressions, clicks, conversions grouped by dimensions like campaign, date, ad set.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
platform_api: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Platform identifier. Examples: facebook-ads, google-ads, tiktok-ads, shopify-store, google-analytics-4, linkedin-ads, pinterest-ads, stripe",
|
|
21
|
+
},
|
|
22
|
+
metrics: {
|
|
23
|
+
type: "array",
|
|
24
|
+
items: { type: "string" },
|
|
25
|
+
description: "Metrics to fetch. Use list_fields to see available metrics. Examples: spend, impressions, clicks, conversions, cpc, ctr",
|
|
26
|
+
},
|
|
27
|
+
dimensions: {
|
|
28
|
+
type: "array",
|
|
29
|
+
items: { type: "string" },
|
|
30
|
+
description: "Dimensions to group by. Examples: campaign_name, date, ad_set_name, country",
|
|
31
|
+
},
|
|
32
|
+
start_date: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Start date in YYYY-MM-DD format",
|
|
35
|
+
},
|
|
36
|
+
end_date: {
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "End date in YYYY-MM-DD format. Defaults to today.",
|
|
39
|
+
},
|
|
40
|
+
time_aggregation: {
|
|
41
|
+
type: "string",
|
|
42
|
+
enum: ["day", "week", "month", "total"],
|
|
43
|
+
description: "Time aggregation level. Default: day",
|
|
44
|
+
},
|
|
45
|
+
account_ids: {
|
|
46
|
+
type: "array",
|
|
47
|
+
items: { type: "string" },
|
|
48
|
+
description: "Specific account IDs. Defaults to all connected accounts.",
|
|
49
|
+
},
|
|
50
|
+
connection_id: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "Specific connection ID to use (optional)",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
required: ["platform_api", "metrics", "start_date"],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "list_connections",
|
|
60
|
+
description: "List all connected marketing platforms in this workspace, including account details and connection status.",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "list_fields",
|
|
68
|
+
description: "List available metrics and dimensions for a specific platform. Use this to discover what data you can query.",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
platform_api: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Platform identifier. Examples: facebook-ads, google-ads, tiktok-ads, shopify-store",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
required: ["platform_api"],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "list_accounts",
|
|
82
|
+
description: "List ad accounts or store accounts for a connected platform.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
platform_api: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Platform identifier",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ["platform_api"],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "connect_platform",
|
|
96
|
+
description: "Start the OAuth flow to connect a new marketing platform. Returns a URL the user must open in their browser to authorize access.",
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
platform_api: {
|
|
101
|
+
type: "string",
|
|
102
|
+
description: "Platform to connect. Examples: facebook-ads, google-ads, tiktok-ads, shopify-store",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
required: ["platform_api"],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "check_connection_status",
|
|
110
|
+
description: "Check the status of an in-progress platform connection (after user clicks the OAuth URL from connect_platform).",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {
|
|
114
|
+
polling_job_id: {
|
|
115
|
+
type: "string",
|
|
116
|
+
description: "The polling job ID returned by connect_platform",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
required: ["polling_job_id"],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "get_spend_summary",
|
|
124
|
+
description: "Get a quick spend summary across all connected ad platforms for a given period.",
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
period: {
|
|
129
|
+
type: "string",
|
|
130
|
+
enum: ["today", "yesterday", "last_7_days", "last_30_days", "this_month"],
|
|
131
|
+
description: "Time period for the summary. Default: last_30_days",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
}));
|
|
138
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
139
|
+
const { name, arguments: args } = request.params;
|
|
140
|
+
try {
|
|
141
|
+
switch (name) {
|
|
142
|
+
case "query_marketing_data": {
|
|
143
|
+
const response = await client.post("/api/v1/mcp/query", args);
|
|
144
|
+
if (response.status !== 200) {
|
|
145
|
+
return {
|
|
146
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
147
|
+
isError: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const result = response.data;
|
|
151
|
+
const rows = result?.data?.rows || [];
|
|
152
|
+
const table = (0, markdown_table_js_1.formatAsMarkdownTable)(rows);
|
|
153
|
+
const cached = result?.cached ? " (cached)" : "";
|
|
154
|
+
return {
|
|
155
|
+
content: [{ type: "text", text: `${table}\n\n_${rows.length} rows returned${cached}_` }],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
case "list_connections": {
|
|
159
|
+
const response = await client.get("/api/v1/mcp/connections");
|
|
160
|
+
if (response.status !== 200) {
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
163
|
+
isError: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const result = response.data;
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: "text", text: (0, markdown_table_js_1.formatConnectionsList)(result?.connections || []) }],
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
case "list_fields": {
|
|
172
|
+
const response = await client.post("/api/v1/mcp/fields", args);
|
|
173
|
+
if (response.status !== 200) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
176
|
+
isError: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const platformName = platforms_js_1.PLATFORM_DISPLAY_NAMES[args?.platform_api] || args?.platform_api;
|
|
180
|
+
return {
|
|
181
|
+
content: [{ type: "text", text: `# ${platformName} Fields\n\n${(0, markdown_table_js_1.formatFieldsList)(response.data)}` }],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
case "list_accounts": {
|
|
185
|
+
const response = await client.post("/api/v1/mcp/accounts", args);
|
|
186
|
+
if (response.status !== 200) {
|
|
187
|
+
return {
|
|
188
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
189
|
+
isError: true,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
content: [{ type: "text", text: `## Accounts\n\n\`\`\`json\n${JSON.stringify(response.data, null, 2)}\n\`\`\`` }],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
case "connect_platform": {
|
|
197
|
+
const response = await client.post("/api/v1/mcp/connect/initiate", args);
|
|
198
|
+
if (response.status !== 200) {
|
|
199
|
+
return {
|
|
200
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
201
|
+
isError: true,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const result = response.data;
|
|
205
|
+
const platformName = platforms_js_1.PLATFORM_DISPLAY_NAMES[result?.platformApi || ""] || result?.platformApi;
|
|
206
|
+
return {
|
|
207
|
+
content: [{
|
|
208
|
+
type: "text",
|
|
209
|
+
text: `## Connect ${platformName}\n\nPlease open this URL in your browser to authorize access:\n\n${result?.oauthUrl}\n\nAfter completing authorization, use \`check_connection_status\` with polling_job_id: \`${result?.pollingJobId}\` to verify the connection.`,
|
|
210
|
+
}],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
case "check_connection_status": {
|
|
214
|
+
const jobId = args?.polling_job_id;
|
|
215
|
+
const response = await client.get(`/api/v1/mcp/connect/status/${jobId}`);
|
|
216
|
+
if (response.status !== 200) {
|
|
217
|
+
return {
|
|
218
|
+
content: [{ type: "text", text: `Error: ${JSON.stringify(response.data)}` }],
|
|
219
|
+
isError: true,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const result = response.data;
|
|
223
|
+
const status = result?.connectionStatus;
|
|
224
|
+
let message;
|
|
225
|
+
switch (status) {
|
|
226
|
+
case "WAITING":
|
|
227
|
+
message = "Waiting for user to complete authorization in their browser...";
|
|
228
|
+
break;
|
|
229
|
+
case "LOADING_ACCOUNTS":
|
|
230
|
+
message = "Authorization complete! Loading accounts...";
|
|
231
|
+
break;
|
|
232
|
+
case "SUCCESS":
|
|
233
|
+
message = "Connection successful! The platform is now connected and ready to query.";
|
|
234
|
+
break;
|
|
235
|
+
case "FAILED":
|
|
236
|
+
message = `Connection failed: ${result?.errorMessage || "Unknown error"}`;
|
|
237
|
+
break;
|
|
238
|
+
case "FAILED_LOADING_ACCOUNTS":
|
|
239
|
+
message = `Connected but failed to load accounts: ${result?.errorMessage || "Unknown error"}`;
|
|
240
|
+
break;
|
|
241
|
+
case "NO_ACCOUNTS_FOUND":
|
|
242
|
+
message = "Connected but no accounts found. The user may need to grant access to specific accounts.";
|
|
243
|
+
break;
|
|
244
|
+
case "TIMEOUT":
|
|
245
|
+
message = "Connection timed out. Please try again.";
|
|
246
|
+
break;
|
|
247
|
+
default:
|
|
248
|
+
message = `Status: ${status}`;
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
content: [{ type: "text", text: message }],
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
case "get_spend_summary": {
|
|
255
|
+
const period = args?.period || "last_30_days";
|
|
256
|
+
const { startDate, endDate } = getDateRange(period);
|
|
257
|
+
// First get connections to find ad platforms
|
|
258
|
+
const connectionsResponse = await client.get("/api/v1/mcp/connections");
|
|
259
|
+
if (connectionsResponse.status !== 200) {
|
|
260
|
+
return {
|
|
261
|
+
content: [{ type: "text", text: "Failed to fetch connections" }],
|
|
262
|
+
isError: true,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const connectionsData = connectionsResponse.data;
|
|
266
|
+
const connections = connectionsData?.connections || [];
|
|
267
|
+
const connectedAdPlatforms = connections
|
|
268
|
+
.map((c) => c.connection?.platform_api)
|
|
269
|
+
.filter((p) => !!p && platforms_js_1.AD_PLATFORMS.includes(p));
|
|
270
|
+
const uniquePlatforms = [...new Set(connectedAdPlatforms)];
|
|
271
|
+
if (uniquePlatforms.length === 0) {
|
|
272
|
+
return {
|
|
273
|
+
content: [{ type: "text", text: "No ad platforms connected. Connect one using `connect_platform`." }],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const results = [];
|
|
277
|
+
for (const platform of uniquePlatforms) {
|
|
278
|
+
const queryResponse = await client.post("/api/v1/mcp/query", {
|
|
279
|
+
platform_api: platform,
|
|
280
|
+
metrics: ["spend"],
|
|
281
|
+
start_date: startDate,
|
|
282
|
+
end_date: endDate,
|
|
283
|
+
time_aggregation: "total",
|
|
284
|
+
});
|
|
285
|
+
if (queryResponse.status === 200) {
|
|
286
|
+
const queryResult = queryResponse.data;
|
|
287
|
+
const rows = queryResult?.data?.rows || [];
|
|
288
|
+
const totalSpend = rows.reduce((sum, row) => sum + (Number(row?.spend) || 0), 0);
|
|
289
|
+
results.push({ platform, spend: totalSpend });
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
results.push({ platform, spend: 0, error: "Failed to fetch" });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const totalSpend = results.reduce((sum, r) => sum + r.spend, 0);
|
|
296
|
+
const lines = [`## Spend Summary (${period.replace(/_/g, " ")})\n`];
|
|
297
|
+
lines.push("| Platform | Spend |");
|
|
298
|
+
lines.push("| --- | ---: |");
|
|
299
|
+
for (const r of results) {
|
|
300
|
+
const name = platforms_js_1.PLATFORM_DISPLAY_NAMES[r.platform] || r.platform;
|
|
301
|
+
const spend = r.error ? `_${r.error}_` : `$${r.spend.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
302
|
+
lines.push(`| ${name} | ${spend} |`);
|
|
303
|
+
}
|
|
304
|
+
lines.push(`| **Total** | **$${totalSpend.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}** |`);
|
|
305
|
+
return {
|
|
306
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
default:
|
|
310
|
+
return {
|
|
311
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
312
|
+
isError: true,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
318
|
+
return {
|
|
319
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
320
|
+
isError: true,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
function getDateRange(period) {
|
|
326
|
+
const now = new Date();
|
|
327
|
+
const today = now.toISOString().split("T")[0];
|
|
328
|
+
const yesterday = new Date(now);
|
|
329
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
330
|
+
switch (period) {
|
|
331
|
+
case "today":
|
|
332
|
+
return { startDate: today, endDate: today };
|
|
333
|
+
case "yesterday": {
|
|
334
|
+
const d = yesterday.toISOString().split("T")[0];
|
|
335
|
+
return { startDate: d, endDate: d };
|
|
336
|
+
}
|
|
337
|
+
case "last_7_days": {
|
|
338
|
+
const d = new Date(now);
|
|
339
|
+
d.setDate(d.getDate() - 7);
|
|
340
|
+
return { startDate: d.toISOString().split("T")[0], endDate: today };
|
|
341
|
+
}
|
|
342
|
+
case "last_30_days": {
|
|
343
|
+
const d = new Date(now);
|
|
344
|
+
d.setDate(d.getDate() - 30);
|
|
345
|
+
return { startDate: d.toISOString().split("T")[0], endDate: today };
|
|
346
|
+
}
|
|
347
|
+
case "this_month": {
|
|
348
|
+
const d = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
349
|
+
return { startDate: d.toISOString().split("T")[0], endDate: today };
|
|
350
|
+
}
|
|
351
|
+
default: {
|
|
352
|
+
const d = new Date(now);
|
|
353
|
+
d.setDate(d.getDate() - 30);
|
|
354
|
+
return { startDate: d.toISOString().split("T")[0], endDate: today };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//# 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/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "detrics",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Detrics MCP server - Query marketing data from AI assistants",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"detrics": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "marketing", "analytics", "detrics"],
|
|
15
|
+
"author": "Detrics",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.10.0",
|
|
22
|
+
"tsx": "^4.7.0",
|
|
23
|
+
"typescript": "^5.3.0"
|
|
24
|
+
}
|
|
25
|
+
}
|