@buzzposter/mcp 0.3.2 → 0.3.3

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/tools.d.ts CHANGED
@@ -31,8 +31,6 @@ declare class BuzzPosterClient {
31
31
  }): Promise<unknown>;
32
32
  listMedia(): Promise<unknown>;
33
33
  deleteMedia(key: string): Promise<unknown>;
34
- createPreview(data: Record<string, unknown>): Promise<unknown>;
35
- updatePreview(id: string, data: Record<string, unknown>): Promise<unknown>;
36
34
  listSubscribers(params?: Record<string, string>): Promise<unknown>;
37
35
  addSubscriber(data: Record<string, unknown>): Promise<unknown>;
38
36
  listBroadcasts(params?: Record<string, string>): Promise<unknown>;
@@ -122,7 +120,6 @@ declare function registerMediaTools(server: McpServer, client: BuzzPosterClient)
122
120
 
123
121
  interface NewsletterToolOptions {
124
122
  allowDirectSend?: boolean;
125
- apiUrl?: string;
126
123
  }
127
124
  declare function registerNewsletterTools(server: McpServer, client: BuzzPosterClient, options?: NewsletterToolOptions): void;
128
125
 
package/dist/tools.js CHANGED
@@ -6,8 +6,8 @@ var BuzzPosterClient = class {
6
6
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
7
7
  this.apiKey = config.apiKey;
8
8
  }
9
- async request(method, path, body, query) {
10
- const url = new URL(`${this.baseUrl}${path}`);
9
+ async request(method, path2, body, query) {
10
+ const url = new URL(`${this.baseUrl}${path2}`);
11
11
  if (query) {
12
12
  for (const [k, v] of Object.entries(query)) {
13
13
  if (v !== void 0 && v !== "") url.searchParams.set(k, v);
@@ -101,13 +101,6 @@ var BuzzPosterClient = class {
101
101
  async deleteMedia(key) {
102
102
  return this.request("DELETE", `/api/v1/media/${encodeURIComponent(key)}`);
103
103
  }
104
- // Newsletter Preview (no ESP required)
105
- async createPreview(data) {
106
- return this.request("POST", "/api/v1/newsletters/preview", data);
107
- }
108
- async updatePreview(id, data) {
109
- return this.request("PUT", `/api/v1/newsletters/preview/${id}`, data);
110
- }
111
104
  // Newsletter
112
105
  async listSubscribers(params) {
113
106
  return this.request(
@@ -1061,37 +1054,27 @@ import {
1061
1054
  registerAppTool,
1062
1055
  RESOURCE_MIME_TYPE
1063
1056
  } from "@modelcontextprotocol/ext-apps/server";
1057
+ import * as fs from "fs";
1058
+ import * as path from "path";
1059
+ import { fileURLToPath } from "url";
1060
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
1064
1061
  var NEWSLETTER_STUDIO_RESOURCE = "ui://newsletter-studio/app.html";
1065
- function buildStudioHtml(apiUrl) {
1066
- const base = apiUrl.replace(/\/$/, "");
1067
- return `<!DOCTYPE html>
1068
- <html lang="en">
1069
- <head>
1070
- <meta charset="utf-8">
1071
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
1072
- <link rel="stylesheet" href="${base}/newsletter-assets/newsletter-studio.css">
1073
- <style>html,body,#root{margin:0;padding:0;height:100%;}</style>
1074
- </head>
1075
- <body>
1076
- <div id="root"></div>
1077
- <script type="module" src="${base}/newsletter-assets/newsletter-studio.js"></script>
1078
- </body>
1079
- </html>`;
1080
- }
1081
1062
  function registerNewsletterTools(server, client, options = {}) {
1082
- const apiUrl = options.apiUrl || "";
1083
1063
  registerAppResource(
1084
1064
  server,
1085
1065
  NEWSLETTER_STUDIO_RESOURCE,
1086
1066
  NEWSLETTER_STUDIO_RESOURCE,
1087
1067
  { mimeType: RESOURCE_MIME_TYPE },
1088
1068
  async () => {
1069
+ const distDir = __dirname.endsWith("dist") ? __dirname : path.resolve(__dirname, "..", "dist");
1070
+ const htmlPath = path.join(distDir, "newsletter-studio.html");
1071
+ const html = fs.readFileSync(htmlPath, "utf-8");
1089
1072
  return {
1090
1073
  contents: [
1091
1074
  {
1092
1075
  uri: NEWSLETTER_STUDIO_RESOURCE,
1093
1076
  mimeType: RESOURCE_MIME_TYPE,
1094
- text: buildStudioHtml(apiUrl)
1077
+ text: html
1095
1078
  }
1096
1079
  ]
1097
1080
  };
@@ -1151,8 +1134,8 @@ function registerNewsletterTools(server, client, options = {}) {
1151
1134
  server,
1152
1135
  "create_newsletter",
1153
1136
  {
1154
- title: "Create Newsletter Preview",
1155
- description: "Create a newsletter preview. Uploads HTML to a preview URL for review in Newsletter Studio. Does NOT push to ESP \u2014 use push_newsletter_to_esp for that. Always call get_brand_voice first. Use table-based layouts, inline CSS only, 600px max width, email-safe fonts only (Arial, Helvetica, Georgia, Verdana), all images must use absolute URLs, keep under 102KB to avoid Gmail clipping.",
1137
+ title: "Create Newsletter Draft",
1138
+ description: "Push a newsletter to the user's ESP as a draft. Always call get_brand_voice first. Show an HTML preview to the user before calling this. Use table-based layouts, inline CSS only, 600px max width, email-safe fonts only (Arial, Helvetica, Georgia, Verdana), all images must use absolute URLs, keep under 102KB to avoid Gmail clipping. Optionally pass template_id to use an ESP-native template. Use list_esp_templates to discover available templates.",
1156
1139
  inputSchema: {
1157
1140
  subject: z5.string().describe("Email subject line"),
1158
1141
  content: z5.string().describe("HTML content of the newsletter"),
@@ -1166,17 +1149,15 @@ function registerNewsletterTools(server, client, options = {}) {
1166
1149
  resourceUri: NEWSLETTER_STUDIO_RESOURCE,
1167
1150
  csp: {
1168
1151
  resourceDomains: [
1169
- apiUrl,
1170
1152
  "https://cdn.jsdelivr.net",
1171
1153
  "https://fonts.googleapis.com",
1172
1154
  "https://fonts.gstatic.com",
1173
1155
  "https://unpkg.com"
1174
- ].filter(Boolean),
1156
+ ],
1175
1157
  connectDomains: [
1176
- apiUrl,
1177
1158
  "https://fonts.googleapis.com",
1178
1159
  "https://fonts.gstatic.com"
1179
- ].filter(Boolean)
1160
+ ]
1180
1161
  }
1181
1162
  }
1182
1163
  }
@@ -1188,7 +1169,7 @@ function registerNewsletterTools(server, client, options = {}) {
1188
1169
  previewText: args.preview_text
1189
1170
  };
1190
1171
  if (args.template_id) payload.templateId = args.template_id;
1191
- const result = await client.createPreview(payload);
1172
+ const result = await client.createBroadcast(payload);
1192
1173
  const response = {
1193
1174
  ...result,
1194
1175
  subject: args.subject,
@@ -1196,7 +1177,6 @@ function registerNewsletterTools(server, client, options = {}) {
1196
1177
  previewText: args.preview_text
1197
1178
  };
1198
1179
  return {
1199
- _meta: { ui: { resourceUri: NEWSLETTER_STUDIO_RESOURCE } },
1200
1180
  content: [
1201
1181
  { type: "text", text: JSON.stringify(response, null, 2) }
1202
1182
  ]
@@ -1205,15 +1185,15 @@ function registerNewsletterTools(server, client, options = {}) {
1205
1185
  );
1206
1186
  server.tool(
1207
1187
  "update_newsletter",
1208
- "Update an existing newsletter preview.",
1188
+ "Update an existing newsletter draft.",
1209
1189
  {
1210
- preview_id: z5.string().describe("The preview ID to update"),
1190
+ broadcast_id: z5.string().describe("The broadcast/newsletter ID to update"),
1211
1191
  subject: z5.string().optional().describe("Updated subject line"),
1212
1192
  content: z5.string().optional().describe("Updated HTML content"),
1213
1193
  preview_text: z5.string().optional().describe("Updated preview text")
1214
1194
  },
1215
1195
  {
1216
- title: "Update Newsletter Preview",
1196
+ title: "Update Newsletter Draft",
1217
1197
  readOnlyHint: false,
1218
1198
  destructiveHint: false,
1219
1199
  idempotentHint: true,
@@ -1224,45 +1204,7 @@ function registerNewsletterTools(server, client, options = {}) {
1224
1204
  if (args.subject) data.subject = args.subject;
1225
1205
  if (args.content) data.content = args.content;
1226
1206
  if (args.preview_text) data.previewText = args.preview_text;
1227
- const result = await client.updatePreview(args.preview_id, data);
1228
- const response = {
1229
- ...result,
1230
- subject: args.subject,
1231
- content: args.content,
1232
- previewText: args.preview_text
1233
- };
1234
- return {
1235
- _meta: { ui: { resourceUri: NEWSLETTER_STUDIO_RESOURCE } },
1236
- content: [
1237
- { type: "text", text: JSON.stringify(response, null, 2) }
1238
- ]
1239
- };
1240
- }
1241
- );
1242
- server.tool(
1243
- "push_newsletter_to_esp",
1244
- "Push a newsletter to the user's ESP as a draft broadcast. Requires ESP to be configured. Use create_newsletter first for preview, then push when the user is happy with the content.",
1245
- {
1246
- subject: z5.string().describe("Email subject line"),
1247
- content: z5.string().describe("HTML content of the newsletter"),
1248
- preview_text: z5.string().optional().describe("Preview text shown in email clients"),
1249
- template_id: z5.string().optional().describe("ESP-native template ID")
1250
- },
1251
- {
1252
- title: "Push Newsletter to ESP",
1253
- readOnlyHint: false,
1254
- destructiveHint: false,
1255
- idempotentHint: false,
1256
- openWorldHint: true
1257
- },
1258
- async (args) => {
1259
- const payload = {
1260
- subject: args.subject,
1261
- content: args.content,
1262
- previewText: args.preview_text
1263
- };
1264
- if (args.template_id) payload.templateId = args.template_id;
1265
- const result = await client.createBroadcast(payload);
1207
+ const result = await client.updateBroadcast(args.broadcast_id, data);
1266
1208
  const response = {
1267
1209
  ...result,
1268
1210
  subject: args.subject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buzzposter/mcp",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "BuzzPoster MCP server - Social media, newsletters, and media hosting for any AI chatbot",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -42,29 +42,10 @@
42
42
  "zod": "^3.24.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@blocknote/core": "^0.47.0",
46
- "@blocknote/mantine": "^0.47.0",
47
- "@blocknote/react": "^0.47.0",
48
- "@mantine/core": "^8.3.11",
49
- "@mantine/hooks": "^8.3.11",
50
- "@mantine/utils": "^6.0.22",
51
- "@tiptap/core": "^3.13.0",
52
- "@tiptap/pm": "^3.13.0",
53
45
  "@types/node": "^22.0.0",
54
46
  "@types/react": "^18.3.0",
55
47
  "@types/react-dom": "^18.3.0",
56
48
  "@vitejs/plugin-react": "^5.1.4",
57
- "prosemirror-commands": "^1.6.0",
58
- "prosemirror-dropcursor": "^1.8.0",
59
- "prosemirror-history": "^1.4.0",
60
- "prosemirror-inputrules": "^1.4.0",
61
- "prosemirror-keymap": "^1.2.0",
62
- "prosemirror-model": "^1.25.0",
63
- "prosemirror-schema-list": "^1.4.0",
64
- "prosemirror-state": "^1.4.0",
65
- "prosemirror-tables": "^1.8.0",
66
- "prosemirror-transform": "^1.10.0",
67
- "prosemirror-view": "^1.41.0",
68
49
  "react": "^18.3.0",
69
50
  "react-dom": "^18.3.0",
70
51
  "tsup": "^8.3.0",