@buygolinks/mcp 0.17.1 → 0.20.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/README.md +1 -0
- package/package.json +1 -1
- package/src/index.js +44 -0
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ Most MCP clients use the same shape. Point them at the `npx -y @buygolinks/mcp`
|
|
|
64
64
|
|---|---|
|
|
65
65
|
| `create_link` | Create a short link. The destination URL is passed through untouched (include your own affiliate tag). |
|
|
66
66
|
| `update_link` | Edit a link's destination URL, title, source label, custom domain, password, archive state, or custom alias (e.g. `summer-sale` → `https://click.example.com/summer-sale`). Repointing the destination preserves the short code, alias, and click history. |
|
|
67
|
+
| `refresh_link_image` | Re-attempt fetching a link's product/preview image (Amazon PDP scrape for `/dp/` links, Open Graph otherwise). Use when a link has no thumbnail or a stale one. Returns `{ found: false }` if nothing could be fetched this time. |
|
|
67
68
|
| `list_links` | List your links with click counts. |
|
|
68
69
|
| `get_link_stats` | Per-link analytics (by day, country, device, browser, hour, weekday). |
|
|
69
70
|
| `get_overview_stats` | Account-wide analytics. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buygolinks/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "MCP server for buygolinks.com — create and manage branded short links with Amazon affiliate geo-routing from any MCP-compatible AI agent (Claude Desktop, Cursor, Cline, Continue, Hermes).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/index.js
CHANGED
|
@@ -91,6 +91,18 @@ const TOOLS = [
|
|
|
91
91
|
required: ['link_id'],
|
|
92
92
|
},
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
name: 'refresh_link_image',
|
|
96
|
+
description:
|
|
97
|
+
'Re-attempt fetching the product/preview image for an existing short link. Re-runs the same best-effort scrape used at link creation — the Amazon product-image scraper for Amazon /dp/ links, or a generic Open Graph (og:image / twitter:image) scrape for any other URL — and rehosts the result on buygolinks storage. Use this when a link was created without an image (the thumbnail shows a letter/placeholder) or to update a stale image. Returns { found: true, link } with the updated `product_image_url` on success, or { found: false } if no image could be fetched this time (the existing image, if any, is left untouched — try again later).',
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {
|
|
101
|
+
link_id: { type: 'number', description: 'The numeric id of the link (from list_links / create_link).' },
|
|
102
|
+
},
|
|
103
|
+
required: ['link_id'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
94
106
|
{
|
|
95
107
|
name: 'list_links',
|
|
96
108
|
description:
|
|
@@ -446,6 +458,10 @@ const TOOLS = [
|
|
|
446
458
|
domain_id: { type: ['number', 'null'], description: 'Optional id of one of the user\'s active custom domains (from list_domains). The campaign\'s short link will resolve at that hostname. If omitted, defaults to the user\'s first active custom domain, or buygolinks.com if they have none. Pass null to force the platform default.' },
|
|
447
459
|
conversion_pixel_id: { type: ['number', 'null'], description: 'Optional id of one of the user\'s tracking pixels (from list_tracking_pixels) to fire when this campaign converts (server-side via the pixel\'s CAPI token when set). Pass null for no conversion pixel.' },
|
|
448
460
|
conversion_event: { type: 'string', description: 'Event name to fire on conversion (e.g. "Purchase", "Lead", "CompletePayment"). Must be a valid event for the conversion pixel\'s platform; defaults to that pixel\'s default_event.' },
|
|
461
|
+
report_value_mode: { type: 'string', enum: ['payout', 'fixed', 'adjusted'], description: 'What revenue VALUE to report back to the ad platform on a CAPI conversion. "payout" (default) = the real conversion payout; "fixed" = always report report_value_fixed (e.g. 1); "adjusted" = real payout minus report_value_adjust_pct % then minus report_value_adjust_flat (so the user\'s margin/cost is withheld from what the platform optimizes against). Floored at 0.' },
|
|
462
|
+
report_value_fixed: { type: ['number', 'null'], description: 'Used when report_value_mode = "fixed": the exact value (USD) reported on every conversion regardless of real payout.' },
|
|
463
|
+
report_value_adjust_pct: { type: ['number', 'null'], description: 'Used when report_value_mode = "adjusted": percentage (0–100) subtracted from the real payout first (e.g. 10 reports payout − 10%).' },
|
|
464
|
+
report_value_adjust_flat: { type: ['number', 'null'], description: 'Used when report_value_mode = "adjusted": flat amount (USD) subtracted after the percentage.' },
|
|
449
465
|
direct_slug: { type: ['string', 'null'], description: 'Optional direct-link tag, unique per user (lowercased alnum + dashes, e.g. "bsu-fb-cold"). For running traffic STRAIGHT to a lander with no tracker hop: put `?utm_campaign={direct_slug}` on the ad URL and the property tag stitches the page view to this campaign. Returns 409 (direct_slug_taken) if another campaign already uses it. Pass null to clear.' },
|
|
450
466
|
fallback_url: { type: ['string', 'null'], description: 'Optional URL the click falls back to when the flow yields no live offer — the never-dead-end guarantee. Pass null to use the platform default.' },
|
|
451
467
|
offer_ids: { type: 'array', items: { type: 'number' } },
|
|
@@ -479,6 +495,10 @@ const TOOLS = [
|
|
|
479
495
|
domain_id: { type: ['number', 'null'], description: 'Id of one of the user\'s active custom domains, or null to move the campaign back to buygolinks.com.' },
|
|
480
496
|
conversion_pixel_id: { type: ['number', 'null'], description: 'Id of a tracking pixel to fire on conversion, or null to clear.' },
|
|
481
497
|
conversion_event: { type: 'string', description: 'Event the conversion pixel fires (must be valid for that pixel\'s platform).' },
|
|
498
|
+
report_value_mode: { type: 'string', enum: ['payout', 'fixed', 'adjusted'], description: 'What revenue value to report back to the ad platform on conversion: "payout" (real), "fixed" (report_value_fixed), or "adjusted" (real payout − report_value_adjust_pct% − report_value_adjust_flat, floored at 0).' },
|
|
499
|
+
report_value_fixed: { type: ['number', 'null'], description: 'Fixed value (USD) reported on every conversion when report_value_mode = "fixed". Null to clear.' },
|
|
500
|
+
report_value_adjust_pct: { type: ['number', 'null'], description: 'Percentage (0–100) subtracted from real payout when report_value_mode = "adjusted". Null to clear.' },
|
|
501
|
+
report_value_adjust_flat: { type: ['number', 'null'], description: 'Flat USD amount subtracted (after the %) when report_value_mode = "adjusted". Null to clear.' },
|
|
482
502
|
direct_slug: { type: ['string', 'null'], description: 'Direct-link tag for utm_campaign-based stitching (unique per user), or null to clear. Returns 409 (direct_slug_taken) on collision.' },
|
|
483
503
|
fallback_url: { type: ['string', 'null'], description: 'Never-dead-end fallback URL when no live offer exists, or null to use the platform default.' },
|
|
484
504
|
archived: { type: 'boolean' },
|
|
@@ -680,6 +700,12 @@ const TOOLS = [
|
|
|
680
700
|
'List the distinct pages observed across ALL the user\'s properties (the pageview stream), most-viewed first. Each entry is `{ url, path, title, property_id, property_name, views }`. Any of these pages can be used as a campaign LANDER — pass its `url` to `create_lander` (the page title makes a good lander name) and then wire the resulting lander into a campaign flow via `set_campaign_flow`. Use this to turn a real page on the user\'s site into a lander without retyping its URL.',
|
|
681
701
|
inputSchema: { type: 'object', properties: {} },
|
|
682
702
|
},
|
|
703
|
+
{
|
|
704
|
+
name: 'list_observed_campaign_tags',
|
|
705
|
+
description:
|
|
706
|
+
'List the distinct `utm_campaign` values that have actually been SEEN arriving on the user\'s properties/visits over the last 90 days, most-active first. Each entry is `{ utm_campaign, events, utm_source, utm_medium, lander_url, claimed_by }` where `claimed_by` is `{ id, name }` of the BGL campaign whose `direct_slug` already owns that tag, or null if unclaimed. Use this to WIRE UP AN ALREADY-RUNNING DIRECT-LINK CAMPAIGN: when an ad on FB/Google points straight at a lander (no tracker hop) with `?utm_campaign={tag}`, that tag shows up here once the universal property tag reports a page view. Pick an unclaimed tag and set it as a campaign\'s `direct_slug` (via `update_campaign`) so BGL attributes that traffic — and its `/click` CTA — to the right campaign + offer. Skip tags whose `claimed_by` is non-null (another campaign already owns them).',
|
|
707
|
+
inputSchema: { type: 'object', properties: {} },
|
|
708
|
+
},
|
|
683
709
|
{
|
|
684
710
|
name: 'get_tracker_overview',
|
|
685
711
|
description:
|
|
@@ -760,6 +786,12 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
760
786
|
});
|
|
761
787
|
break;
|
|
762
788
|
}
|
|
789
|
+
case 'refresh_link_image': {
|
|
790
|
+
result = await api(`/api/links/${Number(args.link_id)}/refresh-image`, {
|
|
791
|
+
method: 'POST',
|
|
792
|
+
});
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
763
795
|
case 'list_links': {
|
|
764
796
|
const qs = args?.include_archived ? '?include_archived=1' : '';
|
|
765
797
|
result = await api(`/api/links${qs}`);
|
|
@@ -950,6 +982,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
950
982
|
if ('domain_id' in args) body.domain_id = args.domain_id;
|
|
951
983
|
if ('traffic_source_id' in args) body.traffic_source_id = args.traffic_source_id;
|
|
952
984
|
if ('conversion_pixel_id' in args) body.conversion_pixel_id = args.conversion_pixel_id;
|
|
985
|
+
if (typeof args.report_value_mode === 'string') body.report_value_mode = args.report_value_mode;
|
|
986
|
+
if ('report_value_fixed' in args) body.report_value_fixed = args.report_value_fixed;
|
|
987
|
+
if ('report_value_adjust_pct' in args) body.report_value_adjust_pct = args.report_value_adjust_pct;
|
|
988
|
+
if ('report_value_adjust_flat' in args) body.report_value_adjust_flat = args.report_value_adjust_flat;
|
|
953
989
|
if ('direct_slug' in args) body.direct_slug = args.direct_slug;
|
|
954
990
|
if ('fallback_url' in args) body.fallback_url = args.fallback_url;
|
|
955
991
|
if (Array.isArray(args.offer_ids)) body.offer_ids = args.offer_ids;
|
|
@@ -973,6 +1009,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
973
1009
|
if (typeof args.cost_value === 'number') body.cost_value = args.cost_value;
|
|
974
1010
|
if ('domain_id' in args) body.domain_id = args.domain_id;
|
|
975
1011
|
if ('conversion_pixel_id' in args) body.conversion_pixel_id = args.conversion_pixel_id;
|
|
1012
|
+
if (typeof args.report_value_mode === 'string') body.report_value_mode = args.report_value_mode;
|
|
1013
|
+
if ('report_value_fixed' in args) body.report_value_fixed = args.report_value_fixed;
|
|
1014
|
+
if ('report_value_adjust_pct' in args) body.report_value_adjust_pct = args.report_value_adjust_pct;
|
|
1015
|
+
if ('report_value_adjust_flat' in args) body.report_value_adjust_flat = args.report_value_adjust_flat;
|
|
976
1016
|
if ('direct_slug' in args) body.direct_slug = args.direct_slug;
|
|
977
1017
|
if ('fallback_url' in args) body.fallback_url = args.fallback_url;
|
|
978
1018
|
if (typeof args.archived === 'boolean') body.archived = args.archived;
|
|
@@ -1058,6 +1098,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
1058
1098
|
result = await api('/api/property-pages');
|
|
1059
1099
|
break;
|
|
1060
1100
|
}
|
|
1101
|
+
case 'list_observed_campaign_tags': {
|
|
1102
|
+
result = await api('/api/observed-campaign-tags');
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1061
1105
|
|
|
1062
1106
|
case 'get_tracker_overview': {
|
|
1063
1107
|
const days = args?.days ? `?days=${Number(args.days)}` : '';
|