posterly-mcp-server 0.19.9 → 0.19.10

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 CHANGED
@@ -19,7 +19,7 @@ Posterly also exposes the same authenticated toolset over HTTP at [poster.ly/mcp
19
19
  ## Requirements
20
20
 
21
21
  - Node.js `20+`
22
- - No API key is required for the public signup tools: `get_agent_signup_info`, `start_signup`, and `get_signup_session`
22
+ - No API key is required for the public setup tools: `get_mcp_status`, `get_agent_signup_info`, `start_signup`, and `get_signup_session`
23
23
  - A Posterly account, API add-on, and API key are required for authenticated tools like `whoami`, `list_accounts`, `create_connect_session`, and `create_post`
24
24
 
25
25
  ## Install
@@ -62,7 +62,7 @@ After paid signup is complete and Posterly shows an API key, add `POSTERLY_API_K
62
62
  3. Pay in Stripe Checkout and set your Posterly password in the browser.
63
63
  4. When Posterly shows your API key, add it as `POSTERLY_API_KEY`.
64
64
  5. Restart your AI client.
65
- 6. Ask the AI to call `whoami`, then continue by connecting your first social account.
65
+ 6. Ask the AI to call `get_mcp_status`, then `whoami`, then continue by connecting your first social account.
66
66
 
67
67
  The signup and connect tools return user-facing next steps by default, so agents should report progress in plain language instead of showing raw curl, HTTP payloads, or JSON. Pass `debug: true` to `start_signup`, `get_signup_session`, `get_connect_link`, `create_connect_session`, or `get_connect_session` only when troubleshooting.
68
68
 
@@ -108,10 +108,11 @@ Add the same server definition to your Cursor MCP settings:
108
108
 
109
109
  ## Available tools
110
110
 
111
- `posterly-mcp-server@0.19.9` exposes 55 tools.
111
+ `posterly-mcp-server@0.19.10` exposes 56 tools.
112
112
 
113
- Public signup tools work before `POSTERLY_API_KEY` exists:
113
+ Public setup tools work before `POSTERLY_API_KEY` exists:
114
114
 
115
+ - `get_mcp_status` (show the installed server version, latest npm version, API origin, API key presence, and update guidance)
115
116
  - `get_agent_signup_info`
116
117
  - `start_signup` (start paid signup and return a Posterly checkout handoff URL)
117
118
  - `get_signup_session` (poll checkout, payment, password, and agent-access status)
package/dist/index.js CHANGED
@@ -2,9 +2,11 @@
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
  import { PosterlyClient } from './lib/api-client.js';
5
+ import { POSTERLY_MCP_VERSION } from './lib/version.js';
5
6
  import { getAgentSignupInfoTool } from './tools/get-agent-signup-info.js';
6
7
  import { getSignupSessionTool } from './tools/get-signup-session.js';
7
8
  import { startSignupTool } from './tools/start-signup.js';
9
+ import { getMcpStatusTool } from './tools/get-mcp-status.js';
8
10
  import { listAccountsTool } from './tools/list-accounts.js';
9
11
  import { disconnectAccountTool } from './tools/disconnect-account.js';
10
12
  import { listBrandsTool } from './tools/list-brands.js';
@@ -59,7 +61,7 @@ import { updateOAuthClientTool } from './tools/update-oauth-client.js';
59
61
  import { deleteOAuthClientTool } from './tools/delete-oauth-client.js';
60
62
  const server = new McpServer({
61
63
  name: 'posterly',
62
- version: '0.19.8',
64
+ version: POSTERLY_MCP_VERSION,
63
65
  });
64
66
  const client = new PosterlyClient();
65
67
  // Register tools
@@ -90,6 +92,15 @@ server.tool(getSignupSessionTool.name, getSignupSessionTool.description, getSign
90
92
  return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
91
93
  }
92
94
  });
95
+ server.tool(getMcpStatusTool.name, getMcpStatusTool.description, getMcpStatusTool.inputSchema.shape, async () => {
96
+ try {
97
+ const text = await getMcpStatusTool.execute(client);
98
+ return { content: [{ type: 'text', text }] };
99
+ }
100
+ catch (err) {
101
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true };
102
+ }
103
+ });
93
104
  server.tool(whoamiTool.name, whoamiTool.description, whoamiTool.inputSchema.shape, async () => {
94
105
  try {
95
106
  const text = await whoamiTool.execute(client);
@@ -815,3 +815,4 @@ export declare class PosterlyClient {
815
815
  size: number;
816
816
  }>;
817
817
  }
818
+ export declare function resolvePosterlyBaseUrl(baseUrl?: string): string;
@@ -5,7 +5,7 @@ export class PosterlyClient {
5
5
  apiKey;
6
6
  constructor(apiKey, baseUrl) {
7
7
  this.apiKey = apiKey || process.env.POSTERLY_API_KEY || '';
8
- this.baseUrl = (baseUrl || process.env.POSTERLY_URL || 'https://www.poster.ly').replace(/\/$/, '');
8
+ this.baseUrl = resolvePosterlyBaseUrl(baseUrl);
9
9
  }
10
10
  hasApiKey() {
11
11
  return Boolean(this.apiKey);
@@ -387,6 +387,22 @@ export class PosterlyClient {
387
387
  });
388
388
  }
389
389
  }
390
+ export function resolvePosterlyBaseUrl(baseUrl) {
391
+ const configured = (baseUrl ||
392
+ process.env.POSTERLY_URL ||
393
+ process.env.POSTERLY_API_BASE_URL ||
394
+ 'https://www.poster.ly').trim();
395
+ try {
396
+ const url = new URL(configured);
397
+ url.pathname = url.pathname.replace(/\/api\/v1\/?$/, '').replace(/\/+$/, '') || '/';
398
+ url.search = '';
399
+ url.hash = '';
400
+ return url.toString().replace(/\/$/, '');
401
+ }
402
+ catch {
403
+ return configured.replace(/\/api\/v1\/?$/, '').replace(/\/$/, '');
404
+ }
405
+ }
390
406
  function guessContentType(filename) {
391
407
  const ext = filename.split('.').pop()?.toLowerCase();
392
408
  const map = {
@@ -0,0 +1 @@
1
+ export declare const POSTERLY_MCP_VERSION = "0.19.10";
@@ -0,0 +1 @@
1
+ export const POSTERLY_MCP_VERSION = '0.19.10';
@@ -222,6 +222,402 @@ export declare const platformSettingsSchema: z.ZodObject<{
222
222
  cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
223
223
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
224
224
  }, z.ZodTypeAny, "passthrough">>;
225
+ export declare const createPostPayloadInputSchema: z.ZodObject<{
226
+ account_id: z.ZodOptional<z.ZodString>;
227
+ username: z.ZodOptional<z.ZodString>;
228
+ platform: z.ZodOptional<z.ZodEnum<["bluesky", "facebook", "gmb", "google-business", "google_business", "google_business_profile", "instagram", "instagram-standalone", "linkedin", "pinterest", "telegram", "threads", "tiktok", "twitter", "x", "youtube"]>>;
229
+ caption: z.ZodOptional<z.ZodString>;
230
+ scheduled_at: z.ZodOptional<z.ZodString>;
231
+ media_url: z.ZodOptional<z.ZodString>;
232
+ media_urls: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
233
+ post_type: z.ZodOptional<z.ZodString>;
234
+ thread_posts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
235
+ instagram_settings: z.ZodOptional<z.ZodObject<{
236
+ __type: z.ZodOptional<z.ZodEnum<["instagram", "instagram-standalone"]>>;
237
+ post_type: z.ZodOptional<z.ZodEnum<["post", "feed", "story", "reel", "carousel"]>>;
238
+ is_trial_reel: z.ZodOptional<z.ZodBoolean>;
239
+ graduation_strategy: z.ZodOptional<z.ZodEnum<["MANUAL", "SS_PERFORMANCE"]>>;
240
+ collaborators: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
241
+ label: z.ZodOptional<z.ZodString>;
242
+ username: z.ZodOptional<z.ZodString>;
243
+ handle: z.ZodOptional<z.ZodString>;
244
+ }, "strip", z.ZodTypeAny, {
245
+ label?: string | undefined;
246
+ username?: string | undefined;
247
+ handle?: string | undefined;
248
+ }, {
249
+ label?: string | undefined;
250
+ username?: string | undefined;
251
+ handle?: string | undefined;
252
+ }>]>, "many">>;
253
+ user_tags: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
254
+ username: z.ZodOptional<z.ZodString>;
255
+ label: z.ZodOptional<z.ZodString>;
256
+ handle: z.ZodOptional<z.ZodString>;
257
+ }, "strip", z.ZodTypeAny, {
258
+ label?: string | undefined;
259
+ username?: string | undefined;
260
+ handle?: string | undefined;
261
+ }, {
262
+ label?: string | undefined;
263
+ username?: string | undefined;
264
+ handle?: string | undefined;
265
+ }>]>, "many">>;
266
+ first_comment: z.ZodOptional<z.ZodString>;
267
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
268
+ reel_cover_url: z.ZodOptional<z.ZodString>;
269
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
270
+ }, "strip", z.ZodTypeAny, {
271
+ post_type?: "post" | "feed" | "story" | "reel" | "carousel" | undefined;
272
+ reel_cover_url?: string | undefined;
273
+ reel_thumb_offset?: number | undefined;
274
+ __type?: "instagram" | "instagram-standalone" | undefined;
275
+ is_trial_reel?: boolean | undefined;
276
+ graduation_strategy?: "MANUAL" | "SS_PERFORMANCE" | undefined;
277
+ collaborators?: (string | {
278
+ label?: string | undefined;
279
+ username?: string | undefined;
280
+ handle?: string | undefined;
281
+ })[] | undefined;
282
+ user_tags?: (string | {
283
+ label?: string | undefined;
284
+ username?: string | undefined;
285
+ handle?: string | undefined;
286
+ })[] | undefined;
287
+ first_comment?: string | undefined;
288
+ media_alt_texts?: Record<string, string> | undefined;
289
+ }, {
290
+ post_type?: "post" | "feed" | "story" | "reel" | "carousel" | undefined;
291
+ reel_cover_url?: string | undefined;
292
+ reel_thumb_offset?: number | undefined;
293
+ __type?: "instagram" | "instagram-standalone" | undefined;
294
+ is_trial_reel?: boolean | undefined;
295
+ graduation_strategy?: "MANUAL" | "SS_PERFORMANCE" | undefined;
296
+ collaborators?: (string | {
297
+ label?: string | undefined;
298
+ username?: string | undefined;
299
+ handle?: string | undefined;
300
+ })[] | undefined;
301
+ user_tags?: (string | {
302
+ label?: string | undefined;
303
+ username?: string | undefined;
304
+ handle?: string | undefined;
305
+ })[] | undefined;
306
+ first_comment?: string | undefined;
307
+ media_alt_texts?: Record<string, string> | undefined;
308
+ }>>;
309
+ platform_settings: z.ZodOptional<z.ZodObject<{
310
+ __type: z.ZodOptional<z.ZodString>;
311
+ post_type: z.ZodOptional<z.ZodString>;
312
+ content_type: z.ZodOptional<z.ZodString>;
313
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
314
+ reel_cover_url: z.ZodOptional<z.ZodString>;
315
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
316
+ reply_settings: z.ZodOptional<z.ZodEnum<["everyone", "following", "mentionedUsers"]>>;
317
+ poll: z.ZodOptional<z.ZodObject<{
318
+ options: z.ZodArray<z.ZodString, "many">;
319
+ duration_minutes: z.ZodOptional<z.ZodNumber>;
320
+ }, "strip", z.ZodTypeAny, {
321
+ options: string[];
322
+ duration_minutes?: number | undefined;
323
+ }, {
324
+ options: string[];
325
+ duration_minutes?: number | undefined;
326
+ }>>;
327
+ reply_control: z.ZodOptional<z.ZodEnum<["everyone", "accounts_you_follow", "mentioned_only"]>>;
328
+ text_attachment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
329
+ text_format_preset_id: z.ZodOptional<z.ZodString>;
330
+ document_title: z.ZodOptional<z.ZodString>;
331
+ document_filename: z.ZodOptional<z.ZodString>;
332
+ mentions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
333
+ thumbnail_url: z.ZodOptional<z.ZodString>;
334
+ thumbnail_method: z.ZodOptional<z.ZodString>;
335
+ privacy_level: z.ZodOptional<z.ZodString>;
336
+ allow_comment: z.ZodOptional<z.ZodBoolean>;
337
+ allow_duet: z.ZodOptional<z.ZodBoolean>;
338
+ allow_stitch: z.ZodOptional<z.ZodBoolean>;
339
+ title: z.ZodOptional<z.ZodString>;
340
+ media_type: z.ZodOptional<z.ZodString>;
341
+ is_commercial_content: z.ZodOptional<z.ZodBoolean>;
342
+ is_your_brand: z.ZodOptional<z.ZodBoolean>;
343
+ is_branded_content: z.ZodOptional<z.ZodBoolean>;
344
+ privacy_status: z.ZodOptional<z.ZodEnum<["public", "unlisted", "private"]>>;
345
+ made_for_kids: z.ZodOptional<z.ZodBoolean>;
346
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
347
+ category_id: z.ZodOptional<z.ZodString>;
348
+ playlist_id: z.ZodOptional<z.ZodString>;
349
+ board_id: z.ZodOptional<z.ZodString>;
350
+ link: z.ZodOptional<z.ZodString>;
351
+ cover_image_url: z.ZodOptional<z.ZodString>;
352
+ video_cover_url: z.ZodOptional<z.ZodString>;
353
+ cover_image_method: z.ZodOptional<z.ZodEnum<["upload", "frame", "api"]>>;
354
+ event: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
355
+ offer: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
356
+ cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
357
+ langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
358
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
359
+ __type: z.ZodOptional<z.ZodString>;
360
+ post_type: z.ZodOptional<z.ZodString>;
361
+ content_type: z.ZodOptional<z.ZodString>;
362
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
363
+ reel_cover_url: z.ZodOptional<z.ZodString>;
364
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
365
+ reply_settings: z.ZodOptional<z.ZodEnum<["everyone", "following", "mentionedUsers"]>>;
366
+ poll: z.ZodOptional<z.ZodObject<{
367
+ options: z.ZodArray<z.ZodString, "many">;
368
+ duration_minutes: z.ZodOptional<z.ZodNumber>;
369
+ }, "strip", z.ZodTypeAny, {
370
+ options: string[];
371
+ duration_minutes?: number | undefined;
372
+ }, {
373
+ options: string[];
374
+ duration_minutes?: number | undefined;
375
+ }>>;
376
+ reply_control: z.ZodOptional<z.ZodEnum<["everyone", "accounts_you_follow", "mentioned_only"]>>;
377
+ text_attachment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
378
+ text_format_preset_id: z.ZodOptional<z.ZodString>;
379
+ document_title: z.ZodOptional<z.ZodString>;
380
+ document_filename: z.ZodOptional<z.ZodString>;
381
+ mentions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
382
+ thumbnail_url: z.ZodOptional<z.ZodString>;
383
+ thumbnail_method: z.ZodOptional<z.ZodString>;
384
+ privacy_level: z.ZodOptional<z.ZodString>;
385
+ allow_comment: z.ZodOptional<z.ZodBoolean>;
386
+ allow_duet: z.ZodOptional<z.ZodBoolean>;
387
+ allow_stitch: z.ZodOptional<z.ZodBoolean>;
388
+ title: z.ZodOptional<z.ZodString>;
389
+ media_type: z.ZodOptional<z.ZodString>;
390
+ is_commercial_content: z.ZodOptional<z.ZodBoolean>;
391
+ is_your_brand: z.ZodOptional<z.ZodBoolean>;
392
+ is_branded_content: z.ZodOptional<z.ZodBoolean>;
393
+ privacy_status: z.ZodOptional<z.ZodEnum<["public", "unlisted", "private"]>>;
394
+ made_for_kids: z.ZodOptional<z.ZodBoolean>;
395
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
396
+ category_id: z.ZodOptional<z.ZodString>;
397
+ playlist_id: z.ZodOptional<z.ZodString>;
398
+ board_id: z.ZodOptional<z.ZodString>;
399
+ link: z.ZodOptional<z.ZodString>;
400
+ cover_image_url: z.ZodOptional<z.ZodString>;
401
+ video_cover_url: z.ZodOptional<z.ZodString>;
402
+ cover_image_method: z.ZodOptional<z.ZodEnum<["upload", "frame", "api"]>>;
403
+ event: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
404
+ offer: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
405
+ cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
406
+ langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
407
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
408
+ __type: z.ZodOptional<z.ZodString>;
409
+ post_type: z.ZodOptional<z.ZodString>;
410
+ content_type: z.ZodOptional<z.ZodString>;
411
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
412
+ reel_cover_url: z.ZodOptional<z.ZodString>;
413
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
414
+ reply_settings: z.ZodOptional<z.ZodEnum<["everyone", "following", "mentionedUsers"]>>;
415
+ poll: z.ZodOptional<z.ZodObject<{
416
+ options: z.ZodArray<z.ZodString, "many">;
417
+ duration_minutes: z.ZodOptional<z.ZodNumber>;
418
+ }, "strip", z.ZodTypeAny, {
419
+ options: string[];
420
+ duration_minutes?: number | undefined;
421
+ }, {
422
+ options: string[];
423
+ duration_minutes?: number | undefined;
424
+ }>>;
425
+ reply_control: z.ZodOptional<z.ZodEnum<["everyone", "accounts_you_follow", "mentioned_only"]>>;
426
+ text_attachment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
427
+ text_format_preset_id: z.ZodOptional<z.ZodString>;
428
+ document_title: z.ZodOptional<z.ZodString>;
429
+ document_filename: z.ZodOptional<z.ZodString>;
430
+ mentions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
431
+ thumbnail_url: z.ZodOptional<z.ZodString>;
432
+ thumbnail_method: z.ZodOptional<z.ZodString>;
433
+ privacy_level: z.ZodOptional<z.ZodString>;
434
+ allow_comment: z.ZodOptional<z.ZodBoolean>;
435
+ allow_duet: z.ZodOptional<z.ZodBoolean>;
436
+ allow_stitch: z.ZodOptional<z.ZodBoolean>;
437
+ title: z.ZodOptional<z.ZodString>;
438
+ media_type: z.ZodOptional<z.ZodString>;
439
+ is_commercial_content: z.ZodOptional<z.ZodBoolean>;
440
+ is_your_brand: z.ZodOptional<z.ZodBoolean>;
441
+ is_branded_content: z.ZodOptional<z.ZodBoolean>;
442
+ privacy_status: z.ZodOptional<z.ZodEnum<["public", "unlisted", "private"]>>;
443
+ made_for_kids: z.ZodOptional<z.ZodBoolean>;
444
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
445
+ category_id: z.ZodOptional<z.ZodString>;
446
+ playlist_id: z.ZodOptional<z.ZodString>;
447
+ board_id: z.ZodOptional<z.ZodString>;
448
+ link: z.ZodOptional<z.ZodString>;
449
+ cover_image_url: z.ZodOptional<z.ZodString>;
450
+ video_cover_url: z.ZodOptional<z.ZodString>;
451
+ cover_image_method: z.ZodOptional<z.ZodEnum<["upload", "frame", "api"]>>;
452
+ event: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
453
+ offer: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
454
+ cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
455
+ langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
456
+ }, z.ZodTypeAny, "passthrough">>>;
457
+ workspace_id: z.ZodOptional<z.ZodString>;
458
+ }, "strip", z.ZodTypeAny, {
459
+ workspace_id?: string | undefined;
460
+ platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
461
+ account_id?: string | undefined;
462
+ scheduled_at?: string | undefined;
463
+ media_url?: string | undefined;
464
+ media_urls?: string[] | undefined;
465
+ post_type?: string | undefined;
466
+ username?: string | undefined;
467
+ caption?: string | undefined;
468
+ thread_posts?: string[] | undefined;
469
+ instagram_settings?: {
470
+ post_type?: "post" | "feed" | "story" | "reel" | "carousel" | undefined;
471
+ reel_cover_url?: string | undefined;
472
+ reel_thumb_offset?: number | undefined;
473
+ __type?: "instagram" | "instagram-standalone" | undefined;
474
+ is_trial_reel?: boolean | undefined;
475
+ graduation_strategy?: "MANUAL" | "SS_PERFORMANCE" | undefined;
476
+ collaborators?: (string | {
477
+ label?: string | undefined;
478
+ username?: string | undefined;
479
+ handle?: string | undefined;
480
+ })[] | undefined;
481
+ user_tags?: (string | {
482
+ label?: string | undefined;
483
+ username?: string | undefined;
484
+ handle?: string | undefined;
485
+ })[] | undefined;
486
+ first_comment?: string | undefined;
487
+ media_alt_texts?: Record<string, string> | undefined;
488
+ } | undefined;
489
+ platform_settings?: z.objectOutputType<{
490
+ __type: z.ZodOptional<z.ZodString>;
491
+ post_type: z.ZodOptional<z.ZodString>;
492
+ content_type: z.ZodOptional<z.ZodString>;
493
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
494
+ reel_cover_url: z.ZodOptional<z.ZodString>;
495
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
496
+ reply_settings: z.ZodOptional<z.ZodEnum<["everyone", "following", "mentionedUsers"]>>;
497
+ poll: z.ZodOptional<z.ZodObject<{
498
+ options: z.ZodArray<z.ZodString, "many">;
499
+ duration_minutes: z.ZodOptional<z.ZodNumber>;
500
+ }, "strip", z.ZodTypeAny, {
501
+ options: string[];
502
+ duration_minutes?: number | undefined;
503
+ }, {
504
+ options: string[];
505
+ duration_minutes?: number | undefined;
506
+ }>>;
507
+ reply_control: z.ZodOptional<z.ZodEnum<["everyone", "accounts_you_follow", "mentioned_only"]>>;
508
+ text_attachment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
509
+ text_format_preset_id: z.ZodOptional<z.ZodString>;
510
+ document_title: z.ZodOptional<z.ZodString>;
511
+ document_filename: z.ZodOptional<z.ZodString>;
512
+ mentions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
513
+ thumbnail_url: z.ZodOptional<z.ZodString>;
514
+ thumbnail_method: z.ZodOptional<z.ZodString>;
515
+ privacy_level: z.ZodOptional<z.ZodString>;
516
+ allow_comment: z.ZodOptional<z.ZodBoolean>;
517
+ allow_duet: z.ZodOptional<z.ZodBoolean>;
518
+ allow_stitch: z.ZodOptional<z.ZodBoolean>;
519
+ title: z.ZodOptional<z.ZodString>;
520
+ media_type: z.ZodOptional<z.ZodString>;
521
+ is_commercial_content: z.ZodOptional<z.ZodBoolean>;
522
+ is_your_brand: z.ZodOptional<z.ZodBoolean>;
523
+ is_branded_content: z.ZodOptional<z.ZodBoolean>;
524
+ privacy_status: z.ZodOptional<z.ZodEnum<["public", "unlisted", "private"]>>;
525
+ made_for_kids: z.ZodOptional<z.ZodBoolean>;
526
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
527
+ category_id: z.ZodOptional<z.ZodString>;
528
+ playlist_id: z.ZodOptional<z.ZodString>;
529
+ board_id: z.ZodOptional<z.ZodString>;
530
+ link: z.ZodOptional<z.ZodString>;
531
+ cover_image_url: z.ZodOptional<z.ZodString>;
532
+ video_cover_url: z.ZodOptional<z.ZodString>;
533
+ cover_image_method: z.ZodOptional<z.ZodEnum<["upload", "frame", "api"]>>;
534
+ event: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
535
+ offer: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
536
+ cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
537
+ langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
538
+ }, z.ZodTypeAny, "passthrough"> | undefined;
539
+ }, {
540
+ workspace_id?: string | undefined;
541
+ platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
542
+ account_id?: string | undefined;
543
+ scheduled_at?: string | undefined;
544
+ media_url?: string | undefined;
545
+ media_urls?: string[] | undefined;
546
+ post_type?: string | undefined;
547
+ username?: string | undefined;
548
+ caption?: string | undefined;
549
+ thread_posts?: string[] | undefined;
550
+ instagram_settings?: {
551
+ post_type?: "post" | "feed" | "story" | "reel" | "carousel" | undefined;
552
+ reel_cover_url?: string | undefined;
553
+ reel_thumb_offset?: number | undefined;
554
+ __type?: "instagram" | "instagram-standalone" | undefined;
555
+ is_trial_reel?: boolean | undefined;
556
+ graduation_strategy?: "MANUAL" | "SS_PERFORMANCE" | undefined;
557
+ collaborators?: (string | {
558
+ label?: string | undefined;
559
+ username?: string | undefined;
560
+ handle?: string | undefined;
561
+ })[] | undefined;
562
+ user_tags?: (string | {
563
+ label?: string | undefined;
564
+ username?: string | undefined;
565
+ handle?: string | undefined;
566
+ })[] | undefined;
567
+ first_comment?: string | undefined;
568
+ media_alt_texts?: Record<string, string> | undefined;
569
+ } | undefined;
570
+ platform_settings?: z.objectInputType<{
571
+ __type: z.ZodOptional<z.ZodString>;
572
+ post_type: z.ZodOptional<z.ZodString>;
573
+ content_type: z.ZodOptional<z.ZodString>;
574
+ media_alt_texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
575
+ reel_cover_url: z.ZodOptional<z.ZodString>;
576
+ reel_thumb_offset: z.ZodOptional<z.ZodNumber>;
577
+ reply_settings: z.ZodOptional<z.ZodEnum<["everyone", "following", "mentionedUsers"]>>;
578
+ poll: z.ZodOptional<z.ZodObject<{
579
+ options: z.ZodArray<z.ZodString, "many">;
580
+ duration_minutes: z.ZodOptional<z.ZodNumber>;
581
+ }, "strip", z.ZodTypeAny, {
582
+ options: string[];
583
+ duration_minutes?: number | undefined;
584
+ }, {
585
+ options: string[];
586
+ duration_minutes?: number | undefined;
587
+ }>>;
588
+ reply_control: z.ZodOptional<z.ZodEnum<["everyone", "accounts_you_follow", "mentioned_only"]>>;
589
+ text_attachment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
590
+ text_format_preset_id: z.ZodOptional<z.ZodString>;
591
+ document_title: z.ZodOptional<z.ZodString>;
592
+ document_filename: z.ZodOptional<z.ZodString>;
593
+ mentions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
594
+ thumbnail_url: z.ZodOptional<z.ZodString>;
595
+ thumbnail_method: z.ZodOptional<z.ZodString>;
596
+ privacy_level: z.ZodOptional<z.ZodString>;
597
+ allow_comment: z.ZodOptional<z.ZodBoolean>;
598
+ allow_duet: z.ZodOptional<z.ZodBoolean>;
599
+ allow_stitch: z.ZodOptional<z.ZodBoolean>;
600
+ title: z.ZodOptional<z.ZodString>;
601
+ media_type: z.ZodOptional<z.ZodString>;
602
+ is_commercial_content: z.ZodOptional<z.ZodBoolean>;
603
+ is_your_brand: z.ZodOptional<z.ZodBoolean>;
604
+ is_branded_content: z.ZodOptional<z.ZodBoolean>;
605
+ privacy_status: z.ZodOptional<z.ZodEnum<["public", "unlisted", "private"]>>;
606
+ made_for_kids: z.ZodOptional<z.ZodBoolean>;
607
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
608
+ category_id: z.ZodOptional<z.ZodString>;
609
+ playlist_id: z.ZodOptional<z.ZodString>;
610
+ board_id: z.ZodOptional<z.ZodString>;
611
+ link: z.ZodOptional<z.ZodString>;
612
+ cover_image_url: z.ZodOptional<z.ZodString>;
613
+ video_cover_url: z.ZodOptional<z.ZodString>;
614
+ cover_image_method: z.ZodOptional<z.ZodEnum<["upload", "frame", "api"]>>;
615
+ event: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
616
+ offer: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
617
+ cta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
618
+ langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
619
+ }, z.ZodTypeAny, "passthrough"> | undefined;
620
+ }>;
225
621
  export declare const createPostInputSchema: z.ZodObject<{
226
622
  account_id: z.ZodOptional<z.ZodString>;
227
623
  username: z.ZodOptional<z.ZodString>;
@@ -455,7 +851,10 @@ export declare const createPostInputSchema: z.ZodObject<{
455
851
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
456
852
  }, z.ZodTypeAny, "passthrough">>>;
457
853
  workspace_id: z.ZodOptional<z.ZodString>;
854
+ } & {
855
+ confirm: z.ZodLiteral<true>;
458
856
  }, "strip", z.ZodTypeAny, {
857
+ confirm: true;
459
858
  workspace_id?: string | undefined;
460
859
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
461
860
  account_id?: string | undefined;
@@ -537,6 +936,7 @@ export declare const createPostInputSchema: z.ZodObject<{
537
936
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
538
937
  }, z.ZodTypeAny, "passthrough"> | undefined;
539
938
  }, {
939
+ confirm: true;
540
940
  workspace_id?: string | undefined;
541
941
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
542
942
  account_id?: string | undefined;
@@ -619,7 +1019,8 @@ export declare const createPostInputSchema: z.ZodObject<{
619
1019
  }, z.ZodTypeAny, "passthrough"> | undefined;
620
1020
  }>;
621
1021
  export type CreatePostInput = z.infer<typeof createPostInputSchema>;
622
- export declare function buildCreatePostPayload(input: CreatePostInput): Parameters<PosterlyClient['createPost']>[0];
1022
+ export type CreatePostPayloadInput = z.infer<typeof createPostPayloadInputSchema>;
1023
+ export declare function buildCreatePostPayload(input: CreatePostPayloadInput | CreatePostInput): Parameters<PosterlyClient['createPost']>[0];
623
1024
  export declare const createPostTool: {
624
1025
  name: string;
625
1026
  description: string;
@@ -856,7 +1257,10 @@ export declare const createPostTool: {
856
1257
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
857
1258
  }, z.ZodTypeAny, "passthrough">>>;
858
1259
  workspace_id: z.ZodOptional<z.ZodString>;
1260
+ } & {
1261
+ confirm: z.ZodLiteral<true>;
859
1262
  }, "strip", z.ZodTypeAny, {
1263
+ confirm: true;
860
1264
  workspace_id?: string | undefined;
861
1265
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
862
1266
  account_id?: string | undefined;
@@ -938,6 +1342,7 @@ export declare const createPostTool: {
938
1342
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
939
1343
  }, z.ZodTypeAny, "passthrough"> | undefined;
940
1344
  }, {
1345
+ confirm: true;
941
1346
  workspace_id?: string | undefined;
942
1347
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
943
1348
  account_id?: string | undefined;
@@ -70,7 +70,7 @@ export const platformSettingsSchema = z.object({
70
70
  // Bluesky
71
71
  langs: z.array(z.string()).optional(),
72
72
  }).passthrough();
73
- export const createPostInputSchema = z.object({
73
+ export const createPostPayloadInputSchema = z.object({
74
74
  account_id: z.string().optional().describe('Social account ID (from list_accounts)'),
75
75
  username: z.string().optional().describe('Account username (alternative to account_id)'),
76
76
  platform: z
@@ -106,8 +106,11 @@ export const createPostInputSchema = z.object({
106
106
  .optional()
107
107
  .describe('Workspace ID to assign the post to (from whoami). If omitted, uses the account\'s workspace or the caller\'s default workspace.'),
108
108
  });
109
+ export const createPostInputSchema = createPostPayloadInputSchema.extend({
110
+ confirm: z.literal(true).describe('Must be true after explicit user confirmation of the post/account/workspace/schedule.'),
111
+ });
109
112
  export function buildCreatePostPayload(input) {
110
- const { thread_posts, caption, post_type, instagram_settings, platform_settings, ...rest } = input;
113
+ const { confirm: _confirm, thread_posts, caption, post_type, instagram_settings, platform_settings, ...rest } = input;
111
114
  if (thread_posts && thread_posts.length > 0) {
112
115
  if (thread_posts.length < 2) {
113
116
  throw new Error('thread_posts must contain at least 2 entries');
@@ -158,6 +161,9 @@ export const createPostTool = {
158
161
  'TIKTOK MEDIA: TikTok supports a single video or a photo slideshow of 1 to 35 images, never multiple videos. Image media auto-detects as a slideshow, so you usually do not set post_type or media_type for photos and every image is posted. Pass `platform_settings.media_type: "PHOTO"` to force a slideshow explicitly.',
159
162
  inputSchema: createPostInputSchema,
160
163
  async execute(client, input) {
164
+ if (input.confirm !== true) {
165
+ throw new Error('Refusing to create post without confirm=true after explicit user confirmation.');
166
+ }
161
167
  const payload = buildCreatePostPayload(input);
162
168
  const { thread_posts, instagram_settings, platform_settings } = input;
163
169
  const result = await client.createPost(payload);
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import type { PosterlyClient } from '../lib/api-client.js';
3
- import { type CreatePostInput } from './create-post.js';
3
+ import { type CreatePostPayloadInput } from './create-post.js';
4
4
  export declare const createPostsBatchTool: {
5
5
  name: string;
6
6
  description: string;
@@ -401,7 +401,9 @@ export declare const createPostsBatchTool: {
401
401
  langs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
402
402
  }, z.ZodTypeAny, "passthrough"> | undefined;
403
403
  }>, "many">;
404
+ confirm: z.ZodLiteral<true>;
404
405
  }, "strip", z.ZodTypeAny, {
406
+ confirm: true;
405
407
  posts: {
406
408
  workspace_id?: string | undefined;
407
409
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
@@ -485,6 +487,7 @@ export declare const createPostsBatchTool: {
485
487
  }, z.ZodTypeAny, "passthrough"> | undefined;
486
488
  }[];
487
489
  }, {
490
+ confirm: true;
488
491
  posts: {
489
492
  workspace_id?: string | undefined;
490
493
  platform?: "instagram" | "instagram-standalone" | "facebook" | "tiktok" | "twitter" | "threads" | "linkedin" | "youtube" | "pinterest" | "google_business" | "telegram" | "bluesky" | "gmb" | "google-business" | "google_business_profile" | "x" | undefined;
@@ -569,6 +572,7 @@ export declare const createPostsBatchTool: {
569
572
  }[];
570
573
  }>;
571
574
  execute(client: PosterlyClient, input: {
572
- posts: CreatePostInput[];
575
+ posts: CreatePostPayloadInput[];
576
+ confirm: true;
573
577
  }): Promise<string>;
574
578
  };