posterly-mcp-server 0.19.1 → 0.19.2
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 +3 -1
- package/dist/index.js +50 -49
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/format.d.ts +21 -0
- package/dist/lib/format.js +125 -0
- package/dist/tools/audit-google-business-profile.js +15 -12
- package/dist/tools/create-oauth-client.js +7 -1
- package/dist/tools/create-post.js +20 -27
- package/dist/tools/create-posts-batch.js +23 -15
- package/dist/tools/create-signed-upload.js +11 -8
- package/dist/tools/create-webhook.js +7 -2
- package/dist/tools/delete-google-business-review-reply.d.ts +1 -1
- package/dist/tools/delete-google-business-review-reply.js +4 -1
- package/dist/tools/delete-oauth-client.js +4 -1
- package/dist/tools/delete-post-group.js +5 -1
- package/dist/tools/delete-post.js +4 -1
- package/dist/tools/delete-webhook.js +4 -1
- package/dist/tools/disconnect-account.js +7 -5
- package/dist/tools/find-slot.js +10 -3
- package/dist/tools/generate-image.js +17 -19
- package/dist/tools/generate-video.js +11 -9
- package/dist/tools/get-account-analytics.js +64 -45
- package/dist/tools/get-brand-profile.js +34 -40
- package/dist/tools/get-brand.js +14 -16
- package/dist/tools/get-connect-link.js +26 -7
- package/dist/tools/get-google-business-review-link.js +6 -6
- package/dist/tools/get-platform-schema.js +23 -16
- package/dist/tools/get-post-analytics.js +53 -50
- package/dist/tools/get-post-missing.js +5 -1
- package/dist/tools/get-post.js +16 -14
- package/dist/tools/get-video-job.d.ts +2 -2
- package/dist/tools/get-video-job.js +28 -11
- package/dist/tools/get-video-options.js +21 -15
- package/dist/tools/get-x-posting-quota.js +12 -9
- package/dist/tools/list-accounts.js +12 -4
- package/dist/tools/list-activity.js +13 -18
- package/dist/tools/list-brand-accounts.js +11 -3
- package/dist/tools/list-brands.js +12 -11
- package/dist/tools/list-google-business-reviews.js +13 -11
- package/dist/tools/list-oauth-clients.js +10 -4
- package/dist/tools/list-platforms.js +12 -5
- package/dist/tools/list-posts.js +12 -7
- package/dist/tools/list-webhooks.js +13 -11
- package/dist/tools/reply-google-business-review.d.ts +1 -1
- package/dist/tools/reply-google-business-review.js +4 -1
- package/dist/tools/run-video-function.js +4 -4
- package/dist/tools/suggest-google-business-review-reply.js +5 -4
- package/dist/tools/test-webhook.js +7 -1
- package/dist/tools/trigger-platform-helper.js +5 -1
- package/dist/tools/update-oauth-client.js +8 -1
- package/dist/tools/update-post-release-id.js +5 -1
- package/dist/tools/update-post-status.d.ts +2 -2
- package/dist/tools/update-post-status.js +7 -1
- package/dist/tools/update-post.js +10 -4
- package/dist/tools/update-webhook.js +7 -1
- package/dist/tools/upload-media-from-url.js +7 -9
- package/dist/tools/upload-media.js +6 -2
- package/dist/tools/whoami.js +18 -17
- package/package.json +1 -1
- package/src/index.ts +50 -49
- package/src/lib/api-client.ts +1 -1
- package/src/lib/format.ts +132 -0
- package/src/tools/audit-google-business-profile.ts +18 -12
- package/src/tools/create-oauth-client.ts +8 -2
- package/src/tools/create-post.ts +20 -28
- package/src/tools/create-posts-batch.ts +23 -18
- package/src/tools/create-signed-upload.ts +11 -8
- package/src/tools/create-webhook.ts +7 -3
- package/src/tools/delete-google-business-review-reply.ts +4 -1
- package/src/tools/delete-oauth-client.ts +4 -1
- package/src/tools/delete-post-group.ts +5 -1
- package/src/tools/delete-post.ts +4 -1
- package/src/tools/delete-webhook.ts +4 -2
- package/src/tools/disconnect-account.ts +7 -5
- package/src/tools/find-slot.ts +13 -5
- package/src/tools/generate-image.ts +20 -20
- package/src/tools/generate-video.ts +11 -9
- package/src/tools/get-account-analytics.ts +70 -49
- package/src/tools/get-brand-profile.ts +34 -38
- package/src/tools/get-brand.ts +14 -14
- package/src/tools/get-connect-link.ts +29 -7
- package/src/tools/get-google-business-review-link.ts +6 -6
- package/src/tools/get-platform-schema.ts +29 -16
- package/src/tools/get-post-analytics.ts +58 -51
- package/src/tools/get-post-missing.ts +5 -2
- package/src/tools/get-post.ts +16 -13
- package/src/tools/get-video-job.ts +31 -11
- package/src/tools/get-video-options.ts +27 -15
- package/src/tools/get-x-posting-quota.ts +12 -9
- package/src/tools/list-accounts.ts +15 -6
- package/src/tools/list-activity.ts +16 -20
- package/src/tools/list-brand-accounts.ts +14 -6
- package/src/tools/list-brands.ts +16 -13
- package/src/tools/list-google-business-reviews.ts +16 -12
- package/src/tools/list-oauth-clients.ts +13 -4
- package/src/tools/list-platforms.ts +15 -5
- package/src/tools/list-posts.ts +15 -9
- package/src/tools/list-webhooks.ts +16 -12
- package/src/tools/reply-google-business-review.ts +4 -1
- package/src/tools/run-video-function.ts +4 -4
- package/src/tools/suggest-google-business-review-reply.ts +5 -4
- package/src/tools/test-webhook.ts +7 -1
- package/src/tools/trigger-platform-helper.ts +5 -1
- package/src/tools/update-oauth-client.ts +9 -2
- package/src/tools/update-post-release-id.ts +5 -2
- package/src/tools/update-post-status.ts +7 -1
- package/src/tools/update-post.ts +10 -5
- package/src/tools/update-webhook.ts +7 -2
- package/src/tools/upload-media-from-url.ts +7 -9
- package/src/tools/upload-media.ts +6 -2
- package/src/tools/whoami.ts +21 -23
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { mdError } from './lib/format.js';
|
|
5
6
|
import { PosterlyClient } from './lib/api-client.js';
|
|
6
7
|
import { listAccountsTool } from './tools/list-accounts.js';
|
|
7
8
|
import { disconnectAccountTool } from './tools/disconnect-account.js';
|
|
@@ -77,7 +78,7 @@ server.tool(
|
|
|
77
78
|
const text = await whoamiTool.execute(client);
|
|
78
79
|
return { content: [{ type: 'text' as const, text }] };
|
|
79
80
|
} catch (err: any) {
|
|
80
|
-
return { content: [{ type: 'text' as const, text:
|
|
81
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
);
|
|
@@ -91,7 +92,7 @@ server.tool(
|
|
|
91
92
|
const text = await listAccountsTool.execute(client, input as any);
|
|
92
93
|
return { content: [{ type: 'text' as const, text }] };
|
|
93
94
|
} catch (err: any) {
|
|
94
|
-
return { content: [{ type: 'text' as const, text:
|
|
95
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
);
|
|
@@ -105,7 +106,7 @@ server.tool(
|
|
|
105
106
|
const text = await disconnectAccountTool.execute(client, input as any);
|
|
106
107
|
return { content: [{ type: 'text' as const, text }] };
|
|
107
108
|
} catch (err: any) {
|
|
108
|
-
return { content: [{ type: 'text' as const, text:
|
|
109
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
);
|
|
@@ -119,7 +120,7 @@ server.tool(
|
|
|
119
120
|
const text = await getConnectLinkTool.execute(client, input as any);
|
|
120
121
|
return { content: [{ type: 'text' as const, text }] };
|
|
121
122
|
} catch (err: any) {
|
|
122
|
-
return { content: [{ type: 'text' as const, text:
|
|
123
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
);
|
|
@@ -133,7 +134,7 @@ server.tool(
|
|
|
133
134
|
const text = await listOAuthClientsTool.execute(client);
|
|
134
135
|
return { content: [{ type: 'text' as const, text }] };
|
|
135
136
|
} catch (err: any) {
|
|
136
|
-
return { content: [{ type: 'text' as const, text:
|
|
137
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
);
|
|
@@ -147,7 +148,7 @@ server.tool(
|
|
|
147
148
|
const text = await createOAuthClientTool.execute(client, input as any);
|
|
148
149
|
return { content: [{ type: 'text' as const, text }] };
|
|
149
150
|
} catch (err: any) {
|
|
150
|
-
return { content: [{ type: 'text' as const, text:
|
|
151
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
);
|
|
@@ -161,7 +162,7 @@ server.tool(
|
|
|
161
162
|
const text = await updateOAuthClientTool.execute(client, input as any);
|
|
162
163
|
return { content: [{ type: 'text' as const, text }] };
|
|
163
164
|
} catch (err: any) {
|
|
164
|
-
return { content: [{ type: 'text' as const, text:
|
|
165
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
);
|
|
@@ -175,7 +176,7 @@ server.tool(
|
|
|
175
176
|
const text = await deleteOAuthClientTool.execute(client, input as any);
|
|
176
177
|
return { content: [{ type: 'text' as const, text }] };
|
|
177
178
|
} catch (err: any) {
|
|
178
|
-
return { content: [{ type: 'text' as const, text:
|
|
179
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
);
|
|
@@ -189,7 +190,7 @@ server.tool(
|
|
|
189
190
|
const text = await listPlatformsTool.execute(client, input as any);
|
|
190
191
|
return { content: [{ type: 'text' as const, text }] };
|
|
191
192
|
} catch (err: any) {
|
|
192
|
-
return { content: [{ type: 'text' as const, text:
|
|
193
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
);
|
|
@@ -203,7 +204,7 @@ server.tool(
|
|
|
203
204
|
const text = await getPlatformSchemaTool.execute(client, input as any);
|
|
204
205
|
return { content: [{ type: 'text' as const, text }] };
|
|
205
206
|
} catch (err: any) {
|
|
206
|
-
return { content: [{ type: 'text' as const, text:
|
|
207
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
);
|
|
@@ -217,7 +218,7 @@ server.tool(
|
|
|
217
218
|
const text = await triggerPlatformHelperTool.execute(client, input as any);
|
|
218
219
|
return { content: [{ type: 'text' as const, text }] };
|
|
219
220
|
} catch (err: any) {
|
|
220
|
-
return { content: [{ type: 'text' as const, text:
|
|
221
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
);
|
|
@@ -231,7 +232,7 @@ server.tool(
|
|
|
231
232
|
const text = await listBrandsTool.execute(client, input as any);
|
|
232
233
|
return { content: [{ type: 'text' as const, text }] };
|
|
233
234
|
} catch (err: any) {
|
|
234
|
-
return { content: [{ type: 'text' as const, text:
|
|
235
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
238
|
);
|
|
@@ -245,7 +246,7 @@ server.tool(
|
|
|
245
246
|
const text = await getBrandTool.execute(client, input as any);
|
|
246
247
|
return { content: [{ type: 'text' as const, text }] };
|
|
247
248
|
} catch (err: any) {
|
|
248
|
-
return { content: [{ type: 'text' as const, text:
|
|
249
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
249
250
|
}
|
|
250
251
|
}
|
|
251
252
|
);
|
|
@@ -259,7 +260,7 @@ server.tool(
|
|
|
259
260
|
const text = await listBrandAccountsTool.execute(client, input as any);
|
|
260
261
|
return { content: [{ type: 'text' as const, text }] };
|
|
261
262
|
} catch (err: any) {
|
|
262
|
-
return { content: [{ type: 'text' as const, text:
|
|
263
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
);
|
|
@@ -273,7 +274,7 @@ server.tool(
|
|
|
273
274
|
const text = await getBrandProfileTool.execute(client, input as any);
|
|
274
275
|
return { content: [{ type: 'text' as const, text }] };
|
|
275
276
|
} catch (err: any) {
|
|
276
|
-
return { content: [{ type: 'text' as const, text:
|
|
277
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
280
|
);
|
|
@@ -287,7 +288,7 @@ server.tool(
|
|
|
287
288
|
const text = await createPostTool.execute(client, input as any);
|
|
288
289
|
return { content: [{ type: 'text' as const, text }] };
|
|
289
290
|
} catch (err: any) {
|
|
290
|
-
return { content: [{ type: 'text' as const, text:
|
|
291
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
291
292
|
}
|
|
292
293
|
}
|
|
293
294
|
);
|
|
@@ -301,7 +302,7 @@ server.tool(
|
|
|
301
302
|
const text = await createPostsBatchTool.execute(client, input as any);
|
|
302
303
|
return { content: [{ type: 'text' as const, text }] };
|
|
303
304
|
} catch (err: any) {
|
|
304
|
-
return { content: [{ type: 'text' as const, text:
|
|
305
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
305
306
|
}
|
|
306
307
|
}
|
|
307
308
|
);
|
|
@@ -315,7 +316,7 @@ server.tool(
|
|
|
315
316
|
const text = await findSlotTool.execute(client, input as any);
|
|
316
317
|
return { content: [{ type: 'text' as const, text }] };
|
|
317
318
|
} catch (err: any) {
|
|
318
|
-
return { content: [{ type: 'text' as const, text:
|
|
319
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
322
|
);
|
|
@@ -329,7 +330,7 @@ server.tool(
|
|
|
329
330
|
const text = await listPostsTool.execute(client, input as any);
|
|
330
331
|
return { content: [{ type: 'text' as const, text }] };
|
|
331
332
|
} catch (err: any) {
|
|
332
|
-
return { content: [{ type: 'text' as const, text:
|
|
333
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
336
|
);
|
|
@@ -343,7 +344,7 @@ server.tool(
|
|
|
343
344
|
const text = await uploadMediaTool.execute(client, input as any);
|
|
344
345
|
return { content: [{ type: 'text' as const, text }] };
|
|
345
346
|
} catch (err: any) {
|
|
346
|
-
return { content: [{ type: 'text' as const, text:
|
|
347
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
347
348
|
}
|
|
348
349
|
}
|
|
349
350
|
);
|
|
@@ -357,7 +358,7 @@ server.tool(
|
|
|
357
358
|
const text = await uploadMediaFromUrlTool.execute(client, input as any);
|
|
358
359
|
return { content: [{ type: 'text' as const, text }] };
|
|
359
360
|
} catch (err: any) {
|
|
360
|
-
return { content: [{ type: 'text' as const, text:
|
|
361
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
361
362
|
}
|
|
362
363
|
}
|
|
363
364
|
);
|
|
@@ -371,7 +372,7 @@ server.tool(
|
|
|
371
372
|
const text = await createSignedUploadTool.execute(client, input as any);
|
|
372
373
|
return { content: [{ type: 'text' as const, text }] };
|
|
373
374
|
} catch (err: any) {
|
|
374
|
-
return { content: [{ type: 'text' as const, text:
|
|
375
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
375
376
|
}
|
|
376
377
|
}
|
|
377
378
|
);
|
|
@@ -385,7 +386,7 @@ server.tool(
|
|
|
385
386
|
const text = await getVideoOptionsTool.execute(client);
|
|
386
387
|
return { content: [{ type: 'text' as const, text }] };
|
|
387
388
|
} catch (err: any) {
|
|
388
|
-
return { content: [{ type: 'text' as const, text:
|
|
389
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
389
390
|
}
|
|
390
391
|
}
|
|
391
392
|
);
|
|
@@ -399,7 +400,7 @@ server.tool(
|
|
|
399
400
|
const text = await runVideoFunctionTool.execute(client, input as any);
|
|
400
401
|
return { content: [{ type: 'text' as const, text }] };
|
|
401
402
|
} catch (err: any) {
|
|
402
|
-
return { content: [{ type: 'text' as const, text:
|
|
403
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
403
404
|
}
|
|
404
405
|
}
|
|
405
406
|
);
|
|
@@ -413,7 +414,7 @@ server.tool(
|
|
|
413
414
|
const text = await generateVideoTool.execute(client, input as any);
|
|
414
415
|
return { content: [{ type: 'text' as const, text }] };
|
|
415
416
|
} catch (err: any) {
|
|
416
|
-
return { content: [{ type: 'text' as const, text:
|
|
417
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
417
418
|
}
|
|
418
419
|
}
|
|
419
420
|
);
|
|
@@ -427,7 +428,7 @@ server.tool(
|
|
|
427
428
|
const text = await getVideoJobTool.execute(client, input as any);
|
|
428
429
|
return { content: [{ type: 'text' as const, text }] };
|
|
429
430
|
} catch (err: any) {
|
|
430
|
-
return { content: [{ type: 'text' as const, text:
|
|
431
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
431
432
|
}
|
|
432
433
|
}
|
|
433
434
|
);
|
|
@@ -441,7 +442,7 @@ server.tool(
|
|
|
441
442
|
const text = await generateImageTool.execute(client, input as any);
|
|
442
443
|
return { content: [{ type: 'text' as const, text }] };
|
|
443
444
|
} catch (err: any) {
|
|
444
|
-
return { content: [{ type: 'text' as const, text:
|
|
445
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
445
446
|
}
|
|
446
447
|
}
|
|
447
448
|
);
|
|
@@ -455,7 +456,7 @@ server.tool(
|
|
|
455
456
|
const text = await getPostTool.execute(client, input as any);
|
|
456
457
|
return { content: [{ type: 'text' as const, text }] };
|
|
457
458
|
} catch (err: any) {
|
|
458
|
-
return { content: [{ type: 'text' as const, text:
|
|
459
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
459
460
|
}
|
|
460
461
|
}
|
|
461
462
|
);
|
|
@@ -469,7 +470,7 @@ server.tool(
|
|
|
469
470
|
const text = await getPostMissingTool.execute(client, input as any);
|
|
470
471
|
return { content: [{ type: 'text' as const, text }] };
|
|
471
472
|
} catch (err: any) {
|
|
472
|
-
return { content: [{ type: 'text' as const, text:
|
|
473
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
476
|
);
|
|
@@ -483,7 +484,7 @@ server.tool(
|
|
|
483
484
|
const text = await updatePostTool.execute(client, input as any);
|
|
484
485
|
return { content: [{ type: 'text' as const, text }] };
|
|
485
486
|
} catch (err: any) {
|
|
486
|
-
return { content: [{ type: 'text' as const, text:
|
|
487
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
487
488
|
}
|
|
488
489
|
}
|
|
489
490
|
);
|
|
@@ -497,7 +498,7 @@ server.tool(
|
|
|
497
498
|
const text = await updatePostStatusTool.execute(client, input as any);
|
|
498
499
|
return { content: [{ type: 'text' as const, text }] };
|
|
499
500
|
} catch (err: any) {
|
|
500
|
-
return { content: [{ type: 'text' as const, text:
|
|
501
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
501
502
|
}
|
|
502
503
|
}
|
|
503
504
|
);
|
|
@@ -511,7 +512,7 @@ server.tool(
|
|
|
511
512
|
const text = await updatePostReleaseIdTool.execute(client, input as any);
|
|
512
513
|
return { content: [{ type: 'text' as const, text }] };
|
|
513
514
|
} catch (err: any) {
|
|
514
|
-
return { content: [{ type: 'text' as const, text:
|
|
515
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
515
516
|
}
|
|
516
517
|
}
|
|
517
518
|
);
|
|
@@ -525,7 +526,7 @@ server.tool(
|
|
|
525
526
|
const text = await deletePostTool.execute(client, input as any);
|
|
526
527
|
return { content: [{ type: 'text' as const, text }] };
|
|
527
528
|
} catch (err: any) {
|
|
528
|
-
return { content: [{ type: 'text' as const, text:
|
|
529
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
529
530
|
}
|
|
530
531
|
}
|
|
531
532
|
);
|
|
@@ -539,7 +540,7 @@ server.tool(
|
|
|
539
540
|
const text = await deletePostGroupTool.execute(client, input as any);
|
|
540
541
|
return { content: [{ type: 'text' as const, text }] };
|
|
541
542
|
} catch (err: any) {
|
|
542
|
-
return { content: [{ type: 'text' as const, text:
|
|
543
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
543
544
|
}
|
|
544
545
|
}
|
|
545
546
|
);
|
|
@@ -553,7 +554,7 @@ server.tool(
|
|
|
553
554
|
const text = await getAccountAnalyticsTool.execute(client, input as any);
|
|
554
555
|
return { content: [{ type: 'text' as const, text }] };
|
|
555
556
|
} catch (err: any) {
|
|
556
|
-
return { content: [{ type: 'text' as const, text:
|
|
557
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
557
558
|
}
|
|
558
559
|
}
|
|
559
560
|
);
|
|
@@ -567,7 +568,7 @@ server.tool(
|
|
|
567
568
|
const text = await getPostAnalyticsTool.execute(client, input as any);
|
|
568
569
|
return { content: [{ type: 'text' as const, text }] };
|
|
569
570
|
} catch (err: any) {
|
|
570
|
-
return { content: [{ type: 'text' as const, text:
|
|
571
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
571
572
|
}
|
|
572
573
|
}
|
|
573
574
|
);
|
|
@@ -581,7 +582,7 @@ server.tool(
|
|
|
581
582
|
const text = await listGoogleBusinessReviewsTool.execute(client, input as any);
|
|
582
583
|
return { content: [{ type: 'text' as const, text }] };
|
|
583
584
|
} catch (err: any) {
|
|
584
|
-
return { content: [{ type: 'text' as const, text:
|
|
585
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
585
586
|
}
|
|
586
587
|
}
|
|
587
588
|
);
|
|
@@ -595,7 +596,7 @@ server.tool(
|
|
|
595
596
|
const text = await getGoogleBusinessReviewLinkTool.execute(client, input as any);
|
|
596
597
|
return { content: [{ type: 'text' as const, text }] };
|
|
597
598
|
} catch (err: any) {
|
|
598
|
-
return { content: [{ type: 'text' as const, text:
|
|
599
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
599
600
|
}
|
|
600
601
|
}
|
|
601
602
|
);
|
|
@@ -609,7 +610,7 @@ server.tool(
|
|
|
609
610
|
const text = await auditGoogleBusinessProfileTool.execute(client, input as any);
|
|
610
611
|
return { content: [{ type: 'text' as const, text }] };
|
|
611
612
|
} catch (err: any) {
|
|
612
|
-
return { content: [{ type: 'text' as const, text:
|
|
613
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
613
614
|
}
|
|
614
615
|
}
|
|
615
616
|
);
|
|
@@ -623,7 +624,7 @@ server.tool(
|
|
|
623
624
|
const text = await suggestGoogleBusinessReviewReplyTool.execute(client, input as any);
|
|
624
625
|
return { content: [{ type: 'text' as const, text }] };
|
|
625
626
|
} catch (err: any) {
|
|
626
|
-
return { content: [{ type: 'text' as const, text:
|
|
627
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
627
628
|
}
|
|
628
629
|
}
|
|
629
630
|
);
|
|
@@ -637,7 +638,7 @@ server.tool(
|
|
|
637
638
|
const text = await replyGoogleBusinessReviewTool.execute(client, input as any);
|
|
638
639
|
return { content: [{ type: 'text' as const, text }] };
|
|
639
640
|
} catch (err: any) {
|
|
640
|
-
return { content: [{ type: 'text' as const, text:
|
|
641
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
641
642
|
}
|
|
642
643
|
}
|
|
643
644
|
);
|
|
@@ -651,7 +652,7 @@ server.tool(
|
|
|
651
652
|
const text = await deleteGoogleBusinessReviewReplyTool.execute(client, input as any);
|
|
652
653
|
return { content: [{ type: 'text' as const, text }] };
|
|
653
654
|
} catch (err: any) {
|
|
654
|
-
return { content: [{ type: 'text' as const, text:
|
|
655
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
655
656
|
}
|
|
656
657
|
}
|
|
657
658
|
);
|
|
@@ -665,7 +666,7 @@ server.tool(
|
|
|
665
666
|
const text = await listActivityTool.execute(client, input as any);
|
|
666
667
|
return { content: [{ type: 'text' as const, text }] };
|
|
667
668
|
} catch (err: any) {
|
|
668
|
-
return { content: [{ type: 'text' as const, text:
|
|
669
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
669
670
|
}
|
|
670
671
|
}
|
|
671
672
|
);
|
|
@@ -679,7 +680,7 @@ server.tool(
|
|
|
679
680
|
const text = await listWebhooksTool.execute(client, input as any);
|
|
680
681
|
return { content: [{ type: 'text' as const, text }] };
|
|
681
682
|
} catch (err: any) {
|
|
682
|
-
return { content: [{ type: 'text' as const, text:
|
|
683
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
683
684
|
}
|
|
684
685
|
}
|
|
685
686
|
);
|
|
@@ -693,7 +694,7 @@ server.tool(
|
|
|
693
694
|
const text = await createWebhookTool.execute(client, input as any);
|
|
694
695
|
return { content: [{ type: 'text' as const, text }] };
|
|
695
696
|
} catch (err: any) {
|
|
696
|
-
return { content: [{ type: 'text' as const, text:
|
|
697
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
697
698
|
}
|
|
698
699
|
}
|
|
699
700
|
);
|
|
@@ -707,7 +708,7 @@ server.tool(
|
|
|
707
708
|
const text = await updateWebhookTool.execute(client, input as any);
|
|
708
709
|
return { content: [{ type: 'text' as const, text }] };
|
|
709
710
|
} catch (err: any) {
|
|
710
|
-
return { content: [{ type: 'text' as const, text:
|
|
711
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
711
712
|
}
|
|
712
713
|
}
|
|
713
714
|
);
|
|
@@ -721,7 +722,7 @@ server.tool(
|
|
|
721
722
|
const text = await deleteWebhookTool.execute(client, input as any);
|
|
722
723
|
return { content: [{ type: 'text' as const, text }] };
|
|
723
724
|
} catch (err: any) {
|
|
724
|
-
return { content: [{ type: 'text' as const, text:
|
|
725
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
725
726
|
}
|
|
726
727
|
}
|
|
727
728
|
);
|
|
@@ -735,7 +736,7 @@ server.tool(
|
|
|
735
736
|
const text = await testWebhookTool.execute(client, input as any);
|
|
736
737
|
return { content: [{ type: 'text' as const, text }] };
|
|
737
738
|
} catch (err: any) {
|
|
738
|
-
return { content: [{ type: 'text' as const, text:
|
|
739
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
739
740
|
}
|
|
740
741
|
}
|
|
741
742
|
);
|
|
@@ -749,7 +750,7 @@ server.tool(
|
|
|
749
750
|
const text = await getXPostingQuotaTool.execute(client, input as any);
|
|
750
751
|
return { content: [{ type: 'text' as const, text }] };
|
|
751
752
|
} catch (err: any) {
|
|
752
|
-
return { content: [{ type: 'text' as const, text:
|
|
753
|
+
return { content: [{ type: 'text' as const, text: mdError(err.message) }], isError: true };
|
|
753
754
|
}
|
|
754
755
|
}
|
|
755
756
|
);
|
package/src/lib/api-client.ts
CHANGED
|
@@ -895,7 +895,7 @@ export class PosterlyClient {
|
|
|
895
895
|
const SIZE_THRESHOLD = 3 * 1024 * 1024; // 3MB
|
|
896
896
|
|
|
897
897
|
if (fileBuffer.length > SIZE_THRESHOLD) {
|
|
898
|
-
// Large file: use signed URL
|
|
898
|
+
// Large file: use signed URL so the API can validate actual bytes before storage.
|
|
899
899
|
const signed = await this.getSignedUploadUrl(
|
|
900
900
|
input.filename,
|
|
901
901
|
contentType,
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
type CellValue = string | number | boolean | null | undefined;
|
|
2
|
+
|
|
3
|
+
export function mdTitle(title: string, subtitle?: string): string {
|
|
4
|
+
return [`## ${title}`, subtitle ? `_${subtitle}_` : ''].filter(Boolean).join('\n');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function mdTable(headers: string[], rows: CellValue[][]): string {
|
|
8
|
+
const visibleRows = rows.filter((row) => row.some((cell) => cell !== undefined && cell !== null && cell !== ''));
|
|
9
|
+
if (visibleRows.length === 0) return '';
|
|
10
|
+
|
|
11
|
+
const header = `| ${headers.map(escapeCell).join(' | ')} |`;
|
|
12
|
+
const divider = `| ${headers.map(() => '---').join(' | ')} |`;
|
|
13
|
+
const body = visibleRows.map((row) => `| ${row.map((cell) => escapeCell(formatCell(cell))).join(' | ')} |`);
|
|
14
|
+
|
|
15
|
+
return [header, divider, ...body].join('\n');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function mdKeyValue(rows: Array<[string, CellValue]>): string {
|
|
19
|
+
return mdTable(['Field', 'Value'], rows);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function mdSection(title: string, body?: string): string {
|
|
23
|
+
if (!body) return '';
|
|
24
|
+
return [`### ${title}`, body].join('\n');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function mdBullets(items: Array<string | null | undefined>): string {
|
|
28
|
+
return items.filter(Boolean).map((item) => `- ${item}`).join('\n');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function mdJson(title: string, value: unknown): string {
|
|
32
|
+
return [`### ${title}`, '```json', JSON.stringify(value, null, 2), '```'].join('\n');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function mdQuote(text: string): string {
|
|
36
|
+
return text.split('\n').map((line) => `> ${line}`).join('\n');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function mdEmpty(title: string, detail: string, nextStep?: string): string {
|
|
40
|
+
return [
|
|
41
|
+
mdTitle(`No ${title}`),
|
|
42
|
+
detail,
|
|
43
|
+
nextStep ? `\n**Next step:** ${nextStep}` : '',
|
|
44
|
+
].filter(Boolean).join('\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function mdSuccess(title: string, rows: Array<[string, CellValue]>, nextStep?: string): string {
|
|
48
|
+
return [
|
|
49
|
+
mdTitle(`✅ ${title}`),
|
|
50
|
+
mdKeyValue(rows),
|
|
51
|
+
nextStep ? `\n**Next step:** ${nextStep}` : '',
|
|
52
|
+
].filter(Boolean).join('\n');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function mdError(message: string): string {
|
|
56
|
+
return [
|
|
57
|
+
mdTitle('⚠️ Posterly tool error'),
|
|
58
|
+
`**Message:** ${message}`,
|
|
59
|
+
].join('\n');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function formatNumber(value: number | null | undefined): string {
|
|
63
|
+
return value == null ? 'n/a' : value.toLocaleString();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function formatPercent(value: number | null | undefined): string {
|
|
67
|
+
return value == null ? 'n/a' : `${value.toLocaleString()}%`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function formatDelta(value: number | null | undefined): string {
|
|
71
|
+
if (value == null) return 'n/a';
|
|
72
|
+
return value >= 0 ? `+${value.toLocaleString()}` : value.toLocaleString();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function formatDateTime(value: string | null | undefined): string {
|
|
76
|
+
if (!value) return 'n/a';
|
|
77
|
+
const date = new Date(value);
|
|
78
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
79
|
+
return date.toLocaleString();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function formatDate(value: string | null | undefined): string {
|
|
83
|
+
if (!value) return 'n/a';
|
|
84
|
+
const date = new Date(value);
|
|
85
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
86
|
+
return date.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function formatBytes(value: number | null | undefined): string {
|
|
90
|
+
if (value == null) return 'n/a';
|
|
91
|
+
if (value < 1024) return `${value} B`;
|
|
92
|
+
const units = ['KB', 'MB', 'GB', 'TB'];
|
|
93
|
+
let size = value / 1024;
|
|
94
|
+
let unitIndex = 0;
|
|
95
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
96
|
+
size /= 1024;
|
|
97
|
+
unitIndex += 1;
|
|
98
|
+
}
|
|
99
|
+
return `${size.toFixed(size >= 10 ? 0 : 1)} ${units[unitIndex]}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function compactText(value: string | null | undefined, maxLength = 90): string {
|
|
103
|
+
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
104
|
+
if (!text) return '';
|
|
105
|
+
return text.length > maxLength ? `${text.slice(0, Math.max(0, maxLength - 1))}…` : text;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function statusLabel(status: string | null | undefined): string {
|
|
109
|
+
const value = String(status || 'unknown').toLowerCase();
|
|
110
|
+
if (['created', 'success', 'succeeded', 'completed', 'published', 'active'].includes(value)) return `✅ ${status}`;
|
|
111
|
+
if (['scheduled', 'queued', 'pending', 'processing'].includes(value)) return `🕒 ${status}`;
|
|
112
|
+
if (['failed', 'error', 'inactive', 'deleted'].includes(value)) return `⚠️ ${status}`;
|
|
113
|
+
if (['draft', 'paused'].includes(value)) return `⏸️ ${status}`;
|
|
114
|
+
return status || 'unknown';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function code(value: CellValue): string {
|
|
118
|
+
return `\`${formatCell(value).replace(/`/g, '\\`')}\``;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function formatCell(value: CellValue): string {
|
|
122
|
+
if (value === null || value === undefined || value === '') return 'n/a';
|
|
123
|
+
if (typeof value === 'boolean') return value ? 'yes' : 'no';
|
|
124
|
+
if (typeof value === 'number') return value.toLocaleString();
|
|
125
|
+
return String(value);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function escapeCell(value: CellValue): string {
|
|
129
|
+
return formatCell(value)
|
|
130
|
+
.replace(/\|/g, '\\|')
|
|
131
|
+
.replace(/\r?\n/g, '<br>');
|
|
132
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { formatDateTime, mdKeyValue, mdSection, mdTable, mdTitle } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
export const auditGoogleBusinessProfileTool = {
|
|
5
6
|
name: 'audit_google_business_profile',
|
|
@@ -22,17 +23,22 @@ export const auditGoogleBusinessProfileTool = {
|
|
|
22
23
|
const result = await client.auditGoogleBusinessProfile(input);
|
|
23
24
|
const audit = result.audit || {};
|
|
24
25
|
const recommendations = Array.isArray(audit.recommendations) ? audit.recommendations : [];
|
|
25
|
-
|
|
26
|
-
`Google Business audit: ${audit.businessName || 'Unknown business'}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
return [
|
|
27
|
+
mdTitle(`Google Business audit: ${audit.businessName || 'Unknown business'}`),
|
|
28
|
+
mdKeyValue([
|
|
29
|
+
['Score', audit.overallScore ?? 'n/a'],
|
|
30
|
+
['Grade', audit.overallGrade || 'n/a'],
|
|
31
|
+
['Fetched', formatDateTime(result.fetchedAt)],
|
|
32
|
+
]),
|
|
33
|
+
recommendations.length > 0
|
|
34
|
+
? mdSection('Top recommendations', mdTable(
|
|
35
|
+
['Priority', 'Recommendation'],
|
|
36
|
+
recommendations.slice(0, 5).map((rec: any) => [
|
|
37
|
+
rec.priority || 'medium',
|
|
38
|
+
rec.description || rec.title || 'Recommendation',
|
|
39
|
+
]),
|
|
40
|
+
))
|
|
41
|
+
: '',
|
|
42
|
+
].filter(Boolean).join('\n\n');
|
|
37
43
|
},
|
|
38
44
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { PosterlyClient } from '../lib/api-client.js';
|
|
3
|
+
import { code, mdSuccess } from '../lib/format.js';
|
|
3
4
|
|
|
4
5
|
const scopeSchema = z.enum(['accounts:read', 'accounts:write', 'posts:read', 'posts:write', 'media:write', 'analytics:read']);
|
|
5
6
|
|
|
@@ -28,9 +29,14 @@ export const createOAuthClientTool = {
|
|
|
28
29
|
is_active?: boolean;
|
|
29
30
|
confirm: true;
|
|
30
31
|
},
|
|
31
|
-
|
|
32
|
+
) {
|
|
32
33
|
const { confirm: _confirm, ...payload } = input;
|
|
33
34
|
const result = await client.createOAuthClient(payload);
|
|
34
|
-
return
|
|
35
|
+
return mdSuccess('OAuth client created', [
|
|
36
|
+
['Client', result.client.client_name],
|
|
37
|
+
['Client ID', code(result.client.client_id)],
|
|
38
|
+
['Redirect URIs', result.client.allowed_redirect_uris.join(', ')],
|
|
39
|
+
['Default scopes', result.client.default_scopes.join(', ')],
|
|
40
|
+
]);
|
|
35
41
|
},
|
|
36
42
|
};
|