@attrkit/mcp 0.4.3 → 0.4.5
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/README.md +1 -1
- package/dist/cli.js +20 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Install Node.js 18 or newer. The `npx -y @attrkit/mcp` command downloads and
|
|
|
33
33
|
starts the server automatically, so no global install is required.
|
|
34
34
|
|
|
35
35
|
Create the first workspace management key under
|
|
36
|
-
[Dashboard → Settings → API keys](https://attrikit.io/en/dashboard/settings/api-keys).
|
|
36
|
+
[Dashboard → Settings → API keys & MCP](https://attrikit.io/en/dashboard/settings/api-keys).
|
|
37
37
|
This one-time bootstrap requires the dashboard.
|
|
38
38
|
|
|
39
39
|
After that first key exists, a workspace-scoped read/write key can manage every
|
package/dist/cli.js
CHANGED
|
@@ -14076,7 +14076,8 @@ function toToolResult(result) {
|
|
|
14076
14076
|
const code = envelope?.error?.code ?? `http_${result.status}`;
|
|
14077
14077
|
const message = envelope?.error?.message ? `: ${envelope.error.message}` : "";
|
|
14078
14078
|
const retryAfter = result.status === 429 && result.retryAfter ? ` (Retry-After: ${result.retryAfter})` : "";
|
|
14079
|
-
const
|
|
14079
|
+
const redact = (text) => text.replace(/\b(?:mk|pk|sk|rk)_[A-Za-z0-9_-]{8,}/g, "[redacted-key]").replace(/\b[Bb]earer\s+[A-Za-z0-9._-]{8,}/g, "Bearer [redacted]").replace(/\bAttriKit-(?:Management|Publishable)\s+\S+/g, "AttriKit-$1 [redacted]").replace(/([?&](?:token|secret|key|password|code|signature)=)[^&\s]+/gi, "$1[redacted]");
|
|
14080
|
+
const excerpt = !envelope?.error?.message && result.rawBody ? ` — body: ${redact(result.rawBody.replace(/\s+/g, " ").trim()).slice(0, 300)}` : "";
|
|
14080
14081
|
const hint = result.status === 401 ? " Check ATTRKIT_API_KEY: this is the same error for a missing, wrong, revoked or expired key." : "";
|
|
14081
14082
|
return {
|
|
14082
14083
|
content: [{
|
|
@@ -14090,7 +14091,8 @@ function toToolResult(result) {
|
|
|
14090
14091
|
const isEmptySuccess = result.status === 204 && (result.rawBody === undefined || result.rawBody === "");
|
|
14091
14092
|
const isJsonEnvelope = result.json !== null && typeof result.json === "object" && !Array.isArray(result.json) && Object.hasOwn(result.json, "data");
|
|
14092
14093
|
const contentType = (result.contentType ?? "").toLowerCase();
|
|
14093
|
-
const
|
|
14094
|
+
const looksLikeMarkup = typeof result.json === "string" && /^\s*<(?:!doctype|html|head|body)\b/i.test(result.json);
|
|
14095
|
+
const isExpectedText = expectedResponse === "text" && typeof result.json === "string" && !contentType.includes("text/html") && !looksLikeMarkup;
|
|
14094
14096
|
if (!isEmptySuccess && !isJsonEnvelope && !isExpectedText) {
|
|
14095
14097
|
const reportedContentType = result.contentType ?? "unknown content type";
|
|
14096
14098
|
const received = result.json === null ? "an empty body" : Array.isArray(result.json) ? "a JSON array" : typeof result.json === "object" ? "a JSON object without a data field" : `a ${typeof result.json} body`;
|
|
@@ -14110,12 +14112,14 @@ ${body}`
|
|
|
14110
14112
|
structuredContent: structured
|
|
14111
14113
|
};
|
|
14112
14114
|
}
|
|
14113
|
-
var SERVER_VERSION = "0.4.
|
|
14115
|
+
var SERVER_VERSION = "0.4.5";
|
|
14114
14116
|
var periodSchema = z4.enum(["7d", "30d", "90d", "all"]).describe("Reporting window. Defaults to 30d.").optional();
|
|
14115
14117
|
var appIdSchema = z4.string().describe("Optional app id to scope the result to one app.").optional();
|
|
14116
14118
|
var requiredAppIdSchema = z4.string().describe("The AttrKit app id.");
|
|
14117
14119
|
var idempotencyKeySchema = z4.string().max(255).describe("Stable retry key for this exact mutation.").optional();
|
|
14118
14120
|
var ownersSchema = z4.record(z4.string(), z4.enum(["attrkit", "revenuecat", "customer"]));
|
|
14121
|
+
var cursorSchema = z4.string().optional().describe("Pass the next_cursor from the previous response to fetch the following page. Omit for the first page.");
|
|
14122
|
+
var listLimitSchema = z4.number().int().min(1).max(200).optional().describe("Rows per page, 1-200. The API defaults to 50, so a workspace with more than that needs paging.");
|
|
14119
14123
|
var spendRowSchema = z4.object({
|
|
14120
14124
|
campaign_id: z4.string().optional().describe("The AttrKit campaign UUID, NOT the ad network's own campaign id. It is the opposite of create_campaign_link.campaign_id and is the most common mistake here: read it from list_campaigns. The API rejects a network id by name. Preferred snake_case spelling."),
|
|
14121
14125
|
campaignId: z4.string().optional().describe("Accepted camelCase alias for campaign_id."),
|
|
@@ -14212,8 +14216,10 @@ function createServer(config, fetchImpl) {
|
|
|
14212
14216
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14213
14217
|
title: "List apps",
|
|
14214
14218
|
description: "List the iOS and Android apps in your AttrKit workspace (id, name, platform, bundle id, store id, status).",
|
|
14215
|
-
inputSchema: {}
|
|
14216
|
-
}, async () => toToolResult(await call("/api/v1/apps"
|
|
14219
|
+
inputSchema: { cursor: cursorSchema, limit: listLimitSchema }
|
|
14220
|
+
}, async ({ cursor, limit }) => toToolResult(await call("/api/v1/apps", {
|
|
14221
|
+
query: { ...cursor ? { cursor } : {}, ...limit === undefined ? {} : { limit: String(limit) } }
|
|
14222
|
+
})));
|
|
14217
14223
|
server.registerTool("create_app", {
|
|
14218
14224
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14219
14225
|
title: "Create an app",
|
|
@@ -14360,8 +14366,15 @@ function createServer(config, fetchImpl) {
|
|
|
14360
14366
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14361
14367
|
title: "List campaigns",
|
|
14362
14368
|
description: "List ad campaigns with their honest profit surface: the scale/cut/hold call, profit p05/p50/p95, spend, retention, and payback. Use this to see how campaigns are performing.",
|
|
14363
|
-
inputSchema: { app_id: appIdSchema, period: periodSchema }
|
|
14364
|
-
}, async ({ app_id, period }) => toToolResult(await call("/api/v1/reports/campaigns", {
|
|
14369
|
+
inputSchema: { app_id: appIdSchema, period: periodSchema, cursor: cursorSchema, limit: listLimitSchema }
|
|
14370
|
+
}, async ({ app_id, period, cursor, limit }) => toToolResult(await call("/api/v1/reports/campaigns", {
|
|
14371
|
+
query: {
|
|
14372
|
+
appId: app_id,
|
|
14373
|
+
period,
|
|
14374
|
+
...cursor ? { cursor } : {},
|
|
14375
|
+
...limit === undefined ? {} : { limit: String(limit) }
|
|
14376
|
+
}
|
|
14377
|
+
})));
|
|
14365
14378
|
server.registerTool("list_ads", {
|
|
14366
14379
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14367
14380
|
title: "List creative-level ad performance",
|