@buzzposter/mcp 0.3.5 → 0.3.6
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/index.js +374 -116
- package/dist/tools.d.ts +6 -1
- package/dist/tools.js +368 -116
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1384,16 +1384,267 @@ This will permanently delete this media file. Call this tool again with confirme
|
|
|
1384
1384
|
);
|
|
1385
1385
|
}
|
|
1386
1386
|
|
|
1387
|
-
// src/tools/
|
|
1387
|
+
// src/tools/newsletter.ts
|
|
1388
1388
|
import { z as z4 } from "zod";
|
|
1389
|
+
function registerNewsletterTools(server2, client2, options = {}) {
|
|
1390
|
+
server2.tool(
|
|
1391
|
+
"manage_newsletters",
|
|
1392
|
+
"Create, update, send, schedule, or list newsletters.\n\nIMPORTANT \u2014 Template-based creation:\n1. Call get_context with include_newsletter_template=true to get the user's template with section IDs\n2. Call create with template_id + sections array (NOT raw content HTML)\n3. The server assembles styled HTML from the template design + your section content\n\nOnly use raw content HTML if the user has no templates or explicitly asks for custom HTML.",
|
|
1393
|
+
{
|
|
1394
|
+
action: z4.enum(["create", "update", "send", "schedule", "list"]),
|
|
1395
|
+
broadcast_id: z4.string().optional().describe("Newsletter ID (update/send/schedule)"),
|
|
1396
|
+
subject: z4.string().optional().describe("Subject line (create/update, also search keyword for list)"),
|
|
1397
|
+
content: z4.string().optional().describe("Raw HTML content (create/update). Only use when no template is available or user explicitly requests custom HTML. When a template exists, use sections instead."),
|
|
1398
|
+
sections: z4.array(z4.object({
|
|
1399
|
+
section_id: z4.string().describe("Section ID from the template's section config"),
|
|
1400
|
+
heading: z4.string().optional(),
|
|
1401
|
+
body: z4.string().optional().describe("Section body (basic HTML OK: p, strong, em, a, ul/li)"),
|
|
1402
|
+
image_url: z4.string().optional(),
|
|
1403
|
+
image_alt: z4.string().optional(),
|
|
1404
|
+
cta_text: z4.string().optional(),
|
|
1405
|
+
cta_url: z4.string().optional(),
|
|
1406
|
+
quote: z4.string().optional(),
|
|
1407
|
+
quote_attribution: z4.string().optional()
|
|
1408
|
+
})).optional().describe("Structured section content matching the template's section IDs. PREFERRED over raw content \u2014 preserves the user's template design and style."),
|
|
1409
|
+
preview_text: z4.string().optional().describe("Preview text (create/update)"),
|
|
1410
|
+
template_id: z4.string().optional().describe("BuzzPoster template ID (from newsletter_templates). Used with sections to auto-generate HTML."),
|
|
1411
|
+
esp_template_id: z4.string().optional().describe("ESP-native template ID (Kit: email_template_id, Beehiiv: post_template_id). Distinct from template_id which references BuzzPoster templates."),
|
|
1412
|
+
scheduled_for: z4.string().optional().describe("ISO datetime (schedule)"),
|
|
1413
|
+
page: z4.string().optional().describe("Page number (list)"),
|
|
1414
|
+
status: z4.string().optional().describe("Filter status (list)"),
|
|
1415
|
+
from_date: z4.string().optional().describe("ISO date from (list)"),
|
|
1416
|
+
to_date: z4.string().optional().describe("ISO date to (list)"),
|
|
1417
|
+
confirmed: z4.boolean().default(false).describe("Confirm action (send/schedule)")
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
title: "Manage Newsletters",
|
|
1421
|
+
readOnlyHint: false,
|
|
1422
|
+
destructiveHint: true,
|
|
1423
|
+
idempotentHint: false,
|
|
1424
|
+
openWorldHint: true
|
|
1425
|
+
},
|
|
1426
|
+
async (args) => {
|
|
1427
|
+
if (args.action === "create") {
|
|
1428
|
+
if (!args.subject) {
|
|
1429
|
+
return { content: [{ type: "text", text: "subject is required for create." }], isError: true };
|
|
1430
|
+
}
|
|
1431
|
+
if (!args.content && !args.sections) {
|
|
1432
|
+
return { content: [{ type: "text", text: "content or sections is required for create." }], isError: true };
|
|
1433
|
+
}
|
|
1434
|
+
const payload = {
|
|
1435
|
+
subject: args.subject,
|
|
1436
|
+
previewText: args.preview_text
|
|
1437
|
+
};
|
|
1438
|
+
if (args.content) payload.content = args.content;
|
|
1439
|
+
if (args.sections) payload.sections = args.sections;
|
|
1440
|
+
if (args.template_id) payload.templateId = args.template_id;
|
|
1441
|
+
if (args.esp_template_id) payload.espTemplateId = args.esp_template_id;
|
|
1442
|
+
const result = await client2.createBroadcast(payload);
|
|
1443
|
+
const r = result;
|
|
1444
|
+
const response = {
|
|
1445
|
+
id: r.id,
|
|
1446
|
+
subject: args.subject,
|
|
1447
|
+
content: args.content ?? r.renderedHtml ?? void 0,
|
|
1448
|
+
previewText: args.preview_text,
|
|
1449
|
+
previewUrl: r.previewUrl,
|
|
1450
|
+
editUrl: r.editUrl,
|
|
1451
|
+
status: "draft"
|
|
1452
|
+
};
|
|
1453
|
+
return {
|
|
1454
|
+
content: [
|
|
1455
|
+
{ type: "text", text: JSON.stringify(response) }
|
|
1456
|
+
]
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
if (args.action === "update") {
|
|
1460
|
+
if (!args.broadcast_id) {
|
|
1461
|
+
return { content: [{ type: "text", text: "broadcast_id is required for update." }], isError: true };
|
|
1462
|
+
}
|
|
1463
|
+
const data = {};
|
|
1464
|
+
if (args.subject) data.subject = args.subject;
|
|
1465
|
+
if (args.content) data.content = args.content;
|
|
1466
|
+
if (args.preview_text) data.previewText = args.preview_text;
|
|
1467
|
+
const result = await client2.updateBroadcast(args.broadcast_id, data);
|
|
1468
|
+
const r = result;
|
|
1469
|
+
const response = {
|
|
1470
|
+
id: args.broadcast_id,
|
|
1471
|
+
subject: args.subject ?? r.subject,
|
|
1472
|
+
content: args.content ?? r.renderedHtml ?? void 0,
|
|
1473
|
+
previewText: args.preview_text,
|
|
1474
|
+
previewUrl: r.previewUrl,
|
|
1475
|
+
editUrl: r.editUrl,
|
|
1476
|
+
status: r.status ?? "draft"
|
|
1477
|
+
};
|
|
1478
|
+
return {
|
|
1479
|
+
content: [
|
|
1480
|
+
{ type: "text", text: JSON.stringify(response) }
|
|
1481
|
+
]
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
if (args.action === "send") {
|
|
1485
|
+
if (!options.allowDirectSend) {
|
|
1486
|
+
return {
|
|
1487
|
+
content: [{
|
|
1488
|
+
type: "text",
|
|
1489
|
+
text: "Direct send is disabled. Enable it in your BuzzPoster dashboard settings under Publishing Rules."
|
|
1490
|
+
}],
|
|
1491
|
+
isError: true
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
if (!args.broadcast_id) {
|
|
1495
|
+
return { content: [{ type: "text", text: "broadcast_id is required for send." }], isError: true };
|
|
1496
|
+
}
|
|
1497
|
+
if (args.confirmed !== true) {
|
|
1498
|
+
let subscriberCount = "unknown";
|
|
1499
|
+
let rulesText = "";
|
|
1500
|
+
try {
|
|
1501
|
+
const subData = await client2.listSubscribers({ perPage: "1" });
|
|
1502
|
+
subscriberCount = String(subData?.totalCount ?? subData?.total ?? subData?.subscribers?.length ?? "unknown");
|
|
1503
|
+
} catch {
|
|
1504
|
+
}
|
|
1505
|
+
try {
|
|
1506
|
+
const rules = await client2.getPublishingRules();
|
|
1507
|
+
rulesText = `
|
|
1508
|
+
### Safety Checks
|
|
1509
|
+
`;
|
|
1510
|
+
rulesText += `- Double confirmation required: ${rules.requireDoubleConfirmNewsletter ? "**yes**" : "no"}
|
|
1511
|
+
`;
|
|
1512
|
+
rulesText += `- Immediate send allowed: ${rules.allowImmediateSend ? "yes" : "**no**"}
|
|
1513
|
+
`;
|
|
1514
|
+
if (rules.requiredDisclaimer) {
|
|
1515
|
+
rulesText += `- Required disclaimer: "${rules.requiredDisclaimer}"
|
|
1516
|
+
`;
|
|
1517
|
+
}
|
|
1518
|
+
} catch {
|
|
1519
|
+
}
|
|
1520
|
+
let espText = "";
|
|
1521
|
+
try {
|
|
1522
|
+
const account = await client2.getAccount();
|
|
1523
|
+
espText = account?.espProvider ? `**ESP:** ${account.espProvider}
|
|
1524
|
+
` : "";
|
|
1525
|
+
} catch {
|
|
1526
|
+
}
|
|
1527
|
+
const preview = `## Send Newsletter Confirmation
|
|
1528
|
+
|
|
1529
|
+
**Broadcast ID:** ${args.broadcast_id}
|
|
1530
|
+
**Subscribers:** ~${subscriberCount} recipients
|
|
1531
|
+
` + espText + rulesText + `
|
|
1532
|
+
**This action cannot be undone.** Once sent, the email goes to every subscriber.
|
|
1533
|
+
|
|
1534
|
+
Call this tool again with confirmed=true to send.`;
|
|
1535
|
+
return { content: [{ type: "text", text: preview }] };
|
|
1536
|
+
}
|
|
1537
|
+
await client2.sendBroadcast(args.broadcast_id);
|
|
1538
|
+
return {
|
|
1539
|
+
content: [{ type: "text", text: "Newsletter sent successfully." }]
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
if (args.action === "schedule") {
|
|
1543
|
+
if (!args.broadcast_id) {
|
|
1544
|
+
return { content: [{ type: "text", text: "broadcast_id is required for schedule." }], isError: true };
|
|
1545
|
+
}
|
|
1546
|
+
if (!args.scheduled_for) {
|
|
1547
|
+
return { content: [{ type: "text", text: "scheduled_for is required for schedule." }], isError: true };
|
|
1548
|
+
}
|
|
1549
|
+
if (args.confirmed !== true) {
|
|
1550
|
+
let subscriberCount = "unknown";
|
|
1551
|
+
let rulesText = "";
|
|
1552
|
+
try {
|
|
1553
|
+
const subData = await client2.listSubscribers({ perPage: "1" });
|
|
1554
|
+
subscriberCount = String(
|
|
1555
|
+
subData?.totalCount ?? subData?.total ?? subData?.subscribers?.length ?? "unknown"
|
|
1556
|
+
);
|
|
1557
|
+
} catch {
|
|
1558
|
+
}
|
|
1559
|
+
try {
|
|
1560
|
+
const rules = await client2.getPublishingRules();
|
|
1561
|
+
rulesText = `
|
|
1562
|
+
### Safety Checks
|
|
1563
|
+
`;
|
|
1564
|
+
rulesText += `- Double confirmation required: ${rules.requireDoubleConfirmNewsletter ? "**yes**" : "no"}
|
|
1565
|
+
`;
|
|
1566
|
+
rulesText += `- Immediate send allowed: ${rules.allowImmediateSend ? "yes" : "**no**"}
|
|
1567
|
+
`;
|
|
1568
|
+
if (rules.requiredDisclaimer) {
|
|
1569
|
+
rulesText += `- Required disclaimer: "${rules.requiredDisclaimer}"
|
|
1570
|
+
`;
|
|
1571
|
+
}
|
|
1572
|
+
} catch {
|
|
1573
|
+
}
|
|
1574
|
+
let espText = "";
|
|
1575
|
+
try {
|
|
1576
|
+
const account = await client2.getAccount();
|
|
1577
|
+
espText = account?.espProvider ? `**ESP:** ${account.espProvider}
|
|
1578
|
+
` : "";
|
|
1579
|
+
} catch {
|
|
1580
|
+
}
|
|
1581
|
+
const preview = `## Schedule Newsletter Confirmation
|
|
1582
|
+
|
|
1583
|
+
**Broadcast ID:** ${args.broadcast_id}
|
|
1584
|
+
**Scheduled for:** ${args.scheduled_for}
|
|
1585
|
+
**Subscribers:** ~${subscriberCount} recipients
|
|
1586
|
+
` + espText + rulesText + `
|
|
1587
|
+
Scheduling can typically be cancelled or rescheduled later, but please verify the time is correct.
|
|
1588
|
+
|
|
1589
|
+
Call this tool again with confirmed=true to schedule.`;
|
|
1590
|
+
return { content: [{ type: "text", text: preview }] };
|
|
1591
|
+
}
|
|
1592
|
+
await client2.scheduleBroadcast(args.broadcast_id, {
|
|
1593
|
+
scheduledFor: args.scheduled_for
|
|
1594
|
+
});
|
|
1595
|
+
return {
|
|
1596
|
+
content: [{
|
|
1597
|
+
type: "text",
|
|
1598
|
+
text: `Newsletter scheduled successfully for ${args.scheduled_for}.`
|
|
1599
|
+
}]
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
if (args.action === "list") {
|
|
1603
|
+
const params = {};
|
|
1604
|
+
if (args.page) params.page = args.page;
|
|
1605
|
+
if (args.status) params.status = args.status;
|
|
1606
|
+
if (args.from_date) params.fromDate = args.from_date;
|
|
1607
|
+
if (args.to_date) params.toDate = args.to_date;
|
|
1608
|
+
if (args.subject) params.subject = args.subject;
|
|
1609
|
+
const result = await client2.listBroadcasts(params);
|
|
1610
|
+
const broadcasts = result?.broadcasts ?? [];
|
|
1611
|
+
if (broadcasts.length === 0) {
|
|
1612
|
+
return {
|
|
1613
|
+
content: [{ type: "text", text: "No newsletters found matching your filters." }]
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
let text = `## Newsletters (${broadcasts.length}`;
|
|
1617
|
+
if (result?.totalCount != null) text += ` of ${result.totalCount}`;
|
|
1618
|
+
text += ")\n\n";
|
|
1619
|
+
for (const b of broadcasts) {
|
|
1620
|
+
const status = (b.status ?? "unknown").toUpperCase();
|
|
1621
|
+
const date = b.sentAt ? new Date(b.sentAt).toLocaleString() : b.createdAt ? new Date(b.createdAt).toLocaleString() : "";
|
|
1622
|
+
text += `- **[${status}]** "${b.subject ?? "(no subject)"}"
|
|
1623
|
+
`;
|
|
1624
|
+
text += ` ID: ${b.id}`;
|
|
1625
|
+
if (date) text += ` | ${b.sentAt ? "Sent" : "Created"}: ${date}`;
|
|
1626
|
+
text += "\n";
|
|
1627
|
+
}
|
|
1628
|
+
return { content: [{ type: "text", text }] };
|
|
1629
|
+
}
|
|
1630
|
+
return {
|
|
1631
|
+
content: [{ type: "text", text: `Unknown action: ${args.action}` }],
|
|
1632
|
+
isError: true
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// src/tools/rss.ts
|
|
1639
|
+
import { z as z5 } from "zod";
|
|
1389
1640
|
function registerRssTools(server2, client2) {
|
|
1390
1641
|
server2.tool(
|
|
1391
1642
|
"rss",
|
|
1392
1643
|
"Fetch RSS/Atom feed entries or extract full article content from a URL. Returns og_image when available.",
|
|
1393
1644
|
{
|
|
1394
|
-
action:
|
|
1395
|
-
url:
|
|
1396
|
-
limit:
|
|
1645
|
+
action: z5.enum(["fetch_feed", "fetch_article"]),
|
|
1646
|
+
url: z5.string().describe("Feed or article URL"),
|
|
1647
|
+
limit: z5.number().optional().describe("Max feed entries (fetch_feed, default 100)")
|
|
1397
1648
|
},
|
|
1398
1649
|
{
|
|
1399
1650
|
title: "RSS Tools",
|
|
@@ -1463,13 +1714,13 @@ function registerRssTools(server2, client2) {
|
|
|
1463
1714
|
}
|
|
1464
1715
|
|
|
1465
1716
|
// src/tools/account.ts
|
|
1466
|
-
import { z as
|
|
1717
|
+
import { z as z6 } from "zod";
|
|
1467
1718
|
function registerAccountTools(server2, client2) {
|
|
1468
1719
|
server2.tool(
|
|
1469
1720
|
"manage_account",
|
|
1470
1721
|
"Get account details/connections or check health status of connected social accounts.",
|
|
1471
1722
|
{
|
|
1472
|
-
action:
|
|
1723
|
+
action: z6.enum(["get_details", "check_health"])
|
|
1473
1724
|
},
|
|
1474
1725
|
{
|
|
1475
1726
|
title: "Manage Account",
|
|
@@ -1568,21 +1819,21 @@ ${lines.join("\n")}`;
|
|
|
1568
1819
|
}
|
|
1569
1820
|
|
|
1570
1821
|
// src/tools/brand-voice.ts
|
|
1571
|
-
import { z as
|
|
1822
|
+
import { z as z7 } from "zod";
|
|
1572
1823
|
function registerBrandVoiceTools(server2, client2) {
|
|
1573
1824
|
server2.tool(
|
|
1574
1825
|
"manage_brand_voice",
|
|
1575
1826
|
"Get, create, or update the brand voice profile. Call with action 'get' before creating content.",
|
|
1576
1827
|
{
|
|
1577
|
-
action:
|
|
1578
|
-
name:
|
|
1579
|
-
description:
|
|
1580
|
-
dos:
|
|
1581
|
-
donts:
|
|
1582
|
-
platform_rules:
|
|
1583
|
-
platform_examples:
|
|
1584
|
-
example_posts:
|
|
1585
|
-
confirmed:
|
|
1828
|
+
action: z7.enum(["get", "create", "update"]),
|
|
1829
|
+
name: z7.string().max(80).optional().describe("Voice name (create required, update optional)"),
|
|
1830
|
+
description: z7.string().max(2e3).optional().describe("Voice description (create/update)"),
|
|
1831
|
+
dos: z7.array(z7.string().max(200)).max(15).optional().describe("Writing rules to follow (create/update)"),
|
|
1832
|
+
donts: z7.array(z7.string().max(200)).max(15).optional().describe("Things to avoid (create/update)"),
|
|
1833
|
+
platform_rules: z7.record(z7.string().max(300)).optional().describe("Per-platform guidelines (create/update)"),
|
|
1834
|
+
platform_examples: z7.record(z7.array(z7.string().max(500)).max(3)).optional().describe("Per-platform examples (create/update)"),
|
|
1835
|
+
example_posts: z7.array(z7.string().max(500)).max(5).optional().describe("Example posts (create/update)"),
|
|
1836
|
+
confirmed: z7.boolean().default(false).describe("Confirm write (create/update)")
|
|
1586
1837
|
},
|
|
1587
1838
|
{
|
|
1588
1839
|
title: "Manage Brand Voice",
|
|
@@ -1754,7 +2005,7 @@ function registerBrandVoiceTools(server2, client2) {
|
|
|
1754
2005
|
}
|
|
1755
2006
|
|
|
1756
2007
|
// src/tools/audience.ts
|
|
1757
|
-
import { z as
|
|
2008
|
+
import { z as z8 } from "zod";
|
|
1758
2009
|
function formatAudience(audience) {
|
|
1759
2010
|
const lines = [];
|
|
1760
2011
|
lines.push(`## ${audience.name}${audience.isDefault ? " (default)" : ""}`);
|
|
@@ -1801,17 +2052,17 @@ function registerAudienceTools(server2, client2) {
|
|
|
1801
2052
|
"manage_audiences",
|
|
1802
2053
|
"List, get, create, update, or delete audience profiles.",
|
|
1803
2054
|
{
|
|
1804
|
-
action:
|
|
1805
|
-
name:
|
|
1806
|
-
description:
|
|
1807
|
-
demographics:
|
|
1808
|
-
pain_points:
|
|
1809
|
-
motivations:
|
|
1810
|
-
preferred_platforms:
|
|
1811
|
-
tone_notes:
|
|
1812
|
-
content_preferences:
|
|
1813
|
-
is_default:
|
|
1814
|
-
confirmed:
|
|
2055
|
+
action: z8.enum(["list", "get", "create", "update", "delete"]),
|
|
2056
|
+
name: z8.string().max(100).optional().describe("Audience name (get/create/update/delete)"),
|
|
2057
|
+
description: z8.string().max(500).optional().describe("Description (create/update)"),
|
|
2058
|
+
demographics: z8.string().max(500).optional().describe("Demographics (create/update)"),
|
|
2059
|
+
pain_points: z8.array(z8.string().max(200)).max(10).optional().describe("Pain points, full list (create/update)"),
|
|
2060
|
+
motivations: z8.array(z8.string().max(200)).max(10).optional().describe("Motivations, full list (create/update)"),
|
|
2061
|
+
preferred_platforms: z8.array(z8.string()).max(6).optional().describe("Active platforms, full list (create/update)"),
|
|
2062
|
+
tone_notes: z8.string().max(500).optional().describe("Tone guidance (create/update)"),
|
|
2063
|
+
content_preferences: z8.string().max(500).optional().describe("Content preferences (create/update)"),
|
|
2064
|
+
is_default: z8.boolean().optional().describe("Set as default (create/update)"),
|
|
2065
|
+
confirmed: z8.boolean().default(false).describe("Confirm write (create/update/delete)")
|
|
1815
2066
|
},
|
|
1816
2067
|
{
|
|
1817
2068
|
title: "Manage Audiences",
|
|
@@ -2006,7 +2257,7 @@ Call again with confirmed=true to delete.` }]
|
|
|
2006
2257
|
}
|
|
2007
2258
|
|
|
2008
2259
|
// src/tools/calendar.ts
|
|
2009
|
-
import { z as
|
|
2260
|
+
import { z as z9 } from "zod";
|
|
2010
2261
|
import { registerAppTool as registerAppTool3 } from "@modelcontextprotocol/ext-apps/server";
|
|
2011
2262
|
var BASE_CHAR_LIMITS2 = {
|
|
2012
2263
|
twitter: 280,
|
|
@@ -2027,15 +2278,15 @@ function registerCalendarTools(server2, client2) {
|
|
|
2027
2278
|
title: "Manage Content Calendar",
|
|
2028
2279
|
description: "View content calendar, add posts to queue, or view queue schedule.",
|
|
2029
2280
|
inputSchema: {
|
|
2030
|
-
action:
|
|
2031
|
-
from:
|
|
2032
|
-
to:
|
|
2033
|
-
status:
|
|
2034
|
-
type:
|
|
2035
|
-
content:
|
|
2036
|
-
platforms:
|
|
2037
|
-
media_urls:
|
|
2038
|
-
confirmed:
|
|
2281
|
+
action: z9.enum(["get_calendar", "schedule_to_queue", "get_queue"]),
|
|
2282
|
+
from: z9.string().optional().describe("ISO date from (get_calendar)"),
|
|
2283
|
+
to: z9.string().optional().describe("ISO date to (get_calendar)"),
|
|
2284
|
+
status: z9.string().optional().describe("Filter status (get_calendar)"),
|
|
2285
|
+
type: z9.string().optional().describe("Filter type: social_post or newsletter (get_calendar)"),
|
|
2286
|
+
content: z9.string().optional().describe("Post text (schedule_to_queue)"),
|
|
2287
|
+
platforms: z9.array(z9.string()).optional().describe("Target platforms (schedule_to_queue)"),
|
|
2288
|
+
media_urls: z9.array(z9.string()).optional().describe("Media URLs (schedule_to_queue)"),
|
|
2289
|
+
confirmed: z9.boolean().default(false).describe("Confirm scheduling (schedule_to_queue)")
|
|
2039
2290
|
},
|
|
2040
2291
|
annotations: {
|
|
2041
2292
|
readOnlyHint: false,
|
|
@@ -2262,7 +2513,7 @@ Next slot: ${slotDate2.toLocaleString()} (${dayNames[slotDate2.getDay()]})
|
|
|
2262
2513
|
}
|
|
2263
2514
|
|
|
2264
2515
|
// src/tools/sources.ts
|
|
2265
|
-
import { z as
|
|
2516
|
+
import { z as z10 } from "zod";
|
|
2266
2517
|
var TYPE_LABELS = {
|
|
2267
2518
|
feed: "RSS Feed",
|
|
2268
2519
|
website: "Website",
|
|
@@ -2288,17 +2539,17 @@ function registerSourceTools(server2, client2) {
|
|
|
2288
2539
|
"manage_sources",
|
|
2289
2540
|
"List, add, update, or remove content sources (RSS feeds, websites, channels). Max 10 sources.",
|
|
2290
2541
|
{
|
|
2291
|
-
action:
|
|
2292
|
-
source_id:
|
|
2293
|
-
name:
|
|
2294
|
-
url:
|
|
2295
|
-
type:
|
|
2296
|
-
category:
|
|
2297
|
-
tags:
|
|
2298
|
-
notes:
|
|
2299
|
-
searchQuery:
|
|
2300
|
-
isActive:
|
|
2301
|
-
confirmed:
|
|
2542
|
+
action: z10.enum(["list", "add", "update", "remove"]),
|
|
2543
|
+
source_id: z10.number().optional().describe("Source ID (update/remove)"),
|
|
2544
|
+
name: z10.string().optional().describe("Display name (add/update)"),
|
|
2545
|
+
url: z10.string().optional().describe("Source URL (add/update)"),
|
|
2546
|
+
type: z10.enum(SOURCE_TYPES).optional().describe("Source type (add/update)"),
|
|
2547
|
+
category: z10.string().optional().describe("Category for organization (add/update)"),
|
|
2548
|
+
tags: z10.array(z10.string()).optional().describe("Tags for filtering (add/update)"),
|
|
2549
|
+
notes: z10.string().optional().describe("Notes about the source (add/update)"),
|
|
2550
|
+
searchQuery: z10.string().optional().describe("Search keyword for 'search' type (add/update)"),
|
|
2551
|
+
isActive: z10.boolean().optional().describe("Active status (update)"),
|
|
2552
|
+
confirmed: z10.boolean().default(false).describe("Confirm removal (remove)")
|
|
2302
2553
|
},
|
|
2303
2554
|
{
|
|
2304
2555
|
title: "Manage Content Sources",
|
|
@@ -2404,7 +2655,7 @@ This will permanently remove this content source. Call again with confirmed=true
|
|
|
2404
2655
|
}
|
|
2405
2656
|
|
|
2406
2657
|
// src/tools/wordpress.ts
|
|
2407
|
-
import { z as
|
|
2658
|
+
import { z as z11 } from "zod";
|
|
2408
2659
|
import { registerAppTool as registerAppTool4 } from "@modelcontextprotocol/ext-apps/server";
|
|
2409
2660
|
function mapWpStatus(wpStatus) {
|
|
2410
2661
|
switch (wpStatus) {
|
|
@@ -2453,26 +2704,26 @@ function registerWordPressTools(server2, client2) {
|
|
|
2453
2704
|
title: "Manage WordPress",
|
|
2454
2705
|
description: "CRUD WordPress posts/pages, upload media, list categories/tags.",
|
|
2455
2706
|
inputSchema: {
|
|
2456
|
-
action:
|
|
2457
|
-
post_id:
|
|
2458
|
-
title:
|
|
2459
|
-
content:
|
|
2460
|
-
wp_status:
|
|
2461
|
-
categories:
|
|
2462
|
-
tags:
|
|
2463
|
-
featured_media:
|
|
2464
|
-
excerpt:
|
|
2465
|
-
date:
|
|
2466
|
-
slug:
|
|
2467
|
-
per_page:
|
|
2468
|
-
page:
|
|
2469
|
-
search:
|
|
2470
|
-
filter_categories:
|
|
2471
|
-
filter_tags:
|
|
2472
|
-
force:
|
|
2473
|
-
url:
|
|
2474
|
-
filename:
|
|
2475
|
-
confirmed:
|
|
2707
|
+
action: z11.enum(["create_post", "update_post", "publish_post", "list_posts", "get_post", "create_page", "delete_post", "upload_media", "list_categories", "list_tags"]),
|
|
2708
|
+
post_id: z11.number().optional().describe("WordPress post/page ID (update/publish/get/delete)"),
|
|
2709
|
+
title: z11.string().optional().describe("Title (create_post/create_page/update)"),
|
|
2710
|
+
content: z11.string().optional().describe("HTML content (create_post/create_page/update)"),
|
|
2711
|
+
wp_status: z11.enum(["draft", "publish", "pending", "private", "future"]).optional().describe("Post status (create_post/create_page/update, default draft)"),
|
|
2712
|
+
categories: z11.array(z11.number()).optional().describe("Category IDs (create_post/update)"),
|
|
2713
|
+
tags: z11.array(z11.number()).optional().describe("Tag IDs (create_post/update)"),
|
|
2714
|
+
featured_media: z11.number().optional().describe("Featured image ID (create_post/create_page/update)"),
|
|
2715
|
+
excerpt: z11.string().optional().describe("Excerpt (create_post/create_page/update)"),
|
|
2716
|
+
date: z11.string().optional().describe("ISO 8601 date (create_post/update, required for 'future')"),
|
|
2717
|
+
slug: z11.string().optional().describe("URL slug (create_post/create_page/update)"),
|
|
2718
|
+
per_page: z11.string().optional().describe("Results per page (list_posts)"),
|
|
2719
|
+
page: z11.string().optional().describe("Page number (list_posts)"),
|
|
2720
|
+
search: z11.string().optional().describe("Search keyword (list_posts)"),
|
|
2721
|
+
filter_categories: z11.string().optional().describe("Filter by category IDs, comma-separated (list_posts)"),
|
|
2722
|
+
filter_tags: z11.string().optional().describe("Filter by tag IDs, comma-separated (list_posts)"),
|
|
2723
|
+
force: z11.boolean().default(false).describe("Permanent delete instead of trash (delete_post)"),
|
|
2724
|
+
url: z11.string().optional().describe("Public image URL (upload_media)"),
|
|
2725
|
+
filename: z11.string().optional().describe("Filename for upload (upload_media)"),
|
|
2726
|
+
confirmed: z11.boolean().default(false).describe("Confirm action (create non-draft/publish/delete)")
|
|
2476
2727
|
},
|
|
2477
2728
|
annotations: {
|
|
2478
2729
|
readOnlyHint: false,
|
|
@@ -2856,7 +3107,7 @@ ${args.force ? "WARNING: This will permanently delete the post and cannot be und
|
|
|
2856
3107
|
}
|
|
2857
3108
|
|
|
2858
3109
|
// src/tools/ghost.ts
|
|
2859
|
-
import { z as
|
|
3110
|
+
import { z as z12 } from "zod";
|
|
2860
3111
|
import { registerAppTool as registerAppTool5 } from "@modelcontextprotocol/ext-apps/server";
|
|
2861
3112
|
function mapGhostStatus(ghostStatus) {
|
|
2862
3113
|
switch (ghostStatus) {
|
|
@@ -2895,22 +3146,22 @@ function registerGhostTools(server2, client2) {
|
|
|
2895
3146
|
title: "Manage Ghost",
|
|
2896
3147
|
description: "CRUD Ghost posts, send newsletters, list members/newsletters.",
|
|
2897
3148
|
inputSchema: {
|
|
2898
|
-
action:
|
|
2899
|
-
post_id:
|
|
2900
|
-
title:
|
|
2901
|
-
html:
|
|
2902
|
-
status:
|
|
2903
|
-
tags:
|
|
2904
|
-
featured:
|
|
2905
|
-
custom_excerpt:
|
|
2906
|
-
feature_image:
|
|
2907
|
-
updated_at:
|
|
2908
|
-
newsletter_id:
|
|
2909
|
-
email_only:
|
|
2910
|
-
limit:
|
|
2911
|
-
page:
|
|
2912
|
-
filter:
|
|
2913
|
-
confirmed:
|
|
3149
|
+
action: z12.enum(["create", "update", "publish", "list", "get", "send_newsletter", "list_members", "list_newsletters"]),
|
|
3150
|
+
post_id: z12.string().optional().describe("Ghost post ID (update/publish/get/send_newsletter)"),
|
|
3151
|
+
title: z12.string().optional().describe("Post title (create/update)"),
|
|
3152
|
+
html: z12.string().optional().describe("HTML content (create/update)"),
|
|
3153
|
+
status: z12.enum(["draft", "published", "scheduled"]).optional().describe("Post status (create/update, default draft)"),
|
|
3154
|
+
tags: z12.array(z12.string()).optional().describe("Tag names (create/update)"),
|
|
3155
|
+
featured: z12.boolean().optional().describe("Featured flag (create/update)"),
|
|
3156
|
+
custom_excerpt: z12.string().optional().describe("Custom excerpt (create/update)"),
|
|
3157
|
+
feature_image: z12.string().optional().describe("Feature image URL (create/update)"),
|
|
3158
|
+
updated_at: z12.string().optional().describe("Collision detection timestamp (update/publish/send_newsletter)"),
|
|
3159
|
+
newsletter_id: z12.string().optional().describe("Newsletter ID (send_newsletter)"),
|
|
3160
|
+
email_only: z12.boolean().default(false).describe("Email only, no publish (send_newsletter)"),
|
|
3161
|
+
limit: z12.string().optional().describe("Results per page (list/list_members)"),
|
|
3162
|
+
page: z12.string().optional().describe("Page number (list/list_members)"),
|
|
3163
|
+
filter: z12.string().optional().describe("NQL filter (list_members)"),
|
|
3164
|
+
confirmed: z12.boolean().default(false).describe("Confirm action (create non-draft/publish/send_newsletter)")
|
|
2914
3165
|
},
|
|
2915
3166
|
annotations: {
|
|
2916
3167
|
readOnlyHint: false,
|
|
@@ -3284,7 +3535,7 @@ Call this tool again with confirmed=true to send.`;
|
|
|
3284
3535
|
}
|
|
3285
3536
|
|
|
3286
3537
|
// src/tools/image-templates.ts
|
|
3287
|
-
import { z as
|
|
3538
|
+
import { z as z13 } from "zod";
|
|
3288
3539
|
import {
|
|
3289
3540
|
registerAppResource as registerAppResource3,
|
|
3290
3541
|
registerAppTool as registerAppTool6,
|
|
@@ -3323,13 +3574,13 @@ function registerImageTemplateTools(server2, client2) {
|
|
|
3323
3574
|
title: "Manage Images",
|
|
3324
3575
|
description: "Generate branded images, list templates, or list formats/dimensions.",
|
|
3325
3576
|
inputSchema: {
|
|
3326
|
-
action:
|
|
3327
|
-
template_id:
|
|
3328
|
-
article_image_url:
|
|
3329
|
-
headline:
|
|
3330
|
-
summary:
|
|
3331
|
-
formats:
|
|
3332
|
-
platforms:
|
|
3577
|
+
action: z13.enum(["generate", "list_templates", "list_formats"]),
|
|
3578
|
+
template_id: z13.string().optional().describe("Image template ID, omit for default (generate)"),
|
|
3579
|
+
article_image_url: z13.string().optional().describe("Background image URL (generate)"),
|
|
3580
|
+
headline: z13.string().optional().describe("Headline text overlay (generate)"),
|
|
3581
|
+
summary: z13.string().optional().describe("Summary text below headline (generate)"),
|
|
3582
|
+
formats: z13.array(z13.string()).optional().describe("Output formats: square, portrait, landscape, wide, story (generate)"),
|
|
3583
|
+
platforms: z13.array(z13.string()).optional().describe("Platform shortcuts: instagram, facebook, linkedin, twitter (generate)")
|
|
3333
3584
|
},
|
|
3334
3585
|
annotations: {
|
|
3335
3586
|
readOnlyHint: false,
|
|
@@ -3469,21 +3720,21 @@ function registerImageTemplateTools(server2, client2) {
|
|
|
3469
3720
|
}
|
|
3470
3721
|
|
|
3471
3722
|
// src/tools/publishing-rules.ts
|
|
3472
|
-
import { z as
|
|
3723
|
+
import { z as z14 } from "zod";
|
|
3473
3724
|
function registerPublishingRulesTools(server2, client2) {
|
|
3474
3725
|
server2.tool(
|
|
3475
3726
|
"manage_publishing_rules",
|
|
3476
3727
|
"Get or update publishing safety rules (immediate publish, blocked words, daily limits, default actions, Twitter Premium).",
|
|
3477
3728
|
{
|
|
3478
|
-
action:
|
|
3479
|
-
allow_immediate_publish:
|
|
3480
|
-
allow_immediate_send:
|
|
3481
|
-
social_default_action:
|
|
3482
|
-
newsletter_default_action:
|
|
3483
|
-
max_posts_per_day:
|
|
3484
|
-
blocked_words:
|
|
3485
|
-
twitter_premium:
|
|
3486
|
-
confirmed:
|
|
3729
|
+
action: z14.enum(["get", "update"]),
|
|
3730
|
+
allow_immediate_publish: z14.boolean().optional().describe("Allow immediate social publish (update)"),
|
|
3731
|
+
allow_immediate_send: z14.boolean().optional().describe("Allow immediate newsletter send (update)"),
|
|
3732
|
+
social_default_action: z14.enum(["draft", "schedule", "publish"]).optional().describe("Default social action (update)"),
|
|
3733
|
+
newsletter_default_action: z14.enum(["draft", "schedule", "send"]).optional().describe("Default newsletter action (update)"),
|
|
3734
|
+
max_posts_per_day: z14.number().int().min(1).max(100).nullable().optional().describe("Max posts/day, null=unlimited (update)"),
|
|
3735
|
+
blocked_words: z14.array(z14.string().max(100)).max(200).nullable().optional().describe("Blocked words list (update)"),
|
|
3736
|
+
twitter_premium: z14.boolean().optional().describe("Enable 25K char Twitter limit (update)"),
|
|
3737
|
+
confirmed: z14.boolean().default(false).describe("Confirm update (update)")
|
|
3487
3738
|
},
|
|
3488
3739
|
{
|
|
3489
3740
|
title: "Manage Publishing Rules",
|
|
@@ -3565,15 +3816,15 @@ function registerPublishingRulesTools(server2, client2) {
|
|
|
3565
3816
|
}
|
|
3566
3817
|
|
|
3567
3818
|
// src/tools/context.ts
|
|
3568
|
-
import { z as
|
|
3819
|
+
import { z as z15 } from "zod";
|
|
3569
3820
|
function registerContextTools(server2, client2) {
|
|
3570
3821
|
server2.tool(
|
|
3571
3822
|
"get_context",
|
|
3572
3823
|
"Get brand voice, audience, and knowledge in one call for content creation.",
|
|
3573
3824
|
{
|
|
3574
|
-
platform:
|
|
3575
|
-
topic:
|
|
3576
|
-
include_newsletter_stats:
|
|
3825
|
+
platform: z15.string().optional().describe("Filter voice rules for platform"),
|
|
3826
|
+
topic: z15.string().optional().describe("Filter knowledge items by topic/tag"),
|
|
3827
|
+
include_newsletter_stats: z15.boolean().optional().describe("Include recent analytics")
|
|
3577
3828
|
},
|
|
3578
3829
|
{
|
|
3579
3830
|
title: "Get Context",
|
|
@@ -3647,13 +3898,13 @@ function registerContextTools(server2, client2) {
|
|
|
3647
3898
|
}
|
|
3648
3899
|
|
|
3649
3900
|
// src/tools/team.ts
|
|
3650
|
-
import { z as
|
|
3901
|
+
import { z as z16 } from "zod";
|
|
3651
3902
|
function registerTeamTools(server2, client2) {
|
|
3652
3903
|
server2.tool(
|
|
3653
3904
|
"manage_team",
|
|
3654
3905
|
"Manage team members, invitations, and organizations. List members, invite or remove members, manage invitations, and list organizations.",
|
|
3655
3906
|
{
|
|
3656
|
-
action:
|
|
3907
|
+
action: z16.enum([
|
|
3657
3908
|
"list_members",
|
|
3658
3909
|
"invite_member",
|
|
3659
3910
|
"remove_member",
|
|
@@ -3661,10 +3912,10 @@ function registerTeamTools(server2, client2) {
|
|
|
3661
3912
|
"revoke_invitation",
|
|
3662
3913
|
"list_organizations"
|
|
3663
3914
|
]),
|
|
3664
|
-
email:
|
|
3665
|
-
role:
|
|
3666
|
-
member_id:
|
|
3667
|
-
invitation_id:
|
|
3915
|
+
email: z16.string().optional().describe("Email address (invite_member)"),
|
|
3916
|
+
role: z16.string().optional().describe("Role for the member (invite_member), e.g. 'admin', 'member'"),
|
|
3917
|
+
member_id: z16.string().optional().describe("Member ID (remove_member)"),
|
|
3918
|
+
invitation_id: z16.string().optional().describe("Invitation ID (revoke_invitation)")
|
|
3668
3919
|
},
|
|
3669
3920
|
{
|
|
3670
3921
|
title: "Manage Team",
|
|
@@ -3805,10 +4056,17 @@ var server = new McpServer(
|
|
|
3805
4056
|
},
|
|
3806
4057
|
{}
|
|
3807
4058
|
);
|
|
4059
|
+
var allowDirectSend = false;
|
|
4060
|
+
try {
|
|
4061
|
+
const account = await client.getAccount();
|
|
4062
|
+
allowDirectSend = account?.allowDirectSend === true;
|
|
4063
|
+
} catch {
|
|
4064
|
+
}
|
|
3808
4065
|
registerPostPreviewResource(server);
|
|
3809
4066
|
registerPostTools(server, client);
|
|
3810
4067
|
registerInsightsTools(server, client);
|
|
3811
4068
|
registerMediaTools(server, client);
|
|
4069
|
+
registerNewsletterTools(server, client, { allowDirectSend });
|
|
3812
4070
|
registerRssTools(server, client);
|
|
3813
4071
|
registerAccountTools(server, client);
|
|
3814
4072
|
registerBrandVoiceTools(server, client);
|