appfigures-mcp 0.1.0 → 0.1.1
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 +13 -0
- package/dist/index.js +532 -147
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,3 +28,16 @@ APPFIGURES_TOKEN=pat_... npx appfigures-mcp
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
To use in an MCP client, configure the command to `npx` with args `appfigures-mcp`, and pass `APPFIGURES_TOKEN` in the environment.
|
|
31
|
+
|
|
32
|
+
## API Coverage
|
|
33
|
+
|
|
34
|
+
All endpoints are available via the `appfigures_request` tool (any method/path/query/body).
|
|
35
|
+
Convenience tools (grouped) exist for:
|
|
36
|
+
- `appfigures_products`
|
|
37
|
+
- `appfigures_ratings`
|
|
38
|
+
- `appfigures_featured`
|
|
39
|
+
- `appfigures_sales`
|
|
40
|
+
- `appfigures_ads`
|
|
41
|
+
- `appfigures_reviews`
|
|
42
|
+
- `appfigures_users`
|
|
43
|
+
- `appfigures_data`
|
package/dist/index.js
CHANGED
|
@@ -28309,7 +28309,7 @@ function buildQuery(params) {
|
|
|
28309
28309
|
if (Array.isArray(value)) {
|
|
28310
28310
|
if (value.length === 0)
|
|
28311
28311
|
continue;
|
|
28312
|
-
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value.join(","))}`);
|
|
28312
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(value.map((item) => String(item)).join(","))}`);
|
|
28313
28313
|
continue;
|
|
28314
28314
|
}
|
|
28315
28315
|
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
@@ -28334,21 +28334,79 @@ function getUserAgent() {
|
|
|
28334
28334
|
const userAgent = process.env.APPFIGURES_USER_AGENT;
|
|
28335
28335
|
return userAgent && userAgent.length > 0 ? userAgent : DEFAULT_USER_AGENT;
|
|
28336
28336
|
}
|
|
28337
|
-
|
|
28338
|
-
|
|
28339
|
-
|
|
28340
|
-
return
|
|
28337
|
+
function buildAuthHeader(auth) {
|
|
28338
|
+
if (!auth) {
|
|
28339
|
+
const token = getAuthToken();
|
|
28340
|
+
return token ? `Bearer ${token}` : null;
|
|
28341
|
+
}
|
|
28342
|
+
if (auth.type === "none")
|
|
28343
|
+
return null;
|
|
28344
|
+
if (auth.type === "bearer") {
|
|
28345
|
+
const token = auth.token ?? getAuthToken();
|
|
28346
|
+
return token ? `Bearer ${token}` : null;
|
|
28347
|
+
}
|
|
28348
|
+
const encoded = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
|
|
28349
|
+
return `Basic ${encoded}`;
|
|
28350
|
+
}
|
|
28351
|
+
function buildFormBody(body) {
|
|
28352
|
+
const parts = [];
|
|
28353
|
+
for (const [key, value] of Object.entries(body)) {
|
|
28354
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
28355
|
+
}
|
|
28356
|
+
return parts.join("&");
|
|
28357
|
+
}
|
|
28358
|
+
function isRecordOfPrimitives(value) {
|
|
28359
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
28360
|
+
return false;
|
|
28361
|
+
for (const entry of Object.entries(value)) {
|
|
28362
|
+
const entryValue = entry[1];
|
|
28363
|
+
if (typeof entryValue !== "string" && typeof entryValue !== "number" && typeof entryValue !== "boolean") {
|
|
28364
|
+
return false;
|
|
28365
|
+
}
|
|
28366
|
+
}
|
|
28367
|
+
return true;
|
|
28368
|
+
}
|
|
28369
|
+
async function appfiguresRequest(params) {
|
|
28370
|
+
const { method, path, query, body, contentType, headers, auth } = params;
|
|
28371
|
+
const authorization = buildAuthHeader(auth);
|
|
28372
|
+
if (!authorization && (!headers || !headers.Authorization)) {
|
|
28373
|
+
return "Missing authentication. Set APPFIGURES_TOKEN or pass auth/headers.Authorization.";
|
|
28374
|
+
}
|
|
28375
|
+
if (auth && headers && headers.Authorization) {
|
|
28376
|
+
return "Provide auth or headers.Authorization, not both.";
|
|
28341
28377
|
}
|
|
28342
28378
|
const url2 = `${APPFIGURES_BASE_URL}${path}${query ?? ""}`;
|
|
28343
|
-
const
|
|
28344
|
-
|
|
28345
|
-
headers
|
|
28346
|
-
|
|
28347
|
-
|
|
28379
|
+
const outgoingHeaders = {
|
|
28380
|
+
"User-Agent": getUserAgent(),
|
|
28381
|
+
...headers
|
|
28382
|
+
};
|
|
28383
|
+
if (authorization) {
|
|
28384
|
+
outgoingHeaders.Authorization = authorization;
|
|
28385
|
+
}
|
|
28386
|
+
let requestBody;
|
|
28387
|
+
if (method !== "GET" && method !== "DELETE" && body !== undefined) {
|
|
28388
|
+
if (contentType === "form") {
|
|
28389
|
+
if (isRecordOfPrimitives(body)) {
|
|
28390
|
+
requestBody = buildFormBody(body);
|
|
28391
|
+
outgoingHeaders["Content-Type"] = "application/x-www-form-urlencoded";
|
|
28392
|
+
} else {
|
|
28393
|
+
return "Form bodies must be an object of primitive values.";
|
|
28394
|
+
}
|
|
28395
|
+
} else if (contentType === "text") {
|
|
28396
|
+
requestBody = String(body);
|
|
28397
|
+
outgoingHeaders["Content-Type"] = "text/plain";
|
|
28398
|
+
} else {
|
|
28399
|
+
requestBody = JSON.stringify(body ?? {});
|
|
28400
|
+
outgoingHeaders["Content-Type"] = "application/json";
|
|
28348
28401
|
}
|
|
28402
|
+
}
|
|
28403
|
+
const response = await fetch(url2, {
|
|
28404
|
+
method,
|
|
28405
|
+
headers: outgoingHeaders,
|
|
28406
|
+
body: requestBody
|
|
28349
28407
|
});
|
|
28350
|
-
const
|
|
28351
|
-
const formattedBody = prettyBody(
|
|
28408
|
+
const responseBody = await response.text();
|
|
28409
|
+
const formattedBody = prettyBody(responseBody, response.headers.get("content-type"));
|
|
28352
28410
|
if (!response.ok) {
|
|
28353
28411
|
return `HTTP ${response.status} ${response.statusText}
|
|
28354
28412
|
${formattedBody}`;
|
|
@@ -28362,198 +28420,525 @@ server.registerTool("appfigures_status", {
|
|
|
28362
28420
|
content: [
|
|
28363
28421
|
{
|
|
28364
28422
|
type: "text",
|
|
28365
|
-
text: await
|
|
28423
|
+
text: await appfiguresRequest({ method: "GET", path: "/" })
|
|
28366
28424
|
}
|
|
28367
28425
|
]
|
|
28368
28426
|
}));
|
|
28369
|
-
|
|
28370
|
-
|
|
28371
|
-
|
|
28372
|
-
|
|
28427
|
+
var reportSchemaBase = exports_external.object({
|
|
28428
|
+
start_date: exports_external.string().min(1).optional(),
|
|
28429
|
+
end_date: exports_external.string().min(1).optional(),
|
|
28430
|
+
group_by: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28431
|
+
granularity: exports_external.string().min(1).optional(),
|
|
28432
|
+
products: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28433
|
+
countries: exports_external.array(exports_external.string().min(2)).optional(),
|
|
28434
|
+
format: exports_external.enum(["json", "csv", "JSON", "CSV"]).optional()
|
|
28435
|
+
});
|
|
28436
|
+
var reviewsQuerySchema = exports_external.object({
|
|
28437
|
+
q: exports_external.string().min(1).optional(),
|
|
28438
|
+
products: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28439
|
+
countries: exports_external.array(exports_external.string().min(2)).optional(),
|
|
28440
|
+
page: exports_external.number().int().positive().optional(),
|
|
28441
|
+
count: exports_external.number().int().positive().optional(),
|
|
28442
|
+
lang: exports_external.string().min(1).optional(),
|
|
28443
|
+
author: exports_external.string().min(1).optional(),
|
|
28444
|
+
versions: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28445
|
+
stars: exports_external.array(exports_external.number().int().min(1).max(5)).optional(),
|
|
28446
|
+
sort: exports_external.string().min(1).optional(),
|
|
28447
|
+
start: exports_external.string().min(1).optional(),
|
|
28448
|
+
end: exports_external.string().min(1).optional()
|
|
28449
|
+
});
|
|
28450
|
+
function buildReviewsQuery(input) {
|
|
28451
|
+
return buildQuery({
|
|
28452
|
+
q: input.q,
|
|
28453
|
+
products: input.products,
|
|
28454
|
+
countries: input.countries,
|
|
28455
|
+
page: input.page,
|
|
28456
|
+
count: input.count,
|
|
28457
|
+
lang: input.lang,
|
|
28458
|
+
author: input.author,
|
|
28459
|
+
versions: input.versions,
|
|
28460
|
+
stars: input.stars,
|
|
28461
|
+
sort: input.sort,
|
|
28462
|
+
start: input.start,
|
|
28463
|
+
end: input.end
|
|
28464
|
+
});
|
|
28465
|
+
}
|
|
28466
|
+
function reportQueryFrom(input) {
|
|
28467
|
+
return {
|
|
28468
|
+
start_date: input.start_date,
|
|
28469
|
+
end_date: input.end_date,
|
|
28470
|
+
group_by: input.group_by,
|
|
28471
|
+
granularity: input.granularity,
|
|
28472
|
+
products: input.products,
|
|
28473
|
+
countries: input.countries,
|
|
28474
|
+
format: input.format,
|
|
28475
|
+
networks: input.networks
|
|
28476
|
+
};
|
|
28477
|
+
}
|
|
28478
|
+
server.registerTool("appfigures_products", {
|
|
28479
|
+
description: "Product lookups: get/search/list.",
|
|
28480
|
+
inputSchema: exports_external.discriminatedUnion("action", [
|
|
28481
|
+
exports_external.object({
|
|
28482
|
+
action: exports_external.literal("get"),
|
|
28483
|
+
id: exports_external.number().int().positive()
|
|
28484
|
+
}),
|
|
28485
|
+
exports_external.object({
|
|
28486
|
+
action: exports_external.literal("get_by_store"),
|
|
28487
|
+
store: exports_external.string().min(1),
|
|
28488
|
+
id_in_store: exports_external.string().min(1)
|
|
28489
|
+
}),
|
|
28490
|
+
exports_external.object({
|
|
28491
|
+
action: exports_external.literal("search"),
|
|
28492
|
+
term: exports_external.string().min(1),
|
|
28493
|
+
storefronts: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28494
|
+
page: exports_external.number().int().positive().optional(),
|
|
28495
|
+
count: exports_external.number().int().positive().optional()
|
|
28496
|
+
}),
|
|
28497
|
+
exports_external.object({
|
|
28498
|
+
action: exports_external.literal("list_mine"),
|
|
28499
|
+
store: exports_external.string().min(1).optional(),
|
|
28500
|
+
include_inactive: exports_external.boolean().optional()
|
|
28501
|
+
})
|
|
28502
|
+
])
|
|
28503
|
+
}, async (input) => {
|
|
28504
|
+
if (input.action === "get") {
|
|
28505
|
+
return {
|
|
28506
|
+
content: [
|
|
28507
|
+
{
|
|
28508
|
+
type: "text",
|
|
28509
|
+
text: await appfiguresRequest({
|
|
28510
|
+
method: "GET",
|
|
28511
|
+
path: `/products/${input.id}`
|
|
28512
|
+
})
|
|
28513
|
+
}
|
|
28514
|
+
]
|
|
28515
|
+
};
|
|
28373
28516
|
}
|
|
28374
|
-
|
|
28375
|
-
|
|
28376
|
-
|
|
28377
|
-
|
|
28378
|
-
|
|
28379
|
-
|
|
28380
|
-
|
|
28381
|
-
})
|
|
28382
|
-
|
|
28383
|
-
|
|
28384
|
-
|
|
28385
|
-
|
|
28386
|
-
|
|
28517
|
+
if (input.action === "get_by_store") {
|
|
28518
|
+
return {
|
|
28519
|
+
content: [
|
|
28520
|
+
{
|
|
28521
|
+
type: "text",
|
|
28522
|
+
text: await appfiguresRequest({
|
|
28523
|
+
method: "GET",
|
|
28524
|
+
path: `/products/${encodeURIComponent(input.store)}/${encodeURIComponent(input.id_in_store)}`
|
|
28525
|
+
})
|
|
28526
|
+
}
|
|
28527
|
+
]
|
|
28528
|
+
};
|
|
28529
|
+
}
|
|
28530
|
+
if (input.action === "search") {
|
|
28531
|
+
const query2 = buildQuery({
|
|
28532
|
+
storefronts: input.storefronts ? input.storefronts.join(";") : undefined,
|
|
28533
|
+
page: input.page,
|
|
28534
|
+
count: input.count
|
|
28535
|
+
});
|
|
28536
|
+
return {
|
|
28537
|
+
content: [
|
|
28538
|
+
{
|
|
28539
|
+
type: "text",
|
|
28540
|
+
text: await appfiguresRequest({
|
|
28541
|
+
method: "GET",
|
|
28542
|
+
path: `/products/search/${encodeURIComponent(input.term)}`,
|
|
28543
|
+
query: query2
|
|
28544
|
+
})
|
|
28545
|
+
}
|
|
28546
|
+
]
|
|
28547
|
+
};
|
|
28387
28548
|
}
|
|
28388
|
-
}, async ({ store, id_in_store }) => ({
|
|
28389
|
-
content: [
|
|
28390
|
-
{
|
|
28391
|
-
type: "text",
|
|
28392
|
-
text: await appfiguresGet(`/products/${encodeURIComponent(store)}/${encodeURIComponent(id_in_store)}`)
|
|
28393
|
-
}
|
|
28394
|
-
]
|
|
28395
|
-
}));
|
|
28396
|
-
server.registerTool("appfigures_search_products", {
|
|
28397
|
-
description: "Search for products by term. Requires Public Data API access for non-owned products.",
|
|
28398
|
-
inputSchema: {
|
|
28399
|
-
term: exports_external.string().min(1),
|
|
28400
|
-
storefronts: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28401
|
-
page: exports_external.number().int().positive().optional(),
|
|
28402
|
-
count: exports_external.number().int().positive().optional()
|
|
28403
|
-
}
|
|
28404
|
-
}, async ({ term, storefronts, page, count }) => {
|
|
28405
28549
|
const query = buildQuery({
|
|
28406
|
-
|
|
28407
|
-
|
|
28408
|
-
count
|
|
28550
|
+
store: input.store,
|
|
28551
|
+
include_inactive: input.include_inactive
|
|
28409
28552
|
});
|
|
28410
28553
|
return {
|
|
28411
28554
|
content: [
|
|
28412
28555
|
{
|
|
28413
28556
|
type: "text",
|
|
28414
|
-
text: await
|
|
28557
|
+
text: await appfiguresRequest({
|
|
28558
|
+
method: "GET",
|
|
28559
|
+
path: "/products/mine",
|
|
28560
|
+
query
|
|
28561
|
+
})
|
|
28415
28562
|
}
|
|
28416
28563
|
]
|
|
28417
28564
|
};
|
|
28418
28565
|
});
|
|
28419
|
-
server.registerTool("
|
|
28420
|
-
description: "
|
|
28421
|
-
inputSchema: {
|
|
28422
|
-
|
|
28423
|
-
|
|
28566
|
+
server.registerTool("appfigures_ratings", {
|
|
28567
|
+
description: "Ratings reports.",
|
|
28568
|
+
inputSchema: reportSchemaBase.extend({
|
|
28569
|
+
group_by: exports_external.array(exports_external.enum(["product", "country", "date"])).optional()
|
|
28570
|
+
})
|
|
28571
|
+
}, async (input) => {
|
|
28572
|
+
const query = buildQuery(reportQueryFrom(input));
|
|
28573
|
+
return {
|
|
28574
|
+
content: [
|
|
28575
|
+
{
|
|
28576
|
+
type: "text",
|
|
28577
|
+
text: await appfiguresRequest({
|
|
28578
|
+
method: "GET",
|
|
28579
|
+
path: "/reports/ratings",
|
|
28580
|
+
query
|
|
28581
|
+
})
|
|
28582
|
+
}
|
|
28583
|
+
]
|
|
28584
|
+
};
|
|
28585
|
+
});
|
|
28586
|
+
server.registerTool("appfigures_featured", {
|
|
28587
|
+
description: "Featured reports.",
|
|
28588
|
+
inputSchema: exports_external.discriminatedUnion("action", [
|
|
28589
|
+
exports_external.object({
|
|
28590
|
+
action: exports_external.literal("summary"),
|
|
28591
|
+
start_date: exports_external.string().min(1),
|
|
28592
|
+
end_date: exports_external.string().min(1),
|
|
28593
|
+
products: exports_external.array(exports_external.string().min(1)).optional()
|
|
28594
|
+
}),
|
|
28595
|
+
exports_external.object({
|
|
28596
|
+
action: exports_external.literal("full"),
|
|
28597
|
+
product_id: exports_external.number().int().positive(),
|
|
28598
|
+
start_date: exports_external.string().min(1),
|
|
28599
|
+
end_date: exports_external.string().min(1),
|
|
28600
|
+
countries: exports_external.array(exports_external.string().min(2)).optional()
|
|
28601
|
+
}),
|
|
28602
|
+
exports_external.object({
|
|
28603
|
+
action: exports_external.literal("counts"),
|
|
28604
|
+
end: exports_external.string().min(1).optional(),
|
|
28605
|
+
products: exports_external.array(exports_external.string().min(1)).optional(),
|
|
28606
|
+
count: exports_external.number().int().positive().optional(),
|
|
28607
|
+
granularity: exports_external.string().min(1).optional(),
|
|
28608
|
+
show_empty: exports_external.boolean().optional()
|
|
28609
|
+
}),
|
|
28610
|
+
exports_external.object({
|
|
28611
|
+
action: exports_external.literal("history"),
|
|
28612
|
+
product_id: exports_external.number().int().positive(),
|
|
28613
|
+
featured_category_id: exports_external.number().int().positive()
|
|
28614
|
+
})
|
|
28615
|
+
])
|
|
28616
|
+
}, async (input) => {
|
|
28617
|
+
if (input.action === "summary") {
|
|
28618
|
+
const query = buildQuery({ products: input.products });
|
|
28619
|
+
return {
|
|
28620
|
+
content: [
|
|
28621
|
+
{
|
|
28622
|
+
type: "text",
|
|
28623
|
+
text: await appfiguresRequest({
|
|
28624
|
+
method: "GET",
|
|
28625
|
+
path: `/featured/summary/${encodeURIComponent(input.start_date)}/${encodeURIComponent(input.end_date)}`,
|
|
28626
|
+
query
|
|
28627
|
+
})
|
|
28628
|
+
}
|
|
28629
|
+
]
|
|
28630
|
+
};
|
|
28631
|
+
}
|
|
28632
|
+
if (input.action === "full") {
|
|
28633
|
+
const query = buildQuery({ countries: input.countries });
|
|
28634
|
+
return {
|
|
28635
|
+
content: [
|
|
28636
|
+
{
|
|
28637
|
+
type: "text",
|
|
28638
|
+
text: await appfiguresRequest({
|
|
28639
|
+
method: "GET",
|
|
28640
|
+
path: `/featured/full/${input.product_id}/${encodeURIComponent(input.start_date)}/${encodeURIComponent(input.end_date)}`,
|
|
28641
|
+
query
|
|
28642
|
+
})
|
|
28643
|
+
}
|
|
28644
|
+
]
|
|
28645
|
+
};
|
|
28646
|
+
}
|
|
28647
|
+
if (input.action === "counts") {
|
|
28648
|
+
const query = buildQuery({
|
|
28649
|
+
end: input.end,
|
|
28650
|
+
products: input.products,
|
|
28651
|
+
count: input.count,
|
|
28652
|
+
granularity: input.granularity,
|
|
28653
|
+
show_empty: input.show_empty
|
|
28654
|
+
});
|
|
28655
|
+
return {
|
|
28656
|
+
content: [
|
|
28657
|
+
{
|
|
28658
|
+
type: "text",
|
|
28659
|
+
text: await appfiguresRequest({
|
|
28660
|
+
method: "GET",
|
|
28661
|
+
path: "/featured/counts",
|
|
28662
|
+
query
|
|
28663
|
+
})
|
|
28664
|
+
}
|
|
28665
|
+
]
|
|
28666
|
+
};
|
|
28424
28667
|
}
|
|
28425
|
-
}, async ({ store, include_inactive }) => {
|
|
28426
|
-
const query = buildQuery({
|
|
28427
|
-
store,
|
|
28428
|
-
include_inactive
|
|
28429
|
-
});
|
|
28430
28668
|
return {
|
|
28431
28669
|
content: [
|
|
28432
28670
|
{
|
|
28433
28671
|
type: "text",
|
|
28434
|
-
text: await
|
|
28672
|
+
text: await appfiguresRequest({
|
|
28673
|
+
method: "GET",
|
|
28674
|
+
path: `/featured/history/${input.product_id}/${input.featured_category_id}`
|
|
28675
|
+
})
|
|
28435
28676
|
}
|
|
28436
28677
|
]
|
|
28437
28678
|
};
|
|
28438
28679
|
});
|
|
28439
|
-
server.registerTool("
|
|
28440
|
-
description: "
|
|
28441
|
-
inputSchema:
|
|
28442
|
-
|
|
28443
|
-
|
|
28444
|
-
|
|
28445
|
-
|
|
28446
|
-
|
|
28447
|
-
|
|
28448
|
-
|
|
28449
|
-
|
|
28450
|
-
}, async ({
|
|
28451
|
-
start_date,
|
|
28452
|
-
end_date,
|
|
28453
|
-
group_by,
|
|
28454
|
-
granularity,
|
|
28455
|
-
products,
|
|
28456
|
-
countries,
|
|
28457
|
-
format
|
|
28458
|
-
}) => {
|
|
28459
|
-
const query = buildQuery({
|
|
28460
|
-
start_date,
|
|
28461
|
-
end_date,
|
|
28462
|
-
group_by,
|
|
28463
|
-
granularity,
|
|
28464
|
-
products,
|
|
28465
|
-
countries,
|
|
28466
|
-
format
|
|
28467
|
-
});
|
|
28680
|
+
server.registerTool("appfigures_sales", {
|
|
28681
|
+
description: "Sales-related reports.",
|
|
28682
|
+
inputSchema: exports_external.discriminatedUnion("type", [
|
|
28683
|
+
reportSchemaBase.extend({ type: exports_external.literal("sales") }),
|
|
28684
|
+
reportSchemaBase.extend({ type: exports_external.literal("revenue") }),
|
|
28685
|
+
reportSchemaBase.extend({ type: exports_external.literal("subscriptions") }),
|
|
28686
|
+
reportSchemaBase.extend({ type: exports_external.literal("estimates") })
|
|
28687
|
+
])
|
|
28688
|
+
}, async (input) => {
|
|
28689
|
+
const query = buildQuery(reportQueryFrom(input));
|
|
28690
|
+
const path = input.type === "sales" ? "/reports/sales" : input.type === "revenue" ? "/reports/revenue" : input.type === "subscriptions" ? "/reports/subscriptions" : "/reports/estimates";
|
|
28468
28691
|
return {
|
|
28469
28692
|
content: [
|
|
28470
28693
|
{
|
|
28471
28694
|
type: "text",
|
|
28472
|
-
text: await
|
|
28695
|
+
text: await appfiguresRequest({
|
|
28696
|
+
method: "GET",
|
|
28697
|
+
path,
|
|
28698
|
+
query
|
|
28699
|
+
})
|
|
28473
28700
|
}
|
|
28474
28701
|
]
|
|
28475
28702
|
};
|
|
28476
28703
|
});
|
|
28477
|
-
server.registerTool("
|
|
28478
|
-
description: "
|
|
28479
|
-
inputSchema:
|
|
28480
|
-
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28704
|
+
server.registerTool("appfigures_ads", {
|
|
28705
|
+
description: "Ad revenue and spend reports.",
|
|
28706
|
+
inputSchema: exports_external.discriminatedUnion("type", [
|
|
28707
|
+
reportSchemaBase.extend({
|
|
28708
|
+
type: exports_external.literal("ads"),
|
|
28709
|
+
networks: exports_external.array(exports_external.string().min(1)).optional()
|
|
28710
|
+
}),
|
|
28711
|
+
reportSchemaBase.extend({
|
|
28712
|
+
type: exports_external.literal("adspend"),
|
|
28713
|
+
networks: exports_external.array(exports_external.string().min(1)).optional()
|
|
28714
|
+
})
|
|
28715
|
+
])
|
|
28716
|
+
}, async (input) => {
|
|
28717
|
+
const query = buildQuery(reportQueryFrom(input));
|
|
28718
|
+
const path = input.type === "ads" ? "/reports/ads" : "/reports/adspend";
|
|
28488
28719
|
return {
|
|
28489
28720
|
content: [
|
|
28490
28721
|
{
|
|
28491
28722
|
type: "text",
|
|
28492
|
-
text: await
|
|
28723
|
+
text: await appfiguresRequest({
|
|
28724
|
+
method: "GET",
|
|
28725
|
+
path,
|
|
28726
|
+
query
|
|
28727
|
+
})
|
|
28493
28728
|
}
|
|
28494
28729
|
]
|
|
28495
28730
|
};
|
|
28496
28731
|
});
|
|
28497
|
-
server.registerTool("
|
|
28498
|
-
description: "
|
|
28499
|
-
inputSchema:
|
|
28500
|
-
|
|
28501
|
-
|
|
28502
|
-
|
|
28503
|
-
|
|
28732
|
+
server.registerTool("appfigures_reviews", {
|
|
28733
|
+
description: "Reviews: list, counts, responses.",
|
|
28734
|
+
inputSchema: exports_external.discriminatedUnion("action", [
|
|
28735
|
+
reviewsQuerySchema.extend({ action: exports_external.literal("list") }),
|
|
28736
|
+
reviewsQuerySchema.extend({ action: exports_external.literal("count") }),
|
|
28737
|
+
exports_external.object({
|
|
28738
|
+
action: exports_external.literal("response_get"),
|
|
28739
|
+
review_id: exports_external.string().min(1)
|
|
28740
|
+
}),
|
|
28741
|
+
exports_external.object({
|
|
28742
|
+
action: exports_external.literal("response_post"),
|
|
28743
|
+
review_id: exports_external.string().min(1),
|
|
28744
|
+
content: exports_external.string().min(1)
|
|
28745
|
+
})
|
|
28746
|
+
])
|
|
28747
|
+
}, async (input) => {
|
|
28748
|
+
if (input.action === "list" || input.action === "count") {
|
|
28749
|
+
const query = buildReviewsQuery(input);
|
|
28750
|
+
const path = input.action === "list" ? "/reviews" : "/reviews/count";
|
|
28751
|
+
return {
|
|
28752
|
+
content: [
|
|
28753
|
+
{
|
|
28754
|
+
type: "text",
|
|
28755
|
+
text: await appfiguresRequest({
|
|
28756
|
+
method: "GET",
|
|
28757
|
+
path,
|
|
28758
|
+
query
|
|
28759
|
+
})
|
|
28760
|
+
}
|
|
28761
|
+
]
|
|
28762
|
+
};
|
|
28763
|
+
}
|
|
28764
|
+
if (input.action === "response_get") {
|
|
28765
|
+
return {
|
|
28766
|
+
content: [
|
|
28767
|
+
{
|
|
28768
|
+
type: "text",
|
|
28769
|
+
text: await appfiguresRequest({
|
|
28770
|
+
method: "GET",
|
|
28771
|
+
path: `/reviews/${encodeURIComponent(input.review_id)}/response`
|
|
28772
|
+
})
|
|
28773
|
+
}
|
|
28774
|
+
]
|
|
28775
|
+
};
|
|
28504
28776
|
}
|
|
28505
|
-
}, async ({ product_id, start_date, end_date, countries }) => {
|
|
28506
|
-
const query = buildQuery({
|
|
28507
|
-
countries
|
|
28508
|
-
});
|
|
28509
28777
|
return {
|
|
28510
28778
|
content: [
|
|
28511
28779
|
{
|
|
28512
28780
|
type: "text",
|
|
28513
|
-
text: await
|
|
28781
|
+
text: await appfiguresRequest({
|
|
28782
|
+
method: "POST",
|
|
28783
|
+
path: `/reviews/${encodeURIComponent(input.review_id)}/response`,
|
|
28784
|
+
body: { content: input.content },
|
|
28785
|
+
contentType: "json"
|
|
28786
|
+
})
|
|
28514
28787
|
}
|
|
28515
28788
|
]
|
|
28516
28789
|
};
|
|
28517
28790
|
});
|
|
28518
|
-
server.registerTool("
|
|
28519
|
-
description: "
|
|
28520
|
-
inputSchema:
|
|
28521
|
-
|
|
28522
|
-
|
|
28523
|
-
|
|
28524
|
-
|
|
28525
|
-
|
|
28791
|
+
server.registerTool("appfigures_users", {
|
|
28792
|
+
description: "User administration.",
|
|
28793
|
+
inputSchema: exports_external.discriminatedUnion("action", [
|
|
28794
|
+
exports_external.object({
|
|
28795
|
+
action: exports_external.literal("list"),
|
|
28796
|
+
count: exports_external.number().int().positive().optional(),
|
|
28797
|
+
page: exports_external.number().int().positive().optional()
|
|
28798
|
+
}),
|
|
28799
|
+
exports_external.object({
|
|
28800
|
+
action: exports_external.literal("get"),
|
|
28801
|
+
user: exports_external.string().min(1)
|
|
28802
|
+
}),
|
|
28803
|
+
exports_external.object({
|
|
28804
|
+
action: exports_external.literal("update"),
|
|
28805
|
+
user_id: exports_external.union([exports_external.string().min(1), exports_external.number().int().positive()]),
|
|
28806
|
+
body: exports_external.record(exports_external.string(), exports_external.unknown())
|
|
28807
|
+
}),
|
|
28808
|
+
exports_external.object({
|
|
28809
|
+
action: exports_external.literal("delete"),
|
|
28810
|
+
user_id: exports_external.union([exports_external.string().min(1), exports_external.number().int().positive()])
|
|
28811
|
+
})
|
|
28812
|
+
])
|
|
28813
|
+
}, async (input) => {
|
|
28814
|
+
if (input.action === "list") {
|
|
28815
|
+
return {
|
|
28816
|
+
content: [
|
|
28817
|
+
{
|
|
28818
|
+
type: "text",
|
|
28819
|
+
text: await appfiguresRequest({
|
|
28820
|
+
method: "GET",
|
|
28821
|
+
path: "/users",
|
|
28822
|
+
query: buildQuery({ count: input.count, page: input.page })
|
|
28823
|
+
})
|
|
28824
|
+
}
|
|
28825
|
+
]
|
|
28826
|
+
};
|
|
28827
|
+
}
|
|
28828
|
+
if (input.action === "get") {
|
|
28829
|
+
return {
|
|
28830
|
+
content: [
|
|
28831
|
+
{
|
|
28832
|
+
type: "text",
|
|
28833
|
+
text: await appfiguresRequest({
|
|
28834
|
+
method: "GET",
|
|
28835
|
+
path: `/users/${encodeURIComponent(input.user)}`
|
|
28836
|
+
})
|
|
28837
|
+
}
|
|
28838
|
+
]
|
|
28839
|
+
};
|
|
28840
|
+
}
|
|
28841
|
+
if (input.action === "update") {
|
|
28842
|
+
return {
|
|
28843
|
+
content: [
|
|
28844
|
+
{
|
|
28845
|
+
type: "text",
|
|
28846
|
+
text: await appfiguresRequest({
|
|
28847
|
+
method: "PUT",
|
|
28848
|
+
path: `/users/${encodeURIComponent(String(input.user_id))}`,
|
|
28849
|
+
body: input.body,
|
|
28850
|
+
contentType: "json"
|
|
28851
|
+
})
|
|
28852
|
+
}
|
|
28853
|
+
]
|
|
28854
|
+
};
|
|
28526
28855
|
}
|
|
28527
|
-
}, async ({ end, products, count, granularity, show_empty }) => {
|
|
28528
|
-
const query = buildQuery({
|
|
28529
|
-
end,
|
|
28530
|
-
products,
|
|
28531
|
-
count,
|
|
28532
|
-
granularity,
|
|
28533
|
-
show_empty
|
|
28534
|
-
});
|
|
28535
28856
|
return {
|
|
28536
28857
|
content: [
|
|
28537
28858
|
{
|
|
28538
28859
|
type: "text",
|
|
28539
|
-
text: await
|
|
28860
|
+
text: await appfiguresRequest({
|
|
28861
|
+
method: "DELETE",
|
|
28862
|
+
path: `/users/${encodeURIComponent(String(input.user_id))}`
|
|
28863
|
+
})
|
|
28864
|
+
}
|
|
28865
|
+
]
|
|
28866
|
+
};
|
|
28867
|
+
});
|
|
28868
|
+
server.registerTool("appfigures_data", {
|
|
28869
|
+
description: "Reference data (countries, languages, stores).",
|
|
28870
|
+
inputSchema: exports_external.object({
|
|
28871
|
+
kind: exports_external.enum(["countries", "languages", "stores"])
|
|
28872
|
+
})
|
|
28873
|
+
}, async ({ kind }) => {
|
|
28874
|
+
const path = kind === "countries" ? "/data/countries" : kind === "languages" ? "/data/languages" : "/data/stores";
|
|
28875
|
+
return {
|
|
28876
|
+
content: [
|
|
28877
|
+
{
|
|
28878
|
+
type: "text",
|
|
28879
|
+
text: await appfiguresRequest({ method: "GET", path })
|
|
28880
|
+
}
|
|
28881
|
+
]
|
|
28882
|
+
};
|
|
28883
|
+
});
|
|
28884
|
+
var queryValueSchema = exports_external.union([
|
|
28885
|
+
exports_external.string(),
|
|
28886
|
+
exports_external.number(),
|
|
28887
|
+
exports_external.boolean(),
|
|
28888
|
+
exports_external.array(exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()]))
|
|
28889
|
+
]);
|
|
28890
|
+
var authSchema = exports_external.discriminatedUnion("type", [
|
|
28891
|
+
exports_external.object({
|
|
28892
|
+
type: exports_external.literal("bearer"),
|
|
28893
|
+
token: exports_external.string().min(1).optional()
|
|
28894
|
+
}),
|
|
28895
|
+
exports_external.object({
|
|
28896
|
+
type: exports_external.literal("basic"),
|
|
28897
|
+
username: exports_external.string().min(1),
|
|
28898
|
+
password: exports_external.string().min(1)
|
|
28899
|
+
}),
|
|
28900
|
+
exports_external.object({
|
|
28901
|
+
type: exports_external.literal("none")
|
|
28902
|
+
})
|
|
28903
|
+
]);
|
|
28904
|
+
var baseRequestSchema = exports_external.object({
|
|
28905
|
+
path: exports_external.string().regex(new RegExp("^/"), "Path must start with '/'"),
|
|
28906
|
+
query: exports_external.record(exports_external.string(), queryValueSchema).optional(),
|
|
28907
|
+
headers: exports_external.record(exports_external.string(), exports_external.string().min(1)).optional(),
|
|
28908
|
+
auth: authSchema.optional(),
|
|
28909
|
+
content_type: exports_external.enum(["json", "form", "text"]).optional()
|
|
28910
|
+
});
|
|
28911
|
+
var requestSchema = exports_external.discriminatedUnion("method", [
|
|
28912
|
+
baseRequestSchema.extend({
|
|
28913
|
+
method: exports_external.enum(["GET", "DELETE"])
|
|
28914
|
+
}),
|
|
28915
|
+
baseRequestSchema.extend({
|
|
28916
|
+
method: exports_external.enum(["POST", "PUT", "PATCH"]),
|
|
28917
|
+
body: exports_external.unknown().optional()
|
|
28918
|
+
})
|
|
28919
|
+
]);
|
|
28920
|
+
server.registerTool("appfigures_request", {
|
|
28921
|
+
description: "Call any Appfigures API endpoint. Supports bearer or basic auth and optional query/body.",
|
|
28922
|
+
inputSchema: requestSchema
|
|
28923
|
+
}, async (input) => {
|
|
28924
|
+
const query = input.query && Object.keys(input.query).length > 0 ? buildQuery(input.query) : "";
|
|
28925
|
+
const body = "body" in input && input.body !== undefined ? input.body : undefined;
|
|
28926
|
+
return {
|
|
28927
|
+
content: [
|
|
28928
|
+
{
|
|
28929
|
+
type: "text",
|
|
28930
|
+
text: await appfiguresRequest({
|
|
28931
|
+
method: input.method,
|
|
28932
|
+
path: input.path,
|
|
28933
|
+
query,
|
|
28934
|
+
body,
|
|
28935
|
+
contentType: input.content_type,
|
|
28936
|
+
headers: input.headers,
|
|
28937
|
+
auth: input.auth
|
|
28938
|
+
})
|
|
28540
28939
|
}
|
|
28541
28940
|
]
|
|
28542
28941
|
};
|
|
28543
28942
|
});
|
|
28544
|
-
server.registerTool("appfigures_featured_history", {
|
|
28545
|
-
description: "Get full history for a category and product.",
|
|
28546
|
-
inputSchema: {
|
|
28547
|
-
product_id: exports_external.number().int().positive(),
|
|
28548
|
-
featured_category_id: exports_external.number().int().positive()
|
|
28549
|
-
}
|
|
28550
|
-
}, async ({ product_id, featured_category_id }) => ({
|
|
28551
|
-
content: [
|
|
28552
|
-
{
|
|
28553
|
-
type: "text",
|
|
28554
|
-
text: await appfiguresGet(`/featured/history/${product_id}/${featured_category_id}`)
|
|
28555
|
-
}
|
|
28556
|
-
]
|
|
28557
|
-
}));
|
|
28558
28943
|
var transport = new StdioServerTransport;
|
|
28559
28944
|
await server.connect(transport);
|